我的 Ray-Triangle Intersection 代码是否正确?
Is my Ray-Triangle Intersection code correct?
我在这里问是否有人可以检查我的射线-三角形相交代码是否正确,或者我是否有一些错误,因为它似乎没有按预期工作。
Vector3f:
struct Vector3f
{
Vector3f(): x(0), y(0), z(0) { }
Vector3f(GLfloat a, GLfloat b, GLfloat c): x(a), y(b), z(c) { }
GLfloat x, y, z;
};
叉积和内积:
Vector3f CMath::CrossProduct(Vector3f a, Vector3f b)
{
Vector3f result;
result.x = (a.y * b.z) - (a.z * b.y);
result.y = (a.z * b.x) - (a.x * b.z);
result.z = (a.x * b.y) - (a.y * b.x);
return result;
}
GLfloat CMath::InnerProduct(Vector3f a, Vector3f b)
{
return (a.x * b.x) + (a.y * b.y) + (a.z * b.z);
}
射线-三角形相交检查:
bool CMath::RayIntersectsTriangle(Vector3f p, Vector3f d, Vector3f v0, Vector3f v1, Vector3f v2, Vector3f &hitLocation)
{
Vector3f e1, e2, h, s, q;
GLfloat a, f, u, v, t;
e1.x = v1.x - v0.x;
e1.y = v1.y - v0.y;
e1.z = v1.z - v0.z;
e2.x = v2.x - v0.x;
e2.y = v2.y - v0.y;
e2.z = v2.z - v0.z;
h = CrossProduct(d,e2);
a = InnerProduct(e1,h);
if(a > -0.00001 && a < 0.00001)
return false;
f = 1 / a;
s.x = p.x - v0.x;
s.y = p.y - v0.y;
s.z = p.z - v0.z;
u = f * InnerProduct(s,h);
if(u < 0.0 || u > 1.0)
return false;
q = CrossProduct(s,e1);
v = f * InnerProduct(d,q);
if(v < 0.0 || u + v > 1.0)
return false;
t = f * InnerProduct(e2,d);
if(t > 0.00001)
{
hitLocation.x = p.x + t * d.x;
hitLocation.y = p.y + t * d.y;
hitLocation.z = p.z + t * d.z;
return true;
}
else
return false;
}
只是检查这些功能是否有问题,以了解我的问题是否出在其他地方。
预先感谢您的帮助。
首先,我建议将 InnerProduct
重命名为 DotProduct
(参见 Dot product)。
你有一个由 3 个点 v0
、v1
和 v2
定义的平面和一个由点 p
和方向 d
定义的射线.
在伪代码中,平面与射线的交点为:
n = cross(v1-v0, v2-v0) // normal vector of the plane
t = dot(v0 - p, n) / dot(d, n) // t scale d to the distance along d between p and the plane
hitLocation = p + d * t
另见
当您将其应用于您的代码时,这意味着
Vector3f n = CrossProduct(e1, e2);
注意,由于 s
是 p - v0
(而不是 v0 - p
),光线方向的比例必须反转:
t = - InnerProduct(s, n) / InnerProduct(d, n)
我在这里问是否有人可以检查我的射线-三角形相交代码是否正确,或者我是否有一些错误,因为它似乎没有按预期工作。
Vector3f:
struct Vector3f
{
Vector3f(): x(0), y(0), z(0) { }
Vector3f(GLfloat a, GLfloat b, GLfloat c): x(a), y(b), z(c) { }
GLfloat x, y, z;
};
叉积和内积:
Vector3f CMath::CrossProduct(Vector3f a, Vector3f b)
{
Vector3f result;
result.x = (a.y * b.z) - (a.z * b.y);
result.y = (a.z * b.x) - (a.x * b.z);
result.z = (a.x * b.y) - (a.y * b.x);
return result;
}
GLfloat CMath::InnerProduct(Vector3f a, Vector3f b)
{
return (a.x * b.x) + (a.y * b.y) + (a.z * b.z);
}
射线-三角形相交检查:
bool CMath::RayIntersectsTriangle(Vector3f p, Vector3f d, Vector3f v0, Vector3f v1, Vector3f v2, Vector3f &hitLocation)
{
Vector3f e1, e2, h, s, q;
GLfloat a, f, u, v, t;
e1.x = v1.x - v0.x;
e1.y = v1.y - v0.y;
e1.z = v1.z - v0.z;
e2.x = v2.x - v0.x;
e2.y = v2.y - v0.y;
e2.z = v2.z - v0.z;
h = CrossProduct(d,e2);
a = InnerProduct(e1,h);
if(a > -0.00001 && a < 0.00001)
return false;
f = 1 / a;
s.x = p.x - v0.x;
s.y = p.y - v0.y;
s.z = p.z - v0.z;
u = f * InnerProduct(s,h);
if(u < 0.0 || u > 1.0)
return false;
q = CrossProduct(s,e1);
v = f * InnerProduct(d,q);
if(v < 0.0 || u + v > 1.0)
return false;
t = f * InnerProduct(e2,d);
if(t > 0.00001)
{
hitLocation.x = p.x + t * d.x;
hitLocation.y = p.y + t * d.y;
hitLocation.z = p.z + t * d.z;
return true;
}
else
return false;
}
只是检查这些功能是否有问题,以了解我的问题是否出在其他地方。 预先感谢您的帮助。
首先,我建议将 InnerProduct
重命名为 DotProduct
(参见 Dot product)。
你有一个由 3 个点 v0
、v1
和 v2
定义的平面和一个由点 p
和方向 d
定义的射线.
在伪代码中,平面与射线的交点为:
n = cross(v1-v0, v2-v0) // normal vector of the plane
t = dot(v0 - p, n) / dot(d, n) // t scale d to the distance along d between p and the plane
hitLocation = p + d * t
另见
当您将其应用于您的代码时,这意味着
Vector3f n = CrossProduct(e1, e2);
注意,由于 s
是 p - v0
(而不是 v0 - p
),光线方向的比例必须反转:
t = - InnerProduct(s, n) / InnerProduct(d, n)