6

このクラスを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);
}
4

2 に答える 2

11

与えられた:

  • コントロールポイントp0、p1、p2
  • 時間t

点Bは、時間tでのp0、p1、およびp2によって記述される2次ベジェ曲線上の点です。
q0は、時間tでのp0とp1によって記述される線形ベジェ曲線上の点です。
q1は、時間tでのp1とp2によって記述される線形ベジェ曲線上の点です。
q0とq1の間の線分は、点Bで2次ベジェ曲線に接しています。

したがって、時間tでのベジェ曲線の角度は、q0とq1の間の線分の傾きに等しくなります。

ウィキペディアには、これを示す素敵なgifがあります。黒い点は点Bであり、緑の線分の端点はq0とq1です。

原理は、高次元のベジェ曲線でも同じです。N度ベジェ曲線上の点の角度を見つけるには、制御点[p0、p1、...、p(N-1]のN-1度ベジェ曲線上の点であるq0とq1を見つけます。 )]および[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)
于 2012-09-10T18:26:35.687 に答える
4

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);
}
于 2013-06-11T08:50:09.370 に答える