求三角形和线的交点.InterSection函数的方法
这个算法来自微软DirectX SDK.兰幽草推荐的.
基本算法都想明白了。就是那个t 为什么没有负号.我还没有想明白.不知道为什么 不过结果基本已经正确了。应该比较好用的。bool InterSection(XRay& ray,XTriangle& tri,XPoint& point,float& t, float& u, float& v )
{ // Find vectors for two edges sharing vert0 /***三角形为 v1,v2,v3 两条边为 e1 = v2-v1 e2 = v3 - v1 射线为 ray = p0 + d * t 三角形内部的一点 p = v1 + u * e1 + v * e2 ( u+v<1)
所以: v1 + u * e1 + v * e2 = p0 + d * t ===> u * e1 + v * e2 - t * d = p0 - v1 ===> - t * d + v * e2 + u * e1 = p0 - v1 ===>
| d.x d.y d.z | [-t,v,u] | e2.x e2.y e2.z | = p0 - p1 ===> | e1.x e1.y e1.z |
[-t,v,u] * M = p0 - p1 ;
[-t,v,u] = (p0 - p1) * Inv(M);
t = (p0 - p1) * e1 X e2 / Det(M) = (p0 - p1) X e1 * e2 / Det(M)
v = (p0 - p1) * e1 X d / Det(M) = (p0 - p1) X e1 * d / Det(M)
u = (p0 - p1) * d X e2 / Det(M)
**/
XVector3D e1 = tri.m_points[1] - tri.m_points[0]; XVector3D e2 = tri.m_points[2] - tri.m_points[0];//求出矩阵 M 的 det(M)。并记录 d x e2; XVector3D vCP_dir_e2; ray.m_Dir.cp(e2,vCP_dir_e2);
//得到矩阵的行列式的值
float det = e1.dp(vCP_dir_e2);//保存 (p0 - p1)
XVector3D v_p0_p1;//为了判断方便。det = abs(det)
if( det > 0 ) { v_p0_p1 = ray.m_Point - tri.m_points[0]; } else { v_p0_p1 = tri.m_points[0] - ray.m_Point ; det = -det; }if( det < 0.0000001f )
return false;// u = (p0 - p1) * d X e2 / Det(M) Det(M)以后再除
u = v_p0_p1.dp(vCP_dir_e2); if( u < 0.0f || u > det ) return false;// 保存 (p0 - p1) X e1 XVector3D vCP_p0p1_e1; v_p0_p1.cp(e1,vCP_p0p1_e1);
// v = (p0 - p1) * e1 X d / Det(M) = (p0 - p1) X e1 * d / Det(M) // Det(M)以后再除
v = ray.m_Dir.dp(vCP_p0p1_e1); if( v < 0.0f || u + v > det ) return false;// Calculate t, scale parameters, ray intersects triangle
t = e2.dp(vCP_p0p1_e1); float fInvDet = 1.0f / det; t *= fInvDet; u *= fInvDet; v *= fInvDet;point = ray.m_Point + ray.m_Dir*t;
return true;
}