我有一个3D地形网格,每个网格的每个坐标(x,y,z)
都是已知的。现在,我有一个单调增加/减少的线,其起点也是已知的。我想找到地形和线相遇的点。算法是做什么的?
我能想到的是将3D地形的坐标存储在nxn
矩阵中。然后我会根据地形中的网格对线进行分段。然后我将从距离线最近的网格开始,然后尝试计算该平面是否与该线相交,如果是,则获取坐标并退出。如果不是,那么我将进入下一部分。
但我的算法是最好的还是最优的解决方案?或者是否有任何现有的库已经这样做了?
答案 0 :(得分:1)
不是直接和优化,只是一些提示:
如果您的网格很大,可能值得从您的地形构建octree,以便快速减少必须检查线路的网格节点数。这可以在一个巨大的网格(如512 * 512 ndoes)中更有效,因为只需要考虑光线通过的叶子节点。
此外,八叉树可用作判断网格部分是否可见的手段,因此必须通过检查视锥体中的哪些离开节点来绘制。
但是有一个问题:构建八叉树必须提前完成,花一些时间,树是静态的。它在构造之后不能轻易修改,因为一个节点中的修改可能会影响其他几个节点,而不一定是相邻的节点。
但是,如果您不打算在创建网格后对其进行修改,则八叉树将会有所帮助。
<强>更新强>
现在我明白你计划如何存储你的网格,我相信空间分区将是找到交叉线最近邻居的有效方法。
线性地查找最近的邻居具有O(N)的运行时复杂度,而如果O(log N),则空间分区应用程序具有平均运行时复杂度。
答案 1 :(得分:1)
另一种方法是对地形网格进行三角测量,以生成一组切面,然后将线与这些切面相交。
显然,您需要进行一些优化,例如只检查与线的边界框相交的那些面。你可以做一个相当便宜/快速的小平面边界框来进行边界框检查,它可以很快地打折地形中的大多数三角形。
如果你把三角形排列成一个八叉树(建议使用@ sum1stolemyname但是这些点),那么这个检查可以从“自上而下”完成,你应该能够用一个单一来折叠地形的整个部分计算
答案 2 :(得分:0)
如果地形不是通过一个很好的函数构建的,你将不得不做ray trace,即逐步遍历这条线以找到一个交叉点。此过程可能需要一些时间。
该程序有几个参数。例如。在每一步中都有行走的偏移量。如果偏移太大,可能会忽略地形的某些“高度”,从而得不到正确的交叉点。如果偏移量很小,则会减慢您的过程。
但是,有一个很好的技巧可以节省时间。它描述了here resp。 here。它为地形使用某种优化结构,即它通过以下方式构建几个级别的细节:最精细的细节层次只是地形本身。下一个(较粗略的)细节级别仅包含地形纹理中原始“像素”数量的四分之一,并将4个像素合并为一个,取最大值。下一级细节是类似地构建的:
. . . .
... . ... .. .
....... .... .. .
........ => .... => .. => .
01234567 0246 04 0
1357 26 4
fine => => => => => coarse
如果现在执行光线投射,首先,检查更粗糙的细节级别:
/
/
/.
.
.
.
如果射线已经错过粗略的细节水平,则不必检查更精细的水平。这只是一个非常粗略的想法,如何优化工作。但它运作得很好。实施它是相当多的工作,但是这篇论文是一个很好的帮助。