00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #ifndef WFMATH_VECTOR_H
00031 #define WFMATH_VECTOR_H
00032
00033 #include <wfmath/const.h>
00034
00035 #include <iosfwd>
00036
00037 #include <cmath>
00038
00039 namespace WFMath {
00040
00041 template<int dim>
00042 Vector<dim>& operator+=(Vector<dim>& v1, const Vector<dim>& v2);
00043 template<int dim>
00044 Vector<dim>& operator-=(Vector<dim>& v1, const Vector<dim>& v2);
00045 template<int dim>
00046 Vector<dim>& operator*=(Vector<dim>& v, CoordType d);
00047 template<int dim>
00048 Vector<dim>& operator/=(Vector<dim>& v, CoordType d);
00049
00050 template<int dim>
00051 Vector<dim> operator+(const Vector<dim>& v1, const Vector<dim>& v2);
00052 template<int dim>
00053 Vector<dim> operator-(const Vector<dim>& v1, const Vector<dim>& v2);
00054 template<int dim>
00055 Vector<dim> operator-(const Vector<dim>& v);
00056 template<int dim>
00057 Vector<dim> operator*(CoordType d, const Vector<dim>& v);
00058 template<int dim>
00059 Vector<dim> operator*(const Vector<dim>& v, CoordType d);
00060 template<int dim>
00061 Vector<dim> operator/(const Vector<dim>& v, CoordType d);
00062
00063 template<int dim>
00064 CoordType Dot(const Vector<dim>& v1, const Vector<dim>& v2);
00065
00066 template<int dim>
00067 CoordType Angle(const Vector<dim>& v, const Vector<dim>& u);
00068
00069
00071 template<int dim>
00072 Vector<dim> Prod(const RotMatrix<dim>& m, const Vector<dim>& v);
00074 template<int dim>
00075 Vector<dim> InvProd(const RotMatrix<dim>& m, const Vector<dim>& v);
00077
00080 template<int dim>
00081 Vector<dim> Prod(const Vector<dim>& v, const RotMatrix<dim>& m);
00083 template<int dim>
00084 Vector<dim> ProdInv(const Vector<dim>& v, const RotMatrix<dim>& m);
00085
00087 template<int dim>
00088 Vector<dim> operator*(const RotMatrix<dim>& m, const Vector<dim>& v);
00090 template<int dim>
00091 Vector<dim> operator*(const Vector<dim>& v, const RotMatrix<dim>& m);
00092
00093 template<int dim>
00094 Vector<dim> operator-(const Point<dim>& c1, const Point<dim>& c2);
00095 template<int dim>
00096 Point<dim> operator+(const Point<dim>& c, const Vector<dim>& v);
00097 template<int dim>
00098 Point<dim> operator-(const Point<dim>& c, const Vector<dim>& v);
00099 template<int dim>
00100 Point<dim> operator+(const Vector<dim>& v, const Point<dim>& c);
00101
00102 template<int dim>
00103 Point<dim>& operator+=(Point<dim>& p, const Vector<dim>& v);
00104 template<int dim>
00105 Point<dim>& operator-=(Point<dim>& p, const Vector<dim>& v);
00106
00107 template<int dim>
00108 std::ostream& operator<<(std::ostream& os, const Vector<dim>& v);
00109 template<int dim>
00110 std::istream& operator>>(std::istream& is, Vector<dim>& v);
00111
00112 template<typename Shape>
00113 class ZeroPrimitive;
00114
00116
00120 template<int dim = 3>
00121 class Vector {
00122 friend class ZeroPrimitive<Vector<dim> >;
00123 public:
00125 Vector() : m_valid(false) {}
00127 Vector(const Vector& v);
00129 explicit Vector(const AtlasInType& a);
00131 explicit Vector(const Point<dim>& point);
00132
00136 static const Vector<dim>& ZERO();
00137
00138 friend std::ostream& operator<< <dim>(std::ostream& os, const Vector& v);
00139 friend std::istream& operator>> <dim>(std::istream& is, Vector& v);
00140
00142 AtlasOutType toAtlas() const;
00144 void fromAtlas(const AtlasInType& a);
00145
00146 Vector& operator=(const Vector& v);
00147
00148 bool isEqualTo(const Vector& v, CoordType epsilon = numeric_constants<CoordType>::epsilon()) const;
00149 bool operator==(const Vector& v) const {return isEqualTo(v);}
00150 bool operator!=(const Vector& v) const {return !isEqualTo(v);}
00151
00152 bool isValid() const {return m_valid;}
00154 void setValid(bool valid = true) {m_valid = valid;}
00155
00157 Vector& zero();
00158
00159
00160
00162 friend Vector& operator+=<dim>(Vector& v1, const Vector& v2);
00164 friend Vector& operator-=<dim>(Vector& v1, const Vector& v2);
00166 friend Vector& operator*=<dim>(Vector& v, CoordType d);
00168 friend Vector& operator/=<dim>(Vector& v, CoordType d);
00169
00171 friend Vector operator+<dim>(const Vector& v1, const Vector& v2);
00173 friend Vector operator-<dim>(const Vector& v1, const Vector& v2);
00175 friend Vector operator-<dim>(const Vector& v);
00177 friend Vector operator*<dim>(CoordType d, const Vector& v);
00179 friend Vector operator*<dim>(const Vector& v, CoordType d);
00181 friend Vector operator/<dim>(const Vector& v, CoordType d);
00182
00183
00184 friend Vector Prod<dim>(const RotMatrix<dim>& m, const Vector& v);
00185 friend Vector InvProd<dim>(const RotMatrix<dim>& m, const Vector& v);
00186
00188 CoordType operator[](const int i) const {return m_elem[i];}
00190 CoordType& operator[](const int i) {return m_elem[i];}
00191
00193 friend Vector operator-<dim>(const Point<dim>& c1, const Point<dim>& c2);
00195 friend Point<dim> operator+<dim>(const Point<dim>& c, const Vector& v);
00197 friend Point<dim> operator-<dim>(const Point<dim>& c, const Vector& v);
00199 friend Point<dim> operator+<dim>(const Vector& v, const Point<dim>& c);
00200
00202 friend Point<dim>& operator+=<dim>(Point<dim>& p, const Vector& rhs);
00204 friend Point<dim>& operator-=<dim>(Point<dim>& p, const Vector& rhs);
00205
00206 friend CoordType Cross(const Vector<2>& v1, const Vector<2>& v2);
00207 friend Vector<3> Cross(const Vector<3>& v1, const Vector<3>& v2);
00208
00210 friend CoordType Dot<dim>(const Vector& v1, const Vector& v2);
00212 friend CoordType Angle<dim>(const Vector& v, const Vector& u);
00213
00215 CoordType sqrMag() const;
00217 CoordType mag() const {return std::sqrt(sqrMag());}
00219 Vector& normalize(CoordType norm = 1.0)
00220 {CoordType themag = mag(); return (*this *= norm / themag);}
00221
00223
00234 CoordType sloppyMag() const;
00236
00241 Vector& sloppyNorm(CoordType norm = 1.0);
00242
00243
00244
00246 static CoordType sloppyMagMax();
00248
00254 static CoordType sloppyMagMaxSqrt();
00255
00257 Vector& rotate(int axis1, int axis2, CoordType theta);
00258
00260
00263 Vector& rotate(const Vector& v1, const Vector& v2, CoordType theta);
00264
00266 Vector& rotate(const RotMatrix<dim>&);
00267
00268
00269
00271 Vector& mirror(const int i) { m_elem[i] *= -1; return *this;}
00273 Vector& mirror(const Vector& v)
00274 {return operator-=(*this, 2 * v * Dot(v, *this) / v.sqrMag());}
00276
00279 Vector& mirror() {return operator*=(*this, -1);}
00280
00281
00282
00283
00284
00285
00286
00287
00288
00290 Vector(CoordType x, CoordType y);
00292 Vector(CoordType x, CoordType y, CoordType z);
00293
00295 Vector& rotate(CoordType theta);
00296
00298 Vector& rotateX(CoordType theta);
00300 Vector& rotateY(CoordType theta);
00302 Vector& rotateZ(CoordType theta);
00303
00305 Vector& rotate(const Vector& axis, CoordType theta);
00307 Vector& rotate(const Quaternion& q);
00308
00309
00310
00311
00313 CoordType x() const {return m_elem[0];}
00315 CoordType& x() {return m_elem[0];}
00317 CoordType y() const {return m_elem[1];}
00319 CoordType& y() {return m_elem[1];}
00321 CoordType z() const;
00323 CoordType& z();
00324
00326 Vector& mirrorX() {return mirror(0);}
00328 Vector& mirrorY() {return mirror(1);}
00330 Vector& mirrorZ();
00331
00333 Vector& polar(CoordType r, CoordType theta);
00335 void asPolar(CoordType& r, CoordType& theta) const;
00336
00338 Vector& polar(CoordType r, CoordType theta, CoordType z);
00340 void asPolar(CoordType& r, CoordType& theta, CoordType& z) const;
00342 Vector& spherical(CoordType r, CoordType theta, CoordType phi);
00344 void asSpherical(CoordType& r, CoordType& theta, CoordType& phi) const;
00345
00346 const CoordType* elements() const {return m_elem;}
00347
00348 private:
00349 double _scaleEpsilon(const Vector& v, CoordType epsilon = numeric_constants<CoordType>::epsilon()) const
00350 {return _ScaleEpsilon(m_elem, v.m_elem, dim, epsilon);}
00351
00352 CoordType m_elem[dim];
00353 bool m_valid;
00354 };
00355
00356 template<>
00357 inline CoordType Vector<3>::z() const
00358 {
00359 return m_elem[2];
00360 }
00361
00362 template<>
00363 inline CoordType& Vector<3>::z()
00364 {
00365 return m_elem[2];
00366 }
00367
00368 template<>
00369 inline Vector<3>& Vector<3>::mirrorZ()
00370 {
00371 return mirror(2);
00372 }
00373
00375 CoordType Cross(const Vector<2>& v1, const Vector<2>& v2);
00377 Vector<3> Cross(const Vector<3>& v1, const Vector<3>& v2);
00378
00380
00385 template<int dim>
00386 bool Parallel(const Vector<dim>& v1, const Vector<dim>& v2, bool& same_dir);
00387
00389
00392 template<int dim>
00393 bool Parallel(const Vector<dim>& v1, const Vector<dim>& v2);
00394
00396 template<int dim>
00397 bool Perpendicular(const Vector<dim>& v1, const Vector<dim>& v2);
00398
00399 template <int dim>
00400 inline Vector<dim> operator+(const Vector<dim>& v1, const Vector<dim>& v2)
00401 {
00402 Vector<dim> ans(v1);
00403
00404 ans += v2;
00405
00406 return ans;
00407 }
00408
00409 template <int dim>
00410 inline Vector<dim> operator-(const Vector<dim>& v1, const Vector<dim>& v2)
00411 {
00412 Vector<dim> ans(v1);
00413
00414 ans -= v2;
00415
00416 return ans;
00417 }
00418
00419 template <int dim>
00420 inline Vector<dim> operator*(const Vector<dim>& v, CoordType d)
00421 {
00422 Vector<dim> ans(v);
00423
00424 ans *= d;
00425
00426 return ans;
00427 }
00428
00429 template<int dim>
00430 inline Vector<dim> operator*(CoordType d, const Vector<dim>& v)
00431 {
00432 Vector<dim> ans(v);
00433
00434 ans *= d;
00435
00436 return ans;
00437 }
00438
00439 template <int dim>
00440 inline Vector<dim> operator/(const Vector<dim>& v, CoordType d)
00441 {
00442 Vector<dim> ans(v);
00443
00444 ans /= d;
00445
00446 return ans;
00447 }
00448
00449 template<int dim>
00450 inline bool Parallel(const Vector<dim>& v1,
00451 const Vector<dim>& v2,
00452 bool& same_dir)
00453 {
00454 CoordType dot = Dot(v1, v2);
00455
00456 same_dir = (dot > 0);
00457
00458 return Equal(dot * dot, v1.sqrMag() * v2.sqrMag());
00459 }
00460
00461 template<int dim>
00462 inline bool Parallel(const Vector<dim>& v1, const Vector<dim>& v2)
00463 {
00464 bool same_dir;
00465
00466 return Parallel(v1, v2, same_dir);
00467 }
00468
00469 template<>
00470 inline CoordType Vector<1>::sloppyMagMax()
00471 {
00472 return 1.f;
00473 }
00474
00475 template<>
00476 inline CoordType Vector<2>::sloppyMagMax()
00477 {
00478 return 1.082392200292393968799446410733f;
00479 }
00480
00481 template<>
00482 inline CoordType Vector<3>::sloppyMagMax()
00483 {
00484 return 1.145934719303161490541433900265f;
00485 }
00486
00487 template<>
00488 inline CoordType Vector<1>::sloppyMagMaxSqrt()
00489 {
00490 return 1.f;
00491 }
00492
00493 template<>
00494 inline CoordType Vector<2>::sloppyMagMaxSqrt()
00495 {
00496 return 1.040380795811030899095785063701f;
00497 }
00498
00499 template<>
00500 inline CoordType Vector<3>::sloppyMagMaxSqrt()
00501 {
00502 return 1.070483404496847625250328653179f;
00503 }
00504
00505 }
00506
00507 #endif // WFMATH_VECTOR_H