9 #ifndef __GLAMER__geometry__
10 #define __GLAMER__geometry__
29 template <
typename T =
double>
34 r(r),theta(theta),phi(phi){};
55 if(&p ==
this)
return true;
56 return (r==p.r)*(theta==p.theta)*(phi==p.phi);
72 return r * p.r * ( cos(theta)*cos(p.theta)*cos(phi-p.phi) + sin(theta)*sin(p.theta) );
101 double s1 = sin((theta - p.theta)/2);
102 double s2 = sin((phi - p.phi)/2);
104 return 2*asin(sqrt( s1*s1 + cos(theta)*cos(p.theta)*s2*s2 ) );
119 return Point_3d<T>(-cos(phi)*sin(theta),-sin(theta)*sin(phi),cos(theta));
178 template <
typename T =
double>
182 v[0] = v[1] = v[2] = v[3] = 0;
184 Quaternion(T s,T x,T y,T z){
190 Quaternion(
const Quaternion &q){
202 Quaternion(SphericalPoint<T> sp){
207 Quaternion &operator=(
const Quaternion &q){
216 Quaternion operator*(
const Quaternion &q)
const{
218 v[0]*q.v[0] - v[1]*q.v[1] - v[2]*q.v[2] - v[3]*q.v[3],
219 v[0]*q.v[1] + v[1]*q.v[0] + v[2]*q.v[3] - v[3]*q.v[2],
220 v[0]*q.v[2] - v[1]*q.v[3] + v[2]*q.v[0] + v[3]*q.v[1],
221 v[0]*q.v[3] + v[1]*q.v[2] - v[2]*q.v[1] + v[3]*q.v[0]);
225 Quaternion conj()
const{
226 return Quaternion(v[0],-v[1],-v[2],-v[3]);
233 Quaternion inverse()
const{
234 return this->conj()/(v[0]*v[0] + v[1]*v[1] + v[2]*v[2] + v[3]*v[3]);
239 return sqrt(v[0]*v[0] + v[1]*v[1] + v[2]*v[2] + v[3]*v[3]);
243 Quaternion RotateX(T theta){
244 Quaternion R = q_x_rotation(theta);
245 return R*(*this)*R.conj();
248 Quaternion RotateY(T theta){
249 Quaternion R = q_y_rotation(theta);
250 return R*(*this)*R.conj();
253 Quaternion RotateZ(T theta){
254 Quaternion R = q_z_rotation(theta);
255 return R*(*this)*R.conj();
261 Quaternion RotateYZ(T theta,T phi){
262 Quaternion R = q_z_rotation(theta)*q_z_rotation(phi);
263 return R*(*this)*R.conj();
268 Quaternion Rotate(
const Quaternion &R)
const{
269 return R*(*this)*R.conj();
274 void RotInplace(
const Quaternion &R){
275 *
this = R*(*this)*R.conj();
281 ,
const Quaternion &R){
284 return q.to_point_3d();
289 static SphericalPoint<T> Rotate(
const SphericalPoint<T> &p
290 ,
const Quaternion &R){
293 return q.to_SpericalPoint();
296 Quaternion operator+(
const Quaternion &q)
const{
297 return Quaternion(v[0] + q.v[0] , v[1] + q.v[1] , v[2] + q.v[2] , v[3] + q.v[3] );
300 Quaternion operator-(
const Quaternion &q)
const{
301 return Quaternion(v[0] - q.v[0] , v[1] - q.v[1] , v[2] - q.v[2] , v[3] - q.v[3] );
305 Quaternion operator/(
double s)
const{
306 return Quaternion(v[0]/s,v[1]/s,v[2]/s,v[3]/s);
309 Quaternion operator*(
double s)
const{
310 return Quaternion(v[0]*s,v[1]*s,v[2]*s,v[3]*s);
315 return (*
this*q).to_point_3d();
319 T scalor(
const Quaternion &q)
const{
320 return v[1]*q.v[1] + v[2]*q.v[2] + v[3]*q.v[3];
329 SphericalPoint<T> to_SpericalPoint()
const{
330 SphericalPoint<T> sp;
331 sp.cartisianTOspherical(v+1);
339 T & operator[](
int i){
return v[i];}
340 const T &operator[](
int i)
const{
return v[i]; }
343 static Quaternion q_x_rotation(T theta){
344 return Quaternion(cos(theta/2),sin(theta/2),0,0);
347 static Quaternion q_y_rotation(T theta){
348 return Quaternion(cos(theta/2),0,-sin(theta/2),0);
351 static Quaternion q_z_rotation(T theta){
352 return Quaternion(cos(theta/2),0,0,sin(theta/2));
358 bool intersect(
const PosType a1[],
const PosType a2[]
359 ,
const PosType b1[],
const PosType b2[]);
361 int intersect(
const std::vector<Point_2d> &curve);
362 int intersections(
const std::vector<Point_2d> &curve,std::vector<Point_2d> &intersections,std::vector<std::pair<int,int> > &segments);
371 int orientation(
const PosType p[],
const PosType q[],
const PosType r[]);
375 bool onSegment(
const PosType p[],
const PosType q[],
const PosType r[]);
378 double AngleBetween2d(
double v1[],
double v2[]);
387 template <
typename T>
389 x[0] = r*cos(theta)*cos(phi);
390 x[1] = r*cos(theta)*sin(phi);
395 template <
typename T>
398 ,r*cos(theta)*sin(phi),r*sin(theta) );
402 template <
typename T>
404 r = sqrt( x[0]*x[0] + x[1]*x[1] +x[2]*x[2]);
405 theta = asin(x[2]/r);
406 phi = atan2(x[1],x[0]);
409 template <
typename T>
411 r = sqrt( x[0]*x[0] + x[1]*x[1] +x[2]*x[2]);
412 theta = asin(x[2]/r);
413 phi = atan2(x[1],x[0]);
422 template <
typename T>
427 double ct = cos(theta),st = sin(theta);
428 double cosphi = cos(phi - central.phi);
429 double so = sin(central.theta);
430 double co = cos(central.theta);
432 PosType k = 2/( 1 + so*st + co*ct*cosphi );
434 x[0] = k*(ct*sin(phi - central.phi));
435 x[1] = k*(co*st - so*ct*cosphi);
437 template <
typename T>
442 double ct = cos(theta),st = sin(theta);
443 double cosphi = cos(phi - central.phi);
444 double so = sin(central.theta);
445 double co = cos(central.theta);
447 PosType k = 2/( 1 + so*st + co*ct*cosphi );
449 x[0] = k*(ct*sin(phi - central.phi));
450 x[1] = k*(co*st - so*ct*cosphi);
453 template <
typename T>
457 double ct = cos(theta),st = sin(theta);
458 double cosphi = cos(phi - central.phi);
459 double so = sin(central.theta);
460 double co = cos(central.theta);
462 PosType k = 2/( 1 + so*st + co*ct*cosphi );
464 return Point_2d(k*(ct*sin(phi - central.phi)),k*(co*st - so*ct*cosphi));
474 template <
typename T>
479 double ct = cos(theta),st = sin(theta);
480 double cosphi = cos(phi - central.phi);
481 double so = sin(central.theta);
482 double co = cos(central.theta);
484 x[0] = ct*sin(phi - central.phi);
485 x[1] = co*st - so*ct*cosphi;
487 if(st*so + ct*co*cosphi < 0 ){
488 double s = sqrt( x[0]*x[0] + x[1]*x[0] );
494 template <
typename T>
498 double c = cos(theta);
499 return Point_2d( c*sin(phi - central.phi),
500 cos(central.theta)*sin(theta) - sin(central.theta)*c*cos(phi - central.phi) );
505 template <
typename T>
510 PosType rho = sqrt(x[0]*x[0] + x[1]*x[1]);
511 PosType c = asin(rho);
513 theta = asin( cos(c)*sin(central.theta) + x[1]*cos(central.theta) );
514 phi = central.phi + atan2(x[0] , cos(central.theta)*cos(c)
515 - x[1]*sin(central.theta) );
518 template <
typename T>
523 PosType rho = sqrt(x[0]*x[0] + x[1]*x[1]);
524 PosType c = asin(rho);
526 double at=cos(c)*sin(central.theta) + x[1]*cos(central.theta);
527 at = (at > 1) ? 1 : at;
528 at = (at < -1) ? -1 : at;
530 phi = central.phi + atan2(x[0] , cos(central.theta)*cos(c)
531 - x[1]*sin(central.theta) );
534 template <
typename T>
538 return atan2( sin(central.theta) * sin(phi - central.phi)
539 , cos(phi - central.phi) );
542 template <
typename T>
546 return atan2( cos(central.theta) * cos(theta) + sin(central.theta) * sin(central.theta)
547 *cos(phi - central.phi)
548 , -sin(phi - central.phi) * sin(phi - central.phi) );
552 template <
typename T>
556 PosType rho = sqrt(x[0]*x[0] + x[1]*x[1]);
557 if(rho==0)
return *
this;
559 PosType c = asin(rho);
560 T new_theta = asin( cos(c)*sin(theta) + x[1]*sin(c)*cos(theta)/rho );
561 T new_phi = phi + atan2(x[0]*sin(c),rho*cos(theta)*cos(c)
562 - x[1]*sin(theta)*sin(c) );
568 template <
typename T>
575 return sqrt( (x1[0]-x2[0])*(x1[0]-x2[0]) + (x1[1]-x2[1])*(x1[1]-x2[1])
576 + (x1[2]-x2[2])*(x1[2]-x2[2]) );
580 template <
typename T>
583 if(p1 == p2)
return 0;
584 double ans = sin(p1.theta)*sin(p2.theta) + cos(p1.theta)*cos(p2.theta)*cos(p1.phi-p2.phi);
585 if(fabs(ans) > 1)
return 0;
586 return acos(sin(p1.theta)*sin(p2.theta) + cos(p1.theta)*cos(p2.theta)*cos(p1.phi-p2.phi));
595 long operator[](
long i){
609 std::vector<Point_2d> DeInterset(
const std::vector<Point_2d> &points);
613 template <
typename T>
615 return os <<
"r: " << p.r <<
" theta: " << p.theta <<
" phi: " << p.phi;