Ray-Triangle交叉阴性结果

时间:2017-10-29 22:11:32

标签: java c++ vector lwjgl picking

我试图像https://www.scratchapixel.com/lessons/3d-basic-rendering/ray-tracing-rendering-a-triangle/ray-triangle-intersection-geometric-solution

那样进行射线三角交叉测试

我认为一切正常,除了我得到的t值与我的预期相反。例如,当我测试具有顶点v0 [-1,-1,-10],v1 [1,-1,-10],v2 [0,1,-10]和点(p)[0的三角形时, 0,0]和方向向量(d)[0,0,-1],I' m得到-10的值而不是+10的值。

所以当我解决使用t得到交点时,z值总是被翻转,我不确定这是否与opengl中的坐标系有关,或者我的代码中是否有错误某处??我彻底检查了我的代码,以确保我正在执行像vector,crossproduct,innerProduct等宏操作,就像在网站上一样,我无法弄清楚还有什么可能是错的!

这是java代码,我想我只是希望得到一个解释为什么我的错误符号之前我只是在计算中添加一个负号!

public static boolean RayTriangleIntersectionTest(Vector3f p, Vector3f d, Vector3f v0, Vector3f v1, Vector3f v2)
        {
            Vector3f e1 = VectorFromPoints(v0, v1);
            Vector3f e2 = VectorFromPoints(v0, v2);

            Vector3f h = CrossProduct(d, e2);
            double a = DotProduct(e1, h);

            if (a > -0.00001 && a < 0.00001)
                return false;

            double f = 1.0 / a;

            Vector3f s = VectorFromPoints(v0, p);
            double u = f * DotProduct(s, h);

            if (u < 0.0 || u > 1.0)
                return (false);

            Vector3f q = CrossProduct(s, e1);
            double v = f * DotProduct(p, q);

            if (v < 0.0 || u + v > 1.0)
                return (false);

            // at this stage we can compute t to find out where the intersection point is on the line
            double t = f * DotProduct(e2, q);

            if (t > 0.00001) // ray intersection
                return (true);
            else // line intersection but not a ray intersection
                return (false);
        }

public static Vector3d CrossProduct(Vector3f v0, Vector3f v1)
        {
            Vector3f Vout = new Vector3f();

            Vout.x = v1.y * v0.z - v0.y * v1.z;
            Vout.y = v1.x * v0.z - v0.x * v1.z;
            Vout.z = v1.x * v0.y - v0.x * v1.y;

            return Vout;
        }

        public static double DotProduct(Vector3f v0, Vector3f v1)
        {
            return v0.x * v1.x + v0.y * v1.y + v0.z * v1.z;
        }

        public static Vector3d VectorFromPoints(Vector3f v0, Vector3f v1)
        {
            return new Vector3f(v1.x - v0.x, v1.y - v0.y, v1.z - v0.z);
        }

1 个答案:

答案 0 :(得分:0)

您应该重写您的CrossProduct()方法。它有时会交换v0和v1。 正确的版本是:

Vout.x = v1.z * v0.y - v0.z * v1.y;
Vout.y = v1.x * v0.z - v0.x * v1.z;
Vout.z = v1.y * v0.x - v0.y * v1.x;