00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #ifndef VECTOR3_H
00019 #define VECTOR3_H
00020
00021 #include <iostream>
00022 #include <cmath>
00023
00024 namespace mesh {
00025
00026 #define Real double
00027
00035 class Vector3
00036 {
00037 public:
00038 Real x, y, z;
00039
00040 public:
00041 inline Vector3()
00042 {
00043 }
00044
00045 inline Vector3( Real fX, Real fY, Real fZ )
00046 : x( fX ), y( fY ), z( fZ )
00047 {
00048 }
00049
00050 inline Vector3( Real afCoordinate[3] )
00051 : x( afCoordinate[0] ),
00052 y( afCoordinate[1] ),
00053 z( afCoordinate[2] )
00054 {
00055 }
00056
00057 inline Vector3( int afCoordinate[3] )
00058 {
00059 x = (Real)afCoordinate[0];
00060 y = (Real)afCoordinate[1];
00061 z = (Real)afCoordinate[2];
00062 }
00063
00064 inline Vector3( const Real* const r )
00065 : x( r[0] ), y( r[1] ), z( r[2] )
00066 {
00067 }
00068
00069 inline Vector3( const Vector3& rkVector )
00070 : x( rkVector.x ), y( rkVector.y ), z( rkVector.z )
00071 {
00072 }
00073
00074 inline Real operator [] ( unsigned i ) const
00075 {
00076 return *(&x+i);
00077 }
00078
00079 inline Real& operator [] ( unsigned i )
00080 {
00081 return *(&x+i);
00082 }
00083
00088 inline Vector3& operator = ( const Vector3& rkVector )
00089 {
00090 x = rkVector.x;
00091 y = rkVector.y;
00092 z = rkVector.z;
00093
00094 return *this;
00095 }
00096
00097 inline bool operator == ( const Vector3& rkVector ) const
00098 {
00099 return ( x == rkVector.x && y == rkVector.y && z == rkVector.z );
00100 }
00101
00102 inline bool operator != ( const Vector3& rkVector ) const
00103 {
00104 return ( x != rkVector.x || y != rkVector.y || z != rkVector.z );
00105 }
00106
00107
00108 inline Vector3 operator + ( const Vector3& rkVector ) const
00109 {
00110 Vector3 kSum;
00111
00112 kSum.x = x + rkVector.x;
00113 kSum.y = y + rkVector.y;
00114 kSum.z = z + rkVector.z;
00115
00116 return kSum;
00117 }
00118
00119 inline Vector3 operator - ( const Vector3& rkVector ) const
00120 {
00121 Vector3 kDiff;
00122
00123 kDiff.x = x - rkVector.x;
00124 kDiff.y = y - rkVector.y;
00125 kDiff.z = z - rkVector.z;
00126
00127 return kDiff;
00128 }
00129
00130 inline Vector3 operator * ( Real fScalar ) const
00131 {
00132 Vector3 kProd;
00133
00134 kProd.x = fScalar*x;
00135 kProd.y = fScalar*y;
00136 kProd.z = fScalar*z;
00137
00138 return kProd;
00139 }
00140
00141 inline Vector3 operator * ( const Vector3& rhs) const
00142 {
00143 Vector3 kProd;
00144
00145 kProd.x = rhs.x * x;
00146 kProd.y = rhs.y * y;
00147 kProd.z = rhs.z * z;
00148
00149 return kProd;
00150 }
00151
00152 inline Vector3 operator / ( Real fScalar ) const
00153 {
00154 Vector3 kDiv;
00155
00156 Real fInv = 1.0 / fScalar;
00157 kDiv.x = x * fInv;
00158 kDiv.y = y * fInv;
00159 kDiv.z = z * fInv;
00160
00161 return kDiv;
00162 }
00163
00164 inline Vector3 operator - () const
00165 {
00166 Vector3 kNeg;
00167
00168 kNeg.x = -x;
00169 kNeg.y = -y;
00170 kNeg.z = -z;
00171
00172 return kNeg;
00173 }
00174
00175 inline friend Vector3 operator * ( Real fScalar, const Vector3& rkVector )
00176 {
00177 Vector3 kProd;
00178
00179 kProd.x = fScalar * rkVector.x;
00180 kProd.y = fScalar * rkVector.y;
00181 kProd.z = fScalar * rkVector.z;
00182
00183 return kProd;
00184 }
00185
00186
00187 inline Vector3& operator += ( const Vector3& rkVector )
00188 {
00189 x += rkVector.x;
00190 y += rkVector.y;
00191 z += rkVector.z;
00192
00193 return *this;
00194 }
00195
00196 inline Vector3& operator -= ( Real fScalar )
00197 {
00198 x -= fScalar;
00199 y -= fScalar;
00200 z -= fScalar;
00201
00202 return *this;
00203 }
00204
00205 inline Vector3& operator -= ( const Vector3& rkVector )
00206 {
00207 x -= rkVector.x;
00208 y -= rkVector.y;
00209 z -= rkVector.z;
00210
00211 return *this;
00212 }
00213
00214 inline Vector3& operator *= ( Real fScalar )
00215 {
00216 x *= fScalar;
00217 y *= fScalar;
00218 z *= fScalar;
00219 return *this;
00220 }
00221
00222 inline Vector3& operator *= ( const Vector3& rkVector )
00223 {
00224 x *= rkVector.x;
00225 y *= rkVector.y;
00226 z *= rkVector.z;
00227 return *this;
00228 }
00229
00230 inline Vector3& operator /= ( Real fScalar )
00231 {
00232 Real fInv = 1.0 / fScalar;
00233
00234 x *= fInv;
00235 y *= fInv;
00236 z *= fInv;
00237
00238 return *this;
00239 }
00240
00248 inline Real length () const
00249 {
00250 return ::sqrt( x * x + y * y + z * z );
00251 }
00252
00263 inline Real squared_length () const
00264 {
00265 return x * x + y * y + z * z;
00266 }
00267
00282 inline Real dot_product(const Vector3& vec) const
00283 {
00284 return x * vec.x + y * vec.y + z * vec.z;
00285 }
00286
00296 inline Real normalise()
00297 {
00298 Real fLength = length();
00299
00300
00301 if (1.0 + fLength*fLength > 1.0)
00302 {
00303 Real fInvLength = 1.0 / fLength;
00304 x *= fInvLength;
00305 y *= fInvLength;
00306 z *= fInvLength;
00307 }
00308
00309 return fLength;
00310 }
00311
00339 inline Vector3 cross_product( const Vector3& rkVector ) const
00340 {
00341 Vector3 kCross;
00342
00343 kCross.x = y * rkVector.z - z * rkVector.y;
00344 kCross.y = z * rkVector.x - x * rkVector.z;
00345 kCross.z = x * rkVector.y - y * rkVector.x;
00346
00347 return kCross;
00348 }
00349
00353 inline Vector3 mid_point( const Vector3& vec ) const
00354 {
00355 return Vector3(
00356 ( x + vec.x ) * 0.5,
00357 ( y + vec.y ) * 0.5,
00358 ( z + vec.z ) * 0.5 );
00359 }
00360
00364 inline bool operator < ( const Vector3& rhs ) const
00365 {
00366 if( x < rhs.x && y < rhs.y && z < rhs.z )
00367 return true;
00368 return false;
00369 }
00370
00374 inline bool operator <= ( const Vector3& rhs ) const
00375 {
00376 if( x <= rhs.x && y <= rhs.y && z <= rhs.z )
00377 return true;
00378 return false;
00379 }
00380
00384 inline bool operator < ( Real scalar ) const
00385 {
00386 if( x < scalar && y < scalar && z < scalar )
00387 return true;
00388 return false;
00389 }
00390
00394 inline bool operator <= ( Real scalar ) const
00395 {
00396 if( x <= scalar && y <= scalar && z <= scalar )
00397 return true;
00398 return false;
00399 }
00400
00404 inline bool operator > ( const Vector3& rhs ) const
00405 {
00406 if( x > rhs.x && y > rhs.y && z > rhs.z )
00407 return true;
00408 return false;
00409 }
00410
00414 inline bool operator > ( Real scalar ) const
00415 {
00416 if( x > scalar && y > scalar && z > scalar )
00417 return true;
00418 return false;
00419 }
00420
00424 inline bool operator >= ( Real scalar ) const
00425 {
00426 if( x >= scalar && y >= scalar && z >= scalar )
00427 return true;
00428 return false;
00429 }
00430
00438 inline void make_floor( const Vector3& cmp )
00439 {
00440 if( cmp.x < x ) x = cmp.x;
00441 if( cmp.y < y ) y = cmp.y;
00442 if( cmp.z < z ) z = cmp.z;
00443 }
00444
00452 inline void make_ceil( const Vector3& cmp )
00453 {
00454 if( cmp.x > x ) x = cmp.x;
00455 if( cmp.y > y ) y = cmp.y;
00456 if( cmp.z > z ) z = cmp.z;
00457 }
00458
00466 inline Vector3 perpendicular(void) const
00467 {
00468 Vector3 perp = this->cross_product( Vector3::UNIT_X );
00469
00470
00471 if(perp.is_zero_length())
00472 {
00473
00474
00475
00476 perp = this->cross_product( Vector3::UNIT_Y );
00477 }
00478
00479 return perp;
00480 }
00481
00483 inline bool is_zero_length(void) const
00484 {
00485 Real sqlen = (x * x) + (y * y) + (z * z);
00486 return (1.0 + sqlen == 1.0);
00487
00488 }
00489
00492 inline Vector3 normalised_copy(void) const
00493 {
00494 Vector3 ret = *this;
00495 ret.normalise();
00496 return ret;
00497 }
00498
00502 inline Vector3 reflect(const Vector3& normal)
00503 {
00504 return Vector3( *this - ( 2 * this->dot_product(normal) * normal ) );
00505 }
00506
00507
00508 static const Vector3 ZERO;
00509 static const Vector3 UNIT_X;
00510 static const Vector3 UNIT_Y;
00511 static const Vector3 UNIT_Z;
00512 static const Vector3 UNIT_SCALE;
00513
00516 inline friend std::ostream& operator <<
00517 ( std::ostream& o, const Vector3& v )
00518 {
00519 o << "Vector3(" << v.x << ", " << v.y << ", " << v.z << ")";
00520 return o;
00521 }
00522 };
00523
00524 #undef Real
00525 }
00526
00527 #endif