计算给定控制点的贝塞尔曲线的曲率半径

Computing the Radius of Curvature of a Bezier Curve Given Control Points

我正在尝试编写一个以曲率作为优化参数之一的遗传算法。我想根据贝塞尔曲线的控制点计算曲率。我有一个要优化的最小曲率半径。我一直在参考这篇论文:https://arxiv.org/pdf/1503.01524.pdf

论文中有一个函数,用三角形的边长来得到隐含的曲率半径,我已经实现了。这是我当前的代码:

// Computes the curvature implied by 3 control points of a bezier curve
float curvature(float4 p0, float4 p1, float4 p2) {

    // Get the triangle side lengths
    float a = distance(p0, p1);
    float b = distance(p1, p2);
    float c = distance(p2, p0);

    // Do the curvature calculation
    float num = a * b * c;
    float denom = (a + b + c) * (b + c - a) * (a - b + c) * (a + b - c);

    return num / sqrt(denom);

}

这个函数的结果似乎不正确。我 运行 这个函数用于路径中的每个点,保存最后两个,然后从所有这些点中获取最小半径。当我绘制路径图时,此函数的计算与我在视觉上看到的似乎存在重大差异。正确的方法是什么?

编辑: 我正在寻找计算三个控制点之间的曲率半径,而不是在曲线中的给定点,如果不清楚,我们深表歉意。

曲率半径R(t)等于1/κ(t),其中κ(t)为曲线在t点的曲率,对于a parametric planar curve为:

            x'y" - y'x"
κ(t)  = --------------------
         (x'² + y'²)^(3/2)

(其中 ^(3/2) 实际上是 3/2,但您不能在代码块中使用 html 进行上标格式化,并且(t) 部分已从 x 和 y 的函数中删除,因为这会使阅读变得不必要地困难)

因此,对于具有控件 P₁、P₂ 和 P₃ 的二次贝塞尔曲线,the first and second derivatives use the following control points:

B(t)': P₁' = 2(P₂ - P₁), and P₂' = 2(P₃ - P₂)
B(t)": P₁" = (P'₂ - P'₁)

对 x 和 y 的评估实际上只是 "using the x or y coordinates",所以:

x' = Px₁'(t-1) + Px₂'(t)
y' = Py₁'(t-1) + Py₂'(t)
x" = Px₁"
y" = Py₁"

注意 x" 和 y" 只是常量。我们将这些值插入到 κ(t) 的函数中,当然前提是分母不为零(这表示一条线段,没有曲率半径)然后我们知道 R(t) 是什么,因为那是只是倒数。

但我们实际上不需要做任何这些,因为我们可以做一个简单的观察:将圆也视为参数曲线,我们可以根据以下事实立即找到它的半径曲线导数的矢量长度与圆在同一点的导数相等。此外,我们知道导数的长度在圆上的任何地方都是相同的(因为它是一个圆,根据定义它关于原点径向对称)。因此,我们可以解决以下问题:

B(t)  = P1(1-t)^2 + 2*P2(1-t)t + P3t^2
B(t)' = 2*(P2-P1)(1-t) + 2*(P3-P2)t

C(s)  = { r*sin(s), r*cos(s) }independent of 't')
C(s)' = { r*cos(s), -r*sin(s) }

d = |B(t)'| = |C(s = any value, so let's pick 0)'|
d = C(0)' = | (r,0) | = r

我们完成了。 B(t)点的曲率半径等于B(t)'的向量长度,实现起来容易很多,速度也快运行.

最后,如果您真正想要的只是用圆弧近似曲线部分,那么 https://pomax.github.io/bezierinfo/#arcapproximation 应该涵盖该特定用例的 "how to"。