| [658] | 1 | #include <math.h>
 | 
|---|
 | 2 | #include "vector3d.h"
 | 
|---|
 | 3 | #include "utilgeom.h"
 | 
|---|
 | 4 | //++ 
 | 
|---|
 | 5 | // Class        Vector3d
 | 
|---|
 | 6 | //
 | 
|---|
 | 7 | // include      vector3d.h utilgeom.h  longlat.h math.h
 | 
|---|
 | 8 | //
 | 
|---|
 | 9 | //
 | 
|---|
 | 10 | //    3-D geometry. 
 | 
|---|
 | 11 | //    All computations are made with angles in radians and with spherical
 | 
|---|
 | 12 | //    coordinates theta, phi.
 | 
|---|
 | 13 | //
 | 
|---|
 | 14 | //    Concerning Euler's angles, the reference is :
 | 
|---|
 | 15 | // 
 | 
|---|
 | 16 | //    "Classical Mechanics" 2nd edition, H. Goldstein, Addison Wesley
 | 
|---|
 | 17 | //--
 | 
|---|
 | 18 | //++
 | 
|---|
 | 19 | // Titre        Constructors
 | 
|---|
 | 20 | //--
 | 
|---|
 | 21 | //++
 | 
|---|
 | 22 | Vector3d::Vector3d()
 | 
|---|
 | 23 | //
 | 
|---|
 | 24 | //-- 
 | 
|---|
 | 25 | {
 | 
|---|
 | 26 |   Setxyz(1.,0.,0.);
 | 
|---|
 | 27 | }
 | 
|---|
 | 28 | //++
 | 
|---|
 | 29 | Vector3d::Vector3d(double x, double y, double z) 
 | 
|---|
 | 30 | //
 | 
|---|
 | 31 | //-- 
 | 
|---|
 | 32 | {
 | 
|---|
 | 33 |   _x=x;
 | 
|---|
 | 34 |   _y=y;
 | 
|---|
 | 35 |   _z=z;
 | 
|---|
 | 36 |   xyz2ThetaPhi();
 | 
|---|
 | 37 | }
 | 
|---|
 | 38 | //++
 | 
|---|
 | 39 | Vector3d::Vector3d(double theta, double phi) 
 | 
|---|
 | 40 | //
 | 
|---|
 | 41 | //-- 
 | 
|---|
 | 42 | {
 | 
|---|
 | 43 |   _theta=mod(theta,M_PI); // dans [0;pi]
 | 
|---|
 | 44 |   _phi=mod(phi,pi2); // dans [0;2pi]
 | 
|---|
 | 45 |   ThetaPhi2xyz();
 | 
|---|
 | 46 | }
 | 
|---|
 | 47 | //++
 | 
|---|
 | 48 | Vector3d::Vector3d(const LongLat& ll)
 | 
|---|
 | 49 | //
 | 
|---|
 | 50 | //-- 
 | 
|---|
 | 51 | {
 | 
|---|
 | 52 |   _theta=ll.Theta(); // dans [0;pi]
 | 
|---|
 | 53 |   _phi=ll.Phi(); // dans [0;2pi]
 | 
|---|
 | 54 |   ThetaPhi2xyz();
 | 
|---|
 | 55 | }
 | 
|---|
 | 56 | //++
 | 
|---|
 | 57 | Vector3d::Vector3d(const Vector3d& v) 
 | 
|---|
 | 58 | //
 | 
|---|
 | 59 | //-- 
 | 
|---|
 | 60 | {
 | 
|---|
 | 61 |   _x=v._x;
 | 
|---|
 | 62 |   _y=v._y;
 | 
|---|
 | 63 |   _z=v._z;
 | 
|---|
 | 64 |   _theta=v._theta;
 | 
|---|
 | 65 |   _phi=v._phi;
 | 
|---|
 | 66 | }
 | 
|---|
 | 67 | //++
 | 
|---|
 | 68 | // Titre        Public methods
 | 
|---|
 | 69 | //--
 | 
|---|
 | 70 | //++
 | 
|---|
 | 71 | void Vector3d::SetThetaPhi(double theta, double phi)
 | 
