实现轮廓绘图的方法

时间:2010-11-30 12:56:03

标签: math graphics vector-graphics

我需要实现轮廓绘图算法(而不是仅使用一个)。输入是(连续)函数f:R ^ 2 - > R(该函数在整个域中定义,而不仅仅针对某些输入)。输出应采用矢量形式,即一组样条线或线段。

我正在寻找有关如何实施此建议的建议,最好采用(科学)论文的形式。

我发现了对80年代开发的算法的一些参考(“水平追踪算法”)。在过去的30年里,这个领域有没有发展?用于解决此问题的标准方法是什么?

该算法将用于实时可视化,因此它需要快速,同时仍能产生不错的结果。

(小型,独立且经过良好测试的C / C ++实现也将受到欢迎。)

4 个答案:

答案 0 :(得分:5)

我记得TI-89计算器使用了一个非常简单的方案:

  • 制作网格,尝试网格尺寸
  • 在网格的每个顶点计算您的函数
  • 对于每个方格,如果有两个具有不同符号的f值,则内部会有一些有趣的内容。假设情况如下:
    • 对于方形的每个“有趣”侧(f在端点处具有不同的符号),通过二分(或者如果您在低预算时通过线性插值)找到侧面的f的零。可能有两个或四个有趣的方面。
    • 如果有两个有趣的边,在零点之间画一条直线。
    • 如果有四个有趣的方面,画一个十字架。

现在,你可能想要适应性地改进有趣的方块。 TI-89有一个该死的小屏幕(160x120),这是没有必要的。完全相同的方法可以在一个有趣的方块内使用。

答案 1 :(得分:2)

例如参见xfarbe

答案 2 :(得分:1)

我建议使用最直接的方法:考虑必须为某些f(x,y) = Z找到Z的轮廓。然后使用顶点和边缘的等边三角形网格D = subset(RxR)M = (V,E,r) - 网格,M - 顶点集合V来绘制您的绘图字段E。 1}} - 边集,r - 三角边长,level of detail,LOD。然后,对于V中的每个顶点,计算f的值。然后,对于E中的每个边缘,检查边缘(e[k])在其顶点(fv[i]上)的值是否为v[j]关于Z的不同方面,即f(v[i])>Zf(v[j])<Z。如果是这样,f(x,y) = Z的等高线与某个点(e[k])处的此边c[k]相交,可以线性近似:

  

t =(f(v [i]) - Z)/(f(v [i]) - f(v [j]))
  c'[k] = v [i] *(1-t)+ v [j] * t

由于具有一个边缘轮廓交点的三角形在剩余的两个边缘中的一些边缘处具有第二交叉点(证明是微不足道的),我们获得第二个c'[k]。因此,对于来自M的每个三角形,我们没有或单个线段,近似于轮廓线。绘制所有找到的线段将为我们提供具有一定细节水平f(x,y)=Z的{​​{1}}的近似等值线图。降低r将产生更精细的轮廓,提升r将提供性能。

答案 3 :(得分:0)

我认为您需要在某个网格中为您的函数创建数据数组f [i,j],从每个单元格中收集线段并稍后将它们连接到曲线中。您应该记住可能的圆圈(即网格中存在几条闭合曲线)。确切地说,这个算法用于MathGL(跨平台GPL绘图库) - 参见mglGraph :: Cont()函数的实现。