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
00026
00027 #ifndef GVECTOR3H
00028 #define GVECTOR3H
00029
00030 #include <cmath>
00031
00032 namespace GCS
00033 {
00034
00044 class GVector3
00045 {
00046 public:
00047
00051 union
00052 {
00056 struct
00057 {
00061 double x;
00065 double y;
00069 double z;
00070 };
00071
00075 struct
00076 {
00080 double u;
00084 double v;
00088 double w;
00089 };
00090
00094 float c[3];
00095
00096 };
00097
00098 public:
00099
00103 GVector3() :
00104 x(0),
00105 y(0),
00106 z(0)
00107 {}
00108
00112 GVector3(const double d) :
00113 x(d),
00114 y(d),
00115 z(d)
00116 {
00117 }
00118
00122 GVector3(const double x, const double y, const double z) :
00123 x(x),
00124 y(y),
00125 z(z)
00126 {
00127 }
00128
00133 GVector3(const double* component) :
00134 x(component[0]),
00135 y(component[1]),
00136 z(component[2])
00137 {
00138 }
00139
00143 GVector3(const GVector3& original) :
00144 x(original.x),
00145 y(original.y),
00146 z(original.z)
00147 {
00148 }
00149
00153 double length() const;
00154
00158 double lengthsq() const;
00159
00163 GVector3& reset();
00164
00168 GVector3& set(double x, double y, double z);
00169
00173 GVector3& set(const GVector3& original);
00174
00180 GVector3& normalize();
00181
00185 GVector3& scaleXYZ(const GVector3& scale);
00186
00192 GVector3& scaleXYZ(double x, double y, double z);
00193
00197 GVector3& add(const GVector3& right);
00198
00202 GVector3& sub(const GVector3& right);
00203
00207 GVector3& mul(double scalar);
00208
00214 double dot(const GVector3& right) const;
00215
00222 GVector3 cross(const GVector3& right) const;
00223
00227 GVector3& operator = (const GVector3& original);
00228
00233 GVector3 operator + (const GVector3& right) const;
00234
00239 GVector3 operator - (const GVector3& right) const;
00240
00245 GVector3 operator * (double factor) const;
00246
00250 GVector3& operator += (const GVector3& right);
00251
00255 GVector3& operator -= (const GVector3& right);
00256
00261 bool operator == (const GVector3& comp) const;
00262
00263
00264
00270 double distanceTo(const GVector3& p) const;
00271
00279 double angleTo(const GVector3& v) const;
00280
00286 GVector3& turnAroundAxis(const GVector3& axis, double angle_rad);
00287
00293 GVector3& projectTo(const GVector3& v);
00294
00295 };
00296
00297
00298
00299 inline double GVector3::length() const
00300 {
00301 return std::sqrt(x*x + y*y + z*z);
00302 }
00303
00304 inline double GVector3::lengthsq() const
00305 {
00306 return x*x + y*y + z*z;
00307 }
00308
00309 inline GVector3& GVector3::reset()
00310 {
00311 x=y=z=0;
00312 return *this;
00313 }
00314
00315 inline GVector3& GVector3::set(double x, double y, double z)
00316 {
00317 this->x = x;
00318 this->y = y;
00319 this->z = z;
00320 return *this;
00321 }
00322
00323 inline GVector3& GVector3::set(const GVector3& original)
00324 {
00325 return set(original.x, original.y, original.z);
00326 }
00327
00328 inline GVector3& GVector3::normalize()
00329 {
00330 double l = length();
00331 x /= l;
00332 y /= l;
00333 z /= l;
00334 return *this;
00335 }
00336
00337 inline GVector3& GVector3::scaleXYZ(double x, double y, double z)
00338 {
00339 this->x *= x;
00340 this->y *= y;
00341 this->z *= z;
00342 return *this;
00343 }
00344
00345 inline GVector3& GVector3::scaleXYZ(const GVector3& scale)
00346 {
00347 return scaleXYZ(scale.x,scale.y,scale.z);
00348 }
00349
00350 inline GVector3& GVector3::add(const GVector3& right)
00351 {
00352 x += right.x;
00353 y += right.y;
00354 z += right.z;
00355 return *this;
00356 }
00357
00358 inline GVector3& GVector3::sub(const GVector3& right)
00359 {
00360 x -= right.x;
00361 y -= right.y;
00362 z -= right.z;
00363 return *this;
00364 }
00365
00366 inline GVector3& GVector3::mul(double scalar)
00367 {
00368 x *= scalar;
00369 y *= scalar;
00370 z *= scalar;
00371 return *this;
00372 }
00373
00374 inline double GVector3::dot(const GVector3& right) const
00375 {
00376 return x*right.x +
00377 y*right.y +
00378 z*right.z;
00379 }
00380
00381 inline GVector3 GVector3::cross(const GVector3& right) const
00382 {
00383 return GVector3(
00384 y*right.z - z*right.y,
00385 z*right.x - x*right.z,
00386 x*right.y - y*right.x);
00387 }
00388
00389 inline GVector3& GVector3::operator = (const GVector3& original)
00390 {
00391 return set(original);
00392 }
00393
00394 inline GVector3 GVector3::operator + (const GVector3& right) const
00395 {
00396 return GVector3(x + right.x,
00397 y + right.y,
00398 z + right.z);
00399 }
00400
00401 inline GVector3 GVector3::operator - (const GVector3& right) const
00402 {
00403 return GVector3(x - right.x,
00404 y - right.y,
00405 z - right.z);
00406 }
00407
00408 inline GVector3 GVector3::operator * (double factor) const
00409 {
00410 GVector3 result(*this);
00411 return result.mul(factor);
00412 }
00413
00414 inline GVector3& GVector3::operator += (const GVector3& right)
00415 {
00416 x += right.x;
00417 y += right.y;
00418 z += right.z;
00419 return *this;
00420 }
00421
00422 inline GVector3& GVector3::operator -= (const GVector3& right)
00423 {
00424 x -= right.x;
00425 y -= right.y;
00426 z -= right.z;
00427 return *this;
00428 }
00429
00430 inline bool GVector3::operator == (const GVector3& comp) const
00431 {
00432 double dx,dy,dz;
00433 dx = comp.x - x;
00434 dy = comp.y - y;
00435 dz = comp.z - z;
00436
00437 if (dx<0)
00438 dx = -dx;
00439 if (dy<0)
00440 dy = -dy;
00441 if (dz<0)
00442 dz = -dz;
00443
00444 double tolerance = 0.00001;
00445
00446 return ( dx < tolerance && dy < tolerance && dz < tolerance );
00447 }
00448
00449 inline double GVector3::distanceTo(const GVector3& p) const
00450 {
00451 GVector3 temp = p - *this;
00452 return temp.length();
00453 }
00454
00455 inline double GVector3::angleTo(const GVector3& v) const
00456 {
00457 if (this->length()==0 || v.length() == 0)
00458 return 0;
00459 return std::acos(this->dot(v)/(this->length()*v.length()));
00460 }
00461
00462 inline GVector3& GVector3::turnAroundAxis(const GVector3& axis, double angle_rad)
00463 {
00464 double x,y,z;
00465 double sin_a = std::sin(angle_rad);
00466 double cos_a = std::cos(angle_rad);
00467
00468 x = ( axis.x * axis.x + cos_a * ( 1- axis.x * axis.x ) ) * this->x
00469 + ( axis.x * axis.y * ( 1 - cos_a ) - axis.z * sin_a ) * this->y
00470 + ( axis.x * axis.z * ( 1 - cos_a ) + axis.y * sin_a ) * this->z;
00471
00472 y = ( axis.x * axis.y * ( 1 - cos_a ) + axis.z * sin_a ) * this->x
00473 + ( axis.y * axis.y + cos_a * ( 1- axis.y * axis.y ) ) * this->y
00474 + ( axis.y * axis.z * ( 1 - cos_a ) - axis.x * sin_a ) * this->z;
00475
00476 z = ( axis.z * axis.x * ( 1 - cos_a ) - axis.y * sin_a ) * this->x
00477 + ( axis.y * axis.z * ( 1 - cos_a ) + axis.x * sin_a ) * this->y
00478 + ( axis.z * axis.z + cos_a * ( 1 - axis.z * axis.z ) ) * this->z;
00479
00480 this->x = x;
00481 this->y = y;
00482 this->z = z;
00483
00484 return *this;
00485 }
00486
00487 inline GVector3& GVector3::projectTo(const GVector3& v)
00488 {
00489 double v_length = v.length();
00490 if (v_length==0)
00491 return *this;
00492 GVector3 temp = v;
00493 *this = temp.mul( v.dot(*this)/(v_length*v_length) );
00494 return *this;
00495 }
00496
00497 }
00498
00499 #endif