简体   繁体   English

在3D地形上,给定3D线,找到线和地形之间的交点

[英]On a 3D Terrain, Given a 3D Line, Find the Intersection Point Between the Line and the Terrain

I have a grid of 3D terrain, where each of the coordinate (x,y,z) of each grid are known. 我有一个三维地形网格,每个网格的每个坐标(x,y,z)都是已知的。 Now, I have a monotonously increasing/ decreasing line, which its start point is also known. 现在,我有一个单调增加/减少的线,其起点也是已知的。 I want to find the point where the terrain and the line meets. 我想找到地形和线相遇的点。 What is the algorithm to do it? 算法是做什么的?

What I can think of is to store the coordinate of the 3D terrain in a nxn matrix. 我能想到的是将3D地形的坐标存储在nxn矩阵中。 And then I would segmentize the line based on the grid in the terrain. 然后我会根据地形中的网格对线进行分段。 I would then start with the grid that is the nearest to the line, and then try to compute whether that plane intersects with the line, if yes, then get the coordinate and exit. 然后我将从距离线最近的网格开始,然后尝试计算该平面是否与该线相交,如果是,则获取坐标并退出。 If no, then I would proceed to the next segment. 如果不是,那么我将进入下一部分。

But is my algorithm the best, or the most optimum solution? 但我的算法是最好的还是最优的解决方案? Or is there any existing libraries that already do this? 或者是否有任何现有的库已经这样做了?

Not directly and optimisation, just a few hints: 不是直接和优化,只是一些提示:

If your grid is large, it might be worthwhile to build an octree from your terrain in order to quickly reduce the number of grid nodes you have to check your line against. 如果您的网格很大,那么从您的地形构建八叉树可能是值得的,以便快速减少必须检查线路的网格节点的数量。 This can be more efficient in a huge grid( like 512*512 ndoes) since only the leafnodes your ray is passing through have to be considered. 这可以在巨大的网格(如512 * 512 ndoes)中更有效,因为只需要考虑光线穿过的叶子节点。

Additionally, the Octree can be used as a means to decide wich parts of your grid are visible and therefore have to be drawn, by checking which leave-nodes are in the viewing frustum. 此外,八叉树可用作判断网格部分是否可见的手段,因此必须通过检查视锥体中的哪些离开节点来绘制。

There is a catch, though: building the Octree has to be done in advance, taking some time, and the tree is static. 但是有一个问题:构建八叉树必须提前完成,花一些时间,树是静态的。 It can not be easyly modified after it has been constructes, since a modification in one node might affect several other nodes, not necessarily adjacent ones. 它在构造之后不能轻易修改,因为一个节点中的修改可能会影响其他几个节点,而不一定是相邻的节点。

However, if you do not plan to modify your grid once it is created an octree will be helpful. 但是,如果您不打算在创建网格后对其进行修改,则八叉树将非常有用。

UPDATE UPDATE

Now that i understand how you are planning to store your grid, i believe space partitioning will be an efficent way to find the nearest neighbour of the intersection line. 现在,我了解您计划如何存储您的网格,我相信空间分区将是一种有效的方式来找到交叉线的最近邻居。

Finding the nearest Neighbour linearly has a runtime complexity of O(N), while space-partitioning appoaches have an average runtime complexity if O(log N). 线性地查找最近的邻居具有O(N)的运行时复杂度,而如果O(log N),则空间分区应用具有平均运行时复杂度。

A different approach would be to triangulate the terrain grid to produce a set of facets and then intersect the line with those. 一种不同的方法是对地形网格进行三角测量,以生成一组切面,然后将线与这些切线相交。

Obviously you'd need to do some optimisations like only checking those facets that intersect the bounding box of the line. 显然,您需要进行一些优化,例如只检查与线的边界框相交的那些面。 You can do a quite cheap/quick facet bounding box to line bounding box check which will discount most of the triangles in the terrain very quickly. 你可以做一个非常便宜/快速的小平面边界框到行边界框检查,这将很快折扣地形中的大多数三角形。

If you arrange your triangles in to an octree (as @sum1stolemyname suggested but for the points) then this checking can be done from the "top down" and you should be able to discount whole sections of the the terrain with a single calculation. 如果你将三角形排列成一个八叉树(建议使用@ sum1stolemyname但是对于点),那么这个检查可以从“自上而下”完成,你应该能够通过一次计算来折叠地形的整个部分。

If the terrain is not built via a nice function you will have to do a ray trace , ie traverse the line step by step in order to find an intersection. 如果地形不是通过一个很好的功能构建的,则必须进行光线跟踪 ,即逐步遍历线以找到交叉点。 This procedure can take some time. 此过程可能需要一些时间。

There are several parameters for the procedure. 该过程有几个参数。 Eg there is the offset you walk alogn the line in each step. 例如,在每一步中都有行走的偏移量。 If you take an offset too large, you might leave out some "heights" of your terrain and thus not get the correct intersection. 如果偏移太大,可能会忽略地形的某些“高度”,从而得不到正确的交叉点。 If the offset is to small, it will slow down your procedure. 如果偏移量很小,则会减慢您的过程。

However, there is a nice trick to save time. 但是,有一个很好的技巧可以节省时间。 It's described here resp. 这里描述它。 here . 在这里 It uses some kind of optimization structure for the terrain, ie it builds several levels of details the following way: The finest level of detail is just the terrain itself. 它为地形使用某种优化结构,即它通过以下方式构建多个级别的细节:最精细的细节层次只是地形本身。 The next (coarser) level of detail contains just a forth of the number of original "pixels" in the terrain texture and combines 4 pixels into one, taking the maximum. 下一个(较粗略的)细节级别仅包含地形纹理中原始“像素”数量的四分之一,并将4个像素合并为一个,取最大值。 The next level of detail is constructed analoguesly: 下一级细节是类似地构建的:

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

 01234567        0246     04    0
                 1357     26    4

   fine   =>  =>   =>   =>  =>  coarse

If now the ray cast is performed, first of all, the coarser levels of detail are checked: 如果现在执行光线投射,首先,检查更粗糙的细节级别:

   /
  / 
 /.
  .
  .
  .

If the ray already misses the coarse level of detail, no finer level has to be examined. 如果光线已经错过了粗略的细节水平,则不必检查更精细的水平。 That's just a very rough idea how the optimisation works. 这只是一个非常粗略的想法,如何优化工作。 But it works quite well. 但它运作得很好。 Implementing it is quite a bunch of work, but the paper is a good help. 实施它是相当多的工作,但是这篇论文是一个很好的帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM