段段交叉点

时间:2016-01-24 23:31:50

标签: c# math geometry

假设我有一个由三个坐标A,B和C定义的三角形和一个由3D欧几里德空间中的两个坐标D和E定义的线段。 让我们进一步假设该段与三角形相交。 现在,我需要找出线段在其“边界”处与三角形相交。 所以我的想法是取三角形的每个边缘(AB,BC和CA)并测试其中一个与段DE相交。问题是我没有找到段/段交叉的解决方案。我发现this一个,但它不起作用。非常感谢。

修改 根据MBo的回答,我实现了一个C#方法:

// return: 0 -> segment parallel to plane
// return: 1 -> segment intersects an edge of the face
// return: -1 -> segments intersects the interior or the triangle or not at all
public static int SegmentTriangleIntersection(Vector3D a, Vector3D b, Vector3D c, Vector3D d, Vector3D e)
{
    var ed = e - d;
    var ba = b - a;
    var ca = c - a;
    var ad = a - d;

    var det = (ed.X*-ba.Y*-ca.Z) + (-ba.X*-ca.Y*ed.Z) + (-ca.X*ed.Y*-ba.Z) - (ed.Z*-ba.Y*-ca.X) - (-ba.Z*-ca.Y*ed.X) -
                  (-ca.Z*ed.Y*-ba.X);

    if (Vector3D.IsNearlyEqual(det, 0)) // segment parallel to triangle
        return 0;

    var det_t = (ad.X * -ba.Y * -ca.Z) + (-ba.X * -ca.Y * ad.Z) + (-ca.X * ad.Y * -ba.Z) - (ad.Z * -ba.Y * -ca.X) - (-ba.Z * -ca.Y * ad.X) -
                    (-ca.Z * ad.Y * -ba.X);

    var t = det_t/det;
    if (t >= 0 & t <= 1) // segment intersects plane of triangle
    {
        var det_u = (ed.X*ad.Y*-ca.Z) + (ad.X*-ca.Y*ed.Z) + (-ca.X*ed.Y*ad.Z) - (ed.Z*ad.Y*-ca.X) - (ad.Z*-ca.Y*ed.X) -
                        (-ca.Z*ed.Y*ad.X);
        var u = det_u/det;
        var det_v = (ed.X*-ba.Y*ad.Z) + (-ba.X*ad.Y*ed.Z) + (ad.X*ed.Y*-ba.Z) - (ed.Z*-ba.Y*ad.X) -
                        (-ba.Z*ad.Y*ed.X)-(ad.Z*ed.Y*-ba.X);
        var v = det_v/det;

        if (Vector3D.IsNearlyEqual(u, 0) && v >= 0 && v <= 1)
            return 1;
        if (Vector3D.IsNearlyEqual(v, 0) && u >= 0 && u <= 1)
            return 1;
        if (Vector3D.IsNearlyEqual(v + u, 1) && u >= 0 && v >= 0)
            return 1;
    }
    return -1;
}

1 个答案:

答案 0 :(得分:1)

让我们使用坐标参数方程(粗体矢量):

段DE:
sDE (t)= D + t *( E - D )= D + t * ED
// ED = E - D

段AB:
sAB (u)= A + u *( B - A )= A + u * BA

段AC:
sAC (v)= A + v *( C - A )= A + u * CA

ABC三角形的平面用双参数方程描述:
pABC (u,v)= A + u * BA + v * CA

坐标(u,v)在平面内的点位于三角形内,如果

u in range [0..1]
and 
v in range [0..1]
and
u+v is in range [0..1]

坐标(u,v)的点位于三角形边缘,如果 [边缘条件]

u = 0 and v in range [0..1]    //at AC edge
or
v = 0 and u in range [0..1]    //at AC edge
or
v + u = 1 and u in range (0..1) and v in range (0..1)      //at BC edge

现在让我们为DE段和ABC平面的交点编写等式

sDE (t)= pABC (u,v)
D + t * ED = A + u * BA + v * CA

我们可以求解最后一个方程(每个坐标的3个线性方程组)并找到参数t,u,v

D.X + t * ED.X = A.X + u * BA.X + v * CA.X
D.Y + t * ED.Y = A.Y + u * BA.Y + v * CA.Y
D.Z + t * ED.Z = A.Z + u * BA.Z + v * CA.Z

t * ED.X - u * BA.X - v * CA.X = A.X - D.X
t * ED.Y - u * BA.Y - v * CA.Y = A.Y - D.Y
t * ED.Z - u * BA.Z - v * CA.Z = A.Z - D.Z

首先找到该系统的行列式 - 如果它为零,则段与平面平行。

如果没有,请检查参数t。如果t在范围[0..1]

中,则段与平面相交

如果是,请检查u, v参数是否符合上述边缘条件