|
|
发表于 2006-3-31 21:04:00
|
显示全部楼层
Re:知道屏幕三角形的三个顶点坐标, 怎么检查点A是否在三
这是个直线和三角形相交的算法。
template <class Real>
bool IntrLine3Triangle3<Real>::Test ()
{
// compute the offset origin, edges, and normal
Vector3<Real> kDiff = m_rkLine.Origin - m_rkTriangle.V[0];
Vector3<Real> kEdge1 = m_rkTriangle.V[1] - m_rkTriangle.V[0];
Vector3<Real> kEdge2 = m_rkTriangle.V[2] - m_rkTriangle.V[0];
Vector3<Real> kNormal = kEdge1.Cross(kEdge2);
// Solve Q + t*D = b1*E1 + b2*E2 (Q = kDiff, D = line direction,
// E1 = kEdge1, E2 = kEdge2, N = Cross(E1,E2)) by
// |Dot(D,N)|*b1 = sign(Dot(D,N))*Dot(D,Cross(Q,E2))
// |Dot(D,N)|*b2 = sign(Dot(D,N))*Dot(D,Cross(E1,Q))
// |Dot(D,N)|*t = -sign(Dot(D,N))*Dot(Q,N)
Real fDdN = m_rkLine.Direction.Dot(kNormal);
Real fSign;
if (fDdN > Math<Real>::ZERO_TOLERANCE)
{
fSign = (Real)1.0;
}
else if (fDdN < -Math<Real>::ZERO_TOLERANCE)
{
fSign = (Real)-1.0;
fDdN = -fDdN;
}
else
{
// Line and triangle are parallel, call it a "no intersection"
// even if the line does intersect.
return false;
}
Real fDdQxE2 = fSign*m_rkLine.Direction.Dot(kDiff.Cross(kEdge2));
if (fDdQxE2 >= (Real)0.0)
{
Real fDdE1xQ = fSign*m_rkLine.Direction.Dot(kEdge1.Cross(kDiff));
if (fDdE1xQ >= (Real)0.0)
{
if (fDdQxE2 + fDdE1xQ <= fDdN)
{
// line intersects triangle
return true;
}
// else: b1+b2 > 1, no intersection
}
// else: b2 < 0, no intersection
}
// else: b1 < 0, no intersection
return false;
} |
|