GKIW Moduł 7: Różnice pomiędzy wersjami
Z Studia Informatyczne
Przejdź do nawigacjiPrzejdź do wyszukiwania
Nie podano opisu zmian |
Nie podano opisu zmian |
||
Linia 43: | Linia 43: | ||
|width="500px" valign="top"|[[Grafika:GKIW_M7_Slajd6.png|thumb|500px]] | |width="500px" valign="top"|[[Grafika:GKIW_M7_Slajd6.png|thumb|500px]] | ||
|valign="top"| | |valign="top"| | ||
'''Algorytm malarski I | '''Algorytm malarski I''' | ||
Algorytm malarski (algorytm sortowania ścian)''' należy do grupy algorytmów z listą priorytetów. Algorytmy te wykorzystują informacje zarówno z przestrzeni obiektu jak i z przestrzeni rzutu (łączą operacje z precyzją obiektową i operacje z precyzją obrazową). Algorytm malarski zaproponowany przez Newella, Newella i Sancha w 1972 roku. Jest jednym z najprostszych opisowo i jednocześnie efektywnym. Polega on na posortowaniu elementarnych fragmentów sceny (wielokątów) zależnie od odległości od obserwatora: od najdalszego do najbliższego. Fragmenty są następnie rysowane w tej kolejności. Zakłada się przy tym, że rysunek powstaje analogicznie do malowania obrazu olejnego (stąd nazwa algorytmu). Tzn. fragment później namalowany zasłania (zamalowuje) wszystko, co było dotychczas namalowane w tym miejscu. Oczywiście tę cechę ma każde urządzenie wyświetlające (monitor, wyświetlacz LCD), ale stosowanie tego algorytmu bezpośrednio na drukarce byłoby niemożliwe. | '''Algorytm malarski (algorytm sortowania ścian)''' należy do grupy algorytmów z listą priorytetów. Algorytmy te wykorzystują informacje zarówno z przestrzeni obiektu jak i z przestrzeni rzutu (łączą operacje z precyzją obiektową i operacje z precyzją obrazową). Algorytm malarski zaproponowany przez Newella, Newella i Sancha w 1972 roku. Jest jednym z najprostszych opisowo i jednocześnie efektywnym. Polega on na posortowaniu elementarnych fragmentów sceny (wielokątów) zależnie od odległości od obserwatora: od najdalszego do najbliższego. Fragmenty są następnie rysowane w tej kolejności. Zakłada się przy tym, że rysunek powstaje analogicznie do malowania obrazu olejnego (stąd nazwa algorytmu). Tzn. fragment później namalowany zasłania (zamalowuje) wszystko, co było dotychczas namalowane w tym miejscu. Oczywiście tę cechę ma każde urządzenie wyświetlające (monitor, wyświetlacz LCD), ale stosowanie tego algorytmu bezpośrednio na drukarce byłoby niemożliwe. | ||
|} | |} | ||
Linia 169: | Linia 169: | ||
|width="500px" valign="top"|[[Grafika:GKIW_M7_Slajd15.png|thumb|500px]] | |width="500px" valign="top"|[[Grafika:GKIW_M7_Slajd15.png|thumb|500px]] | ||
|valign="top"| | |valign="top"| | ||
'''Algorytm podziału binarnego III''' | |||
W warunkach rzeczywistej analizy sceny przy wyborze płaszczyzn podziału warto posługiwać się płaszczyznami związanymi bezpośrednio z obiektami (zawierającymi na przykład ściany). Przykład przekroju sceny i odpowiadające mu drzewo podziału prezentuje rysunek. Zakładamy dla uproszczenia, że w każdym obszarze (ponumerowanym) znajduje się jeden obiekt. Stosując algorytm binarnego podziału należy wyznaczyć kolejność rysowania, w taki sposób, aby z punktu widzenia obserwatora rysować obiekty od najdalszych do najbliższych (najpierw zasłaniane potem zasłaniające). Drzewo uwzględnia wszystkie ściany i pozwala wskazać kolejność zasłaniania po przejściu zaproponowanym algorytmem drzewa. | |||
Oczywiście drzewo nie uwzględnia położenia obserwatora, natomiast położenie to wpływa na drogę przejścia przez drzewo. Rysunek pokazuje różne kolejności rysowania obiektów dla dwóch różnych położeń obserwatora. | |||
Ciekawym przypadkiem jest sytuacja, gdy obserwator znajduje się wewnątrz obszaru. Wtedy drzewo binarnego podziału pokazuje właściwą kolejność bez względu na kierunek patrzenia obserwatora ! | |||
Algorytm drzewa binarnego podziału przestrzeni był bardzo długo traktowany jako niezwykle elegancka ciekawostka, ze względu na skomplikowanie tworzenia drzewa podziału. Dopiero silny rozwój gier komputerowych w latach 90 dwudziestego wieku spowodował, że algorytm ten przeżywa swój renesans. Zauważono bowiem, że warto na użytek gier rozdzielić etap tworzenia drzewa od etapu przeglądania. Jeśli przyjmiemy, że w każdym elemencie podziału znajduje się jeden obiekt sceny, to samo przeglądanie algorytmem INORDER± ma złożoność liniową ze względu na liczbę obiektów i to niezależnie od zbalansowania drzewa. | |||
Drzewo zostaje zatem utworzone przez twórców gry w momencie generowania „mapy” gry. Natomiast przeglądane jest w momencie realizacji (wirtualnego poruszania się gracza/bohatera po świecie gry). Co więcej, sprawę można dodatkowo uprościć dzieląc mapę na obszary, w których jest ustalona kolejność rysowania obiektów, a następnie zapisać gotowe schematy kolejności dla poszczególnych obszarów. W tym przypadku podczas realizacji gry nawet przeglądanie drzewa nie jest potrzebne. | |||
Warto dodać, że w latach 1992-1995 (Teller, Luebke, Georges) powstała metoda wyboru potencjalnych elementów widocznych (ang.PVS – Potentially Visible Set) pozwalająca określić przybliżony zakres widoczności obiektów. Metoda ta jest często łączona z generacją drzewa BSP. | |||
|} | |} | ||
---- | ---- | ||
Linia 175: | Linia 186: | ||
|width="500px" valign="top"|[[Grafika:GKIW_M7_Slajd16.png|thumb|500px]] | |width="500px" valign="top"|[[Grafika:GKIW_M7_Slajd16.png|thumb|500px]] | ||
|valign="top"| | |valign="top"| | ||
'''Algorytm bufora głębokości I''' | |||
Algorytm bufora głębokości (Z-bufora) został zaproponowany przez Catmulla w 1974 roku. Jest jednym z najprostszych w implementacji algorytmów rozstrzygania widoczności. Zakłada istnienie bufora o rozmiarze całego wyświetlanego obszaru (ekranu) – występuje w tym przypadku odpowiedniość pozycji piksela ekranu i odpowiadającej mu pozycji w buforze. Dla każdego piksela w buforze zapamiętywana jest odpowiadająca mu głębokość czyli współrzędna zp. | |||
Na początku pracy algorytmu bufor Z jest wypełniany maksymalną wartością współrzędnej z, jaka może wystąpić w analizowanym obszarze. Jednocześnie wszystkie piksele obrazu przyjmują barwę tła. Następnie rysowane są wielokąty (w dowolnej kolejności) – to znaczy wypełniane są ich rzuty odpowiednią barwą. Podczas wypełniania zwykła procedura wypełniająca jest poszerzona o sprawdzenie głębokości odpowiadającej danemu pikselowi. Piksel jest wypełniony tylko wtedy, kiedy jego z jest mniejsze niż wartość zapisana w buforze. | |||
Mechanizm ten powoduje, że podczas wypełniania kolejnych wielokątów szukany jest piksel, którego współrzędna z jest najmniejsza – to znaczy szukany jest punkt leżący najbliżej obserwatora – czyli punkt rzeczywiście widoczny. | |||
|} | |} | ||
---- | ---- | ||
Linia 181: | Linia 198: | ||
|width="500px" valign="top"|[[Grafika:GKIW_M7_Slajd17.png|thumb|500px]] | |width="500px" valign="top"|[[Grafika:GKIW_M7_Slajd17.png|thumb|500px]] | ||
|valign="top"| | |valign="top"| | ||
'''Algorytm bufora głębokości II''' | |||
Algorytm bufora głębokości rozstrzyga widoczność dla dowolnych scen wielościennych, jest niewrażliwy na zasłanianie cykliczne ani przecinanie obiektów. Nie wymaga żadnych dodatkowych struktur danych ani operacji wstępnych. Dodatkowo, biorąc pod uwagę fakt, że wielokąty są obiektami płaskimi można wyznaczyć proste zależności przyrostowe wiążąc kolejne zmiany współrzędnych z wypełnianiem wielokąta liniami. Powoduje to, że dodatkowy czas potrzebny na rozszerzenie algorytmu wypełniania o rozstrzyganie widoczności jest niewielki. Przyjmuje się, że jest to algorytm o złożoności liniowej ze względu na liczbę wielokątów, ale dla ich dużej liczby czas rozstrzygania widoczności staje się w przybliżeniu praktycznie niezależny od liczby wielokątów w danej bryle widzenia. | |||
Algorytm ma tylko jedną wadą – potrzebuje pamięci o rozmiarze obrazu pozwalającej zapisać odległość dla każdego piksela. Jeszcze do niedawna (koniec dwudziestego wieku) był to warunek trudny do spełnienia. Realizacja algorytmu wymagała dodatkowo wykonania podziału obrazu na fragmenty, które mogły być razem z odpowiadającym mu buforem zmieszczone do pamięci. Dzisiaj nie stanowi to żadnego problemu. | |||
Prostota algorytmu sprzyja również implementacji sprzętowej. Stacje graficzne i większość dobrych kart graficznych ma dzisiaj możliwość sprzętowej realizacji bufora głębokości. | |||
|} | |} | ||
---- | ---- | ||
Linia 187: | Linia 210: | ||
|width="500px" valign="top"|[[Grafika:GKIW_M7_Slajd18.png|thumb|500px]] | |width="500px" valign="top"|[[Grafika:GKIW_M7_Slajd18.png|thumb|500px]] | ||
|valign="top"| | |valign="top"| | ||
'''Algorytm rysowania wykresu funkcji z=f(x,y) I''' | |||
Zadanie rysowania powierzchni będącej wykresem funkcji dwóch zmiennych jest jednym z częściej realizowanych zadań grafiki prezentacyjnej. Dodatkowo można zauważyć, że jest to dobry sposób uproszczonego rysowania rzeźby terenu. | |||
Powierzchnia będąca wykresem funkcji z=f(x,y) należy do szczególnej klasy obiektów trójwymiarowych, dla której można pokazać uproszczony algorytm rozstrzygania widoczności. | |||
Można przyjąć, że dziedziną D funkcji dla rozpatrywanego fragmentu powierzchni jest prostokątem [xmin,xmax] x [ymin,ymax]. Jeśli dziedzinę D podzielimy równomierną siatką za pomocą linii równoległych odpowiednio do osi x i osi y, to punkt [xi,yj] będzie węzłem takiej siatki (dla 1 i NX oraz 1 j NY, gdzie NX, NY określają liczbę linii siatki dla każdej współrzędnej). Punkt [zij,xi,yj] dla zij=f(xi,yj) jest węzłem siatki rozpiętej na powierzchni będącej wykresem punkcji. Taki przykład najczęściej występuje w zastosowaniach praktycznych, gdzie wartości węzłowe pochodzą na przykład z pomiarów lub symulacji. Przybliżoną powierzchnię rysujemy łącząc węzły odcinkami. | |||
Watkins w 1974 roku zaproponował algorytm maskowania pozwalający rysować kolejne krzywe (łamane) siatki rozpiętej na powierzchni będącej wykresem funkcji. Można zauważyć dotychczas narysowany fragment (pierwszym takim fragmentem jest obszar powierzchni pomiędzy pierwszymi dwoma krzywymi/łamanymi) może zasłaniać wszystkie później rysowane elementy powierzchni. A zatem do realizacji algorytmu wystarczy zdefiniować bufor górny (ograniczenie górne YOG we współrzędnych rzutu) i bufor dolny (ograniczenie dolne YOD we współrzędnych rzutu), a następnie w każdym kroku sprawdzać położenie rysowanego elementu (odcinka) względem buforów. Jeśli element jest powyżej ograniczenia górnego lub poniżej dolnego to jest rysowany, w przeciwnym przypadku (między ograniczeniami) to nie jest rysowany. Oczywiście każdy narysowany element powiększa (rozszerza w danym kierunku) odpowiednie ograniczenie. | |||
|} | |} | ||
---- | ---- | ||
Linia 193: | Linia 223: | ||
|width="500px" valign="top"|[[Grafika:GKIW_M7_Slajd19.png|thumb|500px]] | |width="500px" valign="top"|[[Grafika:GKIW_M7_Slajd19.png|thumb|500px]] | ||
|valign="top"| | |valign="top"| | ||
'''Algorytm rysowania wykresu funkcji z=f(x,y) II''' | |||
Standardowe podejście w algorytmie maskowania Watkinsa wymaga podczas rysowania analizy położenia odcinka względem łamanej (górnego ograniczenia lub dolnego). Tego typu zadanie jest klasycznym zadaniem geometrii obliczeniowej i nie należy do najprostszych – wymagałoby dodatkowego, znaczącego czasu realizacji. Można zmodyfikować problem tak, aby nie było to w ogóle konieczne. | |||
W tym celu rozpatrzmy tę samą sytuację ale na mapie pikseli. Ograniczenia górne i dolne w tym przypadku odpowiadają zestawowi pikseli, które w kolejnych kolumnach określają minimalną i maksymalną wysokość. Rysując każdy nowy piksel wystarczy sprawdzić jego położenie względem tego minimum lub maksimum. A to jest operacją bardzo prosta. Jeśli nowy piksel jest powyżej maksimum (lub poniżej minimum) to jest rysowany, jeśli pomiędzy minimum i maksimum to rysowany nie jest. Oczywiście rysowany piksel przesuwa odpowiednie maksimum (lub minimum). | |||
|} | |} | ||
---- | ---- | ||
Linia 199: | Linia 234: | ||
|width="500px" valign="top"|[[Grafika:GKIW_M7_Slajd20.png|thumb|500px]] | |width="500px" valign="top"|[[Grafika:GKIW_M7_Slajd20.png|thumb|500px]] | ||
|valign="top"| | |valign="top"| | ||
'''Algorytm rysowania wykresu funkcji z=f(x,y) III''' | |||
Zaproponowany mechanizm maskowania dla mapy pikseli może zostać połączony z algorytmem Bresenhama rysowania odcinka. Tak zmodyfikowany algorytm będzie rysował odcinki z uwzględnieniem rozstrzygania widoczności dla siatki rozpiętej na powierzchni będącej wykresem funkcji dwóch zmiennych. Można pokazać że modyfikacja algorytmu Bresenhama wymaga dodania jednej instrukcji porównania i jednej instrukcji podstawienia. Nie zmienia to znacząco czasu realizacji rysowania odcinków. | |||
Dodatkowo należy zwrócić uwagę na kolejność wyboru do rysowania odcinków siatki. Jeśli byłyby one rysowane w naturalnej kolejności związanej z rodzinami linii dla stałego x, i dla stałego y, to mogłyby wystąpić problemy z wzajemnym zasłanianiem. Dobrym rozwiązaniem jest kolejność typu ZIG-ZAG (tzn. odcinki na przemian z każdej rodziny) lub kolejność zaproponowana na rysunku. | |||
Warto dodatkowo zwrócić uwagę na fakt, że taka wersja algorytmu poprawnie pracuje tylko dla rzutu równoległego wykresu funkcji. Analiza rysowania na mapie pikseli z uwzględnieniem minimum i maksimum kolumny pokazuje, że dla odcinków rysowanych w rzucie perspektywicznym wystąpią błędy. | |||
|} | |} | ||
---- | ---- | ||
Linia 205: | Linia 248: | ||
|width="500px" valign="top"|[[Grafika:GKIW_M7_Slajd21.png|thumb|500px]] | |width="500px" valign="top"|[[Grafika:GKIW_M7_Slajd21.png|thumb|500px]] | ||
|valign="top"| | |valign="top"| | ||
'''Algorytm rysowania wykresu funkcji z=f(x,y) IV''' | |||
Inną możliwością rysowania powierzchni wykresu funkcji jest zastosowanie algorytmu malarskiego. Oczywiście wykres funkcji pozwala zrezygnować sortowania koniecznego w algorytmie malarskim. W tym przypadku wystarczy uwzględnić kolejność wynikającą z odległości „oczek” siatki dziedziny funkcji od obserwatora. Na rysunku oczka o tym samym numerze mogą być rysowane w dowolnej kolejności – nie mogą się wzajemnie zasłaniać. | |||
Zastosowanie algorytmu malarskiego ma dodatkową zaletę: algorytm ten poprawnie rysuje powierzchnię będącą wykresem funkcji także dla rzutu perspektywicznego. | |||
Algorytm rysowania powierzchni będącej wykresem funkcji dwóch zmiennych jest przykładem algorytmu rozstrzygania widoczności dla szczególnej klasy obiektów trójwymiarowych. Drugim przykładem tego typu zadania jest algorytm rysowania figur obrotowych. Szczegóły tego algorytmu czytelnik może znaleźć w książce M.Jankowskiego Elementy grafiki komputerowej. | |||
|} | |} | ||
---- | ---- | ||
Linia 211: | Linia 261: | ||
|width="500px" valign="top"|[[Grafika:GKIW_M7_Slajd22.png|thumb|500px]] | |width="500px" valign="top"|[[Grafika:GKIW_M7_Slajd22.png|thumb|500px]] | ||
|valign="top"| | |valign="top"| | ||
'''Problem złożoności algorytmów zasłaniania I''' | |||
Twórcy algorytmów rozstrzygania widoczności starali się zawsze obniżyć złożoność obliczeniową tych algorytmów. Wielokrotnie były przeprowadzane analizy złożoności algorytmów zasłaniania. Pokazują one, że nawet najtrudniejsze przypadki mogą zostać rozwiązane ze złożonością kwadratową. Z drugiej strony można się zastanawiać nad minimalna liczbą operacji, niezbędnych do rozwiązania problemu zasłaniania. W większości przypadków wyrafinowane algorytmy wyznaczają elementy zasłonięte ze złożonością O(nlogn), gdzie n jest miarą złożoności sceny (liczbą wielokątów lub krawędzi). | |||
Dla algorytmów pracujących w przestrzeni rzutu (z precyzją obrazową) złożoność będzie liniowa. | |||
|} | |} | ||
---- | ---- | ||
Linia 217: | Linia 272: | ||
|width="500px" valign="top"|[[Grafika:GKIW_M7_Slajd23.png|thumb|500px]] | |width="500px" valign="top"|[[Grafika:GKIW_M7_Slajd23.png|thumb|500px]] | ||
|valign="top"| | |valign="top"| | ||
'''Problem złożoności algorytmów zasłaniania II''' | |||
Można pokazać, że dla wybranych scen minimalna złożoność algorytmów pracujących w przestrzeni obiektu musi być rzędu kwadratowego. Wynika to z budowy sceny. Wyrafinowane algorytmy mogą w tym przypadku dać rozwiązanie gorsze niż kwadratowe. | |||
|} | |} | ||
---- | ---- |
Wersja z 10:05, 27 paź 2006
![]() |
![]() |
![]() |
![]() |
![]() |
Bryła wypukła I Zadanie określenia widoczności elementów wielościanu wypukłego można więc rozwiązać na dwa sposoby korzystając z rozwiązań A i B sprawdzających zorientowanie poszczególnych ścian. |