假设我有一个由三个坐标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;
}
答案 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
参数是否符合上述边缘条件