3D网格顶点的交点

时间:2012-04-21 05:15:28

标签: algorithm grid computational-geometry linear-algebra intersection

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

我需要一种算法来将光线与网格外部的原点和进入它的方向相交,与网格的元素相交。也就是说,光线可能会在这个巨大的网格中间移动,然后击中一个基元。由于网格的范围,迭代方法[编辑:(例如射线行进)]是不可接受的慢。我需要的是一些封闭形式的[编辑:恒定时间]解决方案,用于查找原始命中。

我想到的一种可能的方法是确定每次在某个模块化算术空间中的网格单元周围的八个坐标中的每一个上的每一个步骤朝向基元的光线会聚的量。然后,x,y和z除以光线的方向并取最小距离。除了直觉之外,我没有任何证据可以认为这可行,Google也没有帮助; “与网格相交”意味着与网格的相交。

注意:

  • 我真的只关心原始的表面法线(我可以很容易地发现给定距离交叉点,但我并不关心距离本身)。
  • 此时相交的原始类型并不重要。理想情况下,它将是一个盒子。第二选择,球体。但是,我假设无论使用什么算法都可以推广到其他原语,如果最坏的情况发生,那么无论如何这对于这个应用来说并不重要。

谢谢,
伊恩

4 个答案:

答案 0 :(得分:1)

这是另一个想法: 当所有x,y和z坐标都接近整数值时,光线只能击中基元。 如果我们考虑光线的参数方程,那么线上的点由

给出
p=p0 + t * v

其中p0是起点,v是光线的方向向量,我们可以绘制从光线到每个轴上的整数值的距离作为t的函数。 e.g:

dx = abs( ( p0.x + t * v.x + 0.5 ) % 1 - 0.5 )

这将产生三个锯齿图,其周期取决于方向向量的分量(例如,如果方向向量是(1,0,0),则x图将在0和0.5之间线性变化,周期为1,而其他图表将保持不变,无论p0是什么。

您需要找到t的第一个值,其中所有三个图都低于某个阈值级别,由基元的大小决定。因此,在检查更高频率的图之前,通过首先考虑具有最长(非无限)周期的图,可以大大减少要检查的t值的数量。

我无法摆脱这样的感觉:根据三个地块的周期来计算正确的t值是可能的,但是我无法想出任何没有被起始位置破坏的东西而不是作为原点,门槛值不为零。 : - /

答案 1 :(得分:0)

基本上,您需要做的是以函数的形式表达这一行。从那里,您将在数学上必须计算光线是否与每个对象相交,然后确定它是否确保您获得与最靠近源的光线相撞的光线。

这并不快,所以你必须在这里做很多优化。最明显的是使用边界框而不是实际形状。从那里,你可以做一些事情,比如使用八叉树或BST(二进制空间分区)。

嗯,无论如何,我可能会忽略一些可能因为您对系统的额外限制而变得可能的东西,但这就是我必须为一门课程制作光线追踪器的方法。

答案 2 :(得分:0)

你在问题​​中指出迭代解决方案的速度慢得令人无法接受 - 我认为你的意思是在测试网格中每个对象的意义上的迭代。

在线相交的网格立方体上迭代,并为每个立方体测试立方体相交的8个对象。请Bresenham's line drawing algorithm查看如何找到线相交的多维数据集。 请注意,Bresenham不会完全返回光线相交的每个立方体,但是为了找到要测试的基元,我相当确定它是否足够好。 它也有很好的属性:

  1. 非常简单 - 如果你在GPU上运行它会很方便
  2. 沿光线迭代返回结果,因此您可以在找到匹配后立即停止。

答案 3 :(得分:0)

尝试这种方法:

  1. 确定光线的功能;

  2. 假设网格在z轴的不同平面上划分,光线将与每个“z平面”(同一高度的网格节点所在的平面)相交,您可以轻松地计算坐标(x,y,z)来自射线函数的交叉点;

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

  4. 但是光线可能与z平面之间的立方体/球体相交,因此您需要在x,y轴上重复1-3步。这样可以确保不会遗漏任何交叉点。

  5. 扔掉从x,y,z方向搜索中找到的重复立方体/球体。