Przykład zastosowania przeciażeń operatorów i metod stałych - szukanie punktu przecięcia z wielobokiem Bogdan Kreczmer ZPCiR IIAiR PWr pokój 307 budynek C3 bogdan.kreczmer@pwr.wroc.pl Copyright c 2005 2008 Bogdan Kreczmer Niniejszy dokument zawiera materiały do wykładu na temat programowania obiektowego. Jest on udostępniony pod warunkiem wykorzystania wyłacznie do własnych prywatnych potrzeb i może on być kopiowany wyłacznie w całości, razem z niniejsza strona tytułowa.
Planowanie ścieżki bezkolizyjnej robota Problem planowanie ścieżki bezkolizyjnej dla robota typu omni-directional można sprowadzić do planowania ścieżki bezkolizyjnej dla punktu materialnego. Można to zrobić poprzez powiększenie przeszkód o promień obrysu rzutu pionowego korpusu robota. Ten sposób postępowania jest szczególnym przypadkiem wynikajacym z pojęcia przestrzeni konfiguracyjnej, które zostało wprowadzone przez Lozano-Péreza (1983). Copyright c 2005 2008 Bogdan Kreczmer Przykład zastosowania przeciażeń operatorów i metod stałych - szukanie punktu przecięcia z wielobokiem 1
Metody planowania Szukanie ścieżki bezkolizyjnej można sprawdzić do problemu przeszukiwania grafu. Do najbardziej popularnych należa metody grafu widoczności (ang. Visibility Graph) oraz grafu styczności (ang. Tangent Graph). Idea metody: Zbuduj graf (widoczności lub styczności) Znajdź najkrótsza ścieżkę w grafie Graf widoczności Graf styczności Zaleta: Znajdowana jest optymalna ścieżka pod względem długości. Wada: Konieczność tworzenia złożonych struktur grafowych. Copyright c 2005 2008 Bogdan Kreczmer Przykład zastosowania przeciażeń operatorów i metod stałych - szukanie punktu przecięcia z wielobokiem 2
Metoda labiryntowa Metoda labiryntowa buduje ścieżkę bezkolizyjna odcinek po odcinku. Idea metody: 1. Czy odcinek do punktu S przecina wielobok? Jeśli nie to odcinek znaleziony. 2. Omiń przeszkodę i powróć do 1. W celu znalezienia kolejnego odcinka procedura jest powtarzana przyjmujac za S koniec znalezionej części ścieżki. Zaleta: Nie tworzy grafu. Szybko znajduje pojedynczy odcinek ścieżki. Wada: Znaleziona ścieżka jest suboptymalna. Copyright c 2005 2008 Bogdan Kreczmer Przykład zastosowania przeciażeń operatorów i metod stałych - szukanie punktu przecięcia z wielobokiem 3
Opis problemu: Zaimplementować procedurę obliczeniowa pozwalajac a ustalić, czy odcinek łacz acy dwa punkty S i F przecina wielobok W. Jeżeli takie przecięcie wystapi, to należy wyznaczyć punkt przecięcia najbliższy punktowi S. Przypadek gdy odcinek pokrywa się całkowicie lub częściowo z bokiem wieloboku nie jest traktowany jako przecięcie. Copyright c 2005 2008 Bogdan Kreczmer Przykład zastosowania przeciażeń operatorów i metod stałych - szukanie punktu przecięcia z wielobokiem 4
Analiza problemu: Zaimplementować procedurę obliczeniowa pozwalajac a ustalić, czy odcinek łacz acy dwa punkty S i F przecina wielobok W. Jeżeli takie przecięcie wystapi, to należy wyznaczyć punkt przecięcia najbliższy punktowi S. Kluczowe rzeczowniki: odcinek komponenty: wierzchołki punkty Własności: położenie wieloboki, odcinek, punkty Relacje: Istnienie punktów przecięcia wielobok komponenty: wierzchołki punkty punkty Copyright c 2005 2008 Bogdan Kreczmer Przykład zastosowania przeciażeń operatorów i metod stałych - szukanie punktu przecięcia z wielobokiem 5
Problemy i podproblemy Szukanie najbliższego punktu przecięcia dla odcinka i wieloboku Szukanie punktu przecięcia odcinka z brzegiem wieloboku Szukanie punktu przecięcia odcinka z odcinkiem Copyright c 2005 2008 Bogdan Kreczmer Przykład zastosowania przeciażeń operatorów i metod stałych - szukanie punktu przecięcia z wielobokiem 6
Przecięcie Nie zawsze wykrycie punktu wspólnego odcinka i boku figury musi oznaczać przecięcie. Najprostszy przypadek, gdy odcinek SF przecina się z bokiem figury. Odcinek SF ma punkty wspólne z krańcami dwóch boków. Odcinek SF ma punkty wspólne z krańcami dwóch boków, ale tym razem nie można powiedzieć, że przecina wielobok. Jedynie styka się z nim. Copyright c 2005 2008 Bogdan Kreczmer Przykład zastosowania przeciażeń operatorów i metod stałych - szukanie punktu przecięcia z wielobokiem 7
Problemy i podproblemy Szukanie najbliższego punktu przecięcie dla odcinka i wieloboku Szukanie punktu przecięcia odcinka z brzegiem wieloboku Szukanie punktu przecięcia odcinka z odcinkiem Rozpoznanie przecięcia z brzegiem, gdy odcinka przechodzi przez wierzchołek Copyright c 2005 2008 Bogdan Kreczmer Przykład zastosowania przeciażeń operatorów i metod stałych - szukanie punktu przecięcia z wielobokiem 8
Szukanie punktu przecięcia odcinków Równanie parametryczne odcinka: Warunek istnienia punktu wspólnego: { x = ax t + b xo y = a y t + b yo { ax,1 t 1 + b xo,1 = a x,2 t 2 + b xo,2 a y,1 t 2 + b yo,1 = a y,2 t 2 + b yo,2 Układ równań liniowych względem t 1 i t 2 : { ax,1 t 1 a x,2 t 2 = b xo,2 b xo,1 a y,1 t 1 a y,2 t 2 = b yo,2 b yo,1 Copyright c 2005 2008 Bogdan Kreczmer Przykład zastosowania przeciażeń operatorów i metod stałych - szukanie punktu przecięcia z wielobokiem 9
Szukanie punktu przecięcia odcinków Układ równań liniowych względem t 1 i t 2 : { ax,1 t 1 a x,2 t 2 = b xo,2 b xo,1 Rozwiazanie: a y,1 t 1 a y,2 t 2 = b yo,2 b yo,1 W = a x,2 a y,1 a y,2 a x,1 D 1 = a x,2 (b yo,2 b yo,1) a y,2 (b xo,2 b xo,1) D 2 = a x,1 (b yo,2 b yo,1) a y,1 (b xo,2 b xo,1) t 1 = D 1 W, t 2 = D 2 W (W 0) Warunek istnienia pojedynczego punktu wspólnego: 0 t 1 1 0 t 2 1 Copyright c 2005 2008 Bogdan Kreczmer Przykład zastosowania przeciażeń operatorów i metod stałych - szukanie punktu przecięcia z wielobokiem 10
Kiedy przecięcie? Przecięcie wnikajace. Kiedy na pewno odcinek SF wnika w wielobok. α (0,Π) β (0,Π) upraszczaj ac sinα > 0 sinβ > 0 W przypadku, gdy mamy do czynienia z przestrzenia dwuwymiarowa możemy rozszerzyć ja do przestrzeni trójwymiarowej. Pozwala to skorzystać z iloczynu wektorowego i w prosty sposób otrzymać znak sinusa kata między dwoma wektorami. Sprawdzenie powyższego warunku można sprowadzić do prostych działań arytmetycznych. Postępowanie to poprawne, gdyż w tym przypadku miara kata mieści się w przedziale [0, 2Π). ( SF a) z > 0 ( SF b) z > 0 Copyright c 2005 2008 Bogdan Kreczmer Przykład zastosowania przeciażeń operatorów i metod stałych - szukanie punktu przecięcia z wielobokiem 11
Kiedy przecięcie? Przecięcie wnikajace. Kiedy na pewno odcinek SF wnika w wielobok.?? Drugi z przypadków należy potraktować jako przecięcie wnikajace. Pomimo tego, że może mieć miejsce ślizganie się odcinka wewnatrz wieloboku, jednak gdy szukamy najbliższego punktu przecięcia, ten przypadek i tak zostanie wyeliminowany. Copyright c 2005 2008 Bogdan Kreczmer Przykład zastosowania przeciażeń operatorów i metod stałych - szukanie punktu przecięcia z wielobokiem 12
Kiedy przecięcie? Przecięcie wnikajace. Kiedy na pewno odcinek SF wnika w wielobok.?? I tym razem również drugi z przypadków należy potraktować jako przecięcie wnikajace. Pomimo tego, że może mieć miejsce ślizganie się odcinka wewnatrz wieloboku, jednak gdy szukamy najbliższego punktu przecięcia, ten przypadek i tak zostanie wyeliminowany. Copyright c 2005 2008 Bogdan Kreczmer Przykład zastosowania przeciażeń operatorów i metod stałych - szukanie punktu przecięcia z wielobokiem 13
Kiedy przecięcie? Przecięcie wnikajace. Kiedy na pewno odcinek SF wnika w wielobok. α (0,Π) β = Π α = 0 β (0,Π) Szczegółowa analiza pozwala sformułować warunki umożliwiajace stwierdzić czy mamy do czynienia z przecięciem wnikajacym, czy też ze ślizganiem się po brzegu. Warunki te formułowane sa w kontekście procedury szukania przecięcia, która wymaga zbadania całego brzegu wieloboku. Z tego względu dla realizacji jej elementarnego kroku wystarcza informacja tylko o dwóch kolejnych bokach. Copyright c 2005 2008 Bogdan Kreczmer Przykład zastosowania przeciażeń operatorów i metod stałych - szukanie punktu przecięcia z wielobokiem 14
Kiedy przecięcie? Przecięcie wnikajace Pierwszy przypadek brzegowy α (0,Π) β = Π Ze względu na to, że miara kata w tym przypadku mieści się w przedziale [0, Π), więc warunek może być sprowadzony do postaci: sinα > 0 sinβ = 0 cosβ = 1 Korzystajac z formalnego rozszerzenia do 3D możemy użyć iloczynu wektorowego, aby sprawdzić znak funkcji sinus, zaś aby sprawdzić znak funkcji cosinus wykorzystać możemy iloczyn skalarny. ( SF a) z > 0 ( SF b) z = 0 SF b < 0 Copyright c 2005 2008 Bogdan Kreczmer Przykład zastosowania przeciażeń operatorów i metod stałych - szukanie punktu przecięcia z wielobokiem 15
Kiedy przecięcie? Przecięcie wnikajace Drugi przypadek brzegowy α = 0 β (0,Π) Ze względu na to, że miara kata w tym przypadku mieści się w przedziale [0, Π), więc warunek może być sprowadzony do postaci: sinα = 0 cosα = 1 sinβ > 0 Korzystajac z formalnego rozszerzenia do 3D możemy użyć iloczynu wektorowego, aby sprawdzić znak funkcji sinus, zaś aby sprawdzić znak funkcji cosinus wykorzystać możemy iloczyn skalarny. ( SF a) z = 0 SF a > 0 ( SF b) z > 0 Copyright c 2005 2008 Bogdan Kreczmer Przykład zastosowania przeciażeń operatorów i metod stałych - szukanie punktu przecięcia z wielobokiem 16
Kiedy przecięcie? α (0,Π) β (0,Π) α (0,Π) β = Π α = 0 β (0,Π) α (0,Π) β (0,Π] α [0,Π) β (0,Π) Copyright c 2005 2008 Bogdan Kreczmer Przykład zastosowania przeciażeń operatorów i metod stałych - szukanie punktu przecięcia z wielobokiem 17
Kiedy przecięcie? α (0,Π) β (0,Π] α [0,Π) β (0,Π) α (0,Π) (β (0,Π) β = Π) (α (0,Π) α = 0) β (0,Π) sinα > 0 (sinβ > 0 sinβ = 0 cosβ = 1) (sinα > 0 sinα = 0 cosα = 1) sinβ > 0 ( ) ( SF a) z > 0 ( SF b) z > 0 ( SF b) z = 0 SF b < 0 ( ) ( SF a) z > 0 ( SF a) z = 0 SF a > 0 ( SF b) z > 0 Copyright c 2005 2008 Bogdan Kreczmer Przykład zastosowania przeciażeń operatorów i metod stałych - szukanie punktu przecięcia z wielobokiem 18
Implementacja rozwiazania w C (cz. 1) typedef struct OdcinekProstej { float xo, yo, xn, yn; } Odcinek; float CzyPunktWspolny( Odcinek Odc1, Odcinek Odc2, float wx, float wy ) { float x A1, y A1, x A2, y A2, x B, y B; float t1, t2, Wz; x A1 = Odc1.xn Odc1.xo; y A1 = Odc1.yn Odc1.yo; x A2 = Odc2.xn Odc2.xo; y A2 = Odc2.yn Odc2.yo; x B = Odc2.xo Odc1.xo; y B = Odc2.yo Odc1.yo; Wz = x A2 y A1 x A1 y A2; } if ( Wz == 0 ) return MAXFLOAT; t1 = (x A2 y B y A2 x B)/Wz; t2 = (x A1 y B y A1 x B)/Wz; if ( t1 < 0 1 < t1 t2 < 0 1 < t2 ) return MAXFLOAT; wx = x A1 t1 + Odc1.xo; wy = y A1 t1 + Odc1.yo; return t1; Czyż to nie jest koszmarne? Copyright c 2005 2008 Bogdan Kreczmer Przykład zastosowania przeciażeń operatorów i metod stałych - szukanie punktu przecięcia z wielobokiem 19
Implementacja rozwiazania w C (cz. 2) typedef struct Wektor { float x, y; } Wektor; typedef struct Odcinek { Wektor Po, Pn; } Odcinek;... float CzyPunktWspolny( Odcinek Odc1, Odcinek Odc2, Wektor wpprzec ) { Wektor A1 = OdejmijWektory(&Odc1.Pn, &Odc1.Po); Wektor A2 = OdejmijWektory(&Odc2.Pn, &Odc2.Po); Wektor B = OdejmijWektory(&Odc2.Po, &Odc1.Po); float t1, t2, Wz = IloczynWekZ(A2, A1); if ( Wz == 0 ) return MAXFLOAT; t1 = IloczynWekZ(A2,B)/Wz; t2 = IloczynWekZ(A1,B)/Wz; if ( t1 < 0 1 < t1 t2 < 0 1 < t2 ) return MAXFLOAT; wpprzec = DodajWektory(PomnozWektorPrzezLiczbe(A1,t1), Odc1.Po); return t1; } Obiektowo zorientowana implementacja czyni ten zapis bardziej czytelnym. Copyright c 2005 2008 Bogdan Kreczmer Przykład zastosowania przeciażeń operatorów i metod stałych - szukanie punktu przecięcia z wielobokiem 20
Implementacja rozwiazania w C (cz. 3)... Wektor DodajWektory( Wektor W1, Wektor W2 ) { W1.x += W2.x; W1.y += W2.y; return W1; } Wektor OdejmijWektory( Wektor ww1, Wektor ww2 ) { Wektor Wr; Wr.x = ww1 >x ww2 >x; Wr.y = ww1 >y ww2 >y; return Wr; } Wektor PomnozWektorPrzezLiczbe( Wektor W, float L ) { W.x = L; W.y = L; return W; } float IloczynWekZ( Wektor W1, Wektor W2 ) { return W1.x W2.y W1.y W2.y; }... Przekazywanie parametru przez wartość pozwala na uproszczenie zapisu implementacji funkcji (porównaj np. implementację funkcji DodajWektory i OdejmijWektory). Copyright c 2005 2008 Bogdan Kreczmer Przykład zastosowania przeciażeń operatorów i metod stałych - szukanie punktu przecięcia z wielobokiem 21
Diagramy klas w UML Rysunek 1: Diagram klas dla implementacji rozwiazania problemu wykrywania przecięcia. Copyright c 2005 2008 Bogdan Kreczmer Przykład zastosowania przeciażeń operatorów i metod stałych - szukanie punktu przecięcia z wielobokiem 22
Klasa Wektor class Wektor { float x, y; public : Wektor( ) { x = y = 0; } Wektor( float x, float y ) { x = x; y = y; } float x( ) const { return x; } float y( ) const { return y; } Wektor Zmien( float x, float y ) { x = x; y = y; return this ; } Wektor & operator += ( const Wektor &W ) { x += W. x; y += W. y; return this ; } Wektor operator + ( Wektor W ) const { return W += this ; } Wektor & operator = ( const Wektor &W ) { x = W. x; y = W. y; return this ; } Wektor operator ( Wektor W ) const { return Wektor( x W. x, y W. y); } }; float operator ( Wektor W ) const { return x W. y y W. x; } Wektor operator ( float L) const { return Wektor( x L, y L); } Klasa Wektor wyposażona jest w interfejs, który umożliwia kontrolę nad operacjami odczytu i zapisu. Redukuje to możliwość przypadkowych błędów. Wada jest utrudnione odwoływanie się do pól klasy. Copyright c 2005 2008 Bogdan Kreczmer Przykład zastosowania przeciażeń operatorów i metod stałych - szukanie punktu przecięcia z wielobokiem 23
Klasa Odcinek class Odcinek { //.............................................................................. public : Wektor Po, Pn; float CzyPunktWspolny( const Wektor & P2o, const Wektor & P2n, float & t2, Wektor & PPrzec ) const; float CzyPunktWspolny( const Odcinek & Odc, float & t2, Wektor & PPrzec ) const { return CzyPunktWspolny(Odc. Po, Odc. Pn, t2, PPrzec); } }; //............................................................................................. Odcinek jest reprezentowany w klasie Odcinek poprzez swoje dwa punkty krańcowe. Ponadto klasa ta zawiera metody implementujace relację posiadania punktu wspólnego przez dwa odcinki. Copyright c 2005 2008 Bogdan Kreczmer Przykład zastosowania przeciażeń operatorów i metod stałych - szukanie punktu przecięcia z wielobokiem 24
Klasa Wielobok class Wielobok { //............................................................................. public : int Ilosc; Wektor Wierz[MAX WIERZ]; Wielobok( ) { Ilosc = 0; } bool CzyWnika( const Odcinek & Odc, unsigned int Indeks Pop, unsigned int Indeks Bie, unsigned int Indeks Nas ) const; float CzyPrzeciecie( const Odcinek & Odc, Wektor & PntPrz ) const; }; //............................................................................................. Wielobok jest reprezentowany poprzez zbiór swoich wierzchołków. Ich kolejność występowania w tablicy może zadawać orientację jego brzegu. Copyright c 2005 2008 Bogdan Kreczmer Przykład zastosowania przeciażeń operatorów i metod stałych - szukanie punktu przecięcia z wielobokiem 25
Reprezentacja wieloboku Obiekt klasy Wielobok umożliwia reprezentację wieloboku poprzez przechowywanie informacji o współrzędnych kolejnych wierzchołków. Copyright c 2005 2008 Bogdan Kreczmer Przykład zastosowania przeciażeń operatorów i metod stałych - szukanie punktu przecięcia z wielobokiem 26
Reprezentacja wieloboku Korzystanie ze struktur statycznych wewnatrz klasy Wielobok ogranicza zbiór wieloboków, które moga być reprezentowane przez obiekty tej klasy. Kolejność występowania współrzędnych poszczególnych wierzchołków w tablicy nie jest obojętna. Copyright c 2005 2008 Bogdan Kreczmer Przykład zastosowania przeciażeń operatorów i metod stałych - szukanie punktu przecięcia z wielobokiem 27
Reprezentacja wieloboku Kolejność występowania wierzchołków w tablicy w naturalny sposób wyznacza orientację brzegu wieloboku. Tym samym z każdym z boków tej figury możemy skojarzyć odpowiedni wektor zgodny z orientacja brzegu. Copyright c 2005 2008 Bogdan Kreczmer Przykład zastosowania przeciażeń operatorów i metod stałych - szukanie punktu przecięcia z wielobokiem 28
Szukanie punktu przecięcia float Wielobok::CzyPrzeciecie( const Odcinek & Odc, Wektor & PntPrz ) const { float t min = numeric limits<float>::max( ), t, t2; Wektor Pnt; } for (int i n=0, i o= Ilosc 1, i p= Ilosc 2; i n < Ilosc; i p = i o, i o = i n++) if ( (t = Odc.CzyPunktWspolny( Wierz[i o], Wierz[i n], t2, Pnt) ) < t min) { if ( t2 == 1 ) continue ; if ( t2 == 0 ) { if (!CzyWnika(Odc, i p, i o, i n) ) continue ; } t min = t; PntPrz = Pnt; } return t min; Zdekomponowanie podstawowego zadania pozwala łatwiej zapisać rozwiazanie podstawowego problemu. Copyright c 2005 2008 Bogdan Kreczmer Przykład zastosowania przeciażeń operatorów i metod stałych - szukanie punktu przecięcia z wielobokiem 29
Wyznaczanie punktu wspólnego float Odcinek::CzyPunktWspolny( const Wektor & P2o, const Wektor & P2n, float & t2, Wektor & PntPrz ) const { Wektor A1 = Pn Po, A2 = P2n P2o; Wektor B = P2o Po; float Wz = A2 A1; } if ( Wz == 0 ) return numeric limits<float>::max( ); float t1 = (A2 B)/Wz; t2 = (A1 B)/Wz; if (t1 < 0 1 < t1 t2 < 0 1 < t2) return numeric limits<float>::max( ); PntPrz = A1 t1 + Po; return t1; Zdefiniowanie działań na wektorach znaczaco upraszcza zapis metody. Copyright c 2005 2008 Bogdan Kreczmer Przykład zastosowania przeciażeń operatorów i metod stałych - szukanie punktu przecięcia z wielobokiem 30
Sprawdzenie warunku wnikania bool Wielobok::CzyWnika( const Odcinek & Odc, unsigned int Indeks Pop, unsigned int Indeks Bie, unsigned int Indeks Nas ) const { Wektor V sf = Odc. Po Odc. Pn; Wektor V a = Wierz[Indeks Bie] Wierz[Indeks Pop]; Wektor V b = Wierz[Indeks Nas] Wierz[Indeks Bie]; float VsfxVa = V sf V a; float VsfxVb = V sf V b; } return VsfxVa > 0 && (VsfxVb > 0 VsfxVb == 0 && (V sf & V b) < 0) (VsfxVa > 0 VsfxVa == 0 && (V sf & V b) > 0) && VsfxVb > 0; sinα > 0 (sinβ > 0 sinβ = 0 cosβ = 1) (sinα > 0 sinα = 0 cosα = 1) sinβ > 0 Copyright c 2005 2008 Bogdan Kreczmer Przykład zastosowania przeciażeń operatorów i metod stałych - szukanie punktu przecięcia z wielobokiem 31
Jak radzić sobie z błędami obliczeń float Wynik;... if ( Wynik == 0 ) {... } Błędy obliczeń moga sprawić, że wartość zmiennej Wynik będzie nieznacznie różna od 0, choć teoretycznie powinna równać się 0. #define BLAD DLA FLOAT 1E-8 #define BLAD DLA DOUBLE 1E-14 inline int sgn( float x ) { return x+blad DLA FLOAT > 0? x-blad DLA FLOAT < 0? 0 : 1 : -1; } inline int sgn( double x ) { return x+blad DLA DOUBLE > 0? x-blad DLA DOUBLE < 0? 0 : 1 : -1; } if ( sgn( Wynik ) == 0 ) {... } Dobór stałych błędów zależy od stosowanej reprezentacji liczb zmiennoprzecinkowych. Przedstawiony sposób nie daje gwarancji rozwiazania problemu niedokładności obliczeń. Jednak może go znaczaco zredukować. Copyright c 2005 2008 Bogdan Kreczmer Przykład zastosowania przeciażeń operatorów i metod stałych - szukanie punktu przecięcia z wielobokiem 32
Translacja warunków x == 0 sgn(x) == 0 x > 0 sgn(x) == 1 x >= 0 sgn(x)!= -1 x == 7 sgn(x 7) == 0 x!= 7 sgn(x 7)!= 0 x > 7 sgn(x 7) == 1 x >= 7 sgn(x 7)!= 1 Copyright c 2005 2008 Bogdan Kreczmer Przykład zastosowania przeciażeń operatorów i metod stałych - szukanie punktu przecięcia z wielobokiem 33
Szukanie punktu przecięcia (użycie funkcji sgn) float Wielobok::CzyPrzeciecie( const Odcinek & Odc, Wektor & PntPrz ) const { float t min = numeric limits<float>::max( ), t, t2; Wektor Pnt; } for (int i n=0, i o= Ilosc 1, i p= Ilosc 2; i n < Ilosc; i p = i o, i o = i n++) if ( (t = Odc.CzyPunktWspolny( Wierz[i o], Wierz[i n], t2, Pnt) ) < t min) { if (! sgn(t2 1) ) continue ; if (! sgn(t2) ) { if (!CzyWnika(Odc, i p, i o, i n) ) continue ; } t min = t; PntPrz = Pnt; } return t min; Oryginalna postać warunków: t2 == 1 t1 == 0 Copyright c 2005 2008 Bogdan Kreczmer Przykład zastosowania przeciażeń operatorów i metod stałych - szukanie punktu przecięcia z wielobokiem 34
Wyznaczanie punktu wspólnego (użycie funkcji sgn) float Odcinek::CzyPunktWspolny( const Wektor & P2o, const Wektor & P2n, float & t2, Wektor & PntPrz ) const { Wektor A1 = Pn Po, A2 = P2n P2o; Wektor B = P2o Po; float Wz = A2 A1; } if (! sgn( Wz ) ) return numeric limits<float>::max( ); float t1 = (A2 B)/Wz; t2 = (A1 B)/Wz; if ( sgn(t1) == -1 sgn(1 t1) == -1 sgn(t2) == -1 sgn(1 t2) == -1 ) return numeric limits<float>::max( ); PntPrz = A1 t1 + Po; return t1; Oryginalna postać warunków: Wz == 0 t1 < 0 1 < t1 t2 < 0 1 < t2 Copyright c 2005 2008 Bogdan Kreczmer Przykład zastosowania przeciażeń operatorów i metod stałych - szukanie punktu przecięcia z wielobokiem 35
Sprawdzenie warunku wnikania (użycie funkcji sgn) bool Wielobok::CzyWnika( const Odcinek & Odc, unsigned int Indeks Pop, unsigned int Indeks Bie, unsigned int Indeks Nas ) const { Wektor V sf = Odc. Po Odc. Pn; Wektor V a = Wierz[Indeks Bie] Wierz[Indeks Pop]; Wektor V b = Wierz[Indeks Nas] Wierz[Indeks Bie]; float VsfxVa = V sf V a; float VsfxVb = V sf V b; } return sgn(vsfxva) == 1 && (sgn(vsfxvb) == 1!sgn(VsfxVb) && sgn(v sf & V b) == -1) (sgn(vsfxva) == 1!sgn(VsfxVa) && sgn(v sf & V b) == 1) && sgn(vsfxvb) == 1; Oryginalna postać warunków: VsfxVa > 0 && (VsfxVb > 0 VsfxVb == 0 && (V sf & V b) < 0) (VsfxVa > 0 VsfxVa == 0 && (V sf & V b) > 0) && VsfxVb > 0 Copyright c 2005 2008 Bogdan Kreczmer Przykład zastosowania przeciażeń operatorów i metod stałych - szukanie punktu przecięcia z wielobokiem 36
Pytania i ćwiczenia 1. Zakładajac że wszystkie zmienne sa poprawnie zadeklarowane jaki będzie wynik wywołania niniejszej metody: Odcinek Odc; Wektor PPrzec; Odc.CzyPunktWspolny(Odc. Pn,Odc. Po,&PPrzec); Czy otrzymany wynik będzie różny od wywołania: Odc.CzyPunktWspolny(Odc,&PPrzec); 2. Czy przedstawione w poprzednim punkcie wywołania metody CzyPunktWspolny będzie mogło być wykonane w przypadku, gdy obiekt Odc zadeklarowany zostanie jako obiekt stały? Copyright c 2005 2008 Bogdan Kreczmer Przykład zastosowania przeciażeń operatorów i metod stałych - szukanie punktu przecięcia z wielobokiem 37