测试雷三角交叉口

时间:2012-04-14 16:02:53

标签: java math 3d intersection raycasting

我在3D空间中有一组三角形被渲染,一个点(X,Y)在屏幕坐标中,我想找到3D场景中哪个三角形(如果有的话)与它最近的交点。

我知道一般的方法是首先创建一个方向为R和原点Ro的光线。然后由三角形定义的平面上的交点将是Ip = Ro + tR,其中t是某个标量。根据我的理解,一旦找到t的值,则必须使用Areal坐标alpha,beta,gamma来检查交点是否在三角形内部,其中如果0 <= alpha,beta,gamma&lt,则该点在三角形内部; = 1

我的实现是在java中,我的屏幕坐标是使用找到的here

的openGL转换策略计算的

我不需要我的解决方案特别有效,最简单的策略会很好

我知道这是一个标准的问题,我读了一下,有一个问题here指向一些幻灯片here,但他们没有回答我的特定问题。还有另一个here建议使用我没有的openGL函数和互联网上无数的演讲幻灯片,但没有一个回答我的所有问题(或者至少不是我能理解的方式: - ))

问题

如何计算光线的方向?
我一直在使用这些University of Calgary slides

中描述的方法
Vector Du = lookVector.cross(upVector).normalise()  
Vector Dv = lookVector.cross(Du).normalise()  

Float f = width / (2*Math.tan((0.5 * fieldOfView) * Math.PI/180))  
Vector Vp = lookVector.normalise()

Vp.x = Vp.x*f - 0.5 *(width*Du.x + height*Dv.x)
Vp.y = Vp.y*f - 0.5 *(width*Du.y + height*Dv.y)
Vp.z = Vp.z*f - 0.5 *(width*Du.z + height*Dv.z)

然后:

directionVector = new Vector(i*Du.x + j*Dv.x + Vp.x, i*Du.y + j*Dv.y + Vp.y, i*Du.z + j*Dv.z + Vp.z)

其中i和j是循环计数器,对应屏幕上的X,Y点

首先,这是生成光线方向的正确(或最简单)方法吗?如果没有,那是什么?

问题:
我没有lookVector。我的cameria方向存储为围绕主轴的三个旋转(以度为单位)。我尝试使用(0,0,-1),因为我的实现基于openGL,而openGL中的摄像头和openGL'camera'始终指向那个方向。这是有效还是我需要从我的角度计算出一个向量,如果有的话,怎么做?

我没有fieldOfView的值,因为在openGL设置中没有提到它(或者没有提到它)。我可以忽略这一步吗?或者我是否需要解决这个问题,如果是这样,怎么做?

我应该在世界坐标或眼睛坐标中进行测试吗?

我应该在开始比较之前将三角形顶点转换为眼睛坐标,因此在原点处有一个眼睛/摄像头位置吗?或者将所有东西保存在世界坐标中?

如何找到交叉点?
我一直在工作Stanford sildes

我们有一条光线,

Ro + tR

平面A上的一个点及其正常N,它给出了我们

t = ((A - Ro).dotProduct(N)) / R.dotProduct(N)

这种做法是否正确?

如何测试它是否在三角形内?

相同的斯坦福幻灯片表明我们可以通过检查来测试交叉点是否在三角形(A,B,C)内:

R.dotProduct(N)  
((A-Ro)cross(B-Ro)).dot(R) > 0  
((A-Ro)cross(C-Ro)).dot(R) > 0  
((B-Ro)cross(C-Ro)).dot(R) > 0  

这种做法是否正确?

0 个答案:

没有答案