Przykład implementacji przeciażeń operatorów problem kolizji 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.
Opis problemu: Zaimplementować procedurę obliczeniowa umożliwiajac a stwierdzenie, czy dla dwóch platform mobilnych poruszajacych się wzdłuż prostej ruchem jednostajnym zachodzi kolizja. Zakładamy, że kolizja zachodzi jeśli jakaś przeszkoda znajdzie się w obrębie okręgu opisanego na rzucie pionowym korpusu platformy. Platforma mobilna 1 Platforma mobilna 2 1
Analiza problemu Zaimplementować procedurę obliczeniowa umożliwiajac a stwierdzenie, czy dla dwóch platform mobilnych poruszajacych się wzdłuż prostej ruchem jednostajnym zachodzi kolizja. Zakładamy, że kolizja zachodzi jeśli jakaś przeszkoda znajdzie się w obrębie okręgu opisanego na rzucie pionowym korpusu platformy. Kluczowe rzeczowniki: platforma ( mobilna ) Własności: ruch położenie rozmiar Relacje: kolizyjność 2
Rozwiazanie w globalnym układzie współrzędnych Rozwiazaniem problemu jest wyznaczenie najmniejszej odległości na jaka zbliża się do siebie platformy. Kolizja nie nastapi jeżeli odległość ta będzie większa niż suma promieni okręgów opisanych na korpusach obu platform. d(t) = (x 1 x 2 ) 2 +(y 1 y 2 ) 2 x1 (t) = v x,1 t + x 0,1 y 1 (t) = v y,1 t + y 0,1 x2 (t) = v x,2 t + x 0,2 y 2 (t) = v y,2 t + y 0,2 d(t) = ((v x,1 v x,2 )t +(x 0,1 x 0,2 )) 2 +((v y,1 v y,2 )t +(y 0,1 y 0,2 )) 2 3
Rozwiazanie w globalnym układzie współrzędnych d(t) = ((v x,1 v x,2 )t +(x 0,1 x 0,2 )) 2 +((v y,1 v y,2 )t +(y 0,1 y 0,2 )) 2 d(t) = (v x,12 t + x 0,12 ) 2 +(v y,12 t + y 0,12 ) 2 gdzie v x,12 = v x,1 v x,2 analogicznie x 0,12,v y,12,y 0,12. Szukamy wartość t, dla której funkcja d(.) osiaga minimum: dd(t) dt = 0 v x,12 (v x,12 t + x 0,12 )+v y,12 (v y,12 t + y 0,12 ) = 0 t = v x,12x 0,12 + v y,12 y 0,12 v 2 x,12 + v2 y,12 4
Rozwiazanie w lokalnym układzie współrzędnych Transformacja do lokalnego układu współrzędnych platformy nr 2 zwiazanego ze środkiem okręgu opisanego na obrysie jej korpusu. xl (t) = x 1 (t) x 2 (t) y L (t) = y 1 (t) y 2 (t) vx,l (t) = v x,1 (t) v x,2 (t) v y,l (t) = v y,1 (t) v y,2 (t) Dzięki zastosowanej transformacji rozwiazanie problemu znacznie się upraszcza. trzeba liczyć pochodnej, gdyż w tym przypadku problem jest natury geometrycznej. Nie 5
Rozwiazanie w lokalnym układzie współrzędnych W lokalnym układzie współrzędnych jednej z platform problem sprowadza się do wyznaczenia odległości prostej od poczatku układu współrzędnych. e V V L e r α r d d = r sinα d = r sinα = r(e r e V ) = (r e V ) z = (r V L V L ) z = (r V L) z V L 6
d = (r V L) z V L 7
Rozwiazanie w lokalnym układzie współrzędnych W lokalnym układzie współrzędnych jednej z platform problem sprowadza się do wyznaczenia odległości prostej od poczatku układu współrzędnych. e V V L e r α r d d = r sinα Kolizja zachodzi gdy: 8
(r V L ) z V L < R 1 + R 2 9
float Vx1, Vy1, Px1, Py1, R1; float Vx2, Vy2, Px2, Py2, R2;... Implementacja w C (beznadziejna!!!) int CzyKolizja() float Vx, Vy, Px, Py; /.................... Stan platformy nr 2 w układzie lokalnym platformy nr 1 / float d; /....................................... Obliczana odległość minięcia się platformy nr 1 i 2 / Vx = Vx1 - Vx2; /............. Obliczanie prędkości platformy nr 2 w układzie lokalnym platformy nr 1 / Vy = Vy1 - Vy2; Px = Px1 - Px2; /............. Obliczanie położenia platformy nr 2 w układzie lokalnym platformy nr 1 / Py = Py1 - Py2; d = fabs(px Vy - Py Vx)/sqrt(Vx Vx+Vy Vy); /............... Obliczanie odległości minięcia się / return d < R1+R2; } Stosowanie zmiennych globalnym w tym przypadku nie jest uzasadnione. 10
Implementacja w C (Sposób zdecydowanie lepszy) / Vx1, Vy1, Px1, Py1 prędkość i położenie platformy nr 1, R1 promień okręgu obrysowujacego pionowy rzut korpusu platformy, Vx2, Vy2, Px2, Py2 prędkość i położenie platformy nr 2, R2 promień okręgu obrysowujacego pionowy rzut korpusu platformy, / int CzyKolizja( float Vx1, float Vy1, float Px1, float Py1, float R1, float Vx2, float Vy2, float Px2, float Py2, float R2 ) float Vx, Vy, Px, Py, /..................... Stan platformy nr 2 w układzie lokalnym platformy nr 1 / float d; /.........................................Obliczana odległość minięcia się platformy nr 1 i 2 / Vx = Vx1 - Vx2; /............. Obliczanie prędkości platformy nr 2 w układzie lokalnym platformy nr 1 / Vy = Vy1 - Vy2; Px = Px1 - Px2; /............. Obliczanie położenia platformy nr 2 w układzie lokalnym platformy nr 1 / Py = Py1 - Py2; d = fabs(px Vy - Py Vx)/sqrt(Vx Vx+Vy Vy); /................ Obliczenie Odległości minięcia się / } return d < R1+R2; 11
Implementacja w C (Sposób obiektowo zorientowany) typedef struct Wektor float x, y; } Wektor; typedef struct PlatformaMobilna Wektor Pos; /........................................ Położenie platformy / Wektor V; /.................................. Wektor prędkości platformy / float R; /.............. Promień obrysu pionowego rzutu korpusu platformy / } PlatformaMobilna; 12
Implementacja w C (Sposób obiektowo zorientowany) int CzyKolizja( PlatformaMobilna PM1, PlatformaMobilna PM2 ) Wektor V, P; /................................ Stan platformy nr 2 w układzie lokalnym platformy nr 1 / float d; /....................................Obliczana odległość minięcia się platformy nr 1 i 2 / V.x = PM1.Vel.x - PM2.Vel.x; /.. Obliczanie prędkości platformy nr 2 w układzie lokalnym platformy nr 1 / V.y = PM1.Vel.y - PM2.Vel.y; P.x = PM1.Pos.x - PM2.Pos.x; / Obliczanie położenia platformy nr 2 w układzie lokalnym platformy nr 1 / P.y = PM1.Pos.y - PM2.Pos.y; d = fabs(p.x V.y - P.y V.x)/sqrt(V.x V.x+V.y V.y); /.............. Obliczenie Odległości minięcia się / return } d < PM1.R+PM2.R; 13
Implementacja w C++ (bez operatorów) class Wektor //........................................................................... public: float x, y; Wektor Odejmij(Wektor) const; float IloczynWekZ(const Wektor & V) const return x V. y y V. x; } float IloczynSkal(const Wektor & V) const return x V. x + y V. y; } }; //......................................................................................... class PlatformaMobilna //................................................................ public: Wektor Pozycja; Wektor WPredkosci; float R; bool CzyKolizja( const PlatformaMobilna & V) const; }; //......................................................................................... 14
Implementacja w C++ (bez operatorów) Wektor Wektor::Odejmij( Wektor W ) const W. x = x W. x; W. y = y W. y; return W; } bool PlatformaMobilna::CzyKolizja( const PlatformaMobilna & PM ) const Wektor V d = PM. WPredkosci.Odejmij( WPredkosci); Wektor P d = PM. Pozycja.Odejmij( Pozycja); float d = fabs(p d.iloczynwektz(v))/sqrt(v.iloczynskal(v)); return d < PM. R+ R; } 15
Implementacja w C++ class Wektor //................................................................... public: float x, y; Wektor operator (Wektor) const; float operator (const Wektor & V) const return x V. y y V. x; } float operator & (const Wektor & V) const return x V. x + y V. y; } }; //................................................................................. class PlatformaMobilna //........................................................ public: Wektor Pozycja; Wektor WPredkosci; float R; bool CzyKolizja( const PlatformaMobilna & PM) const; }; //................................................................................. 16
Implementacja w C++ Wektor Wektor::operator ( Wektor W ) const W. x = x W. x; W. y = y W. y; return W; } bool PlatformaMobilna::CzyKolizja( const PlatformaMobilna & PM ) const Wektor V = PM. WPredkosci WPredkosci; Wektor r = PM. Pozycja Pozycja; return fabs(r V)/sqrt(V & V) < PM. R+ R; } (r V L ) z V L < R 1 + R 2 17
Implementacja w C++ Wektor Wektor::operator ( Wektor W ) const W. x = x W. x; W. y = y W. y; return W; } bool PlatformaMobilna::CzyKolizja( const PlatformaMobilna & PM ) const Wektor V = PM. WPredkosci WPredkosci; return fabs((pm. Pozycja Pozycja) V)/sqrt(V & V) < PM. R+ R; } (r V L ) z V L < R 1 + R 2 18
Diagramy klas w UML Rysunek 1: Diagram klas dla problemu wykrywania kolizji. 19
1. Dany jest definicja klasy Wektor: struct Wektor float x, y; Pytania i ćwiczenia Wektor operator ( Wektor W ) W. x = x W. x; W. y = y W. y; return W; } float operator (Wektor V) return x V. y y V. x; } float operator & (Wektor V) return x V. x + y V. y; } }; (a) Czy dla powyższej definicji poprawny jest poniższy zapis? Jeżeli tak, to jaki będzie wynik? Jeżeli nie, to co trzeba zrobić aby zapis ten był poprawny? Wektor W; W. x = W. y = 1; cout << (W & W W); (b) Czy dla powyższej definicji poprawny jest poniższy zapis? Jeżeli tak, to jaki będzie wynik? Jeżeli nie, to co trzeba zrobić aby zapis ten był poprawny? Wektor W; W. x = W. y = 1; cout << (W & W W W); 20