线 - 三角交点检查返回错误的交点

时间:2017-08-13 16:21:46

标签: java math 3d geometry intersection

我正在用三角形物体为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的那条线有什么问题?

1 个答案:

答案 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),错误的符号就无关紧要了。