//Jacek Matulewski, e-mail: jacek@fizyka.umk.pl #ifndef WEKTOR_H #define WEKTOR_H //wersja 2.3 #include #include template struct TWektor { public: //pola T X,Y,Z,W; /* union { struct { T X,Y,Z,W; }; T wspolrzedne[4]; }; */ //konstruktor TWektor() :X(0),Y(0),Z(0),W(1) { }; TWektor(T X,T Y,T Z,T W=1) :X(X),Y(Y),Z(Z),W(W) { } //operator indeksowania T& operator[](const int indeks) { switch(indeks) { case 0: return X; break; case 1: return Y; break; case 2: return Z; break; default: throw std::invalid_argument("Indeks spoza zakresu"); break; } //return wspolrzedne[indeks]; }; //operatory relacji bool operator==(const TWektor& w) const { return X==w.X && Y==w.Y && Z==w.Z && W==w.W; } bool operator!=(const TWektor& w) const { return !(*this == w); } bool Rownowazny(const TWektor& w) const { if(W==0 || w.W==0) throw std::exception("Jeden lub oba punkty znajdują się w nieskończoności (W=0)"); return X/W==w.X/w.W && Y/W==w.Y/w.W && Z/W==w.Z/w.W; } //operatory arytmetyczne TWektor& operator+=(const TWektor& w) { if(W==1) { X+=w.X; Y+=w.Y; Z+=w.Z; } else { X=X*w.W+w.X*W; Y=Y*w.W+w.Y*W; Z=Z*w.W+w.Z*W; W*=w.W; } return *this; }; TWektor operator+(const TWektor& w) const { return TWektor(*this) += w; }; TWektor& operator-=(const TWektor& w) { if(W==1) { X-=w.X; Y-=w.Y; Z-=w.Z; } else { X=X*w.W-w.X*W; Y=Y*w.W-w.Y*W; Z=Z*w.W-w.Z*W; W*=w.W; } return *this; }; TWektor operator-(const TWektor& w) const { return TWektor(*this) -= w; }; TWektor& operator*=(const T a) { X*=a; Y*=a; Z*=a; //wspolrzedna W pozostawiamy bez zmian return *this; }; TWektor operator*(const T a) const { return TWektor(*this) *= a; }; TWektor& operator/=(const T a) { if(a==0.0) throw std::invalid_argument("Dzielenie przez zero"); X/=a; Y/=a; Z/=a; //wspolrzedna W pozostawiamy bez zmian return *this; }; TWektor operator/(const T a) const { return TWektor(*this) /= a; }; TWektor operator-() const { return TWektor(-X,-Y,-Z,W); } TWektor operator+() const { return *this; }; //iloczyn skalarny T operator*(const TWektor& w) const { return (X*w.X+Y*w.Y+Z*w.Z)/(W*w.W); //wartosc z przestrzeni trojwymiarowej (to nie jest iloczyn skalarny w rozumieniu przestrzeni 4D) }; //iloczyn wektorowy TWektor operator^(const TWektor& w) const //operator ^ ma niski priorytet { if(W!=1 || w.W!=1) throw std::exception("Iloczyn wektorowy nie jest określony we współrzędnych jednorodnych (współrzędna W musi być równa 1)"); TWektor wynik; wynik.X= Y*w.Z-Z*w.Y; wynik.Y=-(X*w.Z-Z*w.X); wynik.Z= X*w.Y-Y*w.X; return wynik; } TWektor operator%(const TWektor& w) const //operator % ma taki sam priorytet jak * { return *this^w; } //metody T KwadratDlugosci() const { if(W==0) throw std::exception("Punkt znajduje się w nieskończoności (W=0)"); return (X*X+Y*Y+Z*Z)/(W*W); } T Dlugosc() const { return sqrt(KwadratDlugosci()); //return (T)sqrt((long double)KwadratDlugosci()); } void Normuj() //normalizacja w przestrzeni trojwymiarowej { T dlugosc=Dlugosc(); if (dlugosc!=0) *this/=dlugosc; else throw std::invalid_argument("Nie mozna unormowac zerowego wektora"); } TWektor Unormowany() const { TWektor w(*this); w.Normuj(); return w; } T* ZapiszWTablicy(T tablica[3]) const //przeksztalca do wspolrzednych trojwymiarowych { if(W==0) throw std::exception("Punkt znajduje się w nieskończoności (W=0)"); tablica[0]=X/W; tablica[1]=Y/W; tablica[2]=Z/W; return tablica; } T* ZapiszWTablicy4(T tablica[4]) const { tablica[0]=X; tablica[1]=Y; tablica[2]=Z; tablica[3]=W; return tablica; } static TWektor Zero() { return TWektor(0,0,0); } static TWektor WersorX() { return TWektor(1,0,0); } static TWektor WersorY() { return TWektor(0,1,0); } static TWektor WersorZ() { return TWektor(0,0,1); } static TWektor Jeden() { return TWektor(1,1,1); } }; template TWektor inline operator*(const T a,const TWektor &w) { return w*a; //return TWektor(a*w.X,a*w.Y,a*w.Z); } template TWektor IloczynWektorowy(TWektor a,TWektor b) { return a^b; } //specjalizacja dla int template<> int TWektor::Dlugosc() const { return (int)sqrt((long double)KwadratDlugosci()); } typedef TWektor Wektor; //inicjacja wykonywana po teście //static const Wektor WektorZero(0,0,0,1); //Wektor WersorX(1,0,0); //Wektor WersorY(0,1,0); //Wektor WersorZ(0,0,1); #endif