【问题标题】:Calculating the curvature of a closed curve ( or polygon) in matlab在matlab中计算闭合曲线(或多边形)的曲率
【发布时间】:2018-03-27 18:13:02
【问题描述】:

考虑以下一组点

x = [1.34, 0.92, 0.68, 0.25, -0.06, -0.34, -0.49, -0.72, -0.79, -0.94, -1.35, -0.35, 0.54, 0.68, 0.84, 1.20, 1.23, 1.32, 1.34];
y = [0.30, 0.43, 0.90, 1.40, 1.13, 1.08, 1.14, 1.23, 0.52, 0.21, -0.20, -0.73, -0.73, -0.82, -0.71, -0.76, -0.46, -0.13, 0.30];

给出闭合曲线(或多边形):

figure(1)
hold on
plot(x,y,'k');
scatter(x,y,'r');
xlim([-2 2]);
ylim([-2 2]);
axis equal

我希望计算曲线上各点的曲率(尽可能准确)。

到目前为止,我所拥有的是切向量(一阶导数)和曲率(二阶导数)的简单计算:

dsx = diff(x);
dsy = diff(y);
ds = sqrt(dsx.^2+dsy.^2);
Tx = dsx./ds;
Ty = dsy./ds;
ds2 = 0.5*(ds(1:end-1)+ds(2:end));
Hx = diff(Tx)./ds2;
Hy = diff(Ty)./ds2;

但我得到一个非常不准确的曲率:

figure(1)
quiver(x(1:end-2),y(1:end-2),Hx,Hy,'b','autoscalefactor',1.2); 
xlim([-2 2]); ylim([-2 2]);
axis equal

这应该是一个简单的计算,但是它不起作用,请建议:我怎样才能以最简单的近似值找到曲率并在方向和大小上具有合理的精度?

【问题讨论】:

  • 你的曲率是正确的,只是移动了一个点。 diff 计算后续点之间的差异,从而得出点之间的范围。如果你应用它两次,你会得到样本的二阶导数,但结果会移动一个样本。
  • @CrisLuengo,tnx 为您解答。你能提供一个解决方案吗?我会接受,请使用我提供的示例。

标签: matlab computational-geometry


【解决方案1】:

曲率计算是正确的,它是关闭的绘图。请注意,diff 计算后续元素之间的差异,从而产生一个元素少一个的向量。它估计样本对之间的导数。如果重复此操作,您将在样本处获得二阶导数,但不会在第一个或最后一个样本处获得(现在您的元素减少了 2 个)。

您确实注意到了这一点,因为除了一个顶点之外,您只绘制了一个曲率。

所以您需要做的就是在一阶导数之后复制一个点(我将最后一个点添加到开头,因此元素的顺序与输入数组中的顺序相同)。索引语句Tx([end,1:end]) 就是这样做的。

在下面的代码中,我还将法线 (Ty,-Tx) 绘制为黑色。

x = [1.34, 0.92, 0.68, 0.25, -0.06, -0.34, -0.49, -0.72, -0.79, -0.94, -1.35, -0.35, 0.54, 0.68, 0.84, 1.20, 1.23, 1.32, 1.34];
y = [0.30, 0.43, 0.90, 1.40, 1.13, 1.08, 1.14, 1.23, 0.52, 0.21, -0.20, -0.73, -0.73, -0.82, -0.71, -0.76,-0.46, -0.13, 0.30];

% First derivative
dsx = diff(x);
dsy = diff(y);
ds = sqrt(dsx.^2+dsy.^2);
Tx = dsx./ds;
Ty = dsy./ds;

% Second derivative & curvature
ds2 = 0.5*(ds([end,1:end-1])+ds);
Hx = diff(Tx([end,1:end]))./ds2;
Hy = diff(Ty([end,1:end]))./ds2;

% Plot
clf
hold on
plot(x,y,'ro-');
x = x(1:end-1);
y = y(1:end-1); % remove repeated point
quiver(x+dsx/2,y+dsy/2,Ty,-Tx,'k','autoscalefactor',0.3); 
quiver(x,y,Hx,Hy,'b','autoscalefactor',1.2); 
set(gca,'xlim',[-2 2],'ylim',[-1.5 2]);
axis equal

【讨论】:

  • “曲率”与边缘方向向量之间的差异有什么联系?声明ds2 = 0.5*(ds+ds)的目的是什么?
  • @YvesDaoust:感谢您的关注。 ds2 应该是两个相邻边的长度的平均值。如果您认为法线在顶点之间的中间,那是相邻法线之间的边的长度。我已经修复了代码。
  • @YvesDaoust:关于你关于曲率之间的联系和边缘方向向量之间的差异的问题:这正是曲率的定义。例如参见 Wikipedia,Curvature: "Precise definition"。在它上面一点点描述了这些方程的含义:“在几何上,曲率 κ 测量曲线的单位切向量旋转的速度。”
  • 像这样的稀疏多边形上的曲率可能不是很有意义,但这并不意味着不可能将离散近似应用于导数来计算它。更密集采样轮廓上的相同代码将给出轮廓曲率的良好近似值。
  • 您指出了问题所在:这些离散近似值是错误的。但 OP 不在乎。
【解决方案2】:

严格来说,这个问题没有意义。

多边形的顶点没有曲率,边缘的曲率为零。

您需要更具体地说明要评估的数量,例如解释目的。

【讨论】:

  • 不欢迎静音投票。不相信这个答案有用的人应该三思而后行。
  • 我认为问题和例子都很清楚。为了讨论,在计算机中,即使是平滑的曲线也是一个间隔非常小的多边形。
  • @jarhead: 1) 曲率不是“二阶导数”,方向向量的差不是“二阶导数”。 2)在计算机中,平滑曲线可以很好地处理为平滑曲线。 3) 存在微分几何。 4)忽略不相等的段长度我会引入偏差。
  • 不相等的段长度不会被忽略。这就是 OP 代码中的 dsds2 的作用。曲率定义为沿曲线的二阶导数。这是字面意思教科书的定义。我没有投反对票,但这不是一个好的或有用的答案 IMO。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多