我一直在从事二维连续数据的可视化项目。您可以使用这种东西来研究2D map 上的海拔数据或温度模式。从本质上讲,它实际上是将3维平面化为2维彩色的一种方法。在我的特定研究 Realm ,我实际上并没有使用地理海拔数据,但这是一个很好的隐喻,因此在本文中我将坚持使用。
无论如何,在这一点上,我有一个令我非常满意的“连续颜色”渲染器:
渐变是标准色轮,其中红色像素表示坐标较高,紫色像素表示坐标较低。
底层数据结构使用一些非常聪明的(如果我自己说的话)插值算法来实现对 map 细节的任意深度缩放。
在这一点上,我想绘制一些地形轮廓线(使用二次贝塞尔曲线),但是我还没有找到任何好的文献来描述找到这些曲线的有效算法。
为了让您了解我的想法,这是一个穷人的实现(渲染器在遇到与轮廓线相交的像素时仅使用黑色RGB值):
但是,这种方法存在一些问题:
因此,我正在寻找一种 vector 绘制方法,以获取那些漂亮的,完美的1像素厚的曲线。该算法的基本结构必须包括以下步骤:
但是即使在这些约束下,我仍然可以想到几种不同的启发式方法来寻找界限:
所以,这些是我的一些想法...
在深入研究实现之前,我想了解一下StackOverflow上的其他人是否有处理此类问题的经验,并可以为准确,高效的实现提供指导。
编辑:
我对ellisbben提出的“渐变”建议特别感兴趣。我的核心数据结构(忽略一些优化的插值快捷方式)可以表示为一组2D高斯函数的总和,这是完全可区分的。
我想我需要一个数据结构来表示三维斜率,以及一个用于在任意点计算斜率 vector 的函数。我不知道该怎么做(尽管看起来应该很容易),但是如果您有一个解释数学的链接,我将非常有义务!
更新:
由于ellisbben和Azim的出色贡献,我现在可以计算出该场中任意点的轮廓角。绘制真实的地形线将很快出现!
这是更新的渲染图,带有或不带有我一直使用的基于贫民窟栅格的拓 flutter 渲染器。每个图像包括一千个随机采样点,用红点表示。该点的轮廓角由白线表示。在某些情况下,无法在给定点测量斜率(基于插值的粒度),因此出现红点而没有相应的轮廓线。
请享用!
(注意:这些渲染使用的曲面拓 flutter 与以前的渲染不同-因为我在原型(prototype)制作时每次迭代都会随机生成数据结构-但是核心渲染方法是相同的,所以我确定您可以这个想法。)
这是一个有趣的事实:在这些渲染图的右侧,您会看到一堆怪异的轮廓线,它们的水平和垂直 Angular 都很完美。这些是插值过程的构件,该过程使用插值器网格来减少执行核心渲染操作所需的计算数量(减少约500%)。所有这些奇怪的轮廓线都出现在两个插值器网格单元之间的边界上。
幸运的是,这些 Artifact 实际上并不重要。尽管在斜率计算过程中可以检测到伪像,但最终渲染器不会注意到它们,因为它以不同的位深度进行操作。
再次更新:
Aaaaaaaand,作为我睡前的最后一个沉迷,这是另一对效果图,一个是老式的“连续颜色”风格,另一个是20,000个渐变样本。在这套渲染中,我消除了点样本的红点,因为它不必要地使图像困惑。
在这里,由于interpolator集合的网格结构,您可以真正看到我之前提到的那些插值 Artifact 。我要强调的是,这些伪像在最终轮廓渲染中将是完全不可见的(因为任意两个相邻插值器单元之间的幅度差小于渲染图像的位深度)。
胃口好!
最佳答案
gradient是可以帮助您的数学运算符。
如果您可以将插值转换为微分函数,则高度梯度将始终指向最陡峭的上升方向。所有等高曲线均垂直于在该点评估的高度梯度。
您关于从最高点开始的想法很明智,但是如果存在多个以上的局部最大值,则可能会错过功能。
我建议
关于algorithm - 绘制地形图,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/263305/