2013-10-07 15 views
7

Ich habe gesucht, aber offensichtlich nicht gefunden, ein Algorithmus, der es mir erlauben wird, eine Liste von x, y Koordinaten, die bekannt sind, entlang einer Kurve zu sein, um die 4 Kontrollpunkte für eine kubische Bezier zu bekommen Kurve ausspucken.Algorithmus zum Ableiten von Kontrollpunkten einer Bezier-Kurve von Punkten entlang dieser Kurve?

Um genauer zu sein, suche ich nach einem Algorithmus, der mir die zwei Kontrollpunkte gibt, die erforderlich sind, um die Kurve zu formen, während eine Reihe von diskreten Punkten einschließlich der zwei Kontrollpunkte eingegeben werden, die den Anfang und das Ende der Kurve bestimmen .

Danke!

Edit: Okay, wegen Mathe, ein alter Feind, muss ich für die Bezier-Kurve der besten Anpassung an eine Polynomfunktion fragen.

Antwort

9

Also ich nehme an, dass die Endpunkte fest sind, und dann haben Sie eine Anzahl von (x, y) Beispielpunkten, die Sie mit einem kubischen Bezier passen möchten.

Die Anzahl der Beispielpunkte, die Sie haben, wird bestimmen, welchen Ansatz zu nehmen. Schauen wir uns durch ein paar Fälle:

2 Punkte

2 Abtastpunkten ist der einfachste Fall. Das gibt Ihnen insgesamt 4 Punkte, wenn Sie die Endpunkte zählen. Dies ist die Anzahl der Lebensläufe in einem kubischen Bezier. Um dies zu lösen, benötigen Sie einen Parameter (t) -Wert für beide Abtastpunkte. Dann haben Sie ein System von 2 Gleichungen und 2 Punkten, die Sie lösen müssen, wobei die Gleichung die parametrische Gleichung einer Bezier-Kurve bei den von Ihnen gewählten t-Werten ist.

Die t-Werte können beliebig sein, aber Sie erhalten bessere Ergebnisse, wenn Sie entweder 1/3 und 2/3 verwenden oder relative Abstände oder relative Abstände entlang einer Basislinie in Abhängigkeit von Ihren Daten betrachten.

1 Punkt

Dies ist auf 2 Punkte ähnlich, mit der Ausnahme, dass Sie nicht genügend Informationen haben alle Freiheitsgrade eindeutig zu bestimmen. Was ich vorschlagen würde, ist eine quadratische Bezier passen, und dann Grad erhöhen. Ich habe ein detailliertes Beispiel für die quadratische Anpassung in this question geschrieben.

Mehr als 2 Punkte

In diesem Fall gibt es keine eindeutige Lösung. Ich habe die Näherung der kleinsten Quadrate mit guten Ergebnissen verwendet. Die Schritte sind:

  • Auswahl-T-Werte für jede Probe
  • Bauen Sie das System von Gleichungen als Matrix
  • Optional Verkleidung hinzuzufügen oder eine andere Glättungsfunktion
  • die Matrix mit einem Least-Squares-Löse-Solver

Es gibt eine gute Beschreibung dieser Schritte in diesen free cagd textbook, Kapitel 11. Es spricht von B-Splines passend, aber eine kubische Bezier ist eine Art von B-Spline (0,0,0 Knotenvektor ist, 1,1,1 und hat 4 Punkte).

+0

Danke für die schnelle Antwort. Ich dachte, dass Algebra wahrscheinlich erforderlich sein würde, aber das könnte ein bisschen obszön werden, wenn eine Kurve tausende Punkte haben könnte. Ich werde versuchen, große Kurven in kleinere Kurven zu brechen und die Zweipunktmethode anzuwenden. Falls das nicht klappt, werde ich dem mehr als zwei Punkte Versuch geben! – Everlag

+0

Wenn die Kurvengenauigkeit nicht so wichtig ist, könnten Sie versuchen, nur zwei Punkte zu wählen und die 2-Punkte-Methode zu machen. :) – tfinniga

+0

Ich ziele auf eine ordentliche Erholung der Kanten mit dem Sobel-Operator isoliert so genau wäre sehr viel bevorzugt. – Everlag

4

Angenommen, Sie haben eine Kurve y = f haben (x)

eine Bezier-Kurve definieren Sie 4 Punkte benötigen, wie: P1x, P1y, P2x, P2Y, P3x, P3y und P4x und P4Y

P1 und P4 Sie sind die Anfangs-/Endpunkte der Kurve. P2 und P3 sind Kontrollpunkte. Sie wissen bereits, wo der Anfang und das Ende der Kurve ist. Sie müssen P2 und P3 berechnen. Die x-Koordinaten P2x und P3x sind einfach, weil Sie sie einfach auswählen, indem Sie die t der Kurve als zB 1/3 und 2/3 auswählen. Also hast du P2x und P3x Dann hast du ein System von zwei Gleichungen und zwei Unbekannten (P2y und P3y). Nach Knirschen einig mathematischen Sie am Ende mit etwas wie folgt aus:

(. Mein f (x) war ein kubisches Polynom, die auch garantiert, dass ich in der Lage wäre eine kubische Bezier-Kurve, um es genau zu passen)

/** 
    @params {Object} firstPoint = {x:...,y...} 
    @params {Object} lastPoint = {x:...,y...} 
    @params {Object} cubicPoly Definition of a cubic polynomial in the form y=ax^3+bx^2+c. 
    Has a method EvaluateAt, which calculates y for a particular x 

*/ 
var CalcBezierControlPoints = function(firstPoint, lastPoint, cubicPoly) { 
    var xDiff = lastPoint.X - firstPoint.X; 
    var x1 = firstPoint.X + xDiff/3.0; 
    var x2 = firstPoint.X + 2.0 * xDiff/3.0; 

    var y1 = cubicPoly.EvaluateAt(x1); 
    var y2 = cubicPoly.EvaluateAt(x2); 

    var f1 = 0.296296296296296296296; // (1-1/3)^3 
    var f2 = 0.037037037037037037037; // (1-2/3)^3 
    var f3 = 0.296296296296296296296; // (2/3)^3 

    var b1 = y1 - firstPoint.Y * f1 - lastPoint.Y/27.0; 
    var b2 = y2 - firstPoint.Y * f2 - f3 * lastPoint.Y; 

    var c1 = (-2 * b1 + b2)/-0.666666666666666666; 
    var c2 = (b2 - 0.2222222222222 * c1)/0.44444444444444444; 

    var p2 = {}; 
    var p3 = {}; 
    p2.X = x1; 
    p2.Y = c1; 

    p3.X = x2; 
    p3.Y = c2; 

    return ([p2, p3]); 
} 
Verwandte Themen