线-三角形交叉点检查 Returns 错误的交叉点

Line-Triangle Intersection Check Returns Wrong Intersection Point

我正在为带有三角对象的 3D 场景编写一个非常基本的光线投射器,一切正常,直到我决定尝试从场景原点 (0/0/0) 以外的点投射光线。

但是,当我将光线的原点更改为 (0/1/0) 时,相交测试突然返回了其中一个三角形的错误交点。

我故意"shooting"把光线射向三角形中心的方向,所以很明显这里应该是交点。我只是不知道究竟是什么导致我的代码出现错误结果。

(我目前没有使用 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 时击中三角形的中心。但是,我的代码 returns 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 的那条线有什么问题吗?

如果射线由o + t*v给出,三角形平面由法向量n和点p定义,那么我们正在寻找ts.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),错误的符号也没关系。