该框由两个点 Bmax(X_max, Y_max, Z_max) 和 Bmin(X_min, Y_min, Z_min) 定义。从这两点你可以确定盒子的剩余6个顶点,例如:(X_max,Y_max,Z_min),(X_max,Y_min,Z_max)等等......
圆柱体由其底边的两个中心 O1(x1,y1,z1)、O2(x2,y2,z2) 和半径 R 定义。
那些。圆柱体可以处于不同的角度,不一定处于严格的垂直位置,并且立方体始终严格沿轴对齐。
我的任务是确定圆柱体是否与立方体相交。
首先我想实现以下算法:
- 判断是否至少有一端在盒子内部,则相交
- 如果两端都在盒子外面,那么对于立方体的每个面,求平面方程,并检查平面是否与圆柱体相交。但这仍然不是我们检查平面是否与圆柱体相交的方法,我'我不确定这是正确的验证算法。
然后我找到了一个描述另一种算法的文档: https ://www.geometrictools.com/Documentation/IntersectionBoxCylinder.pdf
及其源代码:https://www.geometrictools.com/Downloads/Downloads.html文件 - (GTEngine 7.0 Distribution (ZIP))
我开始测试算法,但结果与预期结果不符。
我是如何测试的:
- 解压存档
- 打开解决方案GeometricTools\GTE\Samples\Intersection\IntersectBoxCylinder\IntersectBoxCylinderDX11.v16.sln
- 我开始调试并渲染场景:
了解 IntersectBoxCylinderWindow3.cpp 后,我意识到当一个盒子与圆柱体相交时,它会使用 TestIntersection() 方法变成红色。您还可以在 CreateScene() 方法中更改形状(长方体和圆柱体)的初始坐标和大小
我设置了拳击的参数:
mCylinder.axis.origin = { 0.0f, 0.0f, 1.5f }; // основание цилиндра
mCylinder.axis.direction = { 0.0f, 0.0f, 1.0f };// направление (можно вычислить если знаем координаты конца и начала)
mCylinder.radius = 1.0f; // радиус
mCylinder.height = 1.0f; // высота
mBox.center = { 0.5f, 0.5f, 0.5f }; // центр
mBox.axis[0] = { 1.0f, 0.0f, 0.0f }; // угол поворота бокса (в моем случае никогда не изменяется)
mBox.axis[1] = { 0.0f, 1.0f, 0.0f };
mBox.axis[2] = { 0.0f, 0.0f, 1.0f };
mBox.extent = { 0.5f, 0.5f, 0.5f }; // Эксцент
我们调试发现没有交集,但算法修复了它并使框变为红色
- 我通过编写以下代码检查了同样的事情:
#include <iostream>
#include "Mathematics/IntrAlignedBox3Cylinder3.h"
#include "Mathematics/Cylinder3.h"
#include "Mathematics/Vector3.h"
#include "Mathematics/Vector.h"
#include "Mathematics/AlignedBox.h"
#include <cmath>
#include <limits.h>
#include <float.h>
// расстояние между точками в пространстве
static double PointPointDistance(Vector3<double> const& point1, Vector3<double> const& point2)
{
return sqrt(pow(point1[0] - point2[0], 2) + pow(point1[1] - point2[1], 2) + pow(point1[2] - point2[2], 2));
}
int32_t main()
{
// центры оснований
Vector3<double> start = {0,0,1.5};
Vector3<double> end = {0,0,2.5};
// высота цилиндра
double height = PointPointDistance(start, end);
// направление цилиндра
Vector3<double> dir = end - start;
Normalize(dir);
Cylinder3<double> cylinder;
cylinder.axis.direction = dir;
cylinder.axis.origin = start;
cylinder.radius = 1;
cylinder.height = height;
AlignedBox3<double> box;
// минимальная/максимальная вершина
box.min = { 0,0,0 };
box.max = { 1,1,1 };
// хит тест
TIQuery<double, AlignedBox3<double>, Cylinder3<double>> mQuery;
bool result = mQuery(box,cylinder).intersect;
return 0;
}
结果也是如此,虽然事实上并非如此
此外,其他几个测试也失败了
我没有找到任何其他具有实现的库,因此我无法自己实现该算法。
有知道的分享一下方法