三维三角形交叉口在3d空间

时间:2009-09-30 05:13:37

标签: algorithm 3d geometry intersection

我正在使用一些3d几何体。我需要找到三角形与另一个三角形的交点。

我可以使用什么算法?

3 个答案:

答案 0 :(得分:4)

本文介绍了一种实现方式:

http://knight.temple.edu/~lakaemper/courses/cis350_2004/etc/moeller_triangle.pdf

请注意,根据您是否想知道交叉点发生的点/线段,或者只是判断是否发生了交叉,有不同的技术。本文将为您提供代表交叉点的线段。

答案 1 :(得分:4)

很多人显然依赖于以下文章(link to source code)中2006年描述的方法的实施(link to PDF):

  

Tropp,Oren,Ayellet Tal和Ilan Shimshoni。 "快速三角形   用于碰撞检测的三角交叉测试。"电脑   动画与虚拟世界17.5(2006):527-535。

然而,该代码存在问题(除了采用旧的编程风格,使用非常规符号并且失去基本的几何解释):"行列式事物"如果做错了,不一定能让你的数学更加健壮。

我建议您使用默勒的方法(link to PDF)或查看在CGAL图书馆(link to PDF)中实施的Delliver的论文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)

相交。这是三角形的图片:

intersecting triangles

这是代码片段(附加到原始代码):

#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;
        }
    }

}

关于算术运算次数的最后说明:由于该方法采用输入预先计算的边缘向量,因此应在表I中添加12 +/-运算。

最后但同样重要的是:如果您认为我误解了某些内容,请自行核实我自己写的内容并给我反馈!

答案 2 :(得分:3)

Devillers等人有一个很好的paper标题为“更快的三角 - 三角交叉测试” - (是的,做了谷歌搜索,但搜索关键词很重要......)

无论如何,他们的观点(与迈克尔M的答案中的默勒论文相比)是,你真的应该通过选择4点组的决定因素得到你的组合信息(论文描述了如何)。这可以避免计算可能存在问题不一致的中间值,并且实际上可能不会更快......

您可以查看这些决定因素,确定4点形成的四面体是右手,左手还是退化(即平面)。该值还确定4个点中的任何一个是在由另外三个形成的平面的一侧还是另一侧,以及由4中的任何两个形成的(指向)线是在一侧还是在另一侧上。由另外两个人组成的线。

总而言之,做一个决定性的事情会使你的数学更加健壮,如果你注意,你通常可以将最初没有做决定性事物的算法转换成那些做的事情。或者,你可以阅读论文。