C# 在三维地形上,给定一条三维线,查找该线与地形之间的交点

C# 在三维地形上,给定一条三维线,查找该线与地形之间的交点,c#,graphics,C#,Graphics,我有一个3D地形网格,每个网格的坐标(x,y,z)都是已知的。现在,我有一条单调递增/递减的直线,它的起点也是已知的。我想找到地形和线的交汇点。算法是什么 我能想到的是将3D地形的坐标存储在nxn矩阵中。然后我会根据地形中的网格分割线。然后我将从离直线最近的网格开始,然后尝试计算该平面是否与直线相交,如果是,则获取坐标并退出。如果没有,那么我将进入下一节 但是我的算法是最好的,还是最好的解决方案?或者现有的库是否已经做到了这一点?不是直接的优化,只是一些提示: 如果网格较大,则可能值得从地形构

我有一个3D地形网格,每个网格的坐标
(x,y,z)
都是已知的。现在,我有一条单调递增/递减的直线,它的起点也是已知的。我想找到地形和线的交汇点。算法是什么

我能想到的是将3D地形的坐标存储在
nxn
矩阵中。然后我会根据地形中的网格分割线。然后我将从离直线最近的网格开始,然后尝试计算该平面是否与直线相交,如果是,则获取坐标并退出。如果没有,那么我将进入下一节


但是我的算法是最好的,还是最好的解决方案?或者现有的库是否已经做到了这一点?

不是直接的优化,只是一些提示:

如果网格较大,则可能值得从地形构建一个网格,以快速减少需要检查线的网格节点数。在一个巨大的网格中(比如512*512 ndoE),这可能会更有效,因为只需要考虑光线通过的叶节点

此外,八叉树还可以作为一种手段,通过检查视锥体中的哪些左节点来确定网格的哪些部分是可见的,因此必须进行绘制

不过有一个陷阱:构建八叉树必须提前完成,需要一些时间,而且树是静态的。在构造之后,无法轻松修改它,因为一个节点中的修改可能会影响其他几个节点,而不一定是相邻的节点

但是,如果您不打算在网格创建后修改网格,则八叉树将非常有用

更新

现在我了解了您计划如何存储网格,我相信空间分区将是找到相交线最近邻居的有效方法


线性查找最近邻的运行时复杂度为O(N),而空间分区方法的平均运行时复杂度为O(logn)。

如果地形不是通过一个好的函数构建的,则必须执行一个步骤,即一步一步地遍历直线以找到交点。这个过程可能需要一些时间

该过程有几个参数。例如,在每一步中都有沿直线行走的偏移量。如果偏移过大,可能会忽略地形的某些“高度”,从而无法获得正确的交点。如果偏移太小,则会减慢您的过程

然而,有一个很好的技巧来节省时间。它被描述为。它对地形使用某种优化结构,即,它通过以下方式构建多个细节级别:最精细的细节级别就是地形本身。下一个(更粗糙的)细节级别仅包含地形纹理中原始“像素”数量的四分之一,并将4个像素合并为一个,取最大值。下一个详细级别的构造类似于:

     .             .       .    .
    ... .         ...     ..    .
  .......        ....     ..    .
 ........    =>  ....  => .. => .

 01234567        0246     04    0
                 1357     26    4

   fine   =>  =>   =>   =>  =>  coarse
如果现在执行光线投射,首先会检查较粗糙的细节级别:

   /
  / 
 /.
  .
  .
  .

如果光线已经错过了粗略的细节级别,则无需检查更精细的级别。这只是一个非常粗略的优化工作原理。但它工作得相当好。实现这一点需要大量的工作,但本文是一个很好的帮助。

另一种方法是对地形网格进行三角化,以生成一组面,然后与这些面相交

显然,您需要进行一些优化,比如只检查与直线边界框相交的面。您可以执行一个非常便宜/快速的面边界框到线边界框检查,这将非常快地折扣地形中的大多数三角形


若你们把三角形排列成八叉树(如@sum1stolemyname所建议的,但对于点),那个么这个检查可以从“自上而下”进行,你们应该能够通过一次计算对地形的整个部分进行折扣。

不确定你们为什么建议使用八叉树,但因为我已经有了一个z坐标矩阵,我可以很容易地检查这条线的哪一段,不是吗?@ngu soon hui:我不完全确定我是否理解如何在2x2矩阵中表示网格。2x2矩阵可以精确存储4个值-2行2列。你能澄清一下吗?我建议使用八叉树来快速消除地形中距离直线不太近而无法与直线相交的区域,以产生更多的“早期输出”,从而减少需要检查的线段数量。这与以下问题有关:如果使用三角形来表示格线四边形,当节点的四个角不在平面中时,可以避免出现问题(请考虑在对角线处折叠的正方形)。特别是当你使用OpenGL进行可视化时。@sum1stolemyname,我也想到了。但我的重点是找到最有效的算法来获得地形和线之间的交点,因为矩形网格非常适合在2x2矩阵中重复(为了便于访问哪个网格),这就是为什么我使用矩形网格。网格顶点的x,y坐标是有规律的间隔的,对吗?这是我从“网格”中了解到的,但我只是想检查一下。每个顶点的z是任意的,但是已知的。@LarsH,是的,x,y是有规则间隔的。你的第三个文档不可见。另外,我对光线跟踪不感兴趣,我只是想找到交点,仅此而已。1)在我的电脑上,它可以毫无问题地查看。2) 光线跟踪用于找到交点。@Ngu-光线跟踪只是算法的名称。您正在跟踪光线(线)的路径。在这种情况下,你只做一次。在更熟悉的用法(对于图像)中,您可以为