2012-09-10 13 views
6

Utworzyłem tę klasę w actionscript, zwraca ona określony punkt beziera. I próbuję to osiągnąć, aby uzyskać kąt aktualnego punktu. Szukałem w Internecie, ale nie mogłem znaleźć wiele. Jak mogę to zrobić?Kąt danego punktu na krzywej Beziera?

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

Jeśli robisz matematyki dostać sam punkt, dlaczego nie można zrobić pochodna do znalezienia nachylenia? następnie wziąć atan2, aby znaleźć kąt? Niezbyt dobrze znane z krzywych Beizera, więc nie czyniąc tego prawdziwą odpowiedzią. –

Odpowiedz

9

Dane:

  • punkty kontrolne P0, P1, P2
  • czas t

punkt B jest punktem na krzywej Béziera drugiego opisanego p0, p1, i p2 w czasie t.
q0 jest punktem na liniowej krzywej Beziera opisanej przez p0 i p1 w czasie t.
q1 jest punktem na liniowej krzywej Beziera opisanej przez p1 i p2 w czasie t.
odcinka linii pomiędzy q0, a Q1 jest styczna do Krzywa Béziera w punkcie B.

Dlatego kąt krzywej Beziera w chwili t jest równa nachyleniu odcinka linii pomiędzy q0, a Q1.

Wikipedia pokazuje to jako lovely gif. Czarna kropka to punkt B, a punktami końcowymi segmentu zielonej linii są q0 i q1.

Zasada jest identyczna dla krzywych Beziera o wyższych wymiarach. Aby znaleźć kąt punktu na krzywej N-stopniu beziera, znajdź q0 i q1, które są punktami na krzywych Beziera dla N-1 stopnia dla punktów kontrolnych [p0, p1, ..., p (N-1)] i [p1, p2, ..., pN]. Kąt jest równy nachyleniu segmentu linii q0-q1.

W Pseudokod:

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

Dziękuję za wyjaśnienie, co musiałbym zrobić, nie mogłem użyć twojego kodu, ponieważ byłby on intensywny dla procesora i nie był wystarczająco dynamiczny, więc Wysłałem swoje rozwiązanie na moje pytanie! – tversteeg

3

Po wyjaśnienie Kevin zrobiłem dynamiczny ale proste rozwiązanie:

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