给定一组与闭合形状相对应的坐标,我想计算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
的预期值。
如果我将df
的{{1}}参数更改为3,就像上一个答案一样,返回的值为smooth.spline
,仍然低于2 * pi(df值smooth.spline为自己计算的是2.472213)。
有更好的方法来计算曲率吗?是3.944053
是通过弧长参数化还是将它合并(以某种方式)拯救这个计算?
答案 0 :(得分:2)
好的,在我们开始之前有一些事情。你在seq
中使用了度数,这会给你不正确的结果(0到360度)。您可以通过在R中取cos(360)
来检查这是错误的,而不是1.这在详细信息下的trig函数文档中有说明。
所以让我们将你的功能改为
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预期值的一半。
它并不完美,但样条曲线存在边缘效应问题。