2012-04-03 7 views
10

Miałem nadzieję, ktoś mógłby mi pomóc dowiedzieć się metodę obliczeniowo niedrogie do wykrywania usterek w linii biegnącej równolegle do krzywej Beziera jak widać tutajDetect „Kinks” w Parallel Lines na krzywe Beziera

Kink in Line Parallel to Bezier Curve

Co mogę zrobić, to móc określić przecięcie załamania, odcinek z punktem początkowym przed przecięciem i pierwszy segment z punktem końcowym po załamaniu. W ten sposób mogę po prostu usunąć niepotrzebne segmenty i dopasować pierwszy i ostatni segment do spotkania na skrzyżowaniu.

Przepraszam, jeśli używam niepoprawnych terminów. Ale o ile rozumiem, sposób, w jaki pozycjonuję te segmenty, polega na określeniu wektora jednostkowego segmentów krzywej Beziera (żółtego) i pomnożenie go przez przesunięcie i znalezienie normalnego wektora w celu utworzenia dwóch nowych punktów początkowych i końcowych dla segmentu przesunięcia (biały).

Matematyka nie jest moją mocną stroną, więc mam nadzieję, że ktoś da mi impuls we właściwym kierunku.

EDIT: Obraz został faktycznie zmieniany przez HTML, więc jeśli masz trudny czas widząc, co mówię tutaj jest bezpośredni link: http://i.stack.imgur.com/xtils.png

+0

Ładny schemat. Co chcesz zrobić w przypadku, gdy sam Bézier sam się krzyżuje? –

+1

W tych przypadkach nie potrzebuję niczego szczególnego. –

+0

faceci na stronie math.stackexchange.com mogą być lepiej przygotowani, aby ci w tym pomóc. –

Odpowiedz

5

W pierwszym przybliżeniu obliczyć radius of curvature twoich Bezier curve. Jeśli przesunięcie jest większe lub równe promieniowi krzywizny, powinieneś szukać załamania.

szczególności, dla Baziera z punktów kontrolnych 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)) 

mi pozostały promień krzywizny w postaci podpisany znak powinien wskazywać stronę krzywej, na której można oczekiwać załamania.

Uwaga: możesz mieć zerowy promień krzywizny lub nieskończony promień krzywizny; może być lepiej zamiast tego porównać |B'(t)|^3 z signed_offset * cross2d(B'(t), B''(t)).

+0

Awesome. Wygląda na to, że zadziała. Dam ci spróbować i wrócę do ciebie. To może trochę potrwać.:) +1 –

+0

Przebacz mi, jeśli to głupie pytanie, ale jak powiedziałem, matematyka nie jest moją mocną stroną. Podczas gdy twoja funkcja cross2d (p, q) przyjmuje do wiadomości, że moje punkty P są współrzędnymi xiy, funkcje B, B 'i B' 'nie. Czy to znaczy, że po prostu wykonuję je raz dla każdej osi? –

+0

'B (t)', 'B '(t)' i 'B' '(t)' powinny być wektorami 2D, podobnie jak 'P0',' P1', 'P2' i' P3' . Zwróć też uwagę, że '| B '(t) |' powinno przyjmować długość wektora 2-D. Najlepiej jest użyć struktury 'Vector2' (lub dowolnej istniejącej struktury, której używasz obecnie dla twoich punktów 2-D), więc nie musisz wielokrotnie przeliczać ciężarów Beziera. Możesz jednak pisać funkcje skalarne i uruchamiać je dla każdej osi, jeśli chcesz. Pamiętaj, że będziesz musiał ponownie je połączyć, obliczając długość wektora i krzyżyk2(). – comingstorm