射线与三角形求交的计算

来源:互联网 发布:99什么意思网络用语 编辑:程序博客网 时间:2024/04/29 21:57

将射线定义为一个基点和向量,那么射线上的任意点可以表示为P = P0 + tV,其中P0为基点,V为向量,t满足 t>=0.采用重心坐标定义三角形,三角形上的任意点可以表示为:P = w V0 + u V1 + v V2, 其中u+v+w = 1. 由此,将射线方程代入上式,则:

P0 + tV = (1 - (u+v)) V0 + uV1+vV2.

利用克莱姆法则计算得出t,u,v. 交点位于三角形内的条件为: 0 <= u <= 1, 0 <= v <= 1, 0 <= u+v <= 1. 否则位于三角形外部的平面上。

该方法是Moller, Trumbore与1997年提出的。

下面我们用代码实现(c++): 

 

当有大量射线和三角形求交的时候,计算是很耗时的。下面我们用TBB库来实现并行计算。我们使用TBB提供的parallel_for. 为了使用parallel_for,我们需要定义一个函数对象类来包装计算的代码:

 

 

 

在ParallelComputeIntersections2::operator()中,我们加入了一些代码来快速判断一条射线和一个三角形有没有可能相交。这些代码对于提高运算速度是很有用的。经过在我本地的数据集测试中(约2万个射线和2万个三角形),这个判断使原来18s的计算时间减少到15s.

下面是主函数

 

 

代码中使用了TBB提供的一个并行向量来存储运算结果。

使用上面提到的数据集测试,在我的双核笔记本上结果如下.

在没有加入快速判断代码的情况下:

 

顺序计算:38.25s

并行计算:18.57s

 

加入快速判断代码的情况下:

顺序计算:26.31s

并行计算:15.11s

 

默认TBB会根据当前CPU核的数量来设置并行任务数量。从结果来看,效果还是比较明显的。

原创粉丝点击