Home · All Namespaces · All Classes · Functions · Coding Style · Scripting · Plugins · File Structure

core/VecMath.hpp

00001 /*
00002  *
00003  * Copyright (C) 2003 Fabien Chereau
00004  *
00005  * This program is free software; you can redistribute it and/or
00006  * modify it under the terms of the GNU General Public License
00007  * as published by the Free Software Foundation; either version 2
00008  * of the License, or (at your option) any later version.
00009  *
00010  * This program is distributed in the hope that it will be useful,
00011  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013  * GNU General Public License for more details.
00014  *
00015  * You should have received a copy of the GNU General Public License
00016  * along with this program; if not, write to the Free Software
00017  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
00018  */
00019 
00020 // Template vector and matrix library.
00021 // Use OpenGL compatible ordering ie. you can pass a matrix or vector to
00022 // openGL functions without changes in the ordering
00023 
00024 #ifndef _VECMATH_H_
00025 #define _VECMATH_H_
00026 
00027 #include <cmath>
00028 #include <QString>
00029 
00030 template<class T> class Vector2;
00031 template<class T> class Vector3;
00032 template<class T> class Vector4;
00033 template<class T> class Matrix4;
00034 
00035 typedef Vector2<double> Vec2d;
00036 typedef Vector2<float>  Vec2f;
00037 typedef Vector2<int>    Vec2i;
00038 
00041 typedef Vector3<double> Vec3d;
00042 
00045 typedef Vector3<float>  Vec3f;
00046 
00049 typedef Vector4<double> Vec4d;
00050 
00053 typedef Vector4<float>  Vec4f;
00054 
00057 typedef Vector4<int>    Vec4i;
00058 
00061 typedef Matrix4<double> Mat4d;
00062 
00065 typedef Matrix4<float>  Mat4f;
00066 
00067 
00071 template<class T> class Vector2
00072 {
00073 public:
00074     inline Vector2();
00075     inline Vector2(const Vector2<T>&);
00076     inline Vector2(T, T);
00077 
00078     inline Vector2& operator=(const Vector2<T>&);
00079     inline Vector2& operator=(const T*);
00080     inline void set(T, T);
00081 
00082     inline bool operator==(const Vector2<T>&) const;
00083     inline bool operator!=(const Vector2<T>&) const;
00084 
00085     inline const T& operator[](int x) const;
00086     inline T& operator[](int);
00087     inline operator const T*() const;
00088     inline operator T*();
00089 
00090     inline Vector2& operator+=(const Vector2<T>&);
00091     inline Vector2& operator-=(const Vector2<T>&);
00092     inline Vector2& operator*=(T);
00093     inline Vector2& operator/=(T);
00094 
00095     inline Vector2 operator-(const Vector2<T>&) const;
00096     inline Vector2 operator+(const Vector2<T>&) const;
00097 
00098     inline Vector2 operator-() const;
00099     inline Vector2 operator+() const;
00100 
00101     inline Vector2 operator*(T) const;
00102     inline Vector2 operator/(T) const;
00103 
00104 
00105     inline T dot(const Vector2<T>&) const;
00106 
00107     inline T length() const;
00108     inline T lengthSquared() const;
00109     inline void normalize();
00110 
00111     T v[2];
00112 };
00113 
00114 
00118 template<class T> class Vector3
00119 {
00120 public:
00121     inline Vector3();
00122     inline Vector3(const Vector3&);
00123     template <class T2> inline Vector3(const Vector3<T2>&);
00124     inline Vector3(T, T, T);
00125     inline Vector3(T);
00126 
00127     inline Vector3& operator=(const Vector3&);
00128     inline Vector3& operator=(const T*);
00129     template <class T2> inline Vector3& operator=(const Vector3<T2>&);
00130     inline void set(T, T, T);
00131 
00132     inline bool operator==(const Vector3<T>&) const;
00133     inline bool operator!=(const Vector3<T>&) const;
00134 
00135     inline T& operator[](int);
00136     inline const T& operator[](int) const;
00137     inline operator const T*() const;
00138     inline operator T*();
00139     inline const T* data() const {return v;}
00140     inline T* data() {return v;}
00141 
00142     inline Vector3& operator+=(const Vector3<T>&);
00143     inline Vector3& operator-=(const Vector3<T>&);
00144     inline Vector3& operator*=(T);
00145     inline Vector3& operator/=(T);
00146 
00147     inline Vector3 operator-(const Vector3<T>&) const;
00148     inline Vector3 operator+(const Vector3<T>&) const;
00149 
00150     inline Vector3 operator-() const;
00151     inline Vector3 operator+() const;
00152 
00153     inline Vector3 operator*(T) const;
00154     inline Vector3 operator/(T) const;
00155 
00156 
00157     inline T dot(const Vector3<T>&) const;
00158     inline Vector3 operator^(const Vector3<T>&) const;
00159 
00160     // Return latitude in rad
00161     inline T latitude() const;
00162     // Return longitude in rad
00163     inline T longitude() const;
00164 
00165     // Distance in radian between two
00166     inline T angle(const Vector3<T>&) const;
00167 
00168     inline T length() const;
00169     inline T lengthSquared() const;
00170     inline void normalize();
00171 
00172     inline void transfo4d(const Mat4d&);
00173     inline void transfo4d(const Mat4f&);
00174     T v[3];     // The 3 values
00175 
00176     QString toString() const {return QString("[%1, %2, %3]").arg(v[0]).arg(v[1]).arg(v[2]);}
00177     QString toStringLonLat() const {return QString("[") + QString::number(longitude()*180./M_PI, 'g', 12) + "," + QString::number(latitude()*180./M_PI, 'g', 12)+"]";}
00178 };
00179 
00180 
00184 template<class T> class Vector4
00185 {
00186 public:
00187     inline Vector4();
00188     inline Vector4(const Vector4<T>&);
00189     inline Vector4(const Vector3<T>&);
00190     inline Vector4(T, T, T);
00191     inline Vector4(T, T, T, T);
00192 
00193     inline Vector4& operator=(const Vector4<T>&);
00194     inline Vector4& operator=(const Vector3<T>&);
00195     inline Vector4& operator=(const T*);
00196     inline void set(T, T, T, T);
00197 
00198     inline bool operator==(const Vector4<T>&) const;
00199     inline bool operator!=(const Vector4<T>&) const;
00200 
00201     inline T& operator[](int);
00202     inline const T& operator[](int) const;
00203     inline operator T*();
00204     inline operator const T*() const;
00205 
00206     inline Vector4& operator+=(const Vector4<T>&);
00207     inline Vector4& operator-=(const Vector4<T>&);
00208     inline Vector4& operator*=(T);
00209     inline Vector4& operator/=(T);
00210 
00211     inline Vector4 operator-(const Vector4<T>&) const;
00212     inline Vector4 operator+(const Vector4<T>&) const;
00213 
00214     inline Vector4 operator-() const;
00215     inline Vector4 operator+() const;
00216 
00217     inline Vector4 operator*(T) const;
00218     inline Vector4 operator/(T) const;
00219 
00220 
00221     inline T dot(const Vector4<T>&) const;
00222 
00223     inline T length() const;
00224     inline T lengthSquared() const;
00225     inline void normalize();
00226 
00227     inline void transfo4d(const Mat4d&);
00228 
00229     T v[4];     // The 4 values
00230 };
00231 
00235 template<class T> class Matrix4
00236 {
00237  public:
00238     Matrix4();
00239     Matrix4(const Matrix4<T>& m);
00240     Matrix4(T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T);
00241     Matrix4(const T*);
00242     Matrix4(const Vector4<T>&, const Vector4<T>&,
00243             const Vector4<T>&, const Vector4<T>&);
00244 
00245     inline Matrix4& operator=(const Matrix4<T>&);
00246     inline Matrix4& operator=(const T*);
00247     inline void set(T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T);
00248 
00249     inline T& operator[](int);
00250     inline operator T*();
00251     inline operator const T*() const;
00252 
00253     inline Matrix4 operator-(const Matrix4<T>&) const;
00254     inline Matrix4 operator+(const Matrix4<T>&) const;
00255     inline Matrix4 operator*(const Matrix4<T>&) const;
00256 
00257     inline Vector3<T> operator*(const Vector3<T>&) const;
00258     inline Vector3<T> multiplyWithoutTranslation(const Vector3<T>& a) const;
00259     inline Vector4<T> operator*(const Vector4<T>&) const;
00260 
00261     inline void transfo(Vector3<T>&) const;
00262 
00263     static Matrix4<T> identity();
00264     static Matrix4<T> translation(const Vector3<T>&);
00265 
00266     //    static Matrix4<T> rotation(const Vector3<T>&);
00267     static Matrix4<T> rotation(const Vector3<T>&, T);
00268     static Matrix4<T> xrotation(T);
00269     static Matrix4<T> yrotation(T);
00270     static Matrix4<T> zrotation(T);
00271     static Matrix4<T> scaling(const Vector3<T>&);
00272     static Matrix4<T> scaling(T);
00273 
00274     Matrix4<T> transpose() const;
00275     Matrix4<T> inverse() const;
00276 
00277     inline void print(void) const;
00278 
00279     T r[16];
00280 };
00281 
00283 template<class T> QDataStream& operator<<(QDataStream& out, const Vector2<T>& v) {out << v[0] << v[1]; return out;}
00284 template<class T> QDataStream& operator<<(QDataStream& out, const Vector3<T>& v) {out << v[0] << v[1] << v[2]; return out;}
00285 template<class T> QDataStream& operator<<(QDataStream& out, const Vector4<T>& v) {out << v[0] << v[1] << v[2] << v[3]; return out;}
00286 template<class T> QDataStream& operator<<(QDataStream& out, const Matrix4<T>& m) {out << m[0] << m[1] << m[2] << m[3] << m[4] << m[5] << m[6] << m[7] << m[8] << m[9] << m[10] << m[11] << m[12] << m[13] << m[14] << m[15]; return out;}
00287 
00288 template<class T> QDataStream& operator>>(QDataStream& in, Vector2<T>& v) {in >> v[0] >> v[1]; return in;}
00289 template<class T> QDataStream& operator>>(QDataStream& in, Vector3<T>& v) {in >> v[0] >> v[1] >> v[2]; return in;}
00290 template<class T> QDataStream& operator>>(QDataStream& in, Vector4<T>& v) {in >> v[0] >> v[1] >> v[2] >> v[3]; return in;}
00291 template<class T> QDataStream& operator>>(QDataStream& in, Matrix4<T>& m) {in >> m[0] >> m[1] >> m[2] >> m[3] >> m[4] >> m[5] >> m[6] >> m[7] >> m[8] >> m[9] >> m[10] >> m[11] >> m[12] >> m[13] >> m[14] >> m[15]; return in;}
00292 
00294 
00295 template<class T> Vector2<T>::Vector2() {}
00296 
00297 template<class T> Vector2<T>::Vector2(const Vector2<T>& a)
00298 {
00299     v[0]=a.v[0]; v[1]=a.v[1];
00300 }
00301 
00302 template<class T> Vector2<T>::Vector2(T x, T y)
00303 {
00304     v[0]=x; v[1]=y;
00305 }
00306 
00307 template<class T> Vector2<T>& Vector2<T>::operator=(const Vector2<T>& a)
00308 {
00309     v[0]=a.v[0]; v[1]=a.v[1];
00310     return *this;
00311 }
00312 
00313 template<class T> Vector2<T>& Vector2<T>::operator=(const T* a)
00314 {
00315     v[0]=a[0]; v[1]=a[1];
00316     return *this;
00317 }
00318 
00319 template<class T> void Vector2<T>::set(T x, T y)
00320 {
00321     v[0]=x; v[1]=y;
00322 }
00323 
00324 
00325 template<class T> bool Vector2<T>::operator==(const Vector2<T>& a) const
00326 {
00327     return (v[0] == a.v[0] && v[1] == a.v[1]);
00328 }
00329 
00330 template<class T> bool Vector2<T>::operator!=(const Vector2<T>& a) const
00331 {
00332     return (v[0] != a.v[0] || v[1] != a.v[1]);
00333 }
00334 
00335 template<class T> const T& Vector2<T>::operator[](int x) const
00336 {
00337     return v[x];
00338 }
00339 
00340 template<class T> T& Vector2<T>::operator[](int x)
00341 {
00342     return v[x];
00343 }
00344 
00345 template<class T> Vector2<T>::operator const T*() const
00346 {
00347     return v;
00348 }
00349 
00350 template<class T> Vector2<T>::operator T*()
00351 {
00352     return v;
00353 }
00354 
00355 
00356 template<class T> Vector2<T>& Vector2<T>::operator+=(const Vector2<T>& a)
00357 {
00358     v[0] += a.v[0]; v[1] += a.v[1];
00359     return *this;
00360 }
00361 
00362 template<class T> Vector2<T>& Vector2<T>::operator-=(const Vector2<T>& a)
00363 {
00364     v[0] -= a.v[0]; v[1] -= a.v[1];
00365     return *this;
00366 }
00367 
00368 template<class T> Vector2<T>& Vector2<T>::operator*=(T s)
00369 {
00370     v[0] *= s; v[1] *= s;
00371     return *this;
00372 }
00373 
00374 template<class T> Vector2<T> Vector2<T>::operator-() const
00375 {
00376     return Vector2<T>(-v[0], -v[1]);
00377 }
00378 
00379 template<class T> Vector2<T> Vector2<T>::operator+() const
00380 {
00381     return *this;
00382 }
00383 
00384 template<class T> Vector2<T> Vector2<T>::operator+(const Vector2<T>& b) const
00385 {
00386     return Vector2<T>(v[0] + b.v[0], v[1] + b.v[1]);
00387 }
00388 
00389 template<class T> Vector2<T> Vector2<T>::operator-(const Vector2<T>& b) const
00390 {
00391     return Vector2<T>(v[0] - b.v[0], v[1] - b.v[1]);
00392 }
00393 
00394 template<class T> Vector2<T> Vector2<T>::operator*(T s) const
00395 {
00396     return Vector2<T>(s * v[0], s * v[1]);
00397 }
00398 
00399 template<class T> Vector2<T> Vector2<T>::operator/(T s) const
00400 {
00401     return Vector2<T>(v[0]/s, v[1]/s);
00402 }
00403 
00404 
00405 template<class T> T Vector2<T>::dot(const Vector2<T>& b) const
00406 {
00407     return v[0] * b.v[0] + v[1] * b.v[1];
00408 }
00409 
00410 
00411 template<class T> T Vector2<T>::length() const
00412 {
00413     return (T) std::sqrt(v[0] * v[0] + v[1] * v[1]);
00414 }
00415 
00416 template<class T> T Vector2<T>::lengthSquared() const
00417 {
00418     return v[0] * v[0] + v[1] * v[1];
00419 }
00420 
00421 template<class T> void Vector2<T>::normalize()
00422 {
00423     T s = (T) 1 / std::sqrt(v[0] * v[0] + v[1] * v[1]);
00424     v[0] *= s;
00425     v[1] *= s;
00426 }
00427 
00428 // template<class T>
00429 // std::ostream& operator<<(std::ostream &o,const Vector2<T> &v) {
00430 //   return o << '[' << v[0] << ',' << v[1] << ']';
00431 // }
00432 
00434 
00435 template<class T> Vector3<T>::Vector3() {}
00436 
00437 template<class T> Vector3<T>::Vector3(const Vector3& a)
00438 {
00439     v[0]=a.v[0]; v[1]=a.v[1]; v[2]=a.v[2];
00440 }
00441 
00442 template<class T> template<class T2> Vector3<T>::Vector3(const Vector3<T2>& a)
00443 {
00444     v[0]=a.v[0]; v[1]=a.v[1]; v[2]=a.v[2];
00445 }
00446 
00447 template<class T> Vector3<T>::Vector3(T x)
00448 {
00449     v[0]=x; v[1]=x; v[2]=x;
00450 }
00451 
00452 template<class T> Vector3<T>::Vector3(T x, T y, T z)
00453 {
00454     v[0]=x; v[1]=y; v[2]=z;
00455 }
00456 
00457 template<class T> Vector3<T>& Vector3<T>::operator=(const Vector3& a)
00458 {
00459     v[0]=a.v[0]; v[1]=a.v[1]; v[2]=a.v[2];
00460     return *this;
00461 }
00462 
00463 template<class T> template <class T2> Vector3<T>& Vector3<T>::operator=(const Vector3<T2>& a)
00464 {
00465     v[0]=a.v[0]; v[1]=a.v[1]; v[2]=a.v[2];
00466     return *this;
00467 }
00468 
00469 template<class T> Vector3<T>& Vector3<T>::operator=(const T* a)
00470 {
00471     v[0]=a[0]; v[1]=a[1]; v[2]=a[2];
00472     return *this;
00473 }
00474 
00475 template<class T> void Vector3<T>::set(T x, T y, T z)
00476 {
00477     v[0]=x; v[1]=y; v[2]=z;
00478 }
00479 
00480 
00481 template<class T> bool Vector3<T>::operator==(const Vector3<T>& a) const
00482 {
00483     return (v[0] == a.v[0] && v[1] == a.v[1] && v[2] == a.v[2]);
00484 }
00485 
00486 template<class T> bool Vector3<T>::operator!=(const Vector3<T>& a) const
00487 {
00488     return (v[0] != a.v[0] || v[1] != a.v[1] || v[2] != a.v[2]);
00489 }
00490 
00491 
00492 template<class T> T& Vector3<T>::operator[](int x)
00493 {
00494     return v[x];
00495 }
00496 
00497 template<class T> const T& Vector3<T>::operator[](int x) const
00498 {
00499     return v[x];
00500 }
00501 
00502 template<class T> Vector3<T>::operator const T*() const
00503 {
00504     return v;
00505 }
00506 
00507 template<class T> Vector3<T>::operator T*()
00508 {
00509     return v;
00510 }
00511 
00512 template<class T> Vector3<T>& Vector3<T>::operator+=(const Vector3<T>& a)
00513 {
00514     v[0] += a.v[0]; v[1] += a.v[1]; v[2] += a.v[2];
00515     return *this;
00516 }
00517 
00518 template<class T> Vector3<T>& Vector3<T>::operator-=(const Vector3<T>& a)
00519 {
00520     v[0] -= a.v[0]; v[1] -= a.v[1]; v[2] -= a.v[2];
00521     return *this;
00522 }
00523 
00524 template<class T> Vector3<T>& Vector3<T>::operator*=(T s)
00525 {
00526     v[0] *= s; v[1] *= s; v[2] *= s;
00527     return *this;
00528 }
00529 
00530 template<class T> Vector3<T>& Vector3<T>::operator/=(T s)
00531 {
00532     v[0] /= s; v[1] /= s; v[2] /= s;
00533     return *this;
00534 }
00535 
00536 template<class T> Vector3<T> Vector3<T>::operator-() const
00537 {
00538     return Vector3<T>(-v[0], -v[1], -v[2]);
00539 }
00540 
00541 template<class T> Vector3<T> Vector3<T>::operator+() const
00542 {
00543     return *this;
00544 }
00545 
00546 template<class T> Vector3<T> Vector3<T>::operator+(const Vector3<T>& b) const
00547 {
00548     return Vector3<T>(v[0] + b.v[0], v[1] + b.v[1], v[2] + b.v[2]);
00549 }
00550 
00551 template<class T> Vector3<T> Vector3<T>::operator-(const Vector3<T>& b) const
00552 {
00553     return Vector3<T>(v[0] - b.v[0], v[1] - b.v[1], v[2] - b.v[2]);
00554 }
00555 
00556 template<class T> Vector3<T> Vector3<T>::operator*(T s) const
00557 {
00558     return Vector3<T>(s * v[0], s * v[1], s * v[2]);
00559 }
00560 
00561 template<class T> Vector3<T> Vector3<T>::operator/(T s) const
00562 {
00563     return Vector3<T>(v[0]/s, v[1]/s, v[2]/s);
00564 }
00565 
00566 
00567 template<class T> T Vector3<T>::dot(const Vector3<T>& b) const
00568 {
00569     return v[0] * b.v[0] + v[1] * b.v[1] + v[2] * b.v[2];
00570 }
00571 
00572 
00573 // cross product
00574 template<class T> Vector3<T> Vector3<T>::operator^(const Vector3<T>& b) const
00575 {
00576     return Vector3<T>(v[1] * b.v[2] - v[2] * b.v[1],
00577                       v[2] * b.v[0] - v[0] * b.v[2],
00578                       v[0] * b.v[1] - v[1] * b.v[0]);
00579 }
00580 
00581 // Angle in radian between two normalized vectors
00582 template<class T> T Vector3<T>::angle(const Vector3<T>& b) const
00583 {
00584     return std::acos(dot(b)/sqrt(lengthSquared()*b.lengthSquared()));
00585 }
00586 
00587 template<class T> T Vector3<T>::length() const
00588 {
00589     return (T) sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]);
00590 }
00591 
00592 template<class T> T Vector3<T>::lengthSquared() const
00593 {
00594     return v[0] * v[0] + v[1] * v[1] + v[2] * v[2];
00595 }
00596 
00597 template<class T> void Vector3<T>::normalize()
00598 {
00599     T s = (T) (1. / std::sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]));
00600     v[0] *= s;
00601     v[1] *= s;
00602     v[2] *= s;
00603 }
00604 
00605 template<class T> void Vector3<T>::transfo4d(const Mat4d& m)
00606 {
00607     const T v0 = v[0];
00608     const T v1 = v[1];
00609     v[0]=m.r[0]*v0 + m.r[4]*v1 + m.r[8]*v[2] + m.r[12];
00610     v[1]=m.r[1]*v0 + m.r[5]*v1 +  m.r[9]*v[2] + m.r[13];
00611     v[2]=m.r[2]*v0 + m.r[6]*v1 + m.r[10]*v[2] + m.r[14];
00612 }
00613 
00614 template<class T> void Vector3<T>::transfo4d(const Mat4f& m)
00615 {
00616     const T v0 = v[0];
00617     const T v1 = v[1];
00618     v[0]=m.r[0]*v0 + m.r[4]*v1 + m.r[8]*v[2] + m.r[12];
00619     v[1]=m.r[1]*v0 + m.r[5]*v1 +  m.r[9]*v[2] + m.r[13];
00620     v[2]=m.r[2]*v0 + m.r[6]*v1 + m.r[10]*v[2] + m.r[14];
00621 }
00622 
00623 // Return latitude in rad
00624 template<class T> T Vector3<T>::latitude() const
00625 {
00626     return std::asin(v[2]/length());
00627 }
00628 
00629 // Return longitude in rad
00630 template<class T> T Vector3<T>::longitude() const
00631 {
00632     return std::atan2(v[1],v[0]);
00633 }
00634 
00635 
00637 
00638 template<class T> Vector4<T>::Vector4() {}
00639 
00640 template<class T> Vector4<T>::Vector4(const Vector4<T>& a)
00641 {
00642     v[0]=a.v[0]; v[1]=a.v[1]; v[2]=a.v[2]; v[3]=a.v[3];
00643 }
00644 
00645 template<class T> Vector4<T>::Vector4(const Vector3<T>& a)
00646 {
00647     v[0]=a.v[0]; v[1]=a.v[1]; v[2]=a.v[2]; v[3]=1;
00648 }
00649 
00650 template<class T> Vector4<T>::Vector4(T x, T y, T z)
00651 {
00652     v[0]=x; v[1]=y; v[2]=z; v[3]=1;
00653 }
00654 
00655 template<class T> Vector4<T>::Vector4(T x, T y, T z, T a)
00656 {
00657     v[0]=x; v[1]=y; v[2]=z; v[3]=a;
00658 }
00659 
00660 template<class T> Vector4<T>& Vector4<T>::operator=(const Vector4<T>& a)
00661 {
00662     v[0]=a.v[0]; v[1]=a.v[1]; v[2]=a.v[2]; v[3]=a.v[3];
00663     return *this;
00664 }
00665 
00666 template<class T> Vector4<T>& Vector4<T>::operator=(const Vector3<T>& a)
00667 {
00668     v[0]=a.v[0]; v[1]=a.v[1]; v[2]=a.v[2]; v[3]=1;
00669     return *this;
00670 }
00671 
00672 template<class T> Vector4<T>& Vector4<T>::operator=(const T* a)
00673 {
00674     v[0]=a[0]; v[1]=a[1]; v[2]=a[2]; v[3]=a[3];
00675     return *this;
00676 }
00677 
00678 template<class T> void Vector4<T>::set(T x, T y, T z, T a)
00679 {
00680     v[0]=x; v[1]=y; v[2]=z; v[3]=a;
00681 }
00682 
00683 template<class T> bool Vector4<T>::operator==(const Vector4<T>& a) const
00684 {
00685     return (v[0] == a.v[0] && v[1] == a.v[1] && v[2] == a.v[2] && v[3] == a.v[3]);
00686 }
00687 
00688 template<class T> bool Vector4<T>::operator!=(const Vector4<T>& a) const
00689 {
00690     return (v[0] != a.v[0] || v[1] != a.v[1] || v[2] != a.v[2] || v[3] != a.v[3]);
00691 }
00692 
00693 template<class T> T& Vector4<T>::operator[](int x)
00694 {
00695     return v[x];
00696 }
00697 
00698 template<class T> const T& Vector4<T>::operator[](int x) const
00699 {
00700     return v[x];
00701 }
00702 
00703 template<class T> Vector4<T>::operator T*()
00704 {
00705     return v;
00706 }
00707 
00708 template<class T> Vector4<T>::operator const T*() const
00709 {
00710     return v;
00711 }
00712 
00713 template<class T> Vector4<T>& Vector4<T>::operator+=(const Vector4<T>& a)
00714 {
00715     v[0] += a.v[0]; v[1] += a.v[1]; v[2] += a.v[2]; v[3] += a.v[3];
00716     return *this;
00717 }
00718 
00719 template<class T> Vector4<T>& Vector4<T>::operator-=(const Vector4<T>& a)
00720 {
00721     v[0] -= a.v[0]; v[1] -= a.v[1]; v[2] -= a.v[2]; v[3] -= a/v[3];
00722     return *this;
00723 }
00724 
00725 template<class T> Vector4<T>& Vector4<T>::operator*=(T s)
00726 {
00727     v[0] *= s; v[1] *= s; v[2] *= s; v[3] *= s;
00728     return *this;
00729 }
00730 
00731 template<class T> Vector4<T> Vector4<T>::operator-() const
00732 {
00733     return Vector4<T>(-v[0], -v[1], -v[2], -v[3]);
00734 }
00735 
00736 template<class T> Vector4<T> Vector4<T>::operator+() const
00737 {
00738     return *this;
00739 }
00740 
00741 template<class T> Vector4<T> Vector4<T>::operator+(const Vector4<T>& b) const
00742 {
00743     return Vector4<T>(v[0] + b.v[0], v[1] + b.v[1], v[2] + b.v[2], v[3] + b.v[3]);
00744 }
00745 
00746 template<class T> Vector4<T> Vector4<T>::operator-(const Vector4<T>& b) const
00747 {
00748     return Vector4<T>(v[0] - b.v[0], v[1] - b.v[1], v[2] - b.v[2], v[3] - b.v[3]);
00749 }
00750 
00751 template<class T> Vector4<T> Vector4<T>::operator*(T s) const
00752 {
00753     return Vector4<T>(s * v[0], s * v[1], s * v[2], s * v[3]);
00754 }
00755 
00756 template<class T> Vector4<T> Vector4<T>::operator/(T s) const
00757 {
00758     return Vector4<T>(v[0]/s, v[1]/s, v[2]/s, v[3]/s);
00759 }
00760 
00761 template<class T> T Vector4<T>::dot(const Vector4<T>& b) const
00762 {
00763     return v[0] * b.v[0] + v[1] * b.v[1] + v[2] * b.v[2] + v[3] * b.v[3];
00764 }
00765 
00766 template<class T> T Vector4<T>::length() const
00767 {
00768     return (T) sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2] + v[3] * v[3]);
00769 }
00770 
00771 template<class T> T Vector4<T>::lengthSquared() const
00772 {
00773     return v[0] * v[0] + v[1] * v[1] + v[2] * v[2] + v[3] * v[3];
00774 }
00775 
00776 template<class T> void Vector4<T>::normalize()
00777 {
00778     T s = (T) (1. / sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2] + v[3] * v[3]));
00779     v[0] *= s;
00780     v[1] *= s;
00781     v[2] *= s;
00782     v[3] *= s;
00783 }
00784 
00785 template<class T> void Vector4<T>::transfo4d(const Mat4d& m)
00786 {
00787     (*this)=m*(*this);
00788 }
00789 /*
00790 template<class T>
00791 std::ostream& operator<<(std::ostream &o,const Vector4<T> &v) {
00792   return o << '[' << v[0] << ',' << v[1] << ',' << v[2] << ',' << v[3] << ']';
00793 }*/
00794 
00795 
00797 
00798 template<class T> Matrix4<T>::Matrix4() {}
00799 
00800 template<class T> Matrix4<T>::Matrix4(const Matrix4<T>& m)
00801 {
00802     memcpy(r,m.r,sizeof(T)*16);
00803 }
00804 
00805 template<class T> Matrix4<T>::Matrix4(const T* m)
00806 {
00807     memcpy(r,m,sizeof(T)*16);
00808 }
00809 
00810 template<class T> Matrix4<T>& Matrix4<T>::operator=(const Matrix4<T>& m)
00811 {
00812     memcpy(r,m.r,sizeof(T)*16);
00813     return (*this);
00814 }
00815 
00816 template<class T> Matrix4<T>::Matrix4(const Vector4<T>& v0,
00817                                       const Vector4<T>& v1,
00818                                       const Vector4<T>& v2,
00819                                       const Vector4<T>& v3)
00820 {
00821     r[0] = v0.v[0];
00822     r[1] = v0.v[1];
00823     r[2] = v0.v[2];
00824     r[3] = v0.v[3];
00825     r[4] = v1.v[0];
00826     r[5] = v1.v[1];
00827     r[6] = v1.v[2];
00828     r[7] = v1.v[3];
00829     r[8] = v2.v[0];
00830     r[9] = v2.v[1];
00831     r[10] = v2.v[2];
00832     r[11] = v2.v[3];
00833     r[12] = v3.v[0];
00834     r[13] = v3.v[1];
00835     r[14] = v3.v[2];
00836     r[15] = v3.v[3];
00837 }
00838 
00839 
00840 template<class T> Matrix4<T>::Matrix4(T a, T b, T c, T d, T e, T f, T g, T h, T i, T j, T k, T l, T m, T n, T o, T p)
00841 {
00842     r[0]=a; r[1]=b; r[2]=c; r[3]=d; r[4]=e; r[5]=f; r[6]=g; r[7]=h;
00843     r[8]=i; r[9]=j; r[10]=k; r[11]=l; r[12]=m; r[13]=n; r[14]=o; r[15]=p;
00844 }
00845 
00846 template<class T> void Matrix4<T>::set(T a, T b, T c, T d, T e, T f, T g, T h, T i, T j, T k, T l, T m, T n, T o, T p)
00847 {
00848     r[0]=a; r[1]=b; r[2]=c; r[3]=d; r[4]=e; r[5]=f; r[6]=g; r[7]=h;
00849     r[8]=i; r[9]=j; r[10]=k; r[11]=l; r[12]=m; r[13]=n; r[14]=o; r[15]=p;
00850 }
00851 
00852 template<class T> T& Matrix4<T>::operator[](int n)
00853 {
00854     return r[n];
00855 }
00856 
00857 template<class T> Matrix4<T>::operator T*()
00858 {
00859     return r;
00860 }
00861 
00862 template<class T> Matrix4<T>::operator const T*() const
00863 {
00864     return r;
00865 }
00866 
00867 template<class T> Matrix4<T> Matrix4<T>::identity()
00868 {
00869     return Matrix4<T>(  1, 0, 0, 0,
00870                         0, 1, 0, 0,
00871                         0, 0, 1, 0,
00872                         0, 0, 0, 1  );
00873 }
00874 
00875 
00876 template<class T> Matrix4<T> Matrix4<T>::translation(const Vector3<T>& a)
00877 {
00878     return Matrix4<T>(  1, 0, 0, 0,
00879                         0, 1, 0, 0,
00880                         0, 0, 1, 0,
00881                         a.v[0], a.v[1], a.v[2], 1);
00882 }
00883 
00884 
00885 template<class T> Matrix4<T> Matrix4<T>::rotation(const Vector3<T>& axis, T angle)
00886 {
00887     Vec3d a(axis);
00888     a.normalize();
00889     const T c = (T) cos(angle);
00890     const T s = (T) sin(angle);
00891     const T d = 1-c;
00892     return Matrix4<T>(  a[0]*a[0]*d+c     , a[1]*a[0]*d+a[2]*s, a[0]*a[2]*d-a[1]*s, 0,
00893                         a[0]*a[1]*d-a[2]*s, a[1]*a[1]*d+c     , a[1]*a[2]*d+a[0]*s, 0,
00894                         a[0]*a[2]*d+a[1]*s, a[1]*a[2]*d-a[0]*s, a[2]*a[2]*d+c     , 0,
00895                         0,0,0,1 );
00896 }
00897 
00898 template<class T> Matrix4<T> Matrix4<T>::xrotation(T angle)
00899 {
00900     T c = (T) cos(angle);
00901     T s = (T) sin(angle);
00902 
00903     return Matrix4<T>(1, 0, 0, 0,
00904                       0, c, s, 0,
00905                       0,-s, c, 0,
00906                       0, 0, 0, 1 );
00907 }
00908 
00909 
00910 template<class T> Matrix4<T> Matrix4<T>::yrotation(T angle)
00911 {
00912     T c = (T) cos(angle);
00913     T s = (T) sin(angle);
00914 
00915     return Matrix4<T>( c, 0,-s, 0,
00916                        0, 1, 0, 0,
00917                        s, 0, c, 0,
00918                        0, 0, 0, 1 );
00919 }
00920 
00921 
00922 template<class T> Matrix4<T> Matrix4<T>::zrotation(T angle)
00923 {
00924     T c = (T) cos(angle);
00925     T s = (T) sin(angle);
00926 
00927     return Matrix4<T>(c, s, 0, 0,
00928                      -s, c, 0, 0,
00929                       0, 0, 1, 0,
00930                       0, 0, 0, 1 );
00931 }
00932 
00933 
00934 template<class T> Matrix4<T> Matrix4<T>::scaling(const Vector3<T>& s)
00935 {
00936     return Matrix4<T>(s[0], 0  , 0  , 0,
00937                       0   ,s[1], 0  , 0,
00938                       0   , 0  ,s[2], 0,
00939                       0   , 0  , 0  , 1);
00940 }
00941 
00942 
00943 template<class T> Matrix4<T> Matrix4<T>::scaling(T scale)
00944 {
00945     return scaling(Vector3<T>(scale, scale, scale));
00946 }
00947 
00948 // multiply column vector by a 4x4 matrix in homogeneous coordinate (use a[3]=1)
00949 template<class T> Vector3<T> Matrix4<T>::operator*(const Vector3<T>& a) const
00950 {
00951     return Vector3<T>(  r[0]*a.v[0] + r[4]*a.v[1] +  r[8]*a.v[2] + r[12],
00952                         r[1]*a.v[0] + r[5]*a.v[1] +  r[9]*a.v[2] + r[13],
00953                         r[2]*a.v[0] + r[6]*a.v[1] + r[10]*a.v[2] + r[14] );
00954 }
00955 
00956 template<class T> Vector3<T> Matrix4<T>::multiplyWithoutTranslation(const Vector3<T>& a) const
00957 {
00958     return Vector3<T>(  r[0]*a.v[0] + r[4]*a.v[1] +  r[8]*a.v[2],
00959                         r[1]*a.v[0] + r[5]*a.v[1] +  r[9]*a.v[2],
00960                         r[2]*a.v[0] + r[6]*a.v[1] + r[10]*a.v[2] );
00961 }
00962 
00963 // multiply column vector by a 4x4 matrix in homogeneous coordinate (considere a[3]=1)
00964 template<class T> Vector4<T> Matrix4<T>::operator*(const Vector4<T>& a) const
00965 {
00966     return Vector4<T>(  r[0]*a.v[0] + r[4]*a.v[1] +  r[8]*a.v[2] + r[12]*a.v[3],
00967                         r[1]*a.v[0] + r[5]*a.v[1] +  r[9]*a.v[2] + r[13]*a.v[3],
00968                         r[2]*a.v[0] + r[6]*a.v[1] + r[10]*a.v[2] + r[14]*a.v[3] );
00969 }
00970 
00971 template<class T> void Matrix4<T>::transfo(Vector3<T>& a) const
00972 {
00973     a.set(  r[0]*a.v[0] + r[4]*a.v[1] +  r[8]*a.v[2] + r[12],
00974             r[1]*a.v[0] + r[5]*a.v[1] +  r[9]*a.v[2] + r[13],
00975             r[2]*a.v[0] + r[6]*a.v[1] + r[10]*a.v[2] + r[14]);
00976 }
00977 
00978 template<class T> Matrix4<T> Matrix4<T>::transpose() const
00979 {
00980     return Matrix4<T>(  r[0], r[4], r[8],  r[12],
00981                         r[1], r[5], r[9],  r[13],
00982                         r[2], r[6], r[10], r[14],
00983                         r[3], r[7], r[11], r[15]);
00984 }
00985 
00986 template<class T> Matrix4<T> Matrix4<T>::operator*(const Matrix4<T>& a) const
00987 {
00988 #define MATMUL(R, C) (r[R] * a.r[C] + r[R+4] * a.r[C+1] + r[R+8] * a.r[C+2] + r[R+12] * a.r[C+3])
00989     return Matrix4<T>(  MATMUL(0,0), MATMUL(1,0), MATMUL(2,0), MATMUL(3,0),
00990                         MATMUL(0,4), MATMUL(1,4), MATMUL(2,4), MATMUL(3,4),
00991                         MATMUL(0,8), MATMUL(1,8), MATMUL(2,8), MATMUL(3,8),
00992                         MATMUL(0,12), MATMUL(1,12), MATMUL(2,12), MATMUL(3,12) );
00993 #undef MATMUL
00994 }
00995 
00996 
00997 template<class T> Matrix4<T> Matrix4<T>::operator+(const Matrix4<T>& a) const
00998 {
00999     return Matrix4<T>(  r[0]+a.r[0], r[1]+a.r[1], r[2]+a.r[2], r[3]+a.r[3],
01000                         r[4]+a.r[4], r[5]+a.r[5], r[6]+a.r[6], r[7]+a.r[7],
01001                         r[8]+a.r[8], r[9]+a.r[9], r[10]+a.r[10], r[11]+a.r[11],
01002                         r[12]+a.r[12], r[13]+a.r[13], r[14]+a.r[14], r[15]+a.r[15] );
01003 }
01004 
01005 template<class T> Matrix4<T> Matrix4<T>::operator-(const Matrix4<T>& a) const
01006 {
01007     return Matrix4<T>(  r[0]-a.r[0], r[1]-a.r[1], r[2]-a.r[2], r[3]-a.r[3],
01008                         r[4]-a.r[4], r[5]-a.r[5], r[6]-a.r[6], r[7]-a.r[7],
01009                         r[8]-a.r[8], r[9]-a.r[9], r[10]-a.r[10], r[11]-a.r[11],
01010                         r[12]-a.r[12], r[13]-a.r[13], r[14]-a.r[14], r[15]-a.r[15] );
01011 }
01012 
01013 /*
01014  * Code ripped from the GLU library
01015  * Compute inverse of 4x4 transformation matrix.
01016  * Code contributed by Jacques Leroy jle@star.be
01017  * Return zero matrix on failure (singular matrix)
01018  */
01019 template<class T> Matrix4<T> Matrix4<T>::inverse() const
01020 {
01021     const T * m = r;
01022     T out[16];
01023 
01024 /* NB. OpenGL Matrices are COLUMN major. */
01025 #define SWAP_ROWS(a, b) { T *_tmp = a; (a)=(b); (b)=_tmp; }
01026 #define MAT(m,r,c) (m)[(c)*4+(r)]
01027 
01028    T wtmp[4][8];
01029    T m0, m1, m2, m3, s;
01030    T *r0, *r1, *r2, *r3;
01031 
01032    r0 = wtmp[0], r1 = wtmp[1], r2 = wtmp[2], r3 = wtmp[3];
01033 
01034    r0[0] = MAT(m, 0, 0), r0[1] = MAT(m, 0, 1),
01035       r0[2] = MAT(m, 0, 2), r0[3] = MAT(m, 0, 3),
01036       r0[4] = 1.0, r0[5] = r0[6] = r0[7] = 0.0,
01037       r1[0] = MAT(m, 1, 0), r1[1] = MAT(m, 1, 1),
01038       r1[2] = MAT(m, 1, 2), r1[3] = MAT(m, 1, 3),
01039       r1[5] = 1.0, r1[4] = r1[6] = r1[7] = 0.0,
01040       r2[0] = MAT(m, 2, 0), r2[1] = MAT(m, 2, 1),
01041       r2[2] = MAT(m, 2, 2), r2[3] = MAT(m, 2, 3),
01042       r2[6] = 1.0, r2[4] = r2[5] = r2[7] = 0.0,
01043       r3[0] = MAT(m, 3, 0), r3[1] = MAT(m, 3, 1),
01044       r3[2] = MAT(m, 3, 2), r3[3] = MAT(m, 3, 3),
01045       r3[7] = 1.0, r3[4] = r3[5] = r3[6] = 0.0;
01046 
01047    /* choose pivot - or die */
01048    if (fabs(r3[0]) > fabs(r2[0]))
01049       SWAP_ROWS(r3, r2);
01050    if (fabs(r2[0]) > fabs(r1[0]))
01051       SWAP_ROWS(r2, r1);
01052    if (fabs(r1[0]) > fabs(r0[0]))
01053       SWAP_ROWS(r1, r0);
01054    if (0.0 == r0[0])
01055       return Matrix4<T>();
01056 
01057    /* eliminate first variable     */
01058    m1 = r1[0] / r0[0];
01059    m2 = r2[0] / r0[0];
01060    m3 = r3[0] / r0[0];
01061    s = r0[1];
01062    r1[1] -= m1 * s;
01063    r2[1] -= m2 * s;
01064    r3[1] -= m3 * s;
01065    s = r0[2];
01066    r1[2] -= m1 * s;
01067    r2[2] -= m2 * s;
01068    r3[2] -= m3 * s;
01069    s = r0[3];
01070    r1[3] -= m1 * s;
01071    r2[3] -= m2 * s;
01072    r3[3] -= m3 * s;
01073    s = r0[4];
01074    if (s != 0.0) {
01075       r1[4] -= m1 * s;
01076       r2[4] -= m2 * s;
01077       r3[4] -= m3 * s;
01078    }
01079    s = r0[5];
01080    if (s != 0.0) {
01081       r1[5] -= m1 * s;
01082       r2[5] -= m2 * s;
01083       r3[5] -= m3 * s;
01084    }
01085    s = r0[6];
01086    if (s != 0.0) {
01087       r1[6] -= m1 * s;
01088       r2[6] -= m2 * s;
01089       r3[6] -= m3 * s;
01090    }
01091    s = r0[7];
01092    if (s != 0.0) {
01093       r1[7] -= m1 * s;
01094       r2[7] -= m2 * s;
01095       r3[7] -= m3 * s;
01096    }
01097 
01098    /* choose pivot - or die */
01099    if (fabs(r3[1]) > fabs(r2[1]))
01100       SWAP_ROWS(r3, r2);
01101    if (fabs(r2[1]) > fabs(r1[1]))
01102       SWAP_ROWS(r2, r1);
01103    if (0.0 == r1[1])
01104       return Matrix4<T>();
01105 
01106    /* eliminate second variable */
01107    m2 = r2[1] / r1[1];
01108    m3 = r3[1] / r1[1];
01109    r2[2] -= m2 * r1[2];
01110    r3[2] -= m3 * r1[2];
01111    r2[3] -= m2 * r1[3];
01112    r3[3] -= m3 * r1[3];
01113    s = r1[4];
01114    if (0.0 != s) {
01115       r2[4] -= m2 * s;
01116       r3[4] -= m3 * s;
01117    }
01118    s = r1[5];
01119    if (0.0 != s) {
01120       r2[5] -= m2 * s;
01121       r3[5] -= m3 * s;
01122    }
01123    s = r1[6];
01124    if (0.0 != s) {
01125       r2[6] -= m2 * s;
01126       r3[6] -= m3 * s;
01127    }
01128    s = r1[7];
01129    if (0.0 != s) {
01130       r2[7] -= m2 * s;
01131       r3[7] -= m3 * s;
01132    }
01133 
01134    /* choose pivot - or die */
01135    if (fabs(r3[2]) > fabs(r2[2]))
01136       SWAP_ROWS(r3, r2);
01137    if (0.0 == r2[2])
01138       return Matrix4<T>();
01139 
01140    /* eliminate third variable */
01141    m3 = r3[2] / r2[2];
01142    r3[3] -= m3 * r2[3], r3[4] -= m3 * r2[4],
01143       r3[5] -= m3 * r2[5], r3[6] -= m3 * r2[6], r3[7] -= m3 * r2[7];
01144 
01145    /* last check */
01146    if (0.0 == r3[3])
01147       return Matrix4<T>();
01148 
01149    s = 1.0 / r3[3];     /* now back substitute row 3 */
01150    r3[4] *= s;
01151    r3[5] *= s;
01152    r3[6] *= s;
01153    r3[7] *= s;
01154 
01155    m2 = r2[3];          /* now back substitute row 2 */
01156    s = 1.0 / r2[2];
01157    r2[4] = s * (r2[4] - r3[4] * m2), r2[5] = s * (r2[5] - r3[5] * m2),
01158       r2[6] = s * (r2[6] - r3[6] * m2), r2[7] = s * (r2[7] - r3[7] * m2);
01159    m1 = r1[3];
01160    r1[4] -= r3[4] * m1, r1[5] -= r3[5] * m1,
01161       r1[6] -= r3[6] * m1, r1[7] -= r3[7] * m1;
01162    m0 = r0[3];
01163    r0[4] -= r3[4] * m0, r0[5] -= r3[5] * m0,
01164       r0[6] -= r3[6] * m0, r0[7] -= r3[7] * m0;
01165 
01166    m1 = r1[2];          /* now back substitute row 1 */
01167    s = 1.0 / r1[1];
01168    r1[4] = s * (r1[4] - r2[4] * m1), r1[5] = s * (r1[5] - r2[5] * m1),
01169       r1[6] = s * (r1[6] - r2[6] * m1), r1[7] = s * (r1[7] - r2[7] * m1);
01170    m0 = r0[2];
01171    r0[4] -= r2[4] * m0, r0[5] -= r2[5] * m0,
01172       r0[6] -= r2[6] * m0, r0[7] -= r2[7] * m0;
01173 
01174    m0 = r0[1];          /* now back substitute row 0 */
01175    s = 1.0 / r0[0];
01176    r0[4] = s * (r0[4] - r1[4] * m0), r0[5] = s * (r0[5] - r1[5] * m0),
01177       r0[6] = s * (r0[6] - r1[6] * m0), r0[7] = s * (r0[7] - r1[7] * m0);
01178 
01179    MAT(out, 0, 0) = r0[4];
01180    MAT(out, 0, 1) = r0[5], MAT(out, 0, 2) = r0[6];
01181    MAT(out, 0, 3) = r0[7], MAT(out, 1, 0) = r1[4];
01182    MAT(out, 1, 1) = r1[5], MAT(out, 1, 2) = r1[6];
01183    MAT(out, 1, 3) = r1[7], MAT(out, 2, 0) = r2[4];
01184    MAT(out, 2, 1) = r2[5], MAT(out, 2, 2) = r2[6];
01185    MAT(out, 2, 3) = r2[7], MAT(out, 3, 0) = r3[4];
01186    MAT(out, 3, 1) = r3[5], MAT(out, 3, 2) = r3[6];
01187    MAT(out, 3, 3) = r3[7];
01188 
01189    return Matrix4<T>(out);
01190 
01191 #undef MAT
01192 #undef SWAP_ROWS
01193 }
01194 
01195 
01196 template<class T> void Matrix4<T>::print(void) const
01197 {
01198     printf("[%5.2lf %5.2lf %5.2lf %17.12le]\n"
01199            "[%5.2lf %5.2lf %5.2lf %17.12le]\n"
01200            "[%5.2lf %5.2lf %5.2lf %17.12le]\n"
01201            "[%5.2lf %5.2lf %5.2lf %17.12le]\n\n",
01202     r[0],r[4],r[8],r[12],
01203     r[1],r[5],r[9],r[13],
01204     r[2],r[6],r[10],r[14],
01205     r[3],r[7],r[11],r[15]);
01206 }
01207 
01208 
01209 template<class T> inline
01210 T operator*(const Vector2<T>&a,const Vector2<T>&b) {
01211   return a.v[0] * b.v[0] + a.v[1] * b.v[1];
01212 }
01213 
01214 template<class T> inline
01215 T operator*(const Vector3<T>&a,const Vector3<T>&b) {
01216   return a.v[0] * b.v[0] + a.v[1] * b.v[1] + a.v[2] * b.v[2];
01217 }
01218 
01219 template<class T> inline
01220 T operator*(const Vector4<T>&a,const Vector4<T>&b) {
01221   return a.v[0]*b.v[0] + a.v[1]*b.v[1] + a.v[2]*b.v[2] + a.v[3]*b.v[3];
01222 }
01223 
01224 template<class T> inline
01225 Vector2<T> operator*(T s,const Vector2<T>&v) {
01226   return Vector2<T>(s*v[0],s*v[1]);
01227 }
01228 
01229 template<class T> inline
01230 Vector3<T> operator*(T s,const Vector3<T>&v) {
01231   return Vector3<T>(s*v[0],s*v[1],s*v[2]);
01232 }
01233 
01234 template<class T> inline
01235 Vector4<T> operator*(T s,const Vector4<T>&v) {
01236   return Vector4<T>(s*v[0],s*v[1],s*v[2],s*v[3]);
01237 }
01238 
01239 
01240 #endif // _VECMATH_H_

Generated on Mon Mar 22 09:55:38 2010 for Stellarium by  doxygen 1.5.5