给定一组对应于闭合形状的坐标,我想计算 total absolute curvature ,这需要计算每个点的曲率,取绝对值,然后求和。足够简单。
我使用了this question的答案从 x y 坐标矩阵 (xymat
) 计算曲率并得到我认为的总绝对曲率:
sum(abs(predict(smooth.spline(xymat), deriv = 2)$y))
问题是总绝对曲率的最小值为 2*pi,并且与圆的绝对曲率完全相同,但此代码计算的值小于 2*pi:
library(purrr)
xymat <- map_df(data.frame(degrees=seq(0:360)),
function(theta) data.frame(x = sin(theta), y = cos(theta)))
sum(abs(predict(smooth.spline(xymat), deriv = 2)$y))
这将返回 1.311098
,而不是预期值 6.283185
。
如果我按照前面的答案将smooth.spline
的df
参数更改为3,则返回值为3.944053
,仍然害羞2*pi(smooth.spline自身计算的df值为2.472213)。
有没有更好的计算曲率的方法? smooth.spline
是通过弧长参数化的还是将其合并(以某种方式)挽救此计算?
最佳答案
好的,在我们开始之前先讲几件事。您在 seq
中使用度数,这会给出不正确的结果(0 到 360 度)。您可以通过在 R 中取 cos(360)
来检查这是否错误,该值不是 1。详细信息下的三角函数文档对此进行了解释。
所以让我们将您的功能更改为这样
xymat <- map_df(data.frame(degrees=seq(0,2*pi,length=360)),
function(theta) data.frame(x = sin(theta), y = cos(theta)))
如果你绘制这个,这确实看起来像一个圆圈。
让我们将其限制在圆的下半部分。如果您在不了解对称性和查看绘图的情况下通过此样条线,则很可能会得到一条穿过圆的水平线。
为什么?因为样条线不知道它在 y = 0 的上方和下方是对称的。样条线试图拟合解释“数据”的函数,而不是跟踪圆弧。它将 y = 0 周围的两组对称点之间的差异分开。如果我们将样条线限制在圆的下半部分,我们可以使用 1 到 -1 之间的 y 值,如下所示:
lower.semicircle <- data.frame(predict(smooth.spline(xymat[91:270,], all.knots = T)))
让我们通过它拟合一条样条线。
lower.semicircle.pred<-data.frame(predict(smooth.spline(lower.semicircle, all.knots = T)))
请注意,我在这里没有使用 deriv
函数。这是针对您链接到的 cars
示例中的另一个问题。您想要总绝对曲率,而他们正在研究曲率的变化率。
我们现在拥有的是使用样条线近似的下半圆。现在您需要所有小连续点之间的距离,就像维基百科页面的积分一样。
让我们使用距离矩阵来计算所有小弧距离。这实际上计算了每个点到每个其他点之间的欧几里得距离。
all.pairwise.distances.in.the.spline.approx<-dist(lower.semicircle.pred, diag=F)
dist.matrix<-as.matrix(all.pairwise.distances.in.the.spline.approx)
seq.of.distances.you.want<-dist.matrix[row(dist.matrix) == col(dist.matrix) + 1]
最后一个对象是您需要求和的内容。
sum(seq.of.distances.you.want)
..下半圆的计算结果为 [1] 3.079
,大约是 2*pi 预期值的一半。
它并不完美,但样条线存在边缘效应问题。
关于r - 根据 R 中的坐标计算总绝对曲率,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50083392/