Obcinanie prymitywów Mirosław Głowacki Wydział Inżynierii Metali i Informatyki Przemysłowej AGH
Obcinanie odcinków Z reguły odcinki linii prostej muszą być obcinane przez prostokąty np. okna Wielokąty i pozostałe prymitywy mogą być obcinane na zasadzie wielokrotnego obcinania odcinków Obcinanie prostokąta przez prostokąt daje najwyżej jeden prostokąt Obcinanie wielokąta wypukłego daje co najwyżej jeden wielokąt wypukły Obcinanie okręgu przez prostokąt może dać aż cztery łuki Obcinany odcinek daje zawsze jeden segment Odcinki leżące dokładnie na brzegu nie są obcinane
Przypadki obcinania odcinków a) przypadki obcinania, b) wynik obcinania
Algorytm prymitywny Aby punkt nie został obcięty muszą być spełnione cztery nierówności x min x x max y min y y max gdzie x min, x max, y min, y max graniczne wartości współrzędnych prostokąta obcinającego
Obcinanie odcinków rozwiązywania równań Jeśli oba końce odcinka leżą wewnątrz prostokąta obcinającego (odcinek AB), to odcinek jest w całości akceptowany Jeśli jeden koniec odcinka leży wewnątrz prostokąta obcinającego, a drugi na zewnątrz (odcinek CD), to odcinek musi zostać obcięty należy obliczyć współrzędne przecięcia
Obcinanie odcinków rozwiązywania równań Jeśli oba końce odcinka leżą na zewnątrz prostokąta obcinającego (odcinki EF, GH, IJ), to odcinek może, ale nie musi przecinać prostokąta należy przeprowadzić dalsze ustalenia i obliczyć przecięcia Rozwiązanie polegające na obliczaniu przecięć z każdym z boków prostokąta jest trudne do zaakceptowania
Przecięcia z brzegiem prostokąta Dla każdego odcinka i krawędzi prostokąta wyznacza się punkt przecięcia zawierających je nieskończonych prostych Następnie należy sprawdzić, czy otrzymany punkt przecięcia jest wewnętrzny tzn. czy leży na obu odcinkach Punkty G i H są punktami wewnętrznymi, a punkty I i J nie. Takie podejście wymaga rozwiązania układu równań i wykonanie mnożenia i dzielenia dla każdej pary: odcinekkrawędź Ponadto istnieje problem linii pionowych, który zostaje rozwiązany poprzez parametryczny opis prostych
Przecięcia z brzegiem prostokąta Aby znaleźć punkt (x, y) przecięcia odcinka z bokiem prostokąta x 0, y 0 (x 1, y 1 )należy rozwiązać układ równań: x = x 0 + t x 1 x 0 y = y 0 + t y 1 y 0 układ może zostać rozwiązany ze względu na t line dla linii i dla t edge dla krawędzi Jeśli obie wartości leżą w zakresie od 0 do 1, to punkt należy do obu odcinków i jest wynikiem obcinania Zaprezentowane podejście wiąże się z dużą liczbą obliczeń i sprawdzeń i jest bardzo nieefektywne
Algorytm Cohena-Sutherlanda Wykorzystuje testy początkowe dla określenia czy nie da się uniknąć obliczania przecięć Jeśli odcinek nie może być bezpośrednio zaakceptowany, to wykonuje się sprawdzanie obszarów Przykładowo dwa proste porównania odciętych pokazują, że punkty końcowe odcinka EF leżą na lewo od prostokąta obcinającego, co eliminuje odcinek Podobnie można odrzucić odcinki dla których oba końce leżą: na prawo od x max, poniżej y min oraz powyżej y max Odcinki, które nie mogą być w całości odrzucone lub zaakceptowane są dzielone na dwie części przez jedną z krawędzi i jedna część jest odrzucana
Algorytm Cohena-Sutherlanda Odcinek jest iteracyjnie dzielony dopóki to co pozostanie nie zostanie w całości zaakceptowane lub odrzucone Algorytm jest szczególnie efektywny gdy: prostokąt obejmuje całość lub większość pola wyświetlania większość prymitywów może zostać w całości zaakceptowana dla małych prostokątów większość prymitywów może zostać w całości odrzucona W celu wykonania testów akceptacji-odrzucenia przedłuża się krawędzie prostokąta tak, aby utworzyły dziewięć pól i każdemu z nich nadaje się odpowiedni kod
Kody obszarów w systemie dwójkowym
Algorytm Cohena-Sutherlanda Każdy z kodów jest czterobitowy i wynika z położenia obszaru względem czterech półpłaszczyzn zewnętrznych dla krawędzi prostokąta obcinającego pierwszy bit półpłaszczyzna powyżej górnej krawędzi ( y > y max ) drugi bit półpłaszczyzna poniżej dolnej krawędzi (y < y min ) trzeci bit półpłaszczyzna na prawo od prawej krawędzi ( x > x max ) czwarty bit półpłaszczyzna na lewo od lewej krawędzi ( x < x min )
Algorytm Cohena-Sutherlanda Poszczególne bity kodów są obliczane jako bity znaku następujących różnic: pierwszy bit kod znaku różnicy ( y max y ) drugi bit kod znaku różnicy ( y y min ) trzeci bit kod znaku różnicy ( x max x ) czwarty bit kod znaku różnicy ( x x min ) Każdemu końcowi odcinka jest przypisywany kod obszaru, w którym się znajduje
Algorytm Cohena-Sutherlanda Jeśli oba kody końców odcinka są zerowe, to odcinek leży wewnątrz prostokąta obcinającego Jeśli któreś z bitów kodu dla obu końców odcinka są równocześnie jedynkami, to odcinek leży w jednej z zewnętrznych półpłaszczyzn Przykładowo, czwarty bit dla końców odcinka EF (kody: 0001 oraz 1001) jest równy 1 Jeśli iloczyn logiczny ( and ) obu kodów nie jest równy zeru, to odcinek można bezpośrednio odrzucić Jeśli odcinek nie został odrzucony ani zaakceptowany, to musi zostać podzielony którąś z krawędzi. Część leżąca w zewnętrznej półpłaszczyźnie jest odrzucana
Algorytm Cohena-Sutherlanda Algorytm powinien korzystać z tego samego porządku testowania krawędzi: np. góra-dółprawa-lewa Jeśli jeden z punktów końcowych odcinka leży w zewnętrznej półpłaszczyźnie, a odcinek nie został odrzucony w całości, to jego drugi koniec musi leżeć w wewnętrznej części półpłaszczyzny, a odcinek przecina krawędź tworzącą tę półpłaszczyznę
Przykład zastosowania algorytmu Ilustracja metody Cohena-Sutherlanda obcinania odcinka.
Algorytm Cohena-Sutherlanda Algorytm wybiera punkt zewnętrzny odcinka i wykorzystuje ustawione dla niego bity kodu do określenia półpłaszczyzny obcinającej Algorytm analizuje kod z lewej do prawej, tzn. poszukuje przecinanych krawędzi w kolejności: góra-dół-prawa-lewa Następnie oblicza się współrzędne punktu przecięcia i przyjmuje się go zamiast punktu zewnętrznego wyznaczając przy tym kod dla tego punktu wykorzystywany w następnej iteracji
Przykładowe odcinki Odcinek AD: punkt A ma kod 0000 punkt D ma kod 1001 odcinek nie może być bezpośrednio zaakceptowany ani odrzucony punkt D jest punktem zewnętrznym jego kod wskazuje, że odcinek przecina krawędzie: górną i lewą zgodnie z przyjętą kolejnością najpierw obcinamy krawędzią górną i otrzymujemy odcinek AB wyznaczamy kod punktu B jako 0000 w kolejnej iteracji odcinek AB może zostać w całości zaakceptowany gdyż oba końce posiadają kod 0000
Przykładowe odcinki Odcinek EI wymaga szeregu iteracji punkt E ma kod 0100 punkt I ma kod 1010 odcinek nie może być bezpośrednio zaakceptowany ani odrzucony punkt E jest punktem zewnętrznym jego kod wskazuje, że odcinek przecina krawędź dolną EI zostaje obcięty do FI kod punktu F obliczono jako 0000, co kończy pierwszą iterację
Przykładowe odcinki punkt F ma kod 0000 algorytm wybiera jako zewnętrzny punkt I o kodzie 1010 odcinek nie może być bezpośrednio zaakceptowany ani odrzucony kod punktu I sugeruje, że odcinek przecina krawędzie: górną i prawą wybrana zostaje górna w drugiej iteracji EI zostaje obcięty do FH kod punktu H obliczono jako 0010 w trzeciej iteracji odcinek zostaje obcięty do FG i G otrzymuje kod 0000 w czwartej iteracji odcinek FG zostaje zaakceptowany
Algorytm Cohena-Sutherlanda Algorytm nie jest nadzwyczaj efektywny gdyż czasami wykonuje niepotrzebne obcinania gdy punkt przecięcia odcinka i krawędzi leży poza prostokątem obcinającym Istnieją inne algorytmy, np. Nicholla, Lee i Nicholla, które dzielą obszar na większą liczbę podobszarów i unikają przecięć zewnętrznych Algorytm Cohena-Sutherlanda ma jednak tę zaletę, że może z łatwością być rozszerzony do przestrzeni 3D i obcinać przy pomocy prostokątnej bryły widzenia
Parametryczny algorytm obcinania odcinków Cyrus i Beck opublikowali w 1978 r. bardziej efektywny algorytm parametryczny Może być stosowany do obcinania odcinków prostokątami i wielokątami wypukłymi na płaszczyźnie oraz wielościanami wypukłymi w przestrzeni 3D Liang i Barsky niezależnie opracowali jeszcze bardziej efektywny algorytm, wyjątkowo szybki w przypadku obcinania przez obszary 2D i 3D o bokach równoległych do osi układu współrzędnych
Algorytmy parametryczne Są oparte na poszukiwaniu wartości parametru t dla przecinających się: odcinka i krawędzi obcinającej Ponieważ każda z krawędzi może przecinać odcinek, więc poszukiwane są cztery wartości parametru t W celu określenia, które z wartości parametru t gwarantują faktyczne przecięcia korzysta się z prostych porównań Współrzędne oblicza się tylko dla jednego lub dwóch faktycznych przecięć. Podejście takie jest oszczędniejsze od algorytmu Cohena- Suterlanda, gdyż unika się powtarzania pętli niezbędnych przy wielokrotnym obcinaniu oraz obliczenia w jednowymiarowej przestrzeni parametrów są prostsze od obliczeń przecięć w przestrzeni 2D i 3D. Linag i Barsky ulepszyli algorytm Cyrusa-Becka poprzez sprawdzanie konieczności obliczania parametru t
Algorytm Cyrusa-Becka Iloczyny skalarne N i P t P E i dla trzech punktów zewnętrznego, wewnętrznego i na granicy obszaru obcinającego.
Algorytm Cyrusa-Becka Wykorzystuje następujące przecięcie dwóch linii: dla krawędzi E i określa się normalną N i skierowaną na zewnątrz prostokąta obcinającego krawędź ta, podobnie jak obcinany odcinek P 0 P 1 są przedłużane w celu znalezienia punktu przecięcia (wartości parametru t t = 0 w punkcie P 0, t = 1 w punkcie P 1 ) z zależności: P P t P P 0 1 0
Algorytm Cyrusa-Becka dla dowolnego punktu P Ei na krawędzi E i rozważane są trzy wektory P(t) P Ei poprowadzone od trzech punktów na odcinku P 0 P 1 : poszukiwanego punktu przecięcia końca odcinka w wewnętrznej półpłaszczyźnie wyznaczonej prze krawędź obcinającą końca odcinka w zewnętrznej półpłaszczyźnie krawędzi To, w którym obszarze leży punkt można określić na podstawie znaku iloczynu skalarnego: N i P t P E i
Algorytm Cyrusa-Becka Wartość iloczynu skalarnego jest : ujemna dla punktu w wewnętrznej półpłaszczyźnie zerowa dla punktu należącego do krawędzi dodatnia dla punktu w zewnętrznej półpłaszczyźnie Definicje wewnętrznej i zewnętrznej półpłaszczyzny określonej przez krawędź odpowiadają numerowaniu krawędzi prostokąta obcinającego w kierunku odwrotnym do ruchu wskazówek zegara Wartość parametru dla przecięcia P 0 P 1 z krawędzią znajduje się z równania N i P t P E i = 0
Algorytm Cyrusa-Becka Po podstawieniu równania parametrycznego w miejsce P(t) otrzymamy: N i P 0 + t P 1 P 0 P E i = 0 a po prostych przekształceniach: N i P 0 P E i + N i t P 1 P 0 = 0
Algorytm Cyrusa-Becka Jeśli oznaczymy D = P 1 P 0 to wzór na parametr t przybierze postać t = N i P 0 P E i N i D poprawną wartość t otrzymuje się tylko wówczas gdy mianownik równania jest różny od 0 wiemy, że z założenia N i 0 podobnie D 0 wtedy gdy P 1 P 0 podobnie N i D 0 jeżeli krawędź E i i odcinek P 0 P 1 nie są równoległe gdyby było inaczej, to algorytm przechodzi do następnego przypadku wszystkie wartości parametru spoza zakresu [0, 1] są automatycznie odrzucane Również gdy parametr mieści się w zakresie [0, 1] istnieją trudności w analizie przecięć
Algorytm Cyrusa-Becka Odcinki leżące ukośnie względem prostokąta obcinającego.
Algorytm Cyrusa- Becka Można posortować wartości parametrów i wybrać wartości pośrednie, tak jak to ma miejsce dla odcinka nr 1 Jak jednak odróżnić ten przypadek od odcinka nr 2, dla którego żadne z przecięć nie należy do prostokąta obcinającego? Które z czterech przecięć odcinka nr 3 leżą na granicy obcinania? Przecięcia są klasyfikowane jako wchodzące (PE) i wychodzące (PL) z prostokąta wycinającego Poruszając się od punktu P 0 do P 1 przecinamy krawędź tak, że wchodzimy do wewnętrznej półpłaszczyzny krawędzi przecięcie jest typu PE Jeśli natomiast wychodzimy z wewnętrznej półpłaszczyzny krawędzi to przecięcie jest typu PL Należy zauważyć, że przy takim podejściu dwa sąsiednie wewnętrzne punkty są klasyfikowane jako przeciwne
Algorytm Cyrusa-Becka Formalnie przecięcia mogą być klasyfikowane jako PE i PL na podstawie kąta pomiędzy P 0 P 1 i N i jeśli kąt jest mniejszy od 90 o, to przecięcie jet typu PL jeśli kąt jest większy od 90 o, to przecięcie jet typu PE Taka informacja jest zawarta w znaku iloczynu dla P 0 P 1 i N i N i D < 0 α > 90 N i D > 0 α < 90
Algorytm Cyrusa-Becka Iloczyn N i i D jest obliczany w trakcie poszukiwania parametru t i wtedy też następuje klasyfikacja przecięć Odcinek nr 3 sugeruje ostatni krok należy wybrać parę PE PL, która określa obcięty odcinek część odcinka, która leży wewnątrz czworokąta obcinającego charakteryzująca się przecięciem PE o największej wartości t, oznaczanej t E oraz przecięciem PL o najmniejszej wartości t, oznaczanej t L obcięty odcinek jest określony przez parametr t z przedziału (t E, t L ) pod warunkiem, że dolną granicą t E jest 0, a górną t L jest 1 Natomiast jeśli t E > t L (przypadek odcinka nr 2) to żadna część odcinka nie leży wewnątrz prostokąta obcinającego i cały odcinek jest odrzucany Wartości t E i t L są podstawą do obliczenia współrzędnych punktów przecięcia
Obcinanie wielokątów Przykłady obcinania wielokąta: a. wiele elementów b. prosty przypadek wielokąta wypukłego c. przypadek wielokąta niewypukłego z wieloma zewnętrznymi krawędziami.
Obcinanie wielokątów Algorytm musi uwzględniać przedstawione przypadki najciekawszy jest przypadek a) wielokąt niewypukły jest dzielony obcinaniem na dwa wielokąty każda krawędź wielokąta musi być testowana względem każdej krawędzi prostokąta obcinającego niekiedy trzeba dodać nowe krawędzie, a istniejące mogą być odrzucone, zachowane bądź podzielone w ogólnym przypadku z jednego wielokąta może powstać kilka wielokątów
Algorytm Sutherlanda-Hodgmana obcinania wielokąta Wykorzystuje strategię dziel i zwyciężaj rozwiązuje się szereg prostych identycznych problemów, które po połączeniu dają pożądany wynik dla całości Prosty problem polega na obcinaniu wielokąta przez jedną, nieskończenie długą krawędź obcinającą kolejne obcięcia czterema krawędziami boków prostokąta obcinającego dają pożądany efekt
Algorytm Sutherlanda-Hodgmana Obcinanie wielokąta krawędź po krawędzi: a. przed obcinaniem, b. obcinanie przez prawą krawędź, c. obcinanie przez dolną krawędź, d. obcinanie przez lewą krawędź, e. obcinanie przez górną krawędź wielokąt jest całkowicie obcięty.
Algorytm Sutherlanda-Hodgmana Polega na obcinaniu dowolnego wielokąta (wypukłego lub niewypukłego) dowolnym wielokątem wypukłym W przestrzeni 3D wielokąty mogą być obcinane przez wypukłe wielościany zdefiniowane przez płaszczyzny Algorytm akceptuje ciąg v 1, v 2,, v n wierzchołków W przestrzeni 2D wierzchołki definiują krawędzie od v i do v i + 1 i v n do v 1 Algorytm obcina względem jednej, nieskończenie długiej krawędzi i oblicza ciąg wierzchołków definiujących obcięty wielokąt Proces jest powtarzany iteracyjnie dla kolejnych krawędzi obcinających Algorytm porusza się wokół wielokąta od v n do v 1 i potem z powrotem do v n, sprawdzając na każdym kroku zależność pomiędzy kolejnymi wierzchołkami i krawędzią obcinającą Za każdym razem należy brać pod uwagę cztery możliwe przypadki
Algorytm Sutherlanda-Hodgmana Cztery przypadki obcinania wielokąta
Algorytm Sutherlanda-Hodgmana Algorytm jest iteracyjny i wykorzystuje strategię dziel i zwyciężaj, tzn. dzieli problem na wiele elementarnych, łatwych do rozwiązania podproblemów. Wykorzystuje fakt, iż wielokąt wypukły można przedstawić jako część wspólną półpłaszczyzn wyznaczanych przez boki tego wielokąta. Znalezienie części wspólnej wielokąta i półpłaszczyzny jest bardzo proste.
Algorytm Sutherlanda-Hodgmana W jednym kroku algorytmu znajdywana jest część wspólna wielokąta oraz półpłaszczyzny, a otrzymany w ten sposób wielokąt jest przetwarzany w kroku kolejnym: W = obcinany wielokąt, W o = wypukły wielokąt obcinający dla wszystkich krawędzi W o wykonuj: L := wyznacz prostą na której leży krawędź W := wyznacz część wspólną wielokąta W i półpłaszczyzny zdefiniowanej przez prostą L
Algorytm Sutherlanda-Hodgmana Po przejrzeniu wszystkich wierzchołków otrzymuje się ciąg wierzchołków wielokąta będącego częścią wspólną W i półpłaszczyzny. Niestety może zdarzyć się tak, że wielokąt zostanie rozdzielony na dwa lub więcej wielokątów i wówczas pojawiają się dodatkowe krawędzie leżące na prostej L. Można je jednak wyeliminować po zakończeniu całego algorytmu. Pewnym problemem jest określenie po której stronie prostej L znajduje się wnętrze wielokąta obcinającego W o. Rozwiązanie jest następujące: należy przeglądać boki W o kolejno, tzn. v 0, v 1, v 1, v 2,, v i, v j,, v n, v 0 i na ich postawie wyznaczać równanie prostej, np. w postaci parametrycznej: v i + t v j v i Wówczas jeśli wierzchołki są podawane w kierunku przeciwnym do ruchu wskazówek zegara, to wektory normalne wszystkich prostych wskazują wnętrze.
Algorytm Sutherlanda-Hodgmana Najważniejszym elementem algorytmu jest wyznaczanie części wspólnej wielokąta W i półpłaszczyzny. Przeglądane są kolejne wierzchołki w ten sposób, że w jednej iteracji analizowana jest tylko jedna krawędź; oznaczmy pierwszy wierzchołek v i przez S, drugi v j przez N: 1 Jeśli obydwa wierzchołki leżą wewnątrz W o, wówczas zapamiętywany jest tylko wierzchołek N. 2 Jeśli obydwa wierzchołki leżą na zewnątrz, wówczas żaden wierzchołek nie jest zapamiętywany.
Algorytm Sutherlanda-Hodgmana W przeciwnym razie krawędź W przecina prostą L i należy obliczyć punkt przecięcia (ozn. P) odcinka SN z prostą: 3 jeśli S leży wewnątrz a N na zewnątrz, to zapamiętywany jest tylko punkt przecięcia P 4 jeśli jest odwrotnie (N wewnątrz, S na zewnątrz) to zapamiętywane są dwa punkty: P i N (w tej kolejności).