2012-04-03 7 views
10

Ich war die Hoffnung, jemand könnte mir ein rechen kostengünstigen Verfahren zum Nachweis von Knicken in einer Linie, die parallel zu einer Bezier-Kurve helfen, herauszufinden, wie SieDetect „Kinks“ in Parallel Lines zu Bezier-Kurve

Kink in Line Parallel to Bezier Curve

hier sehen können

Was ich tun möchte, ist in der Lage, den Schnittpunkt des Knicks, das Segment mit einem Startpunkt vor dem Schnittpunkt und das erste Segment mit einem Endpunkt nach dem Knick zu bestimmen. Auf diese Weise kann ich einfach alle unnötigen Segmente entfernen und das erste und letzte Segment an der Kreuzung anpassen.

Entschuldigung, wenn ich die falschen Begriffe verwende. Aber soweit ich es verstehe, besteht die Art, wie ich diese Segmente positioniere, darin, den Einheitsvektor der Segmente für die Bezier-Kurve (gelb) zu bestimmen und mit dem Offset zu multiplizieren und den normalen Vektor zu finden, um zwei neue Start- und Endpunkte zu erzeugen für das Offset-Segment (weiß).

Mathematik ist nicht mein starker Anzug, also hoffe ich, dass jemand mir einen Stoß in die richtige Richtung geben kann.

EDIT: Das Bild wird von HTML Größe verändert tatsächlich, so, wenn Sie sehen, eine harte Zeit, was ich rede hier der direkte Link: http://i.stack.imgur.com/xtils.png

+0

Schönes Diagramm. Was möchten Sie in dem Fall tun, in dem das Bezier selbst sich selbst kreuzt? –

+1

Ich brauche in diesen Fällen nichts Besonderes. –

+0

die Jungs bei mathe.stackexchange.com möglicherweise besser ausgestattet, um Ihnen dabei zu helfen. –

Antwort

5

Als erste Näherung berechnet die radius of curvature Ihre Bezier curve. Wenn der Versatz größer oder gleich dem Krümmungsradius ist, sollten Sie nach einem Knick suchen.

Insbesondere für eine kubische Bezier-Kontrollpunkte mit P0, P1, P2, P3:

B(t) = P0 * (1-t)^3 + P1 * 3*t*(1-t)^2 + P2 * 3*t^2*(1-t) + P3 * t^3 
-> B'(t) = (P1-P0) * 3*(1-t)^2 + (P2-P1) * 6*t*(1-t) + (P3-P2) * 3*t^2 
-> B''(t) = (P2+P0-2*P1) * 6*(1-t) + (P3+P1-2*P2) * 6*t 

let: cross2d(p, q) = p.x*q.y - p.y*q.x 
then, radius of curvature = |B'(t)|^3/cross2d(B'(t), B''(t)) 

I den Krümmungsradius in signierter Form verlassen haben; Das Zeichen sollte die Seite der Kurve angeben, auf der Sie den Knick erwarten können.

Hinweis: Sie können einen Krümmungsradius von 0 oder einen unendlichen Krümmungsradius haben. Es ist besser, mit signed_offset * cross2d(B'(t), B''(t)) zu vergleichen.

+0

Ehrfürchtig. Das scheint so zu sein. Ich werde es versuchen und zu dir zurückkommen. Könnte mich eine Weile dauern.:) +1 –

+0

Verzeihen Sie mir, wenn das eine dumme Frage ist, aber wie ich sagte, Mathematik ist nicht meine starke Klage. Während Ihre cross2d (p, q) -Funktion merkt, dass meine Punkte P x- und y-Koordinaten sind, tun dies die Funktionen B, B 'und B' 'nicht. Bedeutet das, dass ich diese für jede Achse nur einmal laufen lasse? –

+0

Die Zeichen 'B (t)', 'B '(t)' und 'B' (t)' sollten 2D-Vektoren sein, genau wie 'P0',' P1', 'P2' und' P3' . Beachten Sie auch, dass '| B '(t) |' die Länge des 2-D-Vektors annehmen sollte. Es ist wahrscheinlich am besten, eine 'Vector2'-Struktur (oder eine vorhandene Struktur, die Sie gerade für Ihre 2D-Punkte verwenden) zu verwenden, sodass Sie die Bezier-Gewichte nicht mehrmals neu berechnen müssen. Sie können jedoch Skalarfunktionen schreiben und sie für jede Achse ausführen, wenn Sie möchten. Denken Sie daran, dass Sie sie beim Berechnen der Vektorlänge und des cross2d() erneut zusammensetzen müssen. – comingstorm