2012-09-10 15 views
6

Ich habe diese Klasse in ActionScript erstellt, es gibt einen bestimmten Punkt der Bezier zurück. Und was ich versuche zu erreichen, ist den Winkel des aktuellen Punktes zu erhalten. Ich suchte im Internet, aber ich konnte nicht viel finden. Wie kann ich das machen?Winkel eines gegebenen Punktes auf einer Bezier-Kurve?

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

Wenn Sie Mathe tun den Punkt selbst zu bekommen, warum können Sie nicht nehmen die Ableitung, um die Steigung zu finden? Dann nimm den atan2, um den Winkel zu finden? Nicht vertraut mit Beizer-Kurven, so dass dies keine echte Antwort –

Antwort

9

Gegeben:

  • Kontrollpunkt p0, p1, p2
  • Zeit t

Punkt B ist der Punkt auf der quadratischen Bezier-Kurve durch p0, p1 beschrieben ist, und p2 zur Zeit t.
q0 ist der Punkt auf der linearen Bezierkurve, die zur Zeit t von p0 und p1 beschrieben wird.
q1 ist der Punkt auf der linearen Bezier-Kurve, der zum Zeitpunkt t1 durch p1 und p2 beschrieben wird.
Das Liniensegment zwischen q0 und q1 Tangente an Ihre quadratischen Bezier-Kurve am Punkt B.

Daher ist, ist der Winkel der Bézier-Kurve zum Zeitpunkt t an die Steigung des Liniensegmentes zwischen Q0 und Q1 gleich.

Wikipedia hat eine lovely gif das zeigt dies. Der schwarze Punkt ist Punkt B und die Endpunkte des grünen Liniensegments sind q0 und q1.

Das Prinzip ist für Bezier-Kurven höherer Dimensionen identisch. Um den Winkel eines Punktes auf einer N-Grad-Bezier-Kurve zu finden, finde q0 und q1, die die Punkte auf den N-1-Grad-Bezier-Kurven für die Kontrollpunkte [p0, p1, ..., p (N-1)] und [p1, p2, ..., pN]. Der Winkel ist gleich der Steigung des Liniensegments q0-q1.

In Pseudo-Code:

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) 
+0

Vielen Dank für die Erklärung, was ich tun müsste, konnte ich nicht Ihren Code verwenden, weil es zu intensiv für die CPU wäre und es nicht dynamisch genug war, so Ich habe meine Lösung auf meine Frage gepostet! – tversteeg

3

Nach der Erklärung von Kevin machte ich eine dynamische aber einfache Lösung:

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