贝塞尔曲线上给定点的角度是多少?

7

我用ActionScript创建了这个类,它返回Bezier曲线上给定点的位置。现在我想得到当前点的角度。我在网上搜索了一下,但是没有找到太多相关的资料。请问该如何实现?

public static function quadraticBezierPoint(u:Number, anchor1:Point, anchor2:Point, control:Point):Point {
    var uc:Number = 1 - u;
    var posx:Number = Math.pow(uc, 2) * anchor1.x + 2 * uc * u * control.x + Math.pow(u, 2) * anchor2.x;
    var posy:Number = Math.pow(uc, 2) * anchor1.y + 2 * uc * u * control.y + Math.pow(u, 2) * anchor2.y;
    return new Point(posx, posy);
}

2
如果您正在进行数学计算以获得点本身,为什么不能取导数以找到斜率?然后使用atan2函数找到角度?我对Beizer曲线不太熟悉,所以这并不是一个真正的答案。 - im so confused
2个回答

12

给定:

  • 控制点 p0、p1、p2
  • 时间 t

B 点是由 p0、p1 和 p2 描述的二次贝塞尔曲线上在时间 t 处的点。
q0 是由 p0 和 p1 描述的线性贝塞尔曲线上在时间 t 处的点。
q1 是由 p1 和 p2 描述的线性贝塞尔曲线上在时间 t 处的点。
连接 q0 和 q1 的线段在点 B 处切线与你的二次贝塞尔曲线相切。

因此,在时间 t 的贝塞尔曲线的角度等于 q0 和 q1 之间线段的斜率。

维基百科有一个漂亮的gif 动画演示了这一点。黑点是点 B,绿色线段的端点是 q0 和 q1。

对于更高维度的贝塞尔曲线,原理是相同的。要找到 N 次贝塞尔曲线上某个点的角度,请找到 q0 和 q1,它们是控制点 [p0、p1、...、p(N-1)] 和 [p1、p2、...、pN] 的 N-1 次贝塞尔曲线上的点。角度等于 q0-q1 线段的斜率。

伪代码如下:

def bezierCurve(controlPoints, t):
    if len(controlPoints) == 1:
        return controlPoints[0]
    else:
        allControlPointsButTheLastOne = controlPoints[:-1]
        allControlPointsButTheFirstOne = controlPoints[1:]
        q0 = bezierCurve(allControlPointsButTheLatOne, t)
        q1 = bezierCurve(allControlPointsButTheFirstOne, t)
        return (1-t) * q0 + t * q1

def bezierAngle(controlPoints, t):
    q0 = bezierCurve(controlPoints[:-1], t)
    q1 = bezierCurve(controlPoints[1:], t)
    return math.atan2(q1.y - q0.y, q1.x - q0.x)

谢谢您解释我需要做什么,但我不能使用您的代码,因为它对CPU来说太过繁重,而且不够动态。所以我在我的问题中发布了我的解决方案! - tversteeg

5
在Kevin的解释之后,我制作了一个动态但简单的解决方案:
public static function quadraticBezierAngle(u:Number, anchor1:Point, anchor2:Point, control:Point):Number {
    var uc:Number = 1 - u;
    var dx:Number = (uc * control.x + u * anchor2.x) - (uc * anchor1.x + u * control.x);
    var dy:Number = (uc * control.y + u * anchor2.y) - (uc * anchor1.y + u * control.y);
    return Math.atan2(dy, dx);
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接