#include #include "circle.h" //++ // Class Circle // // include circle.h math.h //-- //++ // // Links Parents // // Geometry // //-- //++ // Titre Constructors //-- //++ Circle::Circle() // //-- { UnitVector temp; SetCircle(temp,M_PI/2.); } //++ Circle::Circle(double theta, double phi, double aperture) // //-- { UnitVector temp(theta,phi); SetCircle(temp,aperture); } //++ Circle::Circle(double x, double y, double z, double aperture) // //-- { UnitVector temp(x,y,z); SetCircle(temp,aperture); } //++ Circle::Circle(const Vector3d& v, double aperture) // //-- { UnitVector temp=v; SetCircle(temp,aperture); } //++ Circle::Circle(const Circle& c) // // copy constructor //-- { UnitVector temp=c.Omega(); SetCircle(temp,c._angouv); } //++ // Titre Public Methods //-- //++ void Circle::SetCircle(const UnitVector& temp, double aperture) // //-- { _spinunitaxis=temp; _angouv=aperture; _spinaxis=_spinunitaxis*fabs(cos(_angouv)); _theta=_spinunitaxis.Theta(); _phi=_spinunitaxis.Phi(); _x=_spinunitaxis.X(); _y=_spinunitaxis.Y(); _z=_spinunitaxis.Z(); } //++ void Circle::SetSpinAxis(double theta, double phi) // //-- { UnitVector temp(theta,phi); SetCircle(temp,_angouv); } //++ void Circle::SetSpinAxis(const Vector3d& u) // //-- { UnitVector temp=u; SetCircle(temp,_angouv); } //++ void Circle::SetSpinAxis(double x, double y, double z) // //-- { UnitVector temp(x,y,z); SetCircle(temp,_angouv); } //++ void Circle::SetApertureAngle(double aperture) // //-- { SetCircle(_spinunitaxis,aperture); } //++ void Circle::SetApertureAngle(const Circle& c) // //-- { SetCircle(_spinunitaxis,c._angouv); } //++ bool Circle::Intersection(const Circle& c, double* psi) const // // psi contains 4 values of the intersection angles. // -1 if circles do not intersect // psi[0]=psi(i,j,0) // psi[1]=psi(i,j,1) // psi[2]=psi(j,i,0) // psi[3]=psi(j,i,1) //-- { double alphak=_angouv; double alphal=c._angouv; Vector3d ok=_spinaxis; Vector3d ol=c._spinaxis; double gamma=ok.SepAngle(ol); if( fabs(alphak-alphal) < gamma && gamma <= (alphak+alphal) && this != &c ) { // then the 2 circles intersect double sg=sin(gamma),cg=cos(gamma); double sak=sin(alphak),cak=cos(alphak); double sal=sin(alphal),cal=cos(alphal); double st=sin(_theta),ct=cos(_theta); double stc=sin(c._theta),ctc=cos(c._theta); double dphi=_phi-c._phi; double sdphi=sin(dphi),cdphi=cos(dphi); double sinusk=stc*sdphi/sg,cosinusk=(ctc*st-stc*ct*cdphi)/sg; double sinusl=-st*sdphi/sg,cosinusl=(ct*stc-st*ctc*cdphi)/sg; double gammaik=scangle(sinusk,cosinusk); double gammail=scangle(sinusl,cosinusl); double omegak=acos((cal-cak*cg)/sg/sak); double omegal=acos((cak-cal*cg)/sg/sal); psi[0]=fmod(gammaik-omegak+pi2,pi2); psi[1]=fmod(gammaik+omegak+pi2,pi2); psi[2]=fmod(gammail-omegal+pi2,pi2); psi[3]=fmod(gammail+omegal+pi2,pi2); if( psi[0] > psi[1] ) { // psi[0]=psi(i,j,0) // psi[1]=psi(i,j,1) // psi[2]=psi(j,i,0) // psi[3]=psi(j,i,1) swap(psi[0],psi[1]); swap(psi[2],psi[3]); } return true; } else { psi[0] = -1.; psi[1] = -1.; psi[2] = -1.; psi[3] = -1.; return false; } } //++ UnitVector Circle::ConvToSphere(double psi) const // // Return UnitVector corresponding to a given position donnee on the circle //-- { psi=mod(psi,pi2); double xout, yout, zout; double cosa=cos(_angouv); double sina=sin(_angouv); double cost=cos(_theta); double sint=sin(_theta); double cosphi=cos(_phi); double sinphi=sin(_phi); double cosp=cos(psi); double sinp=sin(psi); xout = cosa*sint*cosphi+sina*(sinphi*sinp-cost*cosphi*cosp); yout = cosa*sint*sinphi-sina*(cosphi*sinp+cost*sinphi*cosp); zout = cosa*cost+sina*sint*cosp; return UnitVector(xout,yout,zout); } //++ UnitVector Circle::TanOnCircle(double psi) const // // Return UnitVector corresponding to the tangent to the circle // at given position on the circle. //-- { psi=mod(psi,pi2); double xout, yout, zout; double cost=cos(_theta); double sint=sin(_theta); double cosphi=cos(_phi); double sinphi=sin(_phi); double cosp=cos(psi); double sinp=sin(psi); xout = cosp*sinphi+sinp*sint*cosphi; yout = -cosp*cosphi+sinp*sint*sinphi; zout = -sinp*cost; return UnitVector(xout,yout,zout); } //++ UnitVector Circle::EPhi(double psi) const // // Return the vector tangent to the sphere in the plane (xy) // at a given position on the circle. //-- { psi=mod(psi,pi2); return ConvToSphere(psi).EPhi(); } //++ UnitVector Circle::ETheta(double psi) const // // Return the other tangent vector( orthogonal to EPhi)-- // see previous method //-- { psi=mod(psi,pi2); return ConvToSphere(psi).ETheta(); } //++ double Circle::SepAngleTanEPhi02PI(double psi) const // // Return separation angle in [0,2Pi] at a given position on the // circle and EPhi //-- { psi=mod(psi,pi2); UnitVector pol=this->TanOnCircle(psi); UnitVector ephi=this->EPhi(psi); double angle=pol.SepAngle(ephi); if( pol.Z() <= 0 ) angle=pi2-angle; return angle; } //++ void Circle::Print(ostream& os) const // //-- { os << "1 - Circle - Axe de Spin Unitaire : " << _spinunitaxis << endl; os << "1 - Circle - Axe de Spin : " << _spinaxis << endl; os << "2 - Circle - Angle d'ouverture : " << _angouv << endl; os << "3 - Circle - Theta,Phi : " << _theta << "," << _phi << endl; os << "4 - Circle - x,y,z : " << _x << "," << _y << "," << _z << endl; } //++ // // inline double Theta() const // inline double Phi() const // inline double ApertureAngle() const // inline Vector3d Omega() const //-- //++ // Titre Operators //-- Circle& Circle::operator=(const Circle& c) { if( this != &c ) { UnitVector temp(c.Omega()); SetCircle(temp,c.ApertureAngle()); } return *this; } //++ bool Circle::operator==(const Circle& c) const // //-- { bool flag; if( this == &c ) flag=true; else flag=false; return flag; } //++ bool Circle::operator!=(const Circle& c) const // //-- { return (bool)(1-(this->operator==(c))); }