和问题所问的差不多。最好用伪代码回答并引用。正确的答案应该重视速度而不是简单。
Chris Lloyd
问问题
7663 次
4 回答
4
请参阅3D 中光线、线段、平面和三角形的交点。您可以找到对多边形进行三角剖分的方法。
如果你真的需要光线/多边形相交,它在实时渲染的 16.9 (第二版为 13.8)。
我们首先计算射线和[多边形的平面] 之间的交点
pie_p
,这很容易通过用x
射线替换来完成。
n_p DOT (o + td) + d_p = 0 <=> t = (-d_p - n_p DOT o) / (n_p DOT d)
如果分母
|n_p DOT d| < epsilon
是epsilon
非常小的数字,则认为射线平行于多边形平面并且不会发生相交。否则,p
计算射线和多边形平面的交点 :p = o + td
。此后,判断是否p
在多边形内的问题从三个维度减少到了两个维度……
有关详细信息,请参阅本书。
于 2008-11-23T09:24:49.273 回答
3
struct point
{
float x
float y
float z
}
struct ray
{
point R1
point R2
}
struct polygon
{
point P[]
int count
}
float dotProduct(point A, point B)
{
return A.x*B.x + A.y*B.y + A.z*B.z
}
point crossProduct(point A, point B)
{
return point(A.y*B.z-A.z*B.y, A.z*B.x-A.x*B.z, A.x*B.y-A.y*B.x)
}
point vectorSub(point A, point B)
{
return point(A.x-B.x, A.y-B.y, A.z-B.z)
}
point scalarMult(float a, Point B)
{
return point(a*B.x, a*B.y, a*B.z)
}
bool findIntersection(ray Ray, polygon Poly, point& Answer)
{
point plane_normal = crossProduct(vectorSub(Poly.P[1], Poly.P[0]), vectorSub(Poly.P[2], Poly.P[0]))
float denominator = dotProduct(vectorSub(Ray.R2, Poly.P[0]), plane_normal)
if (denominator == 0) { return FALSE } // ray is parallel to the polygon
float ray_scalar = dotProduct(vectorSub(Poly.P[0], Ray.R1), plane_normal)
Answer = vectorAdd(Ray.R1, scalarMult(ray_scalar, Ray.R2))
// verify that the point falls inside the polygon
point test_line = vectorSub(Answer, Poly.P[0])
point test_axis = crossProduct(plane_normal, test_line)
bool point_is_inside = FALSE
point test_point = vectorSub(Poly.P[1], Answer)
bool prev_point_ahead = (dotProduct(test_line, test_point) > 0)
bool prev_point_above = (dotProduct(test_axis, test_point) > 0)
bool this_point_ahead
bool this_point_above
int index = 2;
while (index < Poly.count)
{
test_point = vectorSub(Poly.P[index], Answer)
this_point_ahead = (dotProduct(test_line, test_point) > 0)
if (prev_point_ahead OR this_point_ahead)
{
this_point_above = (dotProduct(test_axis, test_point) > 0)
if (prev_point_above XOR this_point_above)
{
point_is_inside = !point_is_inside
}
}
prev_point_ahead = this_point_ahead
prev_point_above = this_point_above
index++
}
return point_is_inside
}
于 2008-11-23T12:28:08.577 回答
1
整本书的章节都致力于这个特殊的要求——在这里描述一个合适的算法太长了。我建议阅读任何数量的计算机图形学参考作品,特别是:
- 光线追踪简介,编辑。安德鲁·S·格拉斯纳,ISBN 0122861604
于 2008-11-23T09:37:49.437 回答
0
function Collision(PlaneOrigin,PlaneDirection,RayOrigin,RayDirection)
return RayOrigin-RayDirection*Dot(PlaneDirection,RayOrigin-PlaneOrigin)/Dot(PlaneDirection,RayDirection)
end
(PlaneDirection 是垂直于平面的单位向量)
于 2014-02-10T21:49:22.103 回答