【发布时间】:2016-03-23 17:14:25
【问题描述】:
我有应绘制在等高线图中的二维强度数组形式的数据。最后,它应该看起来像带有等高线的地形图,如下图所示:
这个想法是典型的多点触控手势(捏缩放,拖动移动)可用于导航等高线图。数据的最大大小应该在 4k*4k 点左右,每个点 4 字节大。
是否有一些我可以使用的绘图库,或者我必须从头开始?有没有容易实现的算法?
【问题讨论】:
我有应绘制在等高线图中的二维强度数组形式的数据。最后,它应该看起来像带有等高线的地形图,如下图所示:
这个想法是典型的多点触控手势(捏缩放,拖动移动)可用于导航等高线图。数据的最大大小应该在 4k*4k 点左右,每个点 4 字节大。
是否有一些我可以使用的绘图库,或者我必须从头开始?有没有容易实现的算法?
【问题讨论】:
我不知道任何适用于 Android(或 Java)的绘图库,但我确实知道一两点关于绘图的一般知识:
创建轮廓的简单算法是Marching Squares。 Marching squares 从您的数据数组中创建多边形。 Java 中应该有很多这种算法的示例(尝试Google Code Search,但在使用之前请阅读许可证)。
如果你想放大很远,你可能想从这些多边形中创建 贝塞尔曲线 来平滑它们,可以找到一个示例算法(带有应该很容易移植到 Java 的代码)@ 987654323@.
注意:如果你想用颜色填充轮廓,你应该考虑使用片段着色器而不是创建多边形。将数据作为纹理发送到着色器,并使用强度为每个像素分配颜色。为此,您应该了解一些 OpenGL。
【讨论】:
正如@Markus Johnsson 所说,可视化二维数据数组的一种方法是使用 Marching Squares 算法。但在您的情况下,您似乎需要基于 isolines 而不是 isobands (使用 Markus 提到的多边形)的实现。
基于等值线的实现更容易从头开始编写。这主要是因为您必须仅检查给定值是否低于或高于特定等值(相对于等带实现中的低于-高于特定范围)。这仅会导致在单个 isocell 中绘制 16 种可能的线配置(与 isobands 实现中的 80 个多边形配置相比)。
在创建等高线图之前,通常需要对数据进行插值。一种方法是使用Bicubic Interpolation。
我最近编写了一个基于 Marching Squares 算法及其等值带变体的填充二维等高线图的简单实现。此实现还使用提到的双三次插值来平滑数据。你可以找到这个简单的包here。它是在 GNU GPLv3 许可(或更高版本)下编写的。为了在您的项目中使用它,您必须将org.contour2dplot.* 复制并粘贴到项目的位置。
为了使用上述包绘制等高线图,您需要做的就是准备一个double[][] data 并创建一个Contour2DMap 对象。示例用法如下所示:
// Specify in the constructor width and height of the contour map.
Contour2DMap contour2DMap = new Contour2DMap(600, 600);
// Specify size for the contour map container.
contour2DMap.setPrefSize(600, 600);
// Set data.
contour2DMap.setData(data);
// Set iso factor, which is a step between subsequent iso values.
contour2DMap.setIsoFactor(1.0);
// Set interpolation factor.
contour2DMap.setInterpolationFactor(10);
// Set contour map color scale - "Color" or "Monochromatic".
contour2DMap.setMapColorScale("Color");
// Draw all elements on the contour map.
contour2DMap.draw();
Contour2DMap 对象继承自javafx.scene.layout.Pane,因此您可以将其嵌套在其他javafx.scene.layout.* 对象中,例如BorderPane。
为了使等高线图具有交互性,您可以考虑覆盖javafx.scene.chart.Chart 对象并将Contour2DMap 嵌套在其中。
您也可以考虑为 Marching Squares 算法的等值线变体重写 org.contour2dplot.*。
下面是Contour2DMap的两张截图,分别对应setMapColorScale("Color")和setMapColorScale("Monochromatic")。
【讨论】: