Я пытаюсь сделать тест пересечения луч-треугольник, как это делается на 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], я получаю значение -10 вместо +10 для t.
Поэтому, когда я решаю использовать t для получения точки пересечения, z-значение всегда переворачивается, я не был уверен, было ли это как-то связано с системой координат в opengl или у меня где-то была ошибка в моем коде ?? Я довольно тщательно просмотрел свой код, чтобы убедиться, что выполняю макрооперации, такие как vector, crossproduct, innerProduct и т. Д., Так же, как они делают это на сайте, и я не могу понять, что еще может быть не так!
Это код Java, я думаю, я просто надеялся получить объяснение, почему мой знак t неправильный, прежде чем просто добавить отрицательный знак в мои вычисления!
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);
}
Вам следует переделать свой метод 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;
Других решений пока нет …