00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #ifndef AMOD_MATH_LIB_INCVECTOR2d_H
00024 #define AMOD_MATH_LIB_INCVECTOR2d_H
00025
00026 #include <math.h>
00027 #include "global.H"
00028 #include "point3d.H"
00029
00030 template <class V>
00031 class _vec2d
00032 {
00033 protected :
00034 Greal _x, _y;
00035
00036 public:
00037
00038 _vec2d() : _x(0) , _y(0) {}
00039 _vec2d(Greal x, Greal y) : _x(x) , _y(y) {}
00040
00041 V operator + (const V &v) const { return V(_x+v._x, _y+v._y); }
00042 V operator - (const V &v) const { return V(_x-v._x, _y-v._y); }
00043 Greal operator * (const V &v) const { return _x*v._x+_y*v._y; }
00044 V operator - () const { return V(-_x, -_y); }
00045
00046 V operator * (Greal s) const { return V(_x*s, _y*s); }
00047 V operator / (Greal s) const { return V(_x/s, _y/s); }
00048
00049 Greal operator [](int index) const { return (&_x)[index]; }
00050 Greal& operator [](int index) { return (&_x)[index]; }
00051
00052 Greal length () const { return sqrt(_x*_x+_y*_y); }
00053 Greal lengthSqrd () const { return _x*_x+_y*_y; }
00054
00055 V normalize () const;
00056 V perpend () const { return V(-_y, _x); }
00057
00058 Greal dist (const V &v) const { return (*this-v).length(); }
00059 Greal distSqrd (const V &v) const { return (*this-v).lengthSqrd(); }
00060
00061 bool isEqual (const V &v, Greal epsSqrd = epsNorSqrdMath()) const
00062 { return distSqrd(v)<=epsSqrd;}
00063 bool isExactNull() const { return _x == 0 && _y == 0; }
00064 bool isParallel(const V&) const;
00065
00066 void operator +=(const V &v) { _x += v._x; _y += v._y; }
00067 void operator -=(const V &v) { _x -= v._x; _y -= v._y; }
00068 void operator *=(Greal s) { _x *= s; _y *= s; }
00069 void operator /=(Greal s) { _x /= s; _y /= s; }
00070 bool operator ==(const V &v) const { return v._x == _x && v._y == _y;}
00071 bool operator !=(const V &v) const { return v._x != _x || v._y != _y;}
00072
00073 Greal angle (const V&) const;
00074 bool isNull (Greal epsSqrdMath = epsNorSqrdMath()) const
00075 { return lengthSqrd() <= epsSqrdMath; }
00076
00077 };
00078
00079 template <class V>
00080 inline Greal
00081 det(const _vec2d<V> &v1, const _vec2d<V> &v2) { return v1[0]*v2[1]-v1[1]*v2[0];}
00082
00083
00084
00085
00086
00087 template <class V>
00088 inline ostream &
00089 operator <<(ostream &os, const _vec2d<V> &v)
00090 {
00091 return os << "{" << v[0] << " " << v[1] << "}";
00092 }
00093
00094
00095 template <class V>
00096 inline istream &
00097 operator>>(istream &is, _vec2d<V> &v)
00098 {
00099 char dummy;
00100 return is >> dummy >> v[0] >> v[1] >> dummy;
00101 }
00102
00103 template<class V>
00104 inline V
00105 _vec2d<V>::normalize() const
00106 {
00107 const Greal l = length();
00108 return (l > gEpsZeroMath ? V(_x/l, _y/l) : V(0,0));
00109 }
00110
00111 template<class V>
00112 inline Greal
00113 _vec2d<V>::angle(const V& v) const
00114 {
00115 const V v1 = normalize();
00116 const V v2 = v.normalize();
00117
00118 if (v1.isNull() || v2.isNull())
00119 return 0;
00120
00121 const Greal cross = det(v1, v2);
00122 const Greal dot = v1 * v2;
00123
00124 if (fabs(dot) < epsNorMath())
00125 {
00126 return cross > 0 ? M_PI_2 : 1.5*M_PI;
00127 }
00128 else
00129 {
00130 Greal angle = atan(cross/dot);
00131 if (dot < 0)
00132 angle = angle - M_PI;
00133
00134 return angle >= 0 ? angle : angle + M_PI * 2;
00135 }
00136 }
00137
00138
00139
00140
00141
00142
00143 template<class V>
00144 inline bool
00145 _vec2d<V>::isParallel(const V &v) const
00146 {
00147 const V a = normalize();
00148 const V b = v.normalize();
00149
00150 if (a.isExactNull() || b.isExactNull())
00151 return false;
00152
00153 return (a-b).lengthSqrd() <= epsNorSqrdMath() ||
00154 (a+b).lengthSqrd() <= epsNorSqrdMath();
00155 }
00156 #endif