【问题标题】:Angle of a given point on a Bezier curve?贝塞尔曲线上给定点的角度?
【发布时间】:2012-09-10 18:10:49
【问题描述】:

我在 actionscript 中创建了这个类,它返回给定的贝塞尔曲线点。而我想要实现的是获得当前点的角度。我在互联网上搜索,但找不到太多。我该怎么做?

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);
}

【问题讨论】:

  • 如果你在做数学来得到点本身,你为什么不能用导数来找到斜率?然后拿atan2找角度?对 Beizer 曲线不太熟悉,因此不能将其作为真正的答案

标签: actionscript-3 math geometry bezier


【解决方案1】:

给定:

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

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

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

维基百科有一个lovely gif 证明了这一点。黑点是B点,绿线段的端点是q0和q1。

对于更高维度的贝塞尔曲线,原理是相同的。求 N 度贝塞尔曲线上点的角度,求 q0 和 q1,它们是 N-1 度贝塞尔曲线上控制点 [p0,p1,...,p(N-1 )] 和 [p1, p2,...,pN]。角度等于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 资源并且不够动态,所以我将我的解决方案发布在我的问题!
【解决方案2】:

经过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);
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多