00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #ifndef CVector3dH
00024 #define CVector3dH
00025
00026 #include "math/CString.h"
00027 #include "math/CConstants.h"
00028 #include "extras/CGlobals.h"
00029 #include <math.h>
00030 #include <ostream>
00031
00032
00033
00041
00042
00043
00053
00054 struct cVector3d
00055 {
00056 public:
00057
00058
00059
00060
00062 double x;
00063
00065 double y;
00066
00068 double z;
00069
00070
00071
00072
00073
00074
00075
00091
00092 cVector3d() {}
00093
00095 cVector3d(const char* a_initstr) { set(a_initstr); }
00096
00098 cVector3d(const string& a_initstr) { set(a_initstr); }
00099
00101 cVector3d(const double a_x, const double a_y,
00102 const double a_z) : x(a_x), y(a_y), z(a_z) { }
00103
00105 cVector3d(const cVector3d& a_source) : x(a_source.x), y(a_source.y), z(a_source.z) { }
00106
00108 cVector3d(const double* a_in) : x(a_in[0]), y(a_in[1]), z(a_in[2]) { }
00109
00111 cVector3d(const float* a_in) : x(a_in[0]), y(a_in[1]), z(a_in[2]) { }
00112
00113
00114
00115
00116
00117
00118
00125
00127 double& operator[] (unsigned int index) { return (&x)[index]; }
00128
00130 double operator[] (unsigned int index) const { return ((double*)(&x))[index]; }
00131
00132
00133
00134
00135
00136
00137
00141
00142 inline void zero()
00143 {
00144 x = 0.0;
00145 y = 0.0;
00146 z = 0.0;
00147 }
00148
00149
00157
00158 inline double get(const unsigned int& a_component) const
00159 {
00160 return ((double*)(this))[a_component];
00161 }
00162
00163
00167
00168 inline void operator/= (const double& a_val)
00169 {
00170 x /= a_val;
00171 y /= a_val;
00172 z /= a_val;
00173 }
00174
00175
00179
00180 inline void operator*= (const double& a_val)
00181 {
00182 x *= a_val;
00183 y *= a_val;
00184 z *= a_val;
00185 }
00186
00187
00191
00192 inline void operator+= (const cVector3d& a_input)
00193 {
00194 x += a_input.x;
00195 y += a_input.y;
00196 z += a_input.z;
00197 }
00198
00199
00203
00204 inline void operator-= (const cVector3d& a_input)
00205 {
00206 x -= a_input.x;
00207 y -= a_input.y;
00208 z -= a_input.z;
00209 }
00210
00211
00219
00220 inline void set(const double& a_x, const double& a_y, const double& a_z)
00221 {
00222 x = a_x;
00223 y = a_y;
00224 z = a_z;
00225 }
00226
00227
00243
00244 inline bool set(const char* a_initStr)
00245 {
00246 if (a_initStr == 0) return false;
00247
00248 double ax,ay,az;
00249
00250
00251
00252 const char* curpos = a_initStr;
00253 while(
00254 (*curpos != '\0') &&
00255 (*curpos == ' ' || *curpos == '\t' || *curpos == '(')
00256 )
00257 {
00258 curpos++;
00259 }
00260
00261 int result = sscanf(curpos,"%lf%*[ ,\t\n\r]%lf%*[ ,\t\n\r]%lf",&ax,&ay,&az);
00262
00263
00264 if (result !=3) return false;
00265
00266
00267 x = ax; y = ay; z = az;
00268 return (true);
00269 }
00270
00271
00279
00280 inline bool set(const string& a_initStr)
00281 {
00282 return ( set(a_initStr.c_str()) );
00283 }
00284
00285
00291
00292 inline void copyto(cVector3d& a_destination) const
00293 {
00294 a_destination.x = x;
00295 a_destination.y = y;
00296 a_destination.z = z;
00297 }
00298
00299
00305
00306 inline void copyfrom(const cVector3d &a_source)
00307 {
00308 x = a_source.x;
00309 y = a_source.y;
00310 z = a_source.z;
00311 }
00312
00313
00321
00322 inline void add(const cVector3d& a_vector)
00323 {
00324 x = x + a_vector.x;
00325 y = y + a_vector.y;
00326 z = z + a_vector.z;
00327 }
00328
00329
00339
00340 inline void add(const double& a_x, const double& a_y, const double& a_z)
00341 {
00342 x = x + a_x;
00343 y = y + a_y;
00344 z = z + a_z;
00345 }
00346
00347
00355
00356 inline void addr(const cVector3d& a_vector, cVector3d& a_result) const
00357 {
00358 a_result.x = x + a_vector.x;
00359 a_result.y = y + a_vector.y;
00360 a_result.z = z + a_vector.z;
00361 }
00362
00363
00373
00374 inline void addr(const double& a_x, const double& a_y, const double& a_z, cVector3d& a_result) const
00375 {
00376 a_result.x = x + a_x;
00377 a_result.y = y + a_y;
00378 a_result.z = z + a_z;
00379 }
00380
00381
00389
00390 inline void sub(const cVector3d& a_vector)
00391 {
00392 x = x - a_vector.x;
00393 y = y - a_vector.y;
00394 z = z - a_vector.z;
00395 }
00396
00397
00406
00407 inline void sub(const double& a_x, const double& a_y, const double& a_z)
00408 {
00409 x = x - a_x;
00410 y = y - a_y;
00411 z = z - a_z;
00412 }
00413
00414
00422
00423 inline void subr(const cVector3d& a_vector, cVector3d& a_result) const
00424 {
00425 a_result.x = x - a_vector.x;
00426 a_result.y = y - a_vector.y;
00427 a_result.z = z - a_vector.z;
00428 }
00429
00430
00440
00441 inline void subr(const double& a_x, const double& a_y, const double& a_z,
00442 cVector3d &a_result) const
00443 {
00444 a_result.x = x - a_x;
00445 a_result.y = y - a_y;
00446 a_result.z = z - a_z;
00447 }
00448
00449
00456
00457 inline void mul(const double &a_scalar)
00458 {
00459 x = a_scalar * x;
00460 y = a_scalar * y;
00461 z = a_scalar * z;
00462 }
00463
00464
00472
00473 inline void mulr(const double& a_scalar, cVector3d& a_result) const
00474 {
00475 a_result.x = a_scalar * x;
00476 a_result.y = a_scalar * y;
00477 a_result.z = a_scalar * z;
00478 }
00479
00480
00489
00490 inline void div(const double &a_scalar)
00491 {
00492 x = x / a_scalar;
00493 y = y / a_scalar;
00494 z = z / a_scalar;
00495 }
00496
00497
00505
00506 inline void divr(const double& a_scalar, cVector3d& a_result) const
00507 {
00508 a_result.x = x / a_scalar;
00509 a_result.y = y / a_scalar;
00510 a_result.z = z / a_scalar;
00511 }
00512
00513
00518
00519 inline void negate()
00520 {
00521 x = -x;
00522 y = -y;
00523 z = -z;
00524 }
00525
00526
00533
00534 inline void negater(cVector3d& a_result) const
00535 {
00536 a_result.x = -x;
00537 a_result.y = -y;
00538 a_result.z = -z;
00539 }
00540
00541
00548
00549 inline void cross(const cVector3d& a_vector)
00550 {
00551
00552 double a = (y * a_vector.z) - (z * a_vector.y);
00553 double b = -(x * a_vector.z) + (z * a_vector.x);
00554 double c = (x * a_vector.y) - (y * a_vector.x);
00555
00556
00557 x = a;
00558 y = b;
00559 z = c;
00560 }
00561
00562
00573
00574 inline cVector3d crossAndReturn(const cVector3d& a_vector) const
00575 {
00576 cVector3d r;
00577 crossr(a_vector,r);
00578 return (r);
00579 }
00580
00581
00590
00591 inline void crossr(const cVector3d& a_vector, cVector3d& a_result) const
00592 {
00593 a_result.x = (y * a_vector.z) - (z * a_vector.y);
00594 a_result.y = -(x * a_vector.z) + (z * a_vector.x);
00595 a_result.z = (x * a_vector.y) - (y * a_vector.x);
00596 }
00597
00598
00606
00607 inline double dot(const cVector3d& a_vector) const
00608 {
00609 return((x * a_vector.x) + (y * a_vector.y) + (z * a_vector.z));
00610 }
00611
00612
00619
00620 inline void elementMul(const cVector3d& a_vector)
00621 {
00622 x*=a_vector.x;
00623 y*=a_vector.y;
00624 z*=a_vector.z;
00625 }
00626
00627
00635
00636 inline void elementMulr(const cVector3d& a_vector, cVector3d& a_result) const
00637 {
00638 a_result.x = x*a_vector.x;
00639 a_result.y = y*a_vector.y;
00640 a_result.z = z*a_vector.z;
00641 }
00642
00643
00649
00650 inline double length() const
00651 {
00652 return(sqrt((x * x) + (y * y) + (z * z)));
00653 }
00654
00655
00661
00662 inline double lengthsq(void) const
00663 {
00664 return((x * x) + (y * y) + (z * z));
00665 }
00666
00667
00675
00676 inline void normalize()
00677 {
00678
00679 double length = sqrt((x * x) + (y * y) + (z * z));
00680
00681
00682 x = x / length;
00683 y = y / length;
00684 z = z / length;
00685 }
00686
00687
00696
00697 inline void normalizer(cVector3d& a_result) const
00698 {
00699
00700 double length = sqrt((x * x) + (y * y) + (z * z));
00701
00702
00703 a_result.x = x / length;
00704 a_result.y = y / length;
00705 a_result.z = z / length;
00706 }
00707
00708
00716
00717 inline double distance(const cVector3d& a_vector) const
00718 {
00719
00720 double dx = x - a_vector.x;
00721 double dy = y - a_vector.y;
00722 double dz = z - a_vector.z;
00723
00724
00725 return(sqrt( dx * dx + dy * dy + dz * dz ));
00726 }
00727
00728
00736
00737 inline double distancesq(const cVector3d& a_vector) const
00738 {
00739
00740 double dx = x - a_vector.x;
00741 double dy = y - a_vector.y;
00742 double dz = z - a_vector.z;
00743
00744
00745 return( dx * dx + dy * dy + dz * dz );
00746 }
00747
00748
00759
00760 inline bool equals(const cVector3d& a_vector, const double epsilon=0.0) const
00761 {
00762
00763 if (epsilon == 0.0)
00764 {
00765 if ( (x == a_vector.x) && (y == a_vector.y) && (z == a_vector.z) )
00766 {
00767 return (true);
00768 }
00769 else
00770 {
00771 return (false);
00772 }
00773 }
00774
00775 if ((fabs(a_vector.x-x) < epsilon) &&
00776 (fabs(a_vector.y-y) < epsilon) &&
00777 (fabs(a_vector.z-z) < epsilon))
00778 {
00779 return (true);
00780 }
00781 else
00782 {
00783 return (false);
00784 }
00785 }
00786
00787
00794
00795 inline void str(string& a_string, const unsigned int a_precision=2) const
00796 {
00797 a_string.append("( ");
00798 cStr(a_string, x, a_precision);
00799 a_string.append(", ");
00800 cStr(a_string, y, a_precision);
00801 a_string.append(", ");
00802 cStr(a_string, z, a_precision);
00803 a_string.append(" )");
00804 }
00805
00806
00812
00813 inline string str(const unsigned int a_precision=2) const
00814 {
00815 string a_string;
00816 str(a_string,a_precision);
00817 return (a_string);
00818 }
00819
00820
00826
00827 inline void print(const unsigned int a_precision=2) const
00828 {
00829 string s;
00830 str(s,a_precision);
00831 CHAI_DEBUG_PRINT("%s\n",s.c_str());
00832 }
00833
00834
00843
00844 inline void decompose(const cVector3d& a_input, cVector3d& a_parallel, cVector3d& a_perpendicular)
00845 {
00846 double scale = (this->dot(a_input) / (a_input.dot(a_input)));
00847 a_parallel = a_input;
00848 a_parallel.mul(scale);
00849 this->subr(a_parallel,a_perpendicular);
00850 }
00851
00852
00861
00862 inline void slerp(double a_level, cVector3d const& a_vector1, cVector3d a_vector2)
00863 {
00864
00865 double a_vec1lensq = a_vector1.lengthsq();
00866 double cosomega = a_vector1.dot(a_vector2)/(a_vec1lensq);
00867 if ((cosomega-1.0) > -1e-4 && (cosomega-1.0) < 1e-4) {
00868
00869
00870 *this = a_vector1;
00871 this->mul(1.0-a_level);
00872 a_vector2.mul(a_level);
00873 this->operator +=(a_vector2);
00874 this->mul(sqrt(a_vec1lensq/this->lengthsq()));
00875 } else {
00876 if (cosomega < 0.0) {
00877 cosomega = -cosomega;
00878 a_vector2.negate();
00879 }
00880 double ratio1, ratio2;
00881 if ((cosomega+1.0) > -1e-4 && (cosomega+1.0) < 1e-4) {
00882
00883
00884 if ((a_vector1.x < a_vector1.y) && (a_vector1.x < a_vector1.z)){
00885
00886 a_vector2.x = 0;
00887 a_vector2.y = -a_vector1.z;
00888 a_vector2.z = a_vector1.y;
00889 } else if (a_vector1.y < a_vector1.z) {
00890
00891 a_vector2.x = -a_vector1.z;
00892 a_vector2.y = 0;
00893 a_vector2.z = a_vector1.x;
00894 } else {
00895
00896 a_vector2.x = -a_vector1.y;
00897 a_vector2.y = a_vector1.x;
00898 a_vector2.z = 0;
00899 }
00900
00901 a_vector2.mul(sqrt(a_vec1lensq/a_vector2.lengthsq()));
00902
00903 ratio1 = sin(CHAI_PI*(0.5-a_level));
00904 ratio2 = sin(CHAI_PI*a_level);
00905 } else {
00906 double omega = acos(cosomega);
00907 double sinomega = sin(omega);
00908 ratio1 = sin(omega*(1.0-a_level))/sinomega;
00909 ratio2 = sin(omega*a_level)/sinomega;
00910 }
00911 *this = a_vector1;
00912 this->mul(ratio1);
00913 a_vector2.mul(ratio2);
00914 this->add(a_vector2);
00915 }
00916 }
00917 };
00918
00919
00920
00921
00922
00923
00924
00928
00929 inline cVector3d operator*(const cVector3d& v, const double a_input)
00930 {
00931 return (cVector3d(v.x*a_input,v.y*a_input,v.z*a_input));
00932 }
00933
00934
00938
00939 inline cVector3d operator/(const cVector3d& v, const double a_input)
00940 {
00941 return (cVector3d(v.x/a_input,v.y/a_input,v.z/a_input));
00942 }
00943
00944
00948
00949 inline cVector3d operator*(const double a_input, const cVector3d& v)
00950 {
00951 return cVector3d(v.x*a_input,v.y*a_input,v.z*a_input);
00952 }
00953
00954
00958
00959 inline cVector3d operator+(const cVector3d& v1, const cVector3d& v2)
00960 {
00961 return cVector3d(v1.x+v2.x,v1.y+v2.y,v1.z+v2.z);
00962 }
00963
00964
00968
00969 inline cVector3d operator-(const cVector3d& v1, const cVector3d& v2)
00970 {
00971 return cVector3d(v1.x-v2.x,v1.y-v2.y,v1.z-v2.z);
00972 }
00973
00974
00978
00979 inline double operator*(const cVector3d& v1, const cVector3d& v2)
00980 {
00981 return v1.x*v2.x+v1.y*v2.y+v1.z*v2.z;
00982 }
00983
00984
00989
00990 static inline std::ostream &operator << (std::ostream &a_os, cVector3d const& a_vec)
00991 {
00992 a_os << a_vec.x << ", " << a_vec.y << ", " << a_vec.z;
00993 return a_os;
00994 }
00995
00996
00997
01005
01006 struct cRay3d
01007 {
01009 cVector3d m_origin;
01010
01012 cVector3d m_direction;
01013
01015 cRay3d();
01016
01018 cRay3d(const cVector3d& a_origin, const cVector3d& a_direction) :
01019 m_origin(a_origin), m_direction(a_direction)
01020 { }
01021 };
01022
01023
01024
01032
01033 struct cSegment3d
01034 {
01036 cSegment3d(const cVector3d& a_start, const cVector3d& a_end) :
01037 m_start(a_start), m_end(a_end)
01038 { }
01039
01041 cVector3d m_start;
01042
01044 cVector3d m_end;
01045
01047 double distanceSquaredToPoint(const cVector3d& a_point,
01048 double& a_t,
01049 cVector3d* a_closestPoint=0);
01050 };
01051
01052
01053
01054
01055 #endif
01056