Algorithm 三维网格的交点';s顶点

Algorithm 三维网格的交点';s顶点,algorithm,grid,computational-geometry,linear-algebra,intersection,Algorithm,Grid,Computational Geometry,Linear Algebra,Intersection,想象一个巨大的3D网格(按程序定义,可能无限大;每边至少10^6个坐标)。在每个网格坐标处,都有一个基本体(例如,球体、长方体或其他简单的、易于数学定义的函数) 我需要一个算法来与光线相交,原点在网格外,方向进入网格,与网格元素相交。也就是说,光线可能穿过这个巨大的网格的一半,然后击中一个基本体。由于网格的范围,迭代方法[编辑:(如光线行进)]的速度慢得令人无法接受。我需要的是某种封闭形式的[EDIT:constant time]解决方案,用于查找原语命中 我想到的一种可能的方法是,在x、y和z

想象一个巨大的3D网格(按程序定义,可能无限大;每边至少10^6个坐标)。在每个网格坐标处,都有一个基本体(例如,球体、长方体或其他简单的、易于数学定义的函数)

我需要一个算法来与光线相交,原点在网格外,方向进入网格,与网格元素相交。也就是说,光线可能穿过这个巨大的网格的一半,然后击中一个基本体。由于网格的范围,迭代方法[编辑:(如光线行进)]的速度慢得令人无法接受。我需要的是某种封闭形式的[EDIT:constant time]解决方案,用于查找原语命中

我想到的一种可能的方法是,在x、y和z的模运算空间中,确定光线在每个时间步向围绕网格单元的八个坐标中的每一个基元收敛的量,然后除以光线的方向,取最小距离。除了直觉之外,我没有其他证据认为这是可行的,而谷歌也无济于事;“与栅格相交”指与栅格的面相交

注:

  • 我真的只关心基本体的曲面法线(我可以很容易地找到给定到交点的距离,但我不关心距离本身)
  • 此时,相交的基本体的类型并不重要。理想情况下,它应该是一个盒子。第二选择,球体。然而,我假设使用的任何算法都可以推广到其他原语,如果出现最坏的情况,这对这个应用程序来说都无关紧要
谢谢,

伊恩

基本上,你需要做的是以函数的形式表达这条线。从这里开始,你只需要从数学上计算光线是否与每个物体相交,然后如果它确实相交,你就可以得到它与最接近光源的物体

这不是很快,所以您必须在这里进行大量优化。最明显的是使用边界框而不是实际的形状。从那里,您可以使用八叉树或BST(二进制空间分区)之类的操作


好吧,不管怎么说,由于系统的额外限制,我可能忽略了一些东西,但这就是我如何为课程制作光线跟踪器的原因。

基本上,你需要做的是以函数的形式表达这条线。从这里开始,你只需要从数学上计算光线是否与每个物体相交,然后如果它确实相交,你就可以得到它与最接近光源的物体

这不是很快,所以您必须在这里进行大量优化。最明显的是使用边界框而不是实际的形状。从那里,您可以使用八叉树或BST(二进制空间分区)之类的操作


好吧,不管怎样,可能有一些我忽略了的东西,通过对系统的额外限制而成为可能,但这就是我必须为一个课程制作光线跟踪器的方法。

你在问题中说,迭代解决方案的速度慢得令人无法接受——我想你的意思是迭代,即根据直线测试网格中的每个对象

而是在直线相交的网格立方体上迭代,并对每个立方体测试立方体相交的8个对象。查看如何查找直线与哪个立方体相交。 请注意,Bresenham's不会绝对返回光线相交的每个立方体,但是为了找到要测试的基本体,我相当确信它足够好。 它还具有很好的特性:

  • 非常简单-如果您在GPU上运行它,这将非常方便
  • 沿光线以迭代方式返回结果,因此您可以在找到击中目标后立即停止

  • 你在问题中说,迭代解的速度慢得让人无法接受——我假设你指的是迭代,即根据直线测试网格中的每个对象

    而是在直线相交的网格立方体上迭代,并对每个立方体测试立方体相交的8个对象。查看如何查找直线与哪个立方体相交。 请注意,Bresenham's不会绝对返回光线相交的每个立方体,但是为了找到要测试的基本体,我相当确信它足够好。 它还具有很好的特性:

  • 非常简单-如果您在GPU上运行它,这将非常方便
  • 沿光线以迭代方式返回结果,因此您可以在找到击中目标后立即停止
  • 尝试以下方法:

  • 确定射线的作用

  • 假设网格在z轴上划分为不同的平面,光线将与每个“z平面”(相同高度的网格节点所在的平面)相交,您可以通过光线函数轻松计算相交点的坐标(x、y、z)

  • 滑动z平面,您可以轻松确定哪些交点位于立方体或球体中

  • 但是光线可能与z平面之间的立方体/球体相交,因此需要在x、y轴上重复1-3个步骤。这将确保不留下任何交叉口

  • 扔掉从x、y、z方向搜索中找到的重复立方体/球体

  • 尝试以下方法:

  • 确定射线的作用

  • 假设网格在z轴上划分为不同的平面,光线将与每个“z平面”(相同高度的网格节点所在的平面)相交,您可以通过光线函数轻松计算相交点的坐标(x、y、z)

  • 滑动z平面,您可以轻松确定哪些交点位于立方体或球体中

  • 但是光线可能与z平面之间的立方体/球体相交,因此需要在x、y轴上重复1-3个步骤。这将确保不存在交叉点
    p=p0 + t * v
    
    dx = abs( ( p0.x + t * v.x + 0.5 ) % 1 - 0.5 )