source: Sophya/trunk/SophyaLib/SkyMap/vector3d.cc@ 3856

Last change on this file since 3856 was 2973, checked in by ansari, 19 years ago

1/ Nettoyage+commentaires/doxygen ds Vector3d, UnitVector, LongLat,
SphereCoordSys ...
2/ Ajout de la classe angle pour faciliter les conversions rad<>deg<>arcmin
dans le fichier vector3d.h .cc
3/ nettoyage/uniformisation methodes print pour pixelmap, ajout de la
methode PixelMap<T>::Show()
4/ Ajout methodes SphericalMap<T>::HasSymThetaSlice() et
GetSymThetaSliceIndex(int_4 idx) et leurs implementations pour
SphereHEALPix et SphereThetaPhi en vue de l'optimisation du calcul
transforme Ylm
5/ Ajout methode ResolToSizeIndex ds SphereThetaPhi , SphereHEALPix et
SphereECP

Reza , 20 Juin 2006

File size: 9.2 KB
RevLine 
[2973]1// Classes Angle Vector3d
2// B. Revenu , G. Le Meur 2000
3// R. Ansari 2006
4// LAL (Orsay) / IN2P3-CNRS DAPNIA/SPP (Saclay) / CEA
5
[2615]6#include "sopnamsp.h"
[764]7#include "machdefs.h"
8#include <math.h>
9#include "pexceptions.h"
10#include "vector3d.h"
11#include "utilgeom.h"
[2973]12
13// Class de conversion d'angles R. Ansari , Juin 2006
14double Angle::_deg2rad = M_PI/180.;
15double Angle::_rad2deg = 180./M_PI;
16double Angle::_rad2min = 180./M_PI*60.;
17double Angle::_rad2sec = 180./M_PI*3600.;
18
19/*!
20 \class SOPHYA::Angle
21 \ingroup SkyMap
22 \brief Class to ease angle conversions (radian <> degree <> arcmin <> arcsec).
23 The angle value is kept in radians internally.
24 \code
25 // Example to convert 0.035 radians to arcsec
26 double vr = 0.035;
27 cout << "Angle rad= " << vr << " ->arcsec= " << Angle(vr).ToArcSec() << endl;
28 // Example to convert 2.3 arcmin to radian - we use the conversion operator
29 double vam = 2.3;
30 cout << "Angle arcmin= " << vam << " ->rad= "
31 << (double)Angle(vam, Angle::ArcMin) << endl;
32 \endcode
33
34*/
35
36Angle::Angle(double val, Angle::AngleUnit un)
37{
38 switch (un) {
39 case Angle::Radian :
40 _angrad = val;
41 break;
42 case Angle::Degree :
43 _angrad = val*_deg2rad;
44 break;
45 case Angle::ArcMin :
46 _angrad = val/_rad2min;
47 break;
48 case Angle::ArcSec :
49 _angrad = val/_rad2sec;
50 break;
51 default:
52 _angrad = val;
53 break;
54 }
55}
56
57// 3-D Geometry
58// B. Revenu, G. Le Meur 2000
59// DAPNIA/SPP (Saclay) / CEA LAL - IN2P3/CNRS (Orsay)
60
61/*!
62 \class SOPHYA::Vector3d
63 \ingroup SkyMap
64 \brief 3-D geometry.
65 All computations are made with angles in radians and with spherical
66 coordinates theta, phi.
67 Concerning Euler's angles, the reference is :
68
69 "Classical Mechanics" 2nd edition, H. Goldstein, Addison Wesley
70*/
71
72//! default constructor - unit vector along x direction
[764]73Vector3d::Vector3d()
74{
75 Setxyz(1.,0.,0.);
76}
[2973]77
78//! Constructor with specification of cartesian coordinates
[764]79Vector3d::Vector3d(double x, double y, double z)
80{
81 _x=x;
82 _y=y;
83 _z=z;
84 xyz2ThetaPhi();
85}
[2973]86//! Constructor: unit vector with direction (spherical coordinates) specification
[764]87Vector3d::Vector3d(double theta, double phi)
88{
[1177]89 // _theta=mod(theta,M_PI); // dans [0;pi]
90 // Version precedente fausse: _theta=M_PI est valide. Or mod(M_PI,M_PI)=0!
91 // De plus theta>pi ou <0 n'a pas de sens. Dominique Yvon
92 if( (theta<0.) || (theta>M_PI) )
93 { string exmsg = "Wrong initialisation of theta in Vector3d::Vector3d(double theta, double phi)";
94 throw( ParmError(exmsg) );
95 }
96 _theta=theta; // dans [0;pi]
[764]97 _phi=mod(phi,pi2); // dans [0;2pi]
98 ThetaPhi2xyz();
99}
[2973]100
101//! Constructor: unit vector with longitude-latitude specification
[764]102Vector3d::Vector3d(const LongLat& ll)
103{
104 _theta=ll.Theta(); // dans [0;pi]
105 _phi=ll.Phi(); // dans [0;2pi]
106 ThetaPhi2xyz();
107}
[2973]108
109//! Copy constructor
[764]110Vector3d::Vector3d(const Vector3d& v)
111{
112 _x=v._x;
113 _y=v._y;
114 _z=v._z;
115 _theta=v._theta;
116 _phi=v._phi;
117}
[2973]118
119//! Set/changes the vector direction (result is a unit vector)
120void Vector3d::SetThetaPhi(double theta, double phi)
[764]121{
122 _theta=mod(theta,M_PI);
123 _phi=mod(phi,pi2);
124 ThetaPhi2xyz();
125}
[2973]126
127//! Set/changes the vector specifying cartesian coordinates
[764]128void Vector3d::Setxyz(double x, double y, double z)
129{
130 _x=x;
131 _y=y;
132 _z=z;
133 xyz2ThetaPhi();
134}
135//++
136void Vector3d::ThetaPhi2xyz()
137//
138//--
139{
140 _x=sin(_theta)*cos(_phi);
141 _y=sin(_theta)*sin(_phi);
142 _z=cos(_theta);
143}
144//++
145void Vector3d::xyz2ThetaPhi()
146//
147//--
148{
149 double norm=this->Norm();
150 if( norm != 0. )
151 {
152 _theta=acos(_z/norm); // dans [0,Pi]
153 if( mod(_theta,M_PI) == 0. ) _phi=0.; // on est sur +-Oz, le vecteur z est en phi=0
154 // else _phi=acos(_x/sin(_theta)/norm)+M_PI*(_y<0);
155 else _phi=scangle(_y/sin(_theta)/norm,_x/sin(_theta)/norm);
156 }
157 else // vecteur nul
158 {
159 _theta=0.;
160 _phi=0.;
161 }
162}
[2973]163//! Normalize the vector (-> unit length) for non zero vectors
[764]164Vector3d& Vector3d::Normalize()
165{
166 double norm=this->Norm();
167 if( norm != 0. ) (*this)/=norm;
[2973]168 //DEL else cerr << "Division par zero" << endl;
[764]169 return *this;
170}
[2973]171
172//! Return the vector norm (length)
[764]173double Vector3d::Norm() const
174{
175 return sqrt(_x*_x+_y*_y+_z*_z);
176}
[2973]177
178//! Return the scalar (dot) product of the two vectors
[764]179double Vector3d::Psc(const Vector3d& v) const
180{
181 return _x*v._x+_y*v._y+_z*v._z;
182}
183//++
184double Vector3d::SepAngle(const Vector3d& v) const
185//
186// angular gap between 2 vectors in [0,Pi]
187//--
188{
189 double n1=this->Norm();
190 double n2=v.Norm();
191 double ret;
192 if( n1!=0. && n2!=0. ) ret=acos((this->Psc(v))/n1/n2);
193 else
194 {
195 cerr << "Division par zero" << endl;
196 ret=0.;
197 }
198 return ret;
199}
200//++
201Vector3d Vector3d::Vect(const Vector3d& v) const
202//
203// vector product
204//--
205{
206 double xo=_y*v._z-_z*v._y;
207 double yo=_z*v._x-_x*v._z;
208 double zo=_x*v._y-_y*v._x;
209 return Vector3d(xo,yo,zo);
210}
211//++
212Vector3d Vector3d::VperpPhi() const
213//
214// perpendicular vector, with equal phi
215//--
216{
217 double theta;
218 if( _theta != pi_over_2 ) theta=_theta+(0.5-(_theta>pi_over_2))*M_PI; // on tourne theta de +-pi/2
219 else theta=0.;
220 return Vector3d(theta,_phi);
221}
222//++
223Vector3d Vector3d::VperpTheta() const
224//
225// perpendicular vector with equal theta
226//--
[784]227{ cerr<< " Erreur in Vector3d::VperpTheta()"<<endl;
[764]228 throw PError("Vector3d::VperpTheta() - Logic Error DY/Reza 20/02/2000");
229 // Bug ??? (D. Yvon, Fevrier 2000)
230 // double phi=mod(_phi+pi_over_2,pi2); // on tourne phi de pi/2
231 // return Vector3d(_theta,phi);
232}
233
234Vector3d Vector3d::EPhi() const
235{
236 Vector3d temp;
237 if ( fabs(_z) == 1. ) // si on est en +- Oz
238 {
239 temp=Vector3d(1.,0.,0.);
240 }
241 else
242 {
243 Vector3d k(0,0,-1);
244 temp=this->Vect(k);
245 temp.Normalize();
246 }
247 return temp;
248}
249//++
250Vector3d Vector3d::ETheta() const
251//
252//--
253{
254 Vector3d temp=this->Vect(EPhi());
255 temp.Normalize();
256 return temp;
257}
258
259//++
260Vector3d Vector3d::Euler(double phi, double theta, double psi) const
261//
262// Euler's rotations
263//--
264{
265 double cpsi=cos(psi);
266 double ctheta=cos(theta);
267 double cphi=cos(phi);
268 double spsi=sin(psi);
269 double stheta=sin(theta);
270 double sphi=sin(phi);
271 double xnew=(cpsi*cphi-ctheta*sphi*spsi)*_x
272 +(cpsi*sphi+ctheta*cphi*spsi)*_y
273 +spsi*stheta*_z;
274 double ynew=(-spsi*cphi-ctheta*sphi*cpsi)*_x
275 +(-spsi*sphi+ctheta*cphi*cpsi)*_y
276 +cpsi*stheta*_z;
277 double znew=stheta*sphi*_x-stheta*cphi*_y+ctheta*_z;
278 return Vector3d(xnew,ynew,znew);
279}
280//++
281Vector3d Vector3d::InvEuler(double phi, double theta, double psi) const
282//
283// inverse rotation
284//--
285{
286 double cpsi=cos(psi);
287 double ctheta=cos(theta);
288 double cphi=cos(phi);
289 double spsi=sin(psi);
290 double stheta=sin(theta);
291 double sphi=sin(phi);
292 double xnew=(cpsi*cphi-ctheta*sphi*spsi)*_x
293 -(spsi*cphi+ctheta*sphi*cpsi)*_y
294 +sphi*stheta*_z;
295 double ynew=(cpsi*sphi+ctheta*cphi*spsi)*_x
296 +(-spsi*sphi+ctheta*cphi*cpsi)*_y
297 -cphi*stheta*_z;
298 double znew=stheta*spsi*_x+stheta*cpsi*_y+ctheta*_z;
299 return Vector3d(xnew,ynew,znew);
300}
301//++
[792]302Vector3d Vector3d::Rotate(const Vector3d& omega, double phi) const
[764]303//
304// rotation of angle phi around an axis omega (Maxwell's rule)
305//--
306{
307 Vector3d rotationaxis=omega;
308 rotationaxis.Normalize();
309 double n=this->Psc(rotationaxis);
310 Vector3d myself=*this;
311 Vector3d rotate=n*rotationaxis+(myself-n*rotationaxis)*cos(phi)-(myself^rotationaxis)*sin(phi);
312 return rotate;
313}
314//++
315void Vector3d::Print(ostream& os) const
316//
317//--
318{
319 os << "Vector3: (X,Y,Z)= (" << _x << ", " << _y << ", " << _z
320 << ") --- Theta,Phi= " << _theta << ", " << _phi << "\n"
321 << "Norme = " << this->Norm() << endl;
322}
323//++
324// Titre Operators
325//--
326//++
327Vector3d& Vector3d::operator += (const Vector3d& v)
328//
329//--
330{
331 *this=*this+v;
332 return *this;
333}
334//++
335Vector3d& Vector3d::operator -= (const Vector3d& v)
336//
337//--
338{
339 *this=*this-v;
340 return *this;
341}
342//++
343Vector3d& Vector3d::operator += (double d)
344//
345//--
346{
347 Setxyz(_x+d,_y+d,_z+d);
348 return *this;
349}
350//++
351Vector3d& Vector3d::operator /= (double d)
352//
353//--
354{
355 if( d != 0. ) Setxyz(_x/d,_y/d,_z/d);
356 else cerr << "Division par zero." << endl;
357 return *this;
358}
359//++
360Vector3d& Vector3d::operator *= (double d)
361//
362//--
363{
364 Setxyz(_x*d,_y*d,_z*d);
365 return *this;
366}
367//++
368Vector3d Vector3d::operator ^ (const Vector3d& v) const
369//
370// vector product
371//--
372{
373 return this->Vect(v);
374}
375//++
376Vector3d Vector3d::operator + (double d) const
377//
378//--
379{
380 return Vector3d(_x+d,_y+d,_z+d);
381}
382//++
383Vector3d Vector3d::operator + (const Vector3d& v) const
384//
385//--
386{
387 return Vector3d(_x+v._x,_y+v._y,_z+v._z);
388}
389//++
390Vector3d Vector3d::operator - (double d) const
391//
392//--
393{
394 return *this+(-d);
395}
396//++
397Vector3d Vector3d::operator - (const Vector3d& v) const
398//
399//--
400{
401 return *this+(v*(-1.));
402}
403//++
404Vector3d Vector3d::operator * (double d) const
405//
406//--
407{
408 return Vector3d(d*_x,d*_y,d*_z);
409}
410//++
411double Vector3d::operator * (const Vector3d& v) const
412//
413// dot product
414//--
415{
416 return this->Psc(v);
417}
418//++
419Vector3d Vector3d::operator / (double d) const
420//
421//--
422{
423 Vector3d ret=*this;
424 if( d != 0. ) ret/=d;
425 else cerr << "Division par zero." << endl;
426 return ret;
427}
428//++
429Vector3d& Vector3d::operator = (const Vector3d& v)
430//
431//--
432{
433 if( this != &v )
434 {
435 _x=v._x;
436 _y=v._y;
437 _z=v._z;
438 _theta=v._theta;
439 _phi=v._phi;
440 }
441 return *this;
442}
443//++
444bool Vector3d::operator == (const Vector3d& v)
445//
446//--
447{
448 return (this==&v);
449}
450
Note: See TracBrowser for help on using the repository browser.