【问题标题】:How does Matlab calculate contour lines?Matlab如何计算等高线?
【发布时间】:2017-04-24 23:27:24
【问题描述】:

Matlab 用来生成等高线的算法是什么?换句话说,它是如何将网格上的关卡数据转换成一组线的?

我想要的是:

  • 获取位于轮廓上的点的局部标准?
  • 捕获所有轮廓线的全局过程?

我不需要有关底层代码的详细细节,但一般原则将有助于我解释输出。我在我的研究中使用contour(和派生词),并想了解这一步中引入的数值错误。

这看起来是一个非常简单的问题,但我在 Matlab 的文档中找不到解释,也没有在 SO 或网络上的其他地方找到任何东西。如果它变得很容易找到,我深表歉意。

【问题讨论】:

  • contourccontourcontour3contourf 使用的低级函数。这是一个内置的,所以它是编译的代码,对用户不可见。在较新版本的 MATLAB 的内联文档中,实际上并没有对算法进行任何讨论。旧版本的 MATLAB 可能有更多的内联细节。
  • @excaza 感谢此评论并列出这些相关功能。我知道他们的存在,但可能对其他人有帮助。我没有想过要寻找代码,但是由于它已经编译,所以无论如何都行不通。
  • @tvo 找到答案对我来说并不容易;-) mathworks.com/help/pdf_doc/matlab/graphg.pdf 的最新版本省略了有关算法的详细信息。
  • 谢谢。很好! +1 并接受。

标签: algorithm matlab contour


【解决方案1】:

MATLAB® - Graphics - R2012a,从第5-73页到第5-76页:

轮廓算法

contourc 函数为另一个计算轮廓矩阵 轮廓函数。它是一个不被调用的低级函数 命令行。轮廓算法首先确定哪个 要绘制的等高线水平。如果您指定了输入向量v,则 v 的元素是轮廓级别值,length(v) 确定生成的轮廓级别数。如果你不 指定v,算法选择不超过20个轮廓级别 能被 2 或 5 整除。

高度矩阵Z 关联了XY 矩阵 Z 中的每个值在行和列的交叉处,或者这些 未指定时推断矩阵。行和列 宽度可以变化,但通常它们是恒定的(即,Z 是 常规网格)。在调用contourc 插入轮廓之前, contourf 用额外的行或列填充高度矩阵 边缘。它将 z 值分配给远低于添加的网格单元 矩阵的最小值。填充值使轮廓能够 靠近矩阵边界,以便它们可以填充颜色。 当contourc 创建轮廓矩阵时,它会替换 x,y 包含带有 NaN 的低 z 值的坐标,以防止轮廓 穿过矩阵边缘的线不会被显示。这就是为什么 contourf 返回的等高线矩阵有时包含 NaN 值。 设置当前级别,c,等于要为的最低等高线级别 在[min(Z) max(Z)] 范围内绘制。轮廓算法 检查网格中每个正方形的每条边以查看c 是否介于两者之间 边缘点的两个 z 值。如果是这样,则该级别的轮廓 越过边缘,进行线性插值:

t=(c-Z0)/(Z1-Z0)

Z0是一个边缘点的z值,Z1是边缘点的z值 其他边缘点。

通过插值开始为级别 c 索引新的轮廓线 (i=1) x 和 y:

cx(i) = X0+t*(X1-X0)
cy(i) = Y0+t*(Y1-Y0)

绕着刚刚进入的广场的边缘走;轮廓在 下一个带有 z 值的边,包含 c。递增i,计算 t 用于边缘,然后计算 cx(i)cy(i),如上。标记 广场被参观过。继续检查每个边缘 输入正方形以确定退出边缘,直到行(cx,cy) 在其初始点关闭或退出网格。如果正方形是 输入已经被标记,轮廓线在那里关闭。复制cx, cyci 到等高线数据结构(矩阵 由轮廓函数返回,稍后描述)。

重新初始化 cxcyi。移动到一个没有标记的方块并测试 交叉点的边缘;当您在c 级别找到一个时,重复 前面的操作。任意数量的等高线可以存在 给定的水平。清除所有标记,增加轮廓级别,然后 重复直到c 超过max(Z)。正方形需要额外的逻辑 其中轮廓通过所有四个边缘(鞍点)到 确定要连接的边对。 contourcontour3contourf 返回一个指定所有轮廓的两行矩阵 行:

C = [ value1 xdata(1) xdata(2)...
        numv ydata(1) ydata(2)...]

开始每个轮廓定义的列的第一行 行包含轮廓值,由 v 指定并由 clabel。在该值之下是 (x,y) 顶点的数量 等高线。其余列包含 (x,y) 对的数据。 比如C = contour(peaks(3))计算的轮廓矩阵 如下。

带圆圈的值开始每个轮廓线的定义。

【讨论】:

    【解决方案2】:

    您可以阅读有关行进广场的信息。 (https://en.wikipedia.org/wiki/Marching_squares)

    通常,线性插值是沿网格单元边缘执行的,给出连接以形成折线的轮廓点。

    当单元格太粗糙时,可以进行初步插值,例如双三次插值,以细化网格。

    【讨论】:

    • 但不知道 Matlab 实际使用的是什么。
    • +1 这是一个很好的参考。如果我必须开发一种算法,我基本上会使用相同的方法。这似乎是 Matlab 使用的。我可能可以验证从数据到等高线的线性插值是准确的(直到四舍五入)。好吧,Matlab 的linear 插值实际上是双线性的,但这在边缘上应该无关紧要。你怎么看?
    • @tvo:关于什么?
    • 这是否会验证轮廓是从沿边缘的线性插值获得的。
    • @tvo:您是在问“验证从数据到轮廓线的线性插值是否准确”会“验证轮廓是从沿边缘的线性插值获得的”吗??
    猜你喜欢
    • 2021-02-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多