【问题标题】:Creating interactive contour plots on Android在 Android 上创建交互式等高线图
【发布时间】:2016-03-23 17:14:25
【问题描述】:

我有应绘制在等高线图中的二维强度数组形式的数据。最后,它应该看起来像带有等高线的地形图,如下图所示:

这个想法是典型的多点触控手势(捏缩放,拖动移动)可用于导航等高线图。数据的最大大小应该在 4k*4k 点左右,每个点 4 字节大。

是否有一些我可以使用的绘图库,或者我必须从头开始?有没有容易实现的算法?

【问题讨论】:

    标签: java android plot


    【解决方案1】:

    我不知道任何适用于 Android(或 Java)的绘图库,但我确实知道一两点关于绘图的一般知识:

    创建轮廓的简单算法是Marching Squares。 Marching squares 从您的数据数组中创建多边形。 Java 中应该有很多这种算法的示例(尝试Google Code Search,但在使用之前请阅读许可证)。

    如果你想放大很远,你可能想从这些多边形中创建 贝塞尔曲线 来平滑它们,可以找到一个示例算法(带有应该很容易移植到 Java 的代码)@ 987654323@.

    注意:如果你想用颜色填充轮廓,你应该考虑使用片段着色器而不是创建多边形。将数据作为纹理发送到着色器,并使用强度为每个像素分配颜色。为此,您应该了解一些 OpenGL。

    【讨论】:

      【解决方案2】:

      正如@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")

      【讨论】:

      • 哦,对不起。我将尝试重塑我的答案,以使其对未来的读者更友好。
      • 当我们讨论这个主题时,您可能还想阅读How to offer personal open-source libraries?
      • @MartijnPieters 非常有用的指南。谢谢你。我明白自我推销和简单的帮助别人之间的界限是多么模糊。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-07-16
      • 2012-02-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多