我正在用三角形物体为3D场景编写一个非常基本的raycaster,一切正常,直到我决定尝试从场景原点(0/0/0)以外的点投射光线。
但是,当我将光线的原点更改为(0/1/0)时,相交测试突然为其中一个三角形返回了错误的交点。
我故意将射线“射击”到三角形中心的方向,所以很明显这应该是交点。我只是不知道在我的代码中究竟是什么导致了错误的结果。
(我现在不是在使用Möller-Trumbore,因为我想从更简单,更基本的方法开始,但在优化代码时我会切换到Möller-Trumbore。)
这是我上面提到的三角形的三个顶点的坐标:
-2.0 / 2.0 / 0.0 | 0.0 / 3.0 / 2.0 | 2.0 / 2.0 / 0.0
这是三角形的中心:
0.0 / 2.3333333333333335 / 0.6666666666666666
这是我的光线(原点+ t *方向):
原产地:0.0 / 1.0 / 0.0
方向(标准化):0.0 / 0.894427190999916 /0.4472135954999579
这是我的程序计算出的明显错误的交叉点(在检查并发现该点甚至不在三角形上之前:
0.0 / 5.0 / 1.9999999999999996
所以,是的,不难看出(即使没有计算器)光线应该在大约t = 1.5的中心处击中三角形。但是,我的代码为t。
返回值4.472135954999579这是交叉检查的代码:
public Vector intersectsWithTriangle(Ray ray, Triangle triangle) {
boolean intersects = false;
Vector triangleNormal = triangle.getNormalVector();
double normalDotRayDirection = triangleNormal.dotProduct(ray.getDirection());
if(Math.abs(normalDotRayDirection) == 0) {
// parallel
return null;
}
double d = triangleNormal.dotProduct(triangle.getV1AsVector());
double t = (triangleNormal.dotProduct(ray.getOrigin()) + d) / normalDotRayDirection;
// Check if triangle is behind ray
if (t < 0) return null;
// Get point of intersection between ray and triangle
Vector intersectionPoint = ray.getPosAt(t);
// Check if point is inside the triangle
if(isPointInTriangle(intersectionPoint, triangle, triangleNormal)) {
intersects = true;
return intersectionPoint;
}
return null;
}
任何想法计算t的那条线有什么问题?
答案 0 :(得分:1)
如果光线由o + t*v
给出,三角形平面由法线向量n
和点p
定义,那么我们正在寻找t
s.t. n*(o + t*v) = n*p
t = (n*p - n*o)/(n*v)
。所以你似乎有一个符号错误,t
的正确计算应该是:
double t = (d - triangleNormal.dotProduct(ray.getOrigin())) / normalDotRayDirection;
只要光线原点为(0,0,0)
,错误的符号就无关紧要了。