|---|
 | 72 | //
 | 
|---|
 | 73 | //-- 
 | 
|---|
 | 74 | {
 | 
|---|
 | 75 |   _theta=mod(theta,M_PI);
 | 
|---|
 | 76 |   _phi=mod(phi,pi2);
 | 
|---|
 | 77 |   ThetaPhi2xyz();
 | 
|---|
 | 78 | }
 | 
|---|
 | 79 | //++
 | 
|---|
 | 80 | void Vector3d::Setxyz(double x, double y, double z) 
 | 
|---|
 | 81 | //
 | 
|---|
 | 82 | //-- 
 | 
|---|
 | 83 | {
 | 
|---|
 | 84 |   _x=x;
 | 
|---|
 | 85 |   _y=y;
 | 
|---|
 | 86 |   _z=z;
 | 
|---|
 | 87 |   xyz2ThetaPhi();
 | 
|---|
 | 88 | }
 | 
|---|
 | 89 | //++
 | 
|---|
 | 90 | void Vector3d::ThetaPhi2xyz()
 | 
|---|
 | 91 | //
 | 
|---|
 | 92 | //-- 
 | 
|---|
 | 93 | {
 | 
|---|
 | 94 |   _x=sin(_theta)*cos(_phi);
 | 
|---|
 | 95 |   _y=sin(_theta)*sin(_phi);
 | 
|---|
 | 96 |   _z=cos(_theta);
 | 
|---|
 | 97 | }
 | 
|---|
 | 98 | //++
 | 
|---|
 | 99 | void Vector3d::xyz2ThetaPhi()
 | 
|---|
 | 100 | //
 | 
|---|
 | 101 | //-- 
 | 
|---|
 | 102 | {
 | 
|---|
 | 103 |   double norm=this->Norm();
 | 
|---|
 | 104 |   if( norm != 0. ) 
 | 
|---|
 | 105 |     {
 | 
|---|
 | 106 |       _theta=acos(_z/norm); // dans [0,Pi]
 | 
|---|
 | 107 |       if( mod(_theta,M_PI) == 0. ) _phi=0.; // on est sur +-Oz, le vecteur z est en phi=0
 | 
|---|
 | 108 |       //      else _phi=acos(_x/sin(_theta)/norm)+M_PI*(_y<0);
 | 
|---|
 | 109 |       else _phi=scangle(_y/sin(_theta)/norm,_x/sin(_theta)/norm);
 | 
|---|
 | 110 |     }
 | 
|---|
 | 111 |   else // vecteur nul
 | 
|---|
 | 112 |     {
 | 
|---|
 | 113 |       _theta=0.;
 | 
|---|
 | 114 |       _phi=0.;
 | 
|---|
 | 115 |     }
 | 
|---|
 | 116 | }
 | 
|---|
 | 117 | //++
 | 
|---|
 | 118 | Vector3d& Vector3d::Normalize() 
 | 
|---|
 | 119 | //
 | 
|---|
 | 120 | //-- 
 | 
|---|
 | 121 | {
 | 
|---|
 | 122 |   double norm=this->Norm();
 | 
|---|
 | 123 |   if( norm != 0. )  (*this)/=norm;
 | 
|---|
 | 124 |   else cerr << "Division par zero" << endl;
 | 
|---|
 | 125 |   return *this;
 | 
|---|
 | 126 | } 
 | 
|---|
 | 127 | //++
 | 
|---|
 | 128 | double Vector3d::Norm() const 
 | 
|---|
 | 129 | //
 | 
|---|
 | 130 | //-- 
 | 
|---|
 | 131 | {
 | 
|---|
 | 132 |   return sqrt(_x*_x+_y*_y+_z*_z);
 | 
|---|
 | 133 | }
 | 
|---|
 | 134 | //++
 | 
|---|
 | 135 | double Vector3d::Psc(const Vector3d& v) const 
 | 
|---|
 | 136 | //
 | 
|---|
 | 137 | //    dot product
 | 
|---|
 | 138 | //-- 
 | 
|---|
 | 139 | {
 | 
|---|
 | 140 |   return _x*v._x+_y*v._y+_z*v._z;
 | 
|---|
 | 141 | }
 | 
