3d 空间中的三角形三角形交点
Posted
技术标签:
【中文标题】3d 空间中的三角形三角形交点【英文标题】:Triangle Triangle Intersection in 3d-Space 【发布时间】:2009-09-30 05:13:37 【问题描述】:我正在处理一些 3D 几何图形。我需要找到三角形与另一个三角形的交点。
我可以使用什么算法?
【问题讨论】:
See also triangle-triangle here 【参考方案1】:许多人显然依赖于 2006 年在以下论文 (link to PDF) 中描述的方法的实现 (link to source code):
Tropp、Oren、Ayellet Tal 和 Ilan Shimshoni。 “一个快速的三角形 用于碰撞检测的三角形相交测试。” 计算机 动画和虚拟世界 17.5 (2006): 527-535。
然而,该代码存在一个问题(除了采用旧的编程风格、使用非常规符号并失去基本的几何解释):“决定性事物”不一定会使您的数学更健壮,如果以错误的方式完成.
我建议要么使用 Moeller 的方法 (link to PDF),要么查看 Delliver 的论文 (link to PDF),在 CGAL 库中实现 (link, "Triangle_3_Triangle_3_do_intersect.h")。
一个例子:上面实现的交集例程告诉三角形 (p0,p1,p2) 和 (q0,q1,q2) 由以下点定义
p0 = (-21, -72, 63)
p1 = (-78, 99, 40)
p2 = (-19, -78, -83)
q0 = (96, 77, -51)
q1 = (-95, -1, -16)
q2 = (9, 5, -21)
不相交。这是三角形的图片:
这里是代码sn-p(附加到原始代码):
#include <iostream>
inline void setPoint(double p[3], const double x, const double y, const double z)
p[0] = x; p[1] = y; p[2] = z;
inline void computeEdges(double v0[3], double v1[3], const double p0[3], const double p1[3], const double p2[3])
v0[0] = p1[0]-p0[0];
v0[1] = p1[1]-p0[1];
v0[2] = p1[2]-p0[2];
v1[0] = p2[0]-p0[0];
v1[1] = p2[1]-p0[1];
v1[2] = p2[2]-p0[2];
void main()
unsigned int numErrors(0), count(0);
double p0[3], p1[3], p2[3], q0[3], q1[3], q2[3];
double v0[3], v1[3], w0[3], w1[3];
bool res, answer;
int ret;
std::cout << "Testing the correctness of tr_tri_intersect3D" << std::endl;
// Non excluding triangles in generic positions, big determinants, intersecting
++count;
setPoint(p0, -21, -72, 63);
setPoint(p1, -78, 99, 40);
setPoint(p2, -19, -78, -83);
setPoint(q0, 96, 77, -51);
setPoint(q1, -95, -1, -16);
setPoint(q2, 9, 5, -21);
answer = true;
computeEdges(v0, v1, p0, p1, p2);
computeEdges(w0, w1, q0, q1, q2);
int ret = tr_tri_intersect3D(p0, v0, v1, q0, w0, w1);
bool res = ( ret != 0 );
if( res != answer )
std::cout << "# wrong answer on test " << count << "!\n";
++numErrors;
关于算术运算数量的最后说明:由于该方法采用输入预先计算的边缘向量,因此应将 12 个 +/- 运算添加到论文的表 I.中。
最后但同样重要的是:请自行验证我写的内容,如果您认为我误解了某些内容,请给我反馈!
【讨论】:
刚刚找到此代码,可能对寻求快速、已实现的交付者方法解决方案的人有用:raw.githubusercontent.com/erich666/jgt-code/master/Volume_08/…【参考方案2】:本文描述了一种实现方式:
http://knight.temple.edu/~lakaemper/courses/cis350_2004/etc/moeller_triangle.pdf
请注意,有不同的技术取决于您是想知道发生交叉点的点/线段,还是只知道是否发生了交叉点。本文将为您提供表示交叉点的线段。
【讨论】:
【参考方案3】:Devilers 等人的 paper 很好,标题为“Faster Triangle-Triangle Intersection Tests”——(是的,进行了谷歌搜索,但搜索关键字很重要......)
无论如何,他们的观点(与 MichaelM 回答中的 Moeller 论文相比)是,您确实应该通过对选定的 4 点组进行决定因素来获取您的组合信息(该论文描述了如何)。这样可以避免计算可能存在不一致问题的中间值,并且实际上可能不会更快......
您可以将这些行列式视为确定由 4 个点形成的四面体是右手的、左手的还是退化的(即平面)。该值还决定了 4 个点中的任何一个点是在其他三个点形成的平面的一侧还是另一侧,以及 4 个点中的任何两个所形成的(有向)线是在该平面的一侧还是另一侧。由其他两个组成的线。
长话短说,做决定性的事情会使你的数学更加健壮,如果你注意的话,通常可以将最初没有做决定性事情的算法转换成能做决定性事情的算法。或者,您可以直接阅读论文。
【讨论】:
以上是关于3d 空间中的三角形三角形交点的主要内容,如果未能解决你的问题,请参考以下文章