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 #ifndef _BASE_VECTOR3_HPP_
00026 #define _BASE_VECTOR3_HPP_
00027
00028 #include <iostream>
00029 #include <math.h>
00030
00031 #include <base/base>
00032 #include <base/array>
00033 #include <base/consts>
00034
00035
00036 #ifdef USE_OSG
00037 #include <osg/Vec3>
00038 #endif
00039
00040
00041 namespace base {
00042
00043
00044 class Serializer;
00045
00046
00047
00048 class Vector3
00049 {
00050
00051 public:
00052 Vector3() { x=y=z=Real(0); }
00053 Vector3(Real xc, Real yc, Real zc) { x=xc; y=yc; z=zc; }
00054 Vector3(const Vector3& v) { this->operator=(v); }
00055 #ifdef USE_OSG
00056 Vector3(const osg::Vec3& v) { x=v._v[0]; y=v._v[1]; z=v._v[2]; }
00057 #endif
00058 ~Vector3() {}
00059
00060 enum Coords { X=1, Y=2, Z=3, Coords3D=4 };
00061
00062 void setZero() throw()
00063 { x=y=z=Real(0); }
00064
00065 bool isZero() const throw()
00066 { return (x==0)||(y==0)||(z==0); }
00067
00068 bool equalsZero(Real eps=consts::epsilon)
00069 { return (base::equals(x,0,eps) || base::equals(y,0,eps) || base::equals(z,0,eps)); }
00070
00071 Real& e(Int i) throw()
00072 {
00073 Assertm( ((i>=1)&&(i<=3)), "vector index in bounds (debug only check)");
00074 return (i==1)?x:(i==2)?y:z;
00075 }
00076
00077 const Real& e(Int i) const throw()
00078 {
00079 Assertm( ((i>=1)&&(i<=3)), "vector index in bounds (debug only check)");
00080 return (i==1)?x:(i==2)?y:z;
00081 }
00082
00083 Real& at(Int i) throw(std::out_of_range)
00084 {
00085 if ((i < 1) || (i > 3))
00086 throw std::out_of_range(Exception("vector index out of bounds"));
00087
00088 return (i==1)?x:(i==2)?y:z;
00089 }
00090
00091 const Real& at(Int i) const throw(std::out_of_range)
00092 {
00093 if ((i < 1) || (i > 3))
00094 throw std::out_of_range(Exception("vector index out of bounds"));
00095
00096 return (i==1)?x:(i==2)?y:z;
00097 }
00098
00099 Real& operator[](Int i)
00100 { return e(i); }
00101
00102 const Real& operator[](Int i) const
00103 { return e(i); }
00104
00105 Vector3& operator=(const Vector3& src) throw()
00106 {
00107 if (&src != this) {
00108 x=src.x; y=src.y; z=src.z;
00109 }
00110 return *this;
00111 }
00112
00113
00114 bool operator==(const Vector3& v) const throw()
00115 {
00116 if (&v == this) return true;
00117
00118 return ((x==v.x)&&(y==v.y)&&(z==v.z));
00119 }
00120
00121 bool operator!=(const Vector3& v) const throw()
00122 {
00123 if (&v == this) return false;
00124
00125 return ((x!=v.x)||(y!=v.y)||(z!=v.z));
00126 }
00127
00128
00129 bool equals(const Vector3& v, Real epsilon = consts::epsilon) const throw()
00130 {
00131 if (&v == this) return true;
00132
00133 return (base::equals(x,v.x,epsilon) && base::equals(y,v.y,epsilon) && base::equals(z,v.z,epsilon));
00134 }
00135
00136
00137 Real norm() const throw()
00138 { return (x*x+y*y+z*z); }
00139
00140 Real magnitude() const throw()
00141 { return sqrt(norm()); }
00142
00143 Real length() const throw()
00144 { return magnitude(); }
00145
00146 Vector3& negate() throw()
00147 { x=-x; y=-y; z=-z; return *this; }
00148
00149 Vector3& normalize()
00150 { Real l=length(); Assert(l>0); x/=l; y/=l; z/=l; return *this; }
00151
00152 Real magNormalize()
00153 { Real l=length(); Assert(l>0); x/=l; y/=l; z/=l; return l; }
00154
00155 Vector3& cross(const Vector3& p) throw()
00156 { Vector3 r(y*p.z-z*p.y, -(x*p.z-z*p.x), x*p.y-y*p.x); return (*this=r); }
00157
00158 Vector3& cross(const Vector3& a, const Vector3& b) throw()
00159 { *this=a; return cross(b); }
00160
00161 Real dot(const Vector3& p) const throw()
00162 { return x*p.x+y*p.y+z*p.z; }
00163
00164
00165 Vector3& operator+=(const Vector3& v2) throw()
00166 { x+=v2.x; y+=v2.y; z+=v2.z; return *this; }
00167
00168 Vector3& operator-=(const Vector3& v2) throw()
00169 { x-=v2.x; y-=v2.y; z-=v2.z; return *this; }
00170
00171 Vector3& operator*=(const Real& s) throw()
00172 { x*=s; y*=s; z*=s; return *this; }
00173
00174 Vector3& operator/=(const Real& s)
00175 { x/=s; y/=s; z/=s; return *this; }
00176
00177 Int largestAxis() const {
00178 Real a[Y+1];
00179 Int axis = ( (a[X] = base::abs(x)) < (a[Y] = base::abs(y)) ) ? Y : X;
00180 return (a[axis] < base::abs(z)) ? Z : axis;
00181 }
00182
00183
00184 const Real* c_array() const { return &x; }
00185 Real* c_array() { return &x; }
00186 #ifdef USE_OSG
00187 osg::Vec3 toVec3() const { return osg::Vec3(x,y,z); }
00188 #endif
00189
00190 static Vector3 min(const base::array<Vector3>& vectors);
00191 static Vector3 max(const base::array<Vector3>& vectors);
00192 static void minmax(const base::array<Vector3>& vectors, Vector3& minimum, Vector3& maximum);
00193
00194
00195 void serialize(Serializer& s);
00196
00197
00198 Real x,y,z;
00199
00200 };
00201
00202
00203
00204
00205 inline Vector3 operator+(const Vector3& v1, const Vector3& v2) throw()
00206 { Vector3 r(v1); return r+=v2; }
00207
00208 inline Vector3 operator-(const Vector3& v1, const Vector3& v2) throw()
00209 { Vector3 r(v1); return r-=v2; }
00210
00211 inline Vector3 operator-(const Vector3& v1) throw()
00212 { Vector3 r(v1); return r.negate(); }
00213
00214 inline Vector3 operator*(const Vector3& v1, const Real& s) throw()
00215 { Vector3 r(v1); return r*=s; }
00216
00217 inline Vector3 operator*(const Real& s, const Vector3& v1) throw()
00218 { Vector3 r(v1); return r*=s; }
00219
00220 inline Vector3 operator/(const Vector3& v1, const Real& s)
00221 { Vector3 r(v1); return r/= s; }
00222
00223 inline std::ostream& operator<<(std::ostream& out, const Vector3& v)
00224 { return out << "(" << v.x << "," << v.y << "," << v.z << ")"; }
00225
00226
00227 inline Vector3 midpoint(const Vector3& v1, const Vector3& v2) throw()
00228 { Vector3 r(v1); r+=v2; return r/=2; }
00229
00230 inline Vector3 cross(const Vector3& v1, const Vector3& v2) throw()
00231 { Vector3 r(v1); return r.cross(v2); }
00232
00233 inline Real dot(const Vector3& v1, const Vector3& v2) throw()
00234 { Vector3 r(v1); return r.dot(v2); }
00235
00236 inline Real operator*(const Vector3& v1, const Vector3& v2)
00237 { return dot(v1,v2); }
00238
00239
00240 }
00241
00242 #endif