Main Page   Class Hierarchy   Compound List   File List   Compound Members   File Members  

vector3d.H

Go to the documentation of this file.
00001 /*
00002  * Copyright 2000, Brown University, Providence, RI.
00003  * 
00004  *                         All Rights Reserved
00005  * 
00006  * Permission to use, copy, modify, and distribute this software and its
00007  * documentation for any purpose other than its incorporation into a
00008  * commercial product is hereby granted without fee, provided that the
00009  * above copyright notice appear in all copies and that both that
00010  * copyright notice and this permission notice appear in supporting
00011  * documentation, and that the name of Brown University not be used in
00012  * advertising or publicity pertaining to distribution of the software
00013  * without specific, written prior permission.
00014  * 
00015  * BROWN UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
00016  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR ANY
00017  * PARTICULAR PURPOSE.  IN NO EVENT SHALL BROWN UNIVERSITY BE LIABLE FOR
00018  * ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
00019  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
00020  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
00021  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
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     // So min(V, V) works (max, too)
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 }; // class _vec3d
00092 
00093 /* ---------- inlined member functions using _point3d template ------ */
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 // The well known AutoCAD's arbitrary axis algorithm.
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     // Note: 
00120     //
00121     // Do not replace the above vec3d(0,1,0), etc. with vec3d::kYDir.
00122     // This method is called from a constructor executed during initialization
00123     // of static objects and at that time the objects such as vec3d::kYDir
00124     // are not yet initalized.
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 /* ---------- inlined global functions using _point3d template ------ */
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

Generated on Mon Sep 15 16:25:57 2003 for gluebase by doxygen1.2.18