GKIW Moduł 3: Różnice pomiędzy wersjami
Z Studia Informatyczne
Przejdź do nawigacjiPrzejdź do wyszukiwania
Nie podano opisu zmian |
m Zastępowanie tekstu – „\</math>” na „\ </math>” |
||
(Nie pokazano 4 wersji utworzonych przez 2 użytkowników) | |||
Linia 1: | Linia 1: | ||
{| border="0" cellpadding=" | __TOC__ | ||
| | = Wykład = | ||
{| border="0" cellpadding="4" width="100%" | |||
|width="500px" valign="top"|[[Grafika:GKIW_M3_Slajd_intro.png|thumb|500px]] | |||
|valign="top"| | |valign="top"| | ||
|} | |} | ||
<hr width="100%"> | <hr width="100%"> | ||
{| border="0" cellpadding=" | {| border="0" cellpadding="4" width="100%" | ||
| | |width="500px" valign="top"|[[Grafika:GKIW_M3_Slajd0.png|thumb|500px]] | ||
|valign="top"|Tworzenie obrazu na monitorze lub urządzeniu drukującym wymaga wypełnienia wybranego obszaru pikseli określonymi barwami w taki sposób, aby powstał zamierzony rysunek. Korzystając z edytora graficznego wybieramy pewne obiekty podstawowe – tak zwane prymitywy (np. odcinek) i żądamy narysowania ich w określonym miejscu. Nie zastanawiamy się w tym momencie nad tym, że żądanie to, z pozoru bardzo proste, wymaga rozwiązanie wielu problemów geometrycznych oraz opracowania skutecznych i szybkich algorytmów. I to bez względu na to czy będzie to realizowane przez odpowiednią bibliotekę czy tez sprzętowo przez kartę graficzną | |valign="top"|Tworzenie obrazu na monitorze lub urządzeniu drukującym wymaga wypełnienia wybranego obszaru pikseli określonymi barwami w taki sposób, aby powstał zamierzony rysunek. Korzystając z edytora graficznego wybieramy pewne obiekty podstawowe – tak zwane prymitywy (np. odcinek) i żądamy narysowania ich w określonym miejscu. Nie zastanawiamy się w tym momencie nad tym, że żądanie to, z pozoru bardzo proste, wymaga rozwiązanie wielu problemów geometrycznych oraz opracowania skutecznych i szybkich algorytmów. I to bez względu na to czy będzie to realizowane przez odpowiednią bibliotekę czy tez sprzętowo przez kartę graficzną | ||
Linia 14: | Linia 18: | ||
<hr width="100%"> | <hr width="100%"> | ||
{| border="0" cellpadding=" | {| border="0" cellpadding="4" width="100%" | ||
| | |width="500px" valign="top"|[[Grafika:GKIW_M3_Slajd1.png|thumb|500px]] | ||
|valign="top"|Jednym z podstawowych problemów tego typu jest '''zadanie narysowania odcinka na mapie pikseli'''. Najprostszym rozwiązaniem wydaje się poprowadzenie prostej przez końce odcinka i opisanie jej równaniem <math>y=m\cdot x</math>. Następnie wyznaczenie wartości <math>y_i\ | |valign="top"|Jednym z podstawowych problemów tego typu jest '''zadanie narysowania odcinka na mapie pikseli'''. Najprostszym rozwiązaniem wydaje się poprowadzenie prostej przez końce odcinka i opisanie jej równaniem <math>y=m\cdot x</math>. Następnie wyznaczenie wartości <math>y_i\ </math>, dla całkowitych wartości <math>x_i\ </math>, odpowiadających kolejnym kolumnom pikseli. Jeśli teraz przybliżymy współrzędne <math>y_i\ </math>, do wartości całkowitej, to otrzymamy współrzędne dla kolejnych pikseli tworzących odcinek tzn. <math>y_i=ROUND(m\cdot x_i)</math> , gdzie <math>ROUND()\,\ </math>, jest operacją zaokrąglania do najbliższej wartości całkowitej. Tak skonstruowany algorytm przyrostowy ma podstawową wadę. Wymaga operacji zmiennopozycyjnych (mnożenia, dodawania, zaokrąglania). | ||
|} | |} | ||
Linia 22: | Linia 26: | ||
<hr width="100%"> | <hr width="100%"> | ||
{| border="0" cellpadding=" | {| border="0" cellpadding="4" width="100%" | ||
| | |width="500px" valign="top"|[[Grafika:GKIW_M3_Slajd2.png|thumb|500px]] | ||
|valign="top"|Rozwiązanie oparte w całości na arytmetyce stałopozycyjnej zaproponował Bresenham w 1965 roku. Jest to algorytm przyrostowy, w którym jedna współrzędna np. x wzrasta w każdym kroku o 1, tzn. <math>x_{i+1}=x_i+1</math> . Bez zmniejszania ogólności można przyjąć, że wystarczy opracować algorytm dla nachylenia odcinka od 0 do 1. (Jest to 1/8 układu współrzędnych. Dla innych wartości można bowiem odpowiednio zamienić zmienne lub znaki przed nimi.) Wzrost y w takim przypadku zależy od wyboru piksela (S lub T), który jest bliżej teoretycznej prostej. O wyborze decyduje zmienna kontrolna d, która jest uaktualniana w każdym kroku. | |valign="top"|Rozwiązanie oparte w całości na arytmetyce stałopozycyjnej zaproponował Bresenham w 1965 roku. Jest to algorytm przyrostowy, w którym jedna współrzędna np. x wzrasta w każdym kroku o 1, tzn. <math>x_{i+1}=x_i+1</math> . Bez zmniejszania ogólności można przyjąć, że wystarczy opracować algorytm dla nachylenia odcinka od 0 do 1. (Jest to 1/8 układu współrzędnych. Dla innych wartości można bowiem odpowiednio zamienić zmienne lub znaki przed nimi.) Wzrost y w takim przypadku zależy od wyboru piksela (S lub T), który jest bliżej teoretycznej prostej. O wyborze decyduje zmienna kontrolna d, która jest uaktualniana w każdym kroku. | ||
Linia 30: | Linia 34: | ||
<hr width="100%"> | <hr width="100%"> | ||
{| border="0" cellpadding=" | {| border="0" cellpadding="4" width="100%" | ||
| | |width="500px" valign="top"|[[Grafika:GKIW_M3_Slajd3.png|thumb|500px]] | ||
|valign="top"|Pełny algorytm Bresenhama dla x2>x1, y2>y1, 0<m<1 wyglądałby tak: | |valign="top"|Pełny algorytm Bresenhama dla x2>x1, y2>y1, 0<m<1 wyglądałby tak: | ||
Linia 60: | Linia 64: | ||
<hr width="100%"> | <hr width="100%"> | ||
{| border="0" cellpadding=" | {| border="0" cellpadding="4" width="100%" | ||
| | |width="500px" valign="top"|[[Grafika:GKIW_M3_Slajd4.png|thumb|500px]] | ||
|valign="top"|Niestety korzystanie z rastra również i w przypadku rysowania odcinka może prowadzić do pewnych problemów. | |valign="top"|Niestety korzystanie z rastra również i w przypadku rysowania odcinka może prowadzić do pewnych problemów. | ||
Pierwszym jest fakt, że odcinek może nie być symetryczny gdy zamienimy końce startowe. Problem ten wymaga korekty podejmowania decyzji dla d=0 w zależności od wzrostu lub spadku wartości współrzędnych. | Pierwszym jest fakt, że odcinek może nie być symetryczny gdy zamienimy końce startowe. Problem ten wymaga korekty podejmowania decyzji dla d=0 w zależności od wzrostu lub spadku wartości współrzędnych. | ||
Poważniejszym problemem jest zmiana jasności. Oba odcinki na rysunku składają się z 7 punktów. Tylko że odcinek po przekątnej rastra jest <math>\sqrt{2}\ | Poważniejszym problemem jest zmiana jasności. Oba odcinki na rysunku składają się z 7 punktów. Tylko że odcinek po przekątnej rastra jest <math>\sqrt{2}\ </math>, razy dłuższy od odcinka poziomego. Jest to problem związany ze skończoną rozdzielczością rastra i podobnie jak usuwanie wrażenia schodków odcinka rozwiązuje się go zmieniając barwy pikseli sąsiednich. | ||
|} | |} | ||
Linia 72: | Linia 76: | ||
<hr width="100%"> | <hr width="100%"> | ||
{| border="0" cellpadding=" | {| border="0" cellpadding="4" width="100%" | ||
| | |width="500px" valign="top"|[[Grafika:GKIW_M3_Slajd5.png|thumb|500px]] | ||
|valign="top"|Na podobnej zasadzie jak rysowanie odcinka, Bresenham opracował algorytm rysowania łuku okręgu. Oczywiście zmieniają się w tym przypadku warunki wyboru pikseli, ale algorytm ten również wykorzystuje tylko operacje na liczbach całkowitych. | |valign="top"|Na podobnej zasadzie jak rysowanie odcinka, Bresenham opracował algorytm rysowania łuku okręgu. Oczywiście zmieniają się w tym przypadku warunki wyboru pikseli, ale algorytm ten również wykorzystuje tylko operacje na liczbach całkowitych. | ||
Linia 82: | Linia 86: | ||
<hr width="100%"> | <hr width="100%"> | ||
{| border="0" cellpadding=" | {| border="0" cellpadding="4" width="100%" | ||
| | |width="500px" valign="top"|[[Grafika:GKIW_M3_Slajd6.png|thumb|500px]] | ||
|valign="top"|Wypełnianie obszaru jest drugim po rysowaniu odcinka lub łuku, najczęściej występującym problemem związanym z prymitywami. Zadanie dla szczególnych przypadków (np. dla prostokąta) jest zadaniem trywialnym. Natomiast w ogólnym przypadku algorytm powinien pracować poprawnie dla dowolnego wielokąta (także wklęsłego), również dla wielokątów z „dziurami”. | |valign="top"|Wypełnianie obszaru jest drugim po rysowaniu odcinka lub łuku, najczęściej występującym problemem związanym z prymitywami. Zadanie dla szczególnych przypadków (np. dla prostokąta) jest zadaniem trywialnym. Natomiast w ogólnym przypadku algorytm powinien pracować poprawnie dla dowolnego wielokąta (także wklęsłego), również dla wielokątów z „dziurami”. | ||
Linia 90: | Linia 94: | ||
<hr width="100%"> | <hr width="100%"> | ||
{| border="0" cellpadding=" | {| border="0" cellpadding="4" width="100%" | ||
| | |width="500px" valign="top"|[[Grafika:GKIW_M3_Slajd7.png|thumb|500px]] | ||
|valign="top"|Analogicznym zadaniem do wypełniania obszaru jest zmiana barwy w danym obszarze. Zadania są równoważne. Algorytm rozwiązujący jedno z nich może posłużyć do rozwiązania drugiego. | |valign="top"|Analogicznym zadaniem do wypełniania obszaru jest zmiana barwy w danym obszarze. Zadania są równoważne. Algorytm rozwiązujący jedno z nich może posłużyć do rozwiązania drugiego. | ||
Linia 98: | Linia 102: | ||
<hr width="100%"> | <hr width="100%"> | ||
{| border="0" cellpadding=" | {| border="0" cellpadding="4" width="100%" | ||
| | |width="500px" valign="top"|[[Grafika:GKIW_M3_Slajd8.png|thumb|500px]] | ||
|valign="top"|Można zauważyć, że jeśli wybierzemy jeden punkt, który jest wewnątrz wypełnianego obszaru, to punkt sąsiedni będzie również punktem wewnątrz albo będzie punktem brzegowym. | |valign="top"|Można zauważyć, że jeśli wybierzemy jeden punkt, który jest wewnątrz wypełnianego obszaru, to punkt sąsiedni będzie również punktem wewnątrz albo będzie punktem brzegowym. | ||
Linia 131: | Linia 135: | ||
<hr width="100%"> | <hr width="100%"> | ||
{| border="0" cellpadding=" | {| border="0" cellpadding="4" width="100%" | ||
| | |width="500px" valign="top"|[[Grafika:GKIW_M3_Slajd9.png|thumb|500px]] | ||
|valign="top"|Wypełnianie przez kontrolę parzystości wykorzystuje pewną właściwość przecięcia brzegu linią prostą. Jeśli punkty przecięcia ponumerujemy kolejnymi liczbami naturalnymi zgodnie z orientacją prostej (na rysunku od lewej do prawej dla prostej poziomej) i jeśli będziemy poruszać się po prostej zgodnie z jej orientacją to każde nieparzyste przecięcie będzie „wejściem” do wnętrza obszaru, natomiast każde parzyste będzie „wyjściem” na zewnątrz. Zatem, aby wypełnić obszar należy go przecięć prostymi odpowiadającymi kolejnym rzędom pikseli, a następnie wypełnić odcinkami pomiędzy każdym nieparzystym przecięciem, a najbliższym parzystym. | |valign="top"|Wypełnianie przez kontrolę parzystości wykorzystuje pewną właściwość przecięcia brzegu linią prostą. Jeśli punkty przecięcia ponumerujemy kolejnymi liczbami naturalnymi zgodnie z orientacją prostej (na rysunku od lewej do prawej dla prostej poziomej) i jeśli będziemy poruszać się po prostej zgodnie z jej orientacją to każde nieparzyste przecięcie będzie „wejściem” do wnętrza obszaru, natomiast każde parzyste będzie „wyjściem” na zewnątrz. Zatem, aby wypełnić obszar należy go przecięć prostymi odpowiadającymi kolejnym rzędom pikseli, a następnie wypełnić odcinkami pomiędzy każdym nieparzystym przecięciem, a najbliższym parzystym. | ||
Linia 139: | Linia 143: | ||
<hr width="100%"> | <hr width="100%"> | ||
{| border="0" cellpadding=" | {| border="0" cellpadding="4" width="100%" | ||
| | |width="500px" valign="top"|[[Grafika:GKIW_M3_Slajd10.png|thumb|500px]] | ||
|valign="top"|Oczywiście należy zmodyfikować to postępowanie dla przypadków szczególnych, gdy punkt przecięcia jest jednocześnie lokalnym ekstremum brzegu, co zaburza prostą regułę parzystości. Lokalizacja lokalnego ekstremum możliwa jest na podstawie położenia końców przecinanych odcinków. Jeśli są po tej samej stronie prostej wypełniającej – przecinany punkt jest lokalnym ekstremum i nie należy jego liczyć przy analizie parzystości. | |valign="top"|Oczywiście należy zmodyfikować to postępowanie dla przypadków szczególnych, gdy punkt przecięcia jest jednocześnie lokalnym ekstremum brzegu, co zaburza prostą regułę parzystości. Lokalizacja lokalnego ekstremum możliwa jest na podstawie położenia końców przecinanych odcinków. Jeśli są po tej samej stronie prostej wypełniającej – przecinany punkt jest lokalnym ekstremum i nie należy jego liczyć przy analizie parzystości. | ||
Linia 149: | Linia 153: | ||
<hr width="100%"> | <hr width="100%"> | ||
{| border="0" cellpadding=" | {| border="0" cellpadding="4" width="100%" | ||
| | |width="500px" valign="top"|[[Grafika:GKIW_M3_Slajd11.png|thumb|500px]] | ||
|valign="top"|W szczególnych przypadkach mogą pojawić się obszary nie dające się wypełnić w sposób spójny – problem „drzazgi”. Jedynym sposobem rozwiązania tego problemu jest nadpróbkowanie. Należy spróbkować i wypełnić drzazgę z większą rozdzielczością, a następnie uśrednić barwę/luminancję wracając do rozdzielczości rastra. | |valign="top"|W szczególnych przypadkach mogą pojawić się obszary nie dające się wypełnić w sposób spójny – problem „drzazgi”. Jedynym sposobem rozwiązania tego problemu jest nadpróbkowanie. Należy spróbkować i wypełnić drzazgę z większą rozdzielczością, a następnie uśrednić barwę/luminancję wracając do rozdzielczości rastra. | ||
Linia 157: | Linia 161: | ||
<hr width="100%"> | <hr width="100%"> | ||
{| border="0" cellpadding=" | {| border="0" cellpadding="4" width="100%" | ||
| | |width="500px" valign="top"|[[Grafika:GKIW_M3_Slajd12.png|thumb|500px]] | ||
|valign="top"|Większość rysowanych obiektów jest definiowana w rzeczywistym układzie kartezjańskim. Przedstawienie takiego obiektu na ekranie monitora (lub z wykorzystaniem innego urządzenia) wymaga określenia fragmentu, który jest obrazowany. Jeśli tylko część prymitywu jest zobrazowana, to oprócz algorytmu rysowania prymitywu jest potrzebny algorytm obcinania go do widocznego fragmentu. | |valign="top"|Większość rysowanych obiektów jest definiowana w rzeczywistym układzie kartezjańskim. Przedstawienie takiego obiektu na ekranie monitora (lub z wykorzystaniem innego urządzenia) wymaga określenia fragmentu, który jest obrazowany. Jeśli tylko część prymitywu jest zobrazowana, to oprócz algorytmu rysowania prymitywu jest potrzebny algorytm obcinania go do widocznego fragmentu. | ||
Linia 165: | Linia 169: | ||
<hr width="100%"> | <hr width="100%"> | ||
{| border="0" cellpadding=" | {| border="0" cellpadding="4" width="100%" | ||
| | |width="500px" valign="top"|[[Grafika:GKIW_M3_Slajd13.png|thumb|500px]] | ||
|valign="top"|Algorytm Cohena-Sutherlanda (1974) służy do obcinania odcinków do prostokątnego okna. Oznacza to, że należy wybrać odcinki (lub ich fragmenty) do obcięcia na podstawie położenia ich końców. | |valign="top"|Algorytm Cohena-Sutherlanda (1974) służy do obcinania odcinków do prostokątnego okna. Oznacza to, że należy wybrać odcinki (lub ich fragmenty) do obcięcia na podstawie położenia ich końców. | ||
Linia 176: | Linia 180: | ||
W takiej sytuacji należy rozważyć przypadek szczególny gdy kody obu końców są zerowe (punkty P1 i K1 na rysunku), wtedy cały rysunek leży wewnątrz okna. | W takiej sytuacji należy rozważyć przypadek szczególny gdy kody obu końców są zerowe (punkty P1 i K1 na rysunku), wtedy cały rysunek leży wewnątrz okna. | ||
Natomiast jeśli kody końców są niezerowe to określają one którymi prostymi należy przyciąć odcinek. Odcinek <math> | Natomiast jeśli kody końców są niezerowe to określają one którymi prostymi należy przyciąć odcinek. Odcinek <math>\overline{P2P2}\ </math>, należy przyciąć prostą prawą (K2=0010). Odcinek <math>\overline{P3P3}\ </math>, prostymi lewą i dolną (P3=0101) oraz prawą i górną (K3=1010). | ||
|} | |} | ||
Linia 182: | Linia 186: | ||
<hr width="100%"> | <hr width="100%"> | ||
{| border="0" cellpadding=" | {| border="0" cellpadding="4" width="100%" | ||
| | |width="500px" valign="top"|[[Grafika:GKIW_M3_Slajd14.png|thumb|500px]] | ||
|valign="top"|W przypadku obcinania wielokąta, zastosowanie algorytmu obcinania odcinków przynosi tylko połowiczny sukces. Wielokąt tworzy bowiem zbiór uporządkowanych wierzchołków. Każdy wierzchołek jest początkiem pewnego boku i jednocześnie jest końcem poprzedniego boku w danym uporządkowaniu. Potraktowanie boków wielokąta jako zbioru odcinków i przycięcie ich powoduje, że tracimy informacje o ich połączeniach. | |valign="top"|W przypadku obcinania wielokąta, zastosowanie algorytmu obcinania odcinków przynosi tylko połowiczny sukces. Wielokąt tworzy bowiem zbiór uporządkowanych wierzchołków. Każdy wierzchołek jest początkiem pewnego boku i jednocześnie jest końcem poprzedniego boku w danym uporządkowaniu. Potraktowanie boków wielokąta jako zbioru odcinków i przycięcie ich powoduje, że tracimy informacje o ich połączeniach. | ||
Linia 196: | Linia 200: | ||
<hr width="100%"> | <hr width="100%"> | ||
{| border="0" cellpadding=" | {| border="0" cellpadding="4" width="100%" | ||
| | |width="500px" valign="top"|[[Grafika:GKIW_M3_Slajd15.png|thumb|500px]] | ||
|valign="top"|Algorytm Cohena-Sutherlanda bardzo efektywnie klasyfikuje odcinki i jednocześnie jest bardzo prosty w implementacji. Powoduje to, że jest chyba najczęściej stosowanym algorytmem przycinania odcinków do prostokątnego okna. | |valign="top"|Algorytm Cohena-Sutherlanda bardzo efektywnie klasyfikuje odcinki i jednocześnie jest bardzo prosty w implementacji. Powoduje to, że jest chyba najczęściej stosowanym algorytmem przycinania odcinków do prostokątnego okna. | ||
Ma jednak jedną wadę. Często odcinki są przycinane kilka razy (różnymi prostymi) zanim uzyskają końcową postać. Z punktu widzenia wyznaczania przecięcia nie jest to efektywne. W 1978 roku Cyrus i Beck zaproponowali całkowicie inne podejście do problemu obcinania. | Ma jednak jedną wadę. Często odcinki są przycinane kilka razy (różnymi prostymi) zanim uzyskają końcową postać. Z punktu widzenia wyznaczania przecięcia nie jest to efektywne. W 1978 roku Cyrus i Beck zaproponowali całkowicie inne podejście do problemu obcinania. | ||
Jeśli opiszemy prostą parametrycznie to wzrost parametru określi naturalny zwrot prostej. Niech punkty P0 i Pk odpowiadają odpowiednio parametrom t=0 i t=tk dla k>0. Wektor <math> | Jeśli opiszemy prostą parametrycznie to wzrost parametru określi naturalny zwrot prostej. Niech punkty P0 i Pk odpowiadają odpowiednio parametrom t=0 i t=tk dla k>0. Wektor <math>\overline{P0Pk}\ </math>, określa zwrot prostej. Można przeanalizować iloczyn skalarny tego wektora i wektora normalnego (skierowanego na zewnątrz) do boku wielokąta. | ||
Jeśli <math> | Jeśli <math>\overline{P0Pk}\circ \overrightarrow{n}_i>0</math> to parametr tk określa punkt Pk.który może być „maksymalnym” punktem przecięcia z wielokątem (np. punkt dla t=t2 na rysunku). | ||
Jeśli <math> | Jeśli <math>\overline{P0Pk}\circ \overrightarrow{n}_i<0</math> to parametr tk określa punkt Pk.który może być „minimalnym” punktem przecięcia z wielokątem (np. punkt dla t=t1 na rysunku). | ||
Cyrus i Beck zaproponowali efektywny zestaw operacji parametrycznych do analizy całego wielokąta. Algorytm ten został w 1984 roku rozszerzony Lianga i Barsky’ego do ogólnego przypadku 2D obcinania prostymi równoległymi do osi układu współrzędnych oraz 3D obcinania płaszczyznami prostopadłymi do osi układu współrzędnych. | Cyrus i Beck zaproponowali efektywny zestaw operacji parametrycznych do analizy całego wielokąta. Algorytm ten został w 1984 roku rozszerzony Lianga i Barsky’ego do ogólnego przypadku 2D obcinania prostymi równoległymi do osi układu współrzędnych oraz 3D obcinania płaszczyznami prostopadłymi do osi układu współrzędnych. | ||
Linia 214: | Linia 218: | ||
<hr width="100%"> | <hr width="100%"> | ||
{| border="0" cellpadding=" | {| border="0" cellpadding="4" width="100%" | ||
| | |width="500px" valign="top"|[[Grafika:GKIW_M3_Slajd16.png|thumb|500px]] | ||
|valign="top"|Geometria obliczeniowa (ang. computational geometry) jest stosunkowo nową dziedziną informatyki. Z jednej strony jest często traktowana jako narzędzie niezbędne do realizacji algorytmów w grafice komputerowej, z drugiej pozwoliła również wprowadzić do grafiki nowe struktury danych lub je usystematyzować. Niektóre zagadnienia takie jak wyznaczenie wypukłej otoczki zbioru punktów (wypukłej skorupki) albo triangulacja wielokąta stanowią samodzielne problemy geometrii obliczeniowej i Czytelnik może znaleźć ich rozwiązania w podręcznikach z tej dziedziny. | |valign="top"|Geometria obliczeniowa (ang. computational geometry) jest stosunkowo nową dziedziną informatyki. Z jednej strony jest często traktowana jako narzędzie niezbędne do realizacji algorytmów w grafice komputerowej, z drugiej pozwoliła również wprowadzić do grafiki nowe struktury danych lub je usystematyzować. Niektóre zagadnienia takie jak wyznaczenie wypukłej otoczki zbioru punktów (wypukłej skorupki) albo triangulacja wielokąta stanowią samodzielne problemy geometrii obliczeniowej i Czytelnik może znaleźć ich rozwiązania w podręcznikach z tej dziedziny. | ||
Linia 222: | Linia 226: | ||
<hr width="100%"> | <hr width="100%"> | ||
{| border="0" cellpadding=" | {| border="0" cellpadding="4" width="100%" | ||
| | |width="500px" valign="top"|[[Grafika:GKIW_M3_Slajd17.png|thumb|500px]] | ||
|valign="top"|Częstym problemem jest konieczność uporządkowania punktów w układzie biegunowym. Wyznaczenie kąta na podstawie współrzędnych kartezjańskich wymagałoby użycia funkcji trygonometrycznych, co znacznie spowalniałoby rozwiązanie zadania. Funkcja alfa daje możliwość porównania kątów bez wyznaczania ich wartości. Należy jednak pamiętać, że wartość funkcji alfa nie jest liniowo związana z wartością kąta i próba szacowania kąta na tej podstawie byłaby poważnym błędem. | |valign="top"|Częstym problemem jest konieczność uporządkowania punktów w układzie biegunowym. Wyznaczenie kąta na podstawie współrzędnych kartezjańskich wymagałoby użycia funkcji trygonometrycznych, co znacznie spowalniałoby rozwiązanie zadania. Funkcja alfa daje możliwość porównania kątów bez wyznaczania ich wartości. Należy jednak pamiętać, że wartość funkcji alfa nie jest liniowo związana z wartością kąta i próba szacowania kąta na tej podstawie byłaby poważnym błędem. | ||
Linia 230: | Linia 234: | ||
<hr width="100%"> | <hr width="100%"> | ||
{| border="0" cellpadding=" | {| border="0" cellpadding="4" width="100%" | ||
| | |width="500px" valign="top"|[[Grafika:GKIW_M3_Slajd18.png|thumb|500px]] | ||
|valign="top"| | |valign="top"|Drugim zagadnieniem, które często występuje jest określenie zorientowania trójki punktów na płaszczyźnie. Zadanie to ma oczywiście eleganckie rozwiązanie w postaci wektorowej. Wystarczy wyznaczyć dwa wektory rozpięte na badanych trzech punktach, a następnie obliczyć ich iloczyn wektorowy. Zwrot wektora wynikowego określi poszukiwane zorientowanie. | ||
Zastosowanie macierzy współrzędnych (przez analogię do macierzy określającej iloczyn wektorowy) upraszcza obliczenia. | |||
Jeśli det '''M''' > 0 mówimy o dodatnim zorientowaniu (lewoskrętnym lub przeciwnym do ruchu wskazówek zegara). | |||
Jeśli det '''M''' < 0 mówimy o ujemnym zorientowaniu (prawoskrętnym lub zgodnym z ruchem wskazówek zegara). | |||
|} | |} | ||
<hr width="100%"> | <hr width="100%"> | ||
{| border="0" cellpadding=" | {| border="0" cellpadding="4" width="100%" | ||
| | |width="500px" valign="top"|[[Grafika:GKIW_M3_Slajd19.png|thumb|500px]] | ||
|valign="top"| | |valign="top"|Zagadnienie sprawdzenia przynależności punktu do wnętrza wielokąta ma bardzo proste rozwiązanie dla wielokąta wypukłego. Jeśli wziąć pod uwagę prostą wyznaczoną przez dwa kolejne wierzchołki wielokąta, to prosta ta dzieli płaszczyznę na dwie półpłaszczyzny, z których tylko jedna zawiera wielokąt. Podstawiając więc współrzędne badanego punktu do równania prostej można na podstawie znaku równania stwierdzić po której stronie prostej punkt się znajduje. A zatem punkt P1 na rysunku będzie po tej samej stronie prostej wyznaczonej przez V1 V2 co np. wierzchołek V4. Natomiast punkty P2 i V4 będą po przeciwnych stronach tej prostej. | ||
Algorytm sprawdzania przynależności punktu do wnętrza wielokąta wypukłego jest następujący. | |||
:Obejść wielokąt zgodnie z porządkiem kolejnych jego wierzchołków. W każdym kroku | |||
:wyznaczyć :prostą przechodzącą przez bieżącyi następny wierzchołek. Sprawdzić czy badany punkt | |||
:jest po tej samej stronie prostej co jeden z wierzchołków wielokąta. Jeśli w którymkolwiek | |||
:kroku badany punkt nie spełnia tego warunku, przerwać sprawdzanie – punkt jest na zewnątrz. | |||
:Jeśli po obejściu całego wielokąta okaże się, że punkt był zawsze (!) po tej samej stronie co | |||
:reszta wielokąta to punkt jest wewnątrz. | |||
Opisany algorytm należy w zależności od potrzeb uzupełnić o analizę samego wielokąta (przynależność lub nie do odpowiednich odcinków co jest zabiegiem technicznym i nie stanowi problemu. | |||
Podstawową wadą zaprezentowanego algorytmu jest fakt, że działa poprawnie tylko dla wielokątów wypukłych. Dla wielokątów wklęsłych będą proste wyznaczone przez kolejne wierzchołki, które będą przecinały wielokąt. | |||
Dla wielokątów dowolnych problem rozwiązuje się algorytmem kontroli parzystości lub algorytmem analizy sumy katów zorientowanych. | |||
Warto przy tym zwrócić uwagę, że rozpatrywane są tylko wielokąty zwykłe, to znaczy takie, których krawędzie nie mają punktów wspólnych poza wierzchołkami. | |||
|} | |} | ||
<hr width="100%"> | <hr width="100%"> | ||
{| border="0" cellpadding=" | {| border="0" cellpadding="4" width="100%" | ||
| | |width="500px" valign="top"|[[Grafika:GKIW_M3_Slajd20.png|thumb|500px]] | ||
|valign="top"| | |valign="top"|Przez analogię do wypełniania wielokąta przez kontrolę parzystości na rastrze pikseli można zaproponować algorytm sprawdzania przynależności punktu do wielokąta. Jeśli z badanego punktu poprowadzimy półprostą (w dowolnym kierunku – z punktu widzenia kierunków układu współrzędnych wygodna będzie np. półprosta pozioma), to może ona przeciąć wielokąt. Jeśli liczba przecięć z bokami wielokąta jest nieparzysta to punkt leży wewnątrz wielokąta (punkt P1 na rysunku). Jeśli liczba przecięć jest parzysta, to punkt jest na zewnątrz (punkt P2 na rysunku). | ||
Algorytm jest bardzo prosty, jednak pamiętając o problemach ze szczególnymi przypadkami w algorytmie wypełniania przez kontrolę parzystości, należy przypuszczać, że podobne sytuacje wystąpią i tutaj. | |||
Oczywiście rozwiązanie jest również analogiczne .Do algorytmu należy dodać dwa warunki. | |||
Jeśli punkt przecięcia jest ekstremum lokalnym, to liczymy go podwójnie. | |||
Jeśli półprosta zawiera cały bok wielokąta, to traktujemy to jako jeden pseudo-wierzchołek. | |||
|} | |} | ||
<hr width="100%"> | <hr width="100%"> | ||
{| border="0" cellpadding=" | {| border="0" cellpadding="4" width="100%" | ||
| | |width="500px" valign="top"|[[Grafika:GKIW_M3_Slajd21.png|thumb|500px]] | ||
|valign="top"| | |valign="top"|Drugim rozwiązaniem problemu sprawdzenia przynależności punktu do wielokąta jest analiza kątów. | ||
Można założyć, że wierzchołki wielokąta są uporządkowane przeciwnie do ruchu wskazówek zegara. Z badanego punktu przez każdy wierzchołek wielokąta prowadzimy półprostą. Badany punkt oraz półproste przechodzące przez kolejne wierzchołki wyznaczają kąt, któremu można przypisać zorientowanie analogicznie jak zorientowanie wielokąta (+ jeśli kolejność ramion kąta jest przeciwna do ruchu wskazówek zegara, i – w sytuacji odwrotnej). Po przyjęciu takich założeń wystarczy zsumować wszystkie kąty związane z punktem badanym. Jeśli <math>suma = 360^\circ</math> to punkt jest wewnątrz wielokąta. Jeśli <math>suma = 0^\circ</math> to na zewnątrz. | |||
Oczywiście należy pamiętać o błędach zaokrąglenia i oczekiwanie np. dokładnie zerowej wartości byłoby nieporozumieniem. Jeśli jesteśmy pewni że w implementacji nie ma błędu, to warunki można postawić jako: <math>suma > 360^\circ</math> i <math>suma < 360^\circ</math>. | |||
|} | |} | ||
<hr width="100%"> | <hr width="100%"> | ||
{| border="0" cellpadding=" | = Literatura = | ||
| | |||
{| border="0" cellpadding="4" width="100%" | |||
|width="500px" valign="top"|[[Grafika:GKIW_M3_Slajd22.png|thumb|500px]] | |||
|valign="top"| | |valign="top"| | ||
|} | |} | ||
<hr width="100%"> | <hr width="100%"> |
Aktualna wersja na dzień 12:04, 5 wrz 2023
Wykład
![]() |
![]() |
Analogicznym zadaniem do wypełniania obszaru jest zmiana barwy w danym obszarze. Zadania są równoważne. Algorytm rozwiązujący jedno z nich może posłużyć do rozwiązania drugiego. |
Literatura
![]() |