|---|
 | 142 | //++
 | 
|---|
 | 143 | double Vector3d::SepAngle(const Vector3d& v) const 
 | 
|---|
 | 144 | //
 | 
|---|
 | 145 | //    angular gap between 2 vectors in [0,Pi]
 | 
|---|
 | 146 | //-- 
 | 
|---|
 | 147 | {
 | 
|---|
 | 148 |   double n1=this->Norm();
 | 
|---|
 | 149 |   double n2=v.Norm();
 | 
|---|
 | 150 |   double ret;
 | 
|---|
 | 151 |   if( n1!=0. && n2!=0. ) ret=acos((this->Psc(v))/n1/n2);
 | 
|---|
 | 152 |   else 
 | 
|---|
 | 153 |     {
 | 
|---|
 | 154 |       cerr << "Division par zero" << endl;
 | 
|---|
 | 155 |       ret=0.;
 | 
|---|
 | 156 |     }
 | 
|---|
 | 157 |   return ret;
 | 
|---|
 | 158 | }
 | 
|---|
 | 159 | //++
 | 
|---|
 | 160 | Vector3d Vector3d::Vect(const Vector3d& v) const 
 | 
|---|
 | 161 | //
 | 
|---|
 | 162 | //    vector product
 | 
|---|
 | 163 | //-- 
 | 
|---|
 | 164 | {
 | 
|---|
 | 165 |   double xo=_y*v._z-_z*v._y;
 | 
|---|
 | 166 |   double yo=_z*v._x-_x*v._z;
 | 
|---|
 | 167 |   double zo=_x*v._y-_y*v._x;
 | 
|---|
 | 168 |   return Vector3d(xo,yo,zo);
 | 
|---|
 | 169 | }
 | 
|---|
 | 170 | //++
 | 
|---|
 | 171 | Vector3d Vector3d::VperpPhi() const 
 | 
|---|
 | 172 | //
 | 
|---|
 | 173 | //    perpendicular vector, with equal phi
 | 
|---|
 | 174 | //-- 
 | 
|---|
 | 175 | {
 | 
|---|
 | 176 |   double theta;
 | 
|---|
 | 177 |   if( _theta != pi_over_2 ) theta=_theta+(0.5-(_theta>pi_over_2))*M_PI; // on tourne theta de +-pi/2
 | 
|---|
 | 178 |   else theta=0.;
 | 
|---|
 | 179 |   return Vector3d(theta,_phi);
 | 
|---|
 | 180 | }
 | 
|---|
 | 181 | //++
 | 
|---|
 | 182 | Vector3d Vector3d::VperpTheta() const 
 | 
|---|
 | 183 | //
 | 
|---|
 | 184 | //    perpendicular vector with equal theta
 | 
|---|
 | 185 | //-- 
 | 
|---|
 | 186 | {
 | 
|---|
 | 187 |   double phi=mod(_phi+pi_over_2,pi2); // on tourne phi de pi/2
 | 
|---|
 | 188 |   return Vector3d(_theta,phi);
 | 
|---|
 | 189 | }
 | 
|---|
 | 190 | 
 | 
|---|
 | 191 | Vector3d Vector3d::EPhi() const 
 | 
|---|
 | 192 | {
 | 
|---|
 | 193 |   Vector3d temp;
 | 
|---|
 | 194 |   if ( fabs(_z) == 1. ) // si on est en +- Oz
 | 
|---|
 | 195 |     {
 | 
|---|
 | 196 |       temp=Vector3d(1.,0.,0.);
 | 
|---|
 | 197 |     }
 | 
|---|
 | 198 |   else 
 | 
|---|
 | 199 |     {
 | 
|---|
 | 200 |       Vector3d k(0,0,-1);
 | 
|---|
 | 201 |       temp=this->Vect(k);
 | 
|---|
 | 202 |       temp.Normalize();
 | 
|---|
 | 203 |     }
 | 
|---|
 | 204 |   return temp;
 | 
|---|
 | 205 | }
 | 
|---|
 | 206 | //++
 | 
