source: Sophya/trunk/SophyaLib/Samba/circle.cc@ 1758

Last change on this file since 1758 was 1758, checked in by lemeur, 24 years ago

nouveau circle, pour ELDESTINO

File size: 7.8 KB
Line 
1#include <math.h>
2#include "circle.h"
3//++
4// Class Circle
5//
6// include circle.h math.h
7//--
8//++
9//
10// Links Parents
11//
12// Geometry
13//
14//--
15//++
16// Titre Constructors
17//--
18//++
19Circle::Circle()
20//
21//--
22{
23 UnitVector temp;
24 SetCircle(temp,M_PI/2.);
25}
26//++
27Circle::Circle(double theta, double phi, double aperture)
28//
29//--
30{
31 UnitVector temp(theta,phi);
32 SetCircle(temp,aperture);
33}
34//++
35Circle::Circle(double x, double y, double z, double aperture)
36//
37//--
38{
39 UnitVector temp(x,y,z);
40 SetCircle(temp,aperture);
41}
42//++
43Circle::Circle(const Vector3d& v, double aperture)
44//
45//--
46{
47 UnitVector temp=v;
48 SetCircle(temp,aperture);
49}
50//++
51Circle::Circle(const Circle& c)
52//
53// copy constructor
54//--
55{
56 UnitVector temp= c.Omega();
57 SetCircle(temp,c._angouv);
58}
59//++
60// Titre Public Methods
61//--
62//++
63void Circle::SetCircle(const UnitVector& temp, double aperture)
64//
65//--
66{
67 _spinunitaxis= temp;
68
69 _angouv = aperture;
70 _cangouv= cos(_angouv);
71 _sangouv= sin(_angouv);
72
73 _spinaxis=_spinunitaxis*fabs(_cangouv);
74
75 _theta =_spinunitaxis.Theta();
76 _ctheta= cos(_theta);
77 _stheta= sin(_theta);
78
79 _phi =_spinunitaxis.Phi();
80 _cphi= cos(_phi);
81 _sphi= sin(_phi);
82
83 _x= _spinunitaxis.X();
84 _y= _spinunitaxis.Y();
85 _z= _spinunitaxis.Z();
86}
87//++
88void Circle::SetSpinAxis(double theta, double phi)
89//
90//--
91{
92 UnitVector temp(theta,phi);
93 SetCircle(temp,_angouv);
94}
95//++
96void Circle::SetSpinAxis(const Vector3d& u)
97//
98//--
99{
100 UnitVector temp=u;
101 SetCircle(temp,_angouv);
102}
103//++
104void Circle::SetSpinAxis(double x, double y, double z)
105//
106//--
107{
108 UnitVector temp(x,y,z);
109 SetCircle(temp,_angouv);
110}
111//++
112void Circle::SetApertureAngle(double aperture)
113//
114//--
115{
116 SetCircle(_spinunitaxis,aperture);
117}
118//++
119void Circle::SetApertureAngle(const Circle& c)
120//
121//--
122{
123 SetCircle(_spinunitaxis,c._angouv);
124}
125
126//++
127bool Circle::Intersection(const Circle& c, double* psi) const
128//
129// psi contains 4 values of the intersection angles.
130// -1 if circles do not intersect
131// psi[0]=psi(i,j,0)
132// psi[1]=psi(i,j,1)
133// psi[2]=psi(j,i,0)
134// psi[3]=psi(j,i,1)
135//--
136{
137 double alphak=_angouv;
138 double alphal=c._angouv;
139 Vector3d ok=_spinaxis;
140 Vector3d ol=c._spinaxis;
141 double gamma=ok.SepAngle(ol);
142
143 if( fabs(alphak-alphal) < gamma && gamma <= (alphak+alphal) && this != &c )
144 {
145 // then the 2 circles intersect
146 double sg=sin(gamma),cg=cos(gamma);
147 double sak=sin(alphak),cak=cos(alphak);
148 double sal=sin(alphal),cal=cos(alphal);
149 double st=sin(_theta),ct=cos(_theta);
150 double stc=sin(c._theta),ctc=cos(c._theta);
151 double dphi=_phi-c._phi;
152 double sdphi=sin(dphi),cdphi=cos(dphi);
153 double sinusk=stc*sdphi/sg,cosinusk=(ctc*st-stc*ct*cdphi)/sg;
154 double sinusl=-st*sdphi/sg,cosinusl=(ct*stc-st*ctc*cdphi)/sg;
155 double gammaik=scangle(sinusk,cosinusk);
156 double gammail=scangle(sinusl,cosinusl);
157 double omegak=acos((cal-cak*cg)/sg/sak);
158 double omegal=acos((cak-cal*cg)/sg/sal);
159 psi[0]=fmod(gammaik-omegak+pi2,pi2);
160 psi[1]=fmod(gammaik+omegak+pi2,pi2);
161 psi[2]=fmod(gammail-omegal+pi2,pi2);
162 psi[3]=fmod(gammail+omegal+pi2,pi2);
163 if( psi[0] > psi[1] )
164 {
165 // psi[0]=psi(i,j,0)
166 // psi[1]=psi(i,j,1)
167 // psi[2]=psi(j,i,0)
168 // psi[3]=psi(j,i,1)
169 swap(psi[0],psi[1]);
170 swap(psi[2],psi[3]);
171 }
172 return true;
173 }
174 else
175 {
176 psi[0] = -1.;
177 psi[1] = -1.;
178 psi[2] = -1.;
179 psi[3] = -1.;
180 return false;
181 }
182}
183//++
184UnitVector Circle::ConvToSphere(double psi) const
185//
186// Return UnitVector corresponding to a given position donnee on the circle
187//--
188{
189 psi=mod(psi,pi2);
190 double xout, yout, zout;
191 double cosa=cos(_angouv);
192 double sina=sin(_angouv);
193 double cost=cos(_theta);
194 double sint=sin(_theta);
195 double cosphi=cos(_phi);
196 double sinphi=sin(_phi);
197 double cosp=cos(psi);
198 double sinp=sin(psi);
199 xout = cosa*sint*cosphi+sina*(sinphi*sinp-cost*cosphi*cosp);
200 yout = cosa*sint*sinphi-sina*(cosphi*sinp+cost*sinphi*cosp);
201 zout = cosa*cost+sina*sint*cosp;
202 return UnitVector(xout,yout,zout);
203}
204//++
205UnitVector Circle::TanOnCircle(double psi) const
206//
207// Return UnitVector corresponding to the tangent to the circle
208// at given position on the circle.
209//--
210{
211 psi=mod(psi,pi2);
212 double xout, yout, zout;
213 double cost=cos(_theta);
214 double sint=sin(_theta);
215 double cosphi=cos(_phi);
216 double sinphi=sin(_phi);
217 double cosp=cos(psi);
218 double sinp=sin(psi);
219 xout = cosp*sinphi+sinp*sint*cosphi;
220 yout = -cosp*cosphi+sinp*sint*sinphi;
221 zout = -sinp*cost;
222 return UnitVector(xout,yout,zout);
223}
224//++
225UnitVector Circle::EPhi(double psi) const
226//
227// Return the vector tangent to the sphere in the plane (xy)
228// at a given position on the circle.
229//--
230{
231 psi=mod(psi,pi2);
232 return ConvToSphere(psi).EPhi();
233}
234//++
235UnitVector Circle::ETheta(double psi) const
236//
237// Return the other tangent vector( orthogonal to EPhi)--
238// see previous method
239//--
240{
241 psi=mod(psi,pi2);
242 return ConvToSphere(psi).ETheta();
243}
244//++
245double Circle::SepAngleTanEPhi02PI(double psi) const
246//
247// Return separation angle in [0,2Pi] at a given position on the
248// circle and EPhi
249//--
250{
251 psi=mod(psi,pi2);
252 UnitVector pol=this->TanOnCircle(psi);
253 UnitVector ephi=this->EPhi(psi);
254 double angle=pol.SepAngle(ephi);
255 if( pol.Z() <= 0 ) angle=pi2-angle;
256 return angle;
257}
258//++
259void Circle::Print(ostream& os) const
260//
261//--
262{
263 os << "1 - Circle - Axe de Spin Unitaire : " << _spinunitaxis << endl;
264 os << "1 - Circle - Axe de Spin : " << _spinaxis << endl;
265 os << "2 - Circle - Angle d'ouverture : " << _angouv << endl;
266 os << "3 - Circle - Theta,Phi : " << _theta << "," << _phi << endl;
267 os << "4 - Circle - x,y,z : " << _x << "," << _y << "," << _z << endl;
268}
269//++
270//
271// inline double Theta() const
272// inline double Phi() const
273// inline double ApertureAngle() const
274// inline Vector3d Omega() const
275//--
276//++
277// Titre Operators
278//--
279
280Circle& Circle::operator=(const Circle& c)
281{
282 if( this != &c )
283 {
284 UnitVector temp(c.Omega());
285 SetCircle(temp,c.ApertureAngle());
286 }
287 return *this;
288}
289//++
290bool Circle::operator==(const Circle& c) const
291//
292//--
293{
294 bool flag;
295 if( this == &c ) flag=true;
296 else flag=false;
297 return flag;
298}
299//++
300bool Circle::operator!=(const Circle& c) const
301//
302//--
303{
304 return (bool)(1-(this->operator==(c)));
305}
306//
307bool Circle::intersection(const Circle* c) const
308{
309 double alphak= _angouv;
310 double alphal= c->_angouv;
311 Vector3d ok= _spinaxis;
312 Vector3d ol= c->_spinaxis;
313 double gamma= ok.SepAngle(ol);
314
315 if(fabs(alphak-alphal) < gamma && gamma <= (alphak+alphal) && this != c) {
316 return true;
317 } else {
318 return false;
319 }
320}
321//
322bool Circle::intersection(const Circle& c, double* psi) const
323{
324 double alphak= _angouv;
325 double alphal= c._angouv;
326 Vector3d ok= _spinaxis;
327 Vector3d ol= c._spinaxis;
328 double gamma= ok.SepAngle(ol);
329
330 if(fabs(alphak-alphal) < gamma && gamma <= (alphak+alphal) && this != &c) {
331
332 double sgamma= sin(gamma);
333 double cgamma= cos(gamma);
334
335 double sdphi= _sphi*c._cphi - _cphi*c._sphi;
336 double cdphi= _cphi*c._cphi + _sphi*c._sphi;
337
338 double ssk= c._stheta*sdphi/sgamma;
339 double csk= (c._ctheta*_stheta-c._stheta*_ctheta*cdphi)/sgamma;
340
341 double ssl= -_stheta*sdphi/sgamma;
342 double csl= (_ctheta*c._stheta-_stheta*c._ctheta*cdphi)/sgamma;
343
344 double ak= atan2(ssk,csk);
345 double al= atan2(ssl,csl);
346 double omegak= acos((c._cangouv-_cangouv*cgamma)/sgamma/_sangouv);
347 double omegal= acos((_cangouv-c._cangouv*cgamma)/sgamma/c._sangouv);
348
349 psi[0]= fmod(ak-omegak+pi2,pi2);
350 psi[1]= fmod(ak+omegak+pi2,pi2);
351 psi[2]= fmod(al-omegal+pi2,pi2);
352 psi[3]= fmod(al+omegal+pi2,pi2);
353
354 if(psi[0] > psi[1]) {
355 swap(psi[0],psi[1]);
356 swap(psi[2],psi[3]);
357 }
358 return true;
359
360 } else {
361 psi[0] = -1.;
362 psi[1] = -1.;
363 psi[2] = -1.;
364 psi[3] = -1.;
365 return false;
366 }
367}
Note: See TracBrowser for help on using the repository browser.