00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #ifndef JOT_VECTOR3D_H
00024 #define JOT_VECTOR3D_H
00025
00026 #include <math.h>
00027 #include "std/config.H"
00028 #include "mlib/global.H"
00029
00030 template <class V>
00031 class _vec3d
00032 {
00033 protected:
00034 Greal _x, _y, _z;
00035
00036 public:
00037
00038 _vec3d() : _x(0), _y(0), _z(0) {}
00039 _vec3d(Greal x, Greal y, Greal z) : _x(x), _y(y), _z(z) {}
00040
00041 const Greal *data() const { return &_x; }
00042
00043 void set(Greal x, Greal y, Greal z) { _x=x; _y=y; _z=z; }
00044
00045 V operator + (const V &v) const { return V(_x+v._x,_y+v._y,_z+v._z); }
00046 V operator - (const V &v) const { return V(_x-v._x,_y-v._y,_z-v._z); }
00047 Greal operator * (const V &v) const { return _x*v._x+_y*v._y+_z*v._z; }
00048 V operator - () const { return V(-_x, -_y, -_z); }
00049
00050 V operator * (Greal s) const { return V(_x*s, _y*s, _z*s); }
00051 V operator / (Greal s) const { return V(_x/s, _y/s, _z/s); }
00052 Greal operator [](int index) const { return (&_x)[index]; }
00053 Greal& operator [](int index) { return (&_x)[index]; }
00054
00055
00056 int operator > (const V &v) const { return length() > v.length();}
00057 int operator < (const V &v) const { return length() < v.length();}
00058
00059 Greal length () const { return sqrt(_x*_x+_y*_y+_z*_z); }
00060 Greal lengthSqrd () const { return _x*_x+_y*_y+_z*_z; }
00061 Greal lengthRect () const { return fabs(_x)+fabs(_y)+fabs(_z);}
00062
00063 Greal dist (const V &v) const { return (*this-v).length(); }
00064 Greal distSqrd (const V &v) const { return (*this-v).lengthSqrd(); }
00065
00066 bool isEqual (const V &v, Greal epsSqrd = epsNorSqrdMath()) const
00067 { return (distSqrd(v) <= epsSqrd); }
00068
00069 void operator +=(const V &v) { _x += v._x; _y += v._y; _z += v._z;}
00070 void operator -=(const V &v) { _x -= v._x; _y -= v._y; _z -= v._z;}
00071 void operator *=(Greal s) { _x *= s; _y *= s; _z *= s; }
00072 void operator /=(Greal s) { _x /= s; _y /= s; _z /= s; }
00073
00074
00075 bool operator ==(const V &v) const{ return v[0]==_x&&v[1]==_y&&v[2]==_z;}
00076 bool operator !=(const V &v) const{ return v[0]!=_x||v[1]!=_y||v[2]!=_z;}
00077 bool isNull (Greal epsSqrd = epsNorSqrdMath()) const
00078 { return lengthSqrd() <= epsSqrd; }
00079
00080 inline Greal angle(const V &) const;
00081 inline V normalize () const;
00082 inline V perpend () const;
00083 inline bool isParallel (const V &) const;
00084 inline bool isPerpend (const V &) const;
00085 inline void orthoplane (int &i1, int &i2) const;
00086 inline void orthoplane (int &i1, int &i2, int &i3) const;
00087 inline V orthogonalize(const V &b) {
00088 return *this - ((*this * b) / (b * b)) * b;
00089 }
00090
00091 };
00092
00093
00094
00095 template <class V>
00096 inline V
00097 _vec3d<V>::normalize() const
00098 {
00099 const Greal l = length();
00100 if (l > gEpsZeroMath)
00101 return V(_x/l, _y/l, _z/l);
00102 return V();
00103 }
00104
00105
00106
00107
00108
00109 template <class V>
00110 inline V
00111 _vec3d<V>::perpend() const
00112 {
00113 const V a = normalize();
00114
00115 return cross(fabs(a._x) < 1.0/64.0 && fabs(a._y) < 1.0/64.0
00116 ? V(0,1,0)
00117 : V(0,0,1), a).normalize();
00118
00119
00120
00121
00122
00123
00124
00125 }
00126
00127
00128 template <class V>
00129 inline bool
00130 _vec3d<V>::isParallel(const V &v) const
00131 {
00132 const V a = normalize();
00133
00134 if (a == V())
00135 return false;
00136
00137 const V b = v.normalize();
00138
00139 if (b == V())
00140 return false;
00141
00142 return (a-b).lengthSqrd() <= epsNorSqrdMath() ||
00143 (a+b).lengthSqrd() <= epsNorSqrdMath();
00144 }
00145
00146
00147 template <class V>
00148 inline bool
00149 _vec3d<V>::isPerpend(const V &v) const
00150 {
00151 const V a = normalize();
00152 const V b = v.normalize();
00153
00154 if (a == V() || b == V())
00155 return false;
00156
00157 return fabs(a * b) < epsNorMath();
00158 }
00159
00160 template <class V>
00161 inline void
00162 _vec3d<V>::orthoplane(int& i1, int& i2, int& i3) const
00163 {
00164 i1 = 0;
00165 i2 = 1;
00166 i3 = 2;
00167
00168 Greal max = fabs(_z);
00169
00170 if (fabs(_x) > max)
00171 {
00172 max = fabs(_x);
00173 i1 = 1;
00174 i2 = 2;
00175 i3 = 0;
00176 }
00177
00178 if (fabs(_y) > max)
00179 {
00180 max = fabs(_y);
00181 i1 = 2;
00182 i2 = 0;
00183 i3 = 1;
00184 }
00185
00186 if ((*this)[i3] < 0)
00187 {
00188 const int tmp = i1;
00189 i1 = i2;
00190 i2 = tmp;
00191 }
00192 }
00193
00194
00195 template <class V>
00196 inline void
00197 _vec3d<V>::orthoplane(int& i1, int& i2) const
00198 {
00199 int i3;
00200 orthoplane(i1, i2, i3);
00201 }
00202
00203
00204 template <class V>
00205 inline Greal
00206 _vec3d<V>::angle(const V& v) const
00207 {
00208 Greal cosAngle = ((*this) * v) / (length() * v.length());
00209
00210 if (cosAngle < -1)
00211 cosAngle = -1;
00212 if (cosAngle > 1)
00213 cosAngle = 1;
00214
00215 return acos(cosAngle);
00216 }
00217
00218
00219
00220 template <class V>
00221 inline ostream &
00222 operator<<(ostream &os, const _vec3d<V> &v)
00223 {
00224 return os << "{ " << v[0] << " " << v[1] << " " << v[2] << " } ";
00225 }
00226
00227
00228 template <class V>
00229 inline istream &
00230 operator>>(istream &is, _vec3d<V> &v)
00231 {
00232 char dummy;
00233 return is >> dummy >> v[0] >> v[1] >> v[2] >> dummy;
00234 }
00235
00236
00237 template <class V>
00238 inline V
00239 cross(const V &v1, const V &v2)
00240 {
00241 return V(v1[1]*v2[2]-v1[2]*v2[1],
00242 v1[2]*v2[0]-v1[0]*v2[2],
00243 v1[0]*v2[1]-v1[1]*v2[0]);
00244 }
00245
00246
00247 template <class V>
00248 inline Greal
00249 det(const V &a, const V &b, const V &c)
00250 {
00251 return (a[0] * (b[1]*c[2] - b[2]*c[1]) +
00252 a[1] * (b[2]*c[0] - b[0]*c[2]) +
00253 a[2] * (b[0]*c[1] - b[1]*c[0]));
00254 }
00255
00256
00257 #endif // JOT_VECTOR3D_H