|---|
 | 207 | Vector3d Vector3d::ETheta() const 
 | 
|---|
 | 208 | //
 | 
|---|
 | 209 | //-- 
 | 
|---|
 | 210 | {
 | 
|---|
 | 211 |   Vector3d temp=this->Vect(EPhi());
 | 
|---|
 | 212 |   temp.Normalize();
 | 
|---|
 | 213 |   return temp;
 | 
|---|
 | 214 | }
 | 
|---|
 | 215 | 
 | 
|---|
 | 216 | //++
 | 
|---|
 | 217 | Vector3d Vector3d::Euler(double phi, double theta, double psi) const 
 | 
|---|
 | 218 | //
 | 
|---|
 | 219 | //    Euler's rotations
 | 
|---|
 | 220 | //-- 
 | 
|---|
 | 221 | {
 | 
|---|
 | 222 |   double cpsi=cos(psi);
 | 
|---|
 | 223 |   double ctheta=cos(theta);
 | 
|---|
 | 224 |   double cphi=cos(phi);
 | 
|---|
 | 225 |   double spsi=sin(psi);
 | 
|---|
 | 226 |   double stheta=sin(theta);
 | 
|---|
 | 227 |   double sphi=sin(phi);
 | 
|---|
 | 228 |   double xnew=(cpsi*cphi-ctheta*sphi*spsi)*_x
 | 
|---|
 | 229 |     +(cpsi*sphi+ctheta*cphi*spsi)*_y
 | 
|---|
 | 230 |     +spsi*stheta*_z;
 | 
|---|
 | 231 |   double ynew=(-spsi*cphi-ctheta*sphi*cpsi)*_x
 | 
|---|
 | 232 |     +(-spsi*sphi+ctheta*cphi*cpsi)*_y
 | 
|---|
 | 233 |     +cpsi*stheta*_z;
 | 
|---|
 | 234 |   double znew=stheta*sphi*_x-stheta*cphi*_y+ctheta*_z;
 | 
|---|
 | 235 |   return Vector3d(xnew,ynew,znew);
 | 
|---|
 | 236 | }
 | 
|---|
 | 237 | //++
 | 
|---|
 | 238 | Vector3d Vector3d::InvEuler(double phi, double theta, double psi) const 
 | 
|---|
 | 239 | //
 | 
|---|
 | 240 | //    inverse rotation
 | 
|---|
 | 241 | //-- 
 | 
|---|
 | 242 | {
 | 
|---|
 | 243 |   double cpsi=cos(psi);
 | 
|---|
 | 244 |   double ctheta=cos(theta);
 | 
|---|
 | 245 |   double cphi=cos(phi);
 | 
|---|
 | 246 |   double spsi=sin(psi);
 | 
|---|
 | 247 |   double stheta=sin(theta);
 | 
|---|
 | 248 |   double sphi=sin(phi);
 | 
|---|
 | 249 |   double xnew=(cpsi*cphi-ctheta*sphi*spsi)*_x
 | 
|---|
 | 250 |     -(spsi*cphi+ctheta*sphi*cpsi)*_y
 | 
|---|
 | 251 |     +sphi*stheta*_z;
 | 
|---|
 | 252 |   double ynew=(cpsi*sphi+ctheta*cphi*spsi)*_x
 | 
|---|
 | 253 |     +(-spsi*sphi+ctheta*cphi*cpsi)*_y
 | 
|---|
 | 254 |     -cphi*stheta*_z;
 | 
|---|
 | 255 |   double znew=stheta*spsi*_x+stheta*cpsi*_y+ctheta*_z;
 | 
|---|
 | 256 |   return Vector3d(xnew,ynew,znew);
 | 
|---|
 | 257 | }
 | 
|---|
 | 258 | //++
 | 
|---|
 | 259 | Vector3d Vector3d::Rotate(const Vector3d& omega, double phi)
 | 
|---|
 | 260 | //
 | 
|---|
 | 261 | //    rotation of angle phi around an axis omega (Maxwell's rule)
 | 
|---|
 | 262 | //-- 
 | 
|---|
 | 263 | {
 | 
|---|
 | 264 |   Vector3d rotationaxis=omega;
 | 
|---|
 | 265 |   rotationaxis.Normalize();
 | 
|---|
 | 266 |   double n=this->Psc(rotationaxis);
 | 
|---|
 | 267 |   Vector3d myself=*this;
 | 
|---|
 | 268 |   Vector3d rotate=n*rotationaxis+(myself-n*rotationaxis)*cos(phi)-(myself^rotationaxis)*sin(phi);
 | 
|---|
 | 269 |   return rotate;
 | 
|---|
 | 270 | } 
 | 
|---|
 | 271 | //++  
 | 
|---|
 | 272 | void Vector3d::Print(ostream& os) const 
 | 
|---|
 | 273 | //
 | 
|---|
 | 274 | //--
 | 
|---|
 | 275 | {
 | 
|---|
 | 276 |   os << "Vector3: (X,Y,Z)= (" << _x << ", " << _y << ", " << _z 
 | 
|---|
 | 277 |      << ") --- Theta,Phi= " << _theta << ", " << _phi << "\n"
 | 
|---|
 | 278 |      << "Norme = " << this->Norm() << endl;
 | 
|---|
 | 279 | }
 | 
|---|
 | 280 | //++
 | 
|---|
 | 281 | // Titre        Operators
 | 
|---|
 | 282 | //--
 | 
|---|
 | 283 | //++
 | 
|---|
 | 284 | Vector3d& Vector3d::operator += (const Vector3d& v) 
 | 
|---|
 | 285 | //
 | 
|---|
 | 286 | //-- 
 | 
|---|
 | 287 | {
 | 
|---|
 | 288 |   *this=*this+v;
 | 
|---|
 | 289 |   return *this;
 | 
|---|
 | 290 | }
 | 
|---|
 | 291 | //++
 | 
|---|
 | 292 | Vector3d& Vector3d::operator -= (const Vector3d& v) 
 | 
|---|
 | 293 | //
 | 
|---|
 | 294 | //-- 
 | 
|---|
 | 295 | {
 | 
|---|
 | 296 |   *this=*this-v;
 | 
|---|
 | 297 |   return *this;
 | 
|---|
 | 298 | }
 | 
|---|
 | 299 | //++
 | 
|---|
 | 300 | Vector3d& Vector3d::operator += (double d) 
 | 
|---|
 | 301 | //
 | 
|---|
 | 302 | //-- 
 | 
|---|
 | 303 | {
 | 
|---|
 | 304 |   Setxyz(_x+d,_y+d,_z+d);
 | 
|---|
 | 305 |   return *this;
 | 
|---|
 | 306 | }
 | 
|---|
 | 307 | //++
 | 
|---|
 | 308 | Vector3d& Vector3d::operator /= (double d) 
 | 
|---|
 | 309 | //
 | 
|---|
 | 310 | //-- 
 | 
|---|
 | 311 | {
 | 
|---|
 | 312 |   if( d != 0. ) Setxyz(_x/d,_y/d,_z/d);
 | 
|---|
 | 313 |   else cerr << "Division par zero." << endl;
 | 
|---|
 | 314 |   return *this;
 | 
|---|
 | 315 | }
 | 
|---|
 | 316 | //++
 | 
|---|
 | 317 | Vector3d& Vector3d::operator *= (double d) 
 | 
|---|
 | 318 | //
 | 
|---|
 | 319 | //-- 
 | 
|---|
 | 320 | {
 | 
|---|
 | 321 |   Setxyz(_x*d,_y*d,_z*d);
 | 
|---|
 | 322 |   return *this;
 | 
|---|
 | 323 | }
 | 
|---|
 | 324 | //++
 | 
|---|
 | 325 | Vector3d Vector3d::operator ^ (const Vector3d& v) const 
 | 
|---|
 | 326 | //
 | 
|---|
 | 327 | //    vector product
 | 
|---|
 | 328 | //-- 
 | 
|---|
 | 329 | {
 | 
|---|
 | 330 |   return this->Vect(v);
 | 
|---|
 | 331 | }
 | 
|---|
 | 332 | //++
 | 
|---|
 | 333 | Vector3d Vector3d::operator + (double d) const 
 | 
|---|
 | 334 | //
 | 
|---|
 | 335 | //-- 
 | 
|---|
 | 336 | {
 | 
|---|
 | 337 |   return Vector3d(_x+d,_y+d,_z+d);
 | 
|---|
 | 338 | }
 | 
|---|
 | 339 | //++
 | 
|---|
 | 340 | Vector3d Vector3d::operator + (const Vector3d& v) const 
 | 
|---|
 | 341 | //
 | 
|---|
 | 342 | //-- 
 | 
|---|
 | 343 | {
 | 
|---|
 | 344 |   return Vector3d(_x+v._x,_y+v._y,_z+v._z);
 | 
|---|
 | 345 | }
 | 
|---|
 | 346 | //++
 | 
|---|
 | 347 | Vector3d Vector3d::operator - (double d) const 
 | 
|---|
 | 348 | //
 | 
|---|
 | 349 | //-- 
 | 
|---|
 | 350 | {
 | 
|---|
 | 351 |   return *this+(-d);
 | 
|---|
 | 352 | }
 | 
|---|
 | 353 | //++
 | 
|---|
 | 354 | Vector3d Vector3d::operator - (const Vector3d& v) const 
 | 
|---|
 | 355 | //
 | 
|---|
 | 356 | //-- 
 | 
|---|
 | 357 | {
 | 
|---|
 | 358 |   return *this+(v*(-1.));
 | 
|---|
 | 359 | }
 | 
|---|
 | 360 | //++
 | 
|---|
 | 361 | Vector3d Vector3d::operator * (double d) const 
 | 
|---|
 | 362 | //
 | 
|---|
 | 363 | //-- 
 | 
|---|
 | 364 | {
 | 
|---|
 | 365 |   return Vector3d(d*_x,d*_y,d*_z);
 | 
|---|
 | 366 | }
 | 
|---|
 | 367 | //++
 | 
|---|
 | 368 | double Vector3d::operator * (const Vector3d& v) const 
 | 
|---|
 | 369 | //
 | 
|---|
 | 370 | //    dot product
 | 
|---|
 | 371 | //-- 
 | 
|---|
 | 372 | {
 | 
|---|
 | 373 |   return this->Psc(v);
 | 
|---|
 | 374 | }
 | 
|---|
 | 375 | //++
 | 
|---|
 | 376 | Vector3d Vector3d::operator / (double d) const 
 | 
|---|
 | 377 | //
 | 
|---|
 | 378 | //-- 
 | 
|---|
 | 379 | {
 | 
|---|
 | 380 |   Vector3d ret=*this;
 | 
|---|
 | 381 |   if( d != 0. ) ret/=d;
 | 
|---|
 | 382 |   else  cerr << "Division par zero." << endl;
 | 
|---|
 | 383 |   return ret;
 | 
|---|
 | 384 | }
 | 
|---|
 | 385 | //++
 | 
|---|
 | 386 | Vector3d& Vector3d::operator = (const Vector3d& v) 
 | 
|---|
 | 387 | //
 | 
|---|
 | 388 | //-- 
 | 
|---|
 | 389 | {
 | 
|---|
 | 390 |   if( this != &v ) 
 | 
|---|
 | 391 |     {
 | 
|---|
 | 392 |       _x=v._x; 
 | 
|---|
 | 393 |       _y=v._y; 
 | 
|---|
 | 394 |       _z=v._z; 
 | 
|---|
 | 395 |       _theta=v._theta; 
 | 
|---|
 | 396 |       _phi=v._phi;
 | 
|---|
 | 397 |     }
 | 
|---|
 | 398 |   return *this;
 | 
|---|
 | 399 | }
 | 
|---|
 | 400 | //++
 | 
|---|
 | 401 | bool Vector3d::operator == (const Vector3d& v) 
 | 
|---|
 | 402 | //
 | 
|---|
 | 403 | //-- 
 | 
|---|
 | 404 | {
 | 
|---|
 | 405 |   return (this==&v);
 | 
|---|
 | 406 | }
 | 
|---|
 | 407 | 
 | 
|---|