将高度图映射到基于网格的轮廓格式

时间:2012-02-28 12:28:53

标签: 2d contour terrain heightmap

我有以下格式的2D高度图

06 36 39 42 43 55 ... 
37 40 43 43 45 46 ...
40 43 44 45 46 48 ...
44 44 46 47 48 50 ...
41 44 45 47 48 48 ...
...

我需要将其重新映射为基于笑脸的轮廓格式(因此可以进一步映射为精灵)

. . . . | . . 
. . . . \ . . 
. . . / / . . 
. . . | . . . 
. . . | . . . 
. / - / . . . 

此处.表示平坦区域,|-直悬崖,/\悬崖角(每个代表2种不同的可能性)。

我尝试了一种标准的行进方格法,但发现只抽取3个邻居会导致相当多的问题,原因是相邻情况过载。 (注意下面的额外不直的悬崖)

. . . . | . \ 
. . . . \ \ .
. . . / / - .
. . . | - . .
. . . | . . .
. / - / . . .

我想要的是一些有助于处理此类事情的算法/方法的参考。我知道,使用某种深度优先搜索的轮廓行走是一种选择但尚未尝试过,并且宁愿将其作为最后的手段。还存在一些特征的表示问题,例如是否包括1个元素厚的悬崖脊或者忽略它们。另一个选择是通过生成的轮廓并更改它们以便它们平滑地组合在一起,但这看起来真的很笨拙......

1 个答案:

答案 0 :(得分:1)

创建插值/最佳拟合函数。你的模型应该是一个二维多项式(xy),其度数“恰到好处”:不要太高,以至于你会过度拟合所有东西,但不能太低,以免丢失细节。

现在,您可以通过设置f(x,y) = height来设置可以切片的数学函数。该等式的解是轮廓。您现在有两种选择,具体取决于您是否可以通过分析解决。

  • 假设您无法通过分析求解,您仍然可以轻松地找出曲线的近似值:
    • 首先将网格着色为f(x,y)>height,将黑色归为f(x,y)<height。请注意所有“过渡”区域,其中在大约&lt; 1网格内存在黑白过渡:这些是轮廓将位于的方格。
    • 随机选择一个过渡方,并在大约&lt; 1网格半径内搜索f(x,y)==height,以找到轮廓上的一个点。在那一点(不一定在网格上),我们计算梯度∇f(x,y) = (∂f/∂x, ∂f/∂y)(“上坡矢量”)。我们在任一方向上旋转90度:(∂f/∂y, -∂f/∂x):这种方式指向轮廓。我们非常缓慢(步长大小比网格小)跟踪轮廓。这将把我们带到轮廓周围。
    • 每次我们在此跟踪过程中通过网格框时,我们会将其标记为{|, - ,/,},具体取决于渐变平均指向的方向。 (如果邻居尚未标记,我们还必须将邻居标记为.;请参阅[*]。)
    • 请注意,之后可能仍会留下转换网格框!例如,如果你有两个山丘,你将填充一个圆圈,但轮廓是两个圆圈。在另一个随机(未标记)“过渡”网格框上重复上述过程(这就是为什么我们需要[*],否则我们可能会注意我们已经考虑过的点的邻居)。重复,直到没有更多未标记的“过渡”网格框。
    • 为您希望绘制为轮廓的每个height级别执行此操作,并且您已完成。
  • 您可能能够像对待圆锥曲线一样进行分析性解决,但这可能不太可能超出此问题的范围。如果您可以求解曲线,您可以使用各种技术对其进行“网格化”(例如,对其进行参数化,然后使用可能半个网格的步长沿着轮廓走,注意最近邻居)

(如果你的一个轮廓与另一个轮廓重叠,则轮廓高度之间的间距太小。如果你对给定的轮廓不满意,则可能性{ - ,|,/,}的范围太小。)< / p>