GLAMERDOC++
Gravitational Lensing Code Library
Loading...
Searching...
No Matches
geometry.h
1//
2// geometry.h
3// GLAMER
4//
5// Created by bmetcalf on 7/24/14.
6//
7//
8
9#ifndef __GLAMER__geometry__
10#define __GLAMER__geometry__
11
12#include <iostream>
13#include <array>
14#include "standard.h"
15#include "point.h"
16//
17// geometry.h
18// GLAMER
19//
20// Created by bmetcalf on 7/23/14.
21//
22//
23namespace Utilities {
24
26namespace Geometry{
27
29template <typename T = double>
31
32public:
33 SphericalPoint(T r,T theta,T phi):
34 r(r),theta(theta),phi(phi){};
35 SphericalPoint():r(0),theta(0),phi(0){};
37 TOspherical(x);
38 }
39
40 SphericalPoint & operator=(const SphericalPoint &p){
41 if(&p != this){
42 r = p.r;
43 theta = p.theta;
44 phi = p.phi;
45 }
46 return *this;
47 }
48
49 SphericalPoint & operator=(Point_3d<T> &x){
50 TOspherical(x);
51 return *this;
52 }
53
54 bool operator==(const SphericalPoint &p) const{
55 if(&p == this) return true;
56 return (r==p.r)*(theta==p.theta)*(phi==p.phi);
57 }
58
59
60 T r;
61 T theta;
62 T phi;
63
65 void TOcartisian(T x[]) const;
67
68 void cartisianTOspherical(T const x[]);
69 void TOspherical(Point_3d<T> &x);
70
72 ,T x[]) const;
73 void StereographicProjection(const SphericalPoint &central,Point_2d &x) const;
75
77 ,T x[]) const;
79 void InverseOrthographicProjection(const SphericalPoint &central,T const x[]);
82
83
86 double s1 = sin((theta - p.theta)/2);
87 double s2 = sin((phi - p.phi)/2);
88
89 return 2*asin(sqrt( s1*s1 + cos(theta)*cos(p.theta)*s2*s2 ) );
90 }
91
96
101
102 // returns the unit theta vector
103 Point_3d<T> theta_hat() const{
104 Point_3d<T> p;
105 p[0] = -sin(theta)*cos(phi);
106 p[1] = -sin(theta)*sin(phi);
107 p[2] = cos(theta);
108
109 return p;
110 }
111
112 // returns the unit phi vector
113 Point_3d<T> phi_hat() const{
114 Point_3d<T> p;
115 p[0] = -sin(phi);
116 p[1] = cos(phi);
117 p[2] = 0;
118
119 return p;
120 }
121
122};
123
124
173template <typename T = double>
174class Quaternion{
175public:
176 Quaternion(){
177 v[0] = v[1] = v[2] = v[3] = 0;
178 }
179 Quaternion(T s,T x,T y,T z){
180 v[0] = s;
181 v[1] = x;
182 v[2] = y;
183 v[3] = z;
184 }
185 Quaternion(const Quaternion &q){
186 v[0] = q.v[0];
187 v[1] = q.v[1];
188 v[2] = q.v[2];
189 v[3] = q.v[3];
190 }
191 Quaternion(Point_3d<T> p){
192 v[0] = 0;
193 v[1] = p[0];
194 v[2] = p[1];
195 v[3] = p[2];
196 }
197 Quaternion(SphericalPoint<T> sp){
198 sp.TOcartisian(v+1);
199 v[0] = 0;
200 }
201
202 Quaternion &operator=(const Quaternion &q){
203 v[0] = q.v[0];
204 v[1] = q.v[1];
205 v[2] = q.v[2];
206 v[3] = q.v[3];
207
208 return *this;
209 }
210
211 Quaternion operator*(const Quaternion &q) const{
212 return Quaternion(
213 v[0]*q.v[0] - v[1]*q.v[1] - v[2]*q.v[2] - v[3]*q.v[3],
214 v[0]*q.v[1] + v[1]*q.v[0] + v[2]*q.v[3] - v[3]*q.v[2],
215 v[0]*q.v[2] - v[1]*q.v[3] + v[2]*q.v[0] + v[3]*q.v[1],
216 v[0]*q.v[3] + v[1]*q.v[2] - v[2]*q.v[1] + v[3]*q.v[0]);
217 }
218
220 Quaternion conj() const{
221 return Quaternion(v[0],-v[1],-v[2],-v[3]);
222 }
228 Quaternion inverse() const{
229 return this->conj()/(v[0]*v[0] + v[1]*v[1] + v[2]*v[2] + v[3]*v[3]);
230 }
231
233 double norm() const{
234 return sqrt(v[0]*v[0] + v[1]*v[1] + v[2]*v[2] + v[3]*v[3]);
235 }
236
238 Quaternion RotateX(T theta){
239 Quaternion R = q_x_rotation(theta);
240 return R*(*this)*R.conj();
241 }
243 Quaternion RotateY(T theta){
244 Quaternion R = q_y_rotation(theta);
245 return R*(*this)*R.conj();
246 }
248 Quaternion RotateZ(T theta){
249 Quaternion R = q_z_rotation(theta);
250 return R*(*this)*R.conj();
251 }
256 Quaternion RotateYZ(T theta,T phi){
257 Quaternion R = q_z_rotation(theta)*q_z_rotation(phi);
258 return R*(*this)*R.conj();
259 }
260
263 Quaternion Rotate(const Quaternion &R) const{
264 return R*(*this)*R.conj();
265 }
266
269 void RotInplace(const Quaternion &R){
270 *this = R*(*this)*R.conj();
271 }
272
273
275 static Point_3d<T> Rotate(const Point_3d<T> &p
276 ,const Quaternion &R){
277 Quaternion q(p);
278 q.RotInplace(R);
279 return q.to_point_3d();
280 }
281
283
284 static SphericalPoint<T> Rotate(const SphericalPoint<T> &p
285 ,const Quaternion &R){
286 Quaternion q(p);
287 q.RotInplace(R);
288 return q.to_SpericalPoint();
289 }
290
291 Quaternion operator+(const Quaternion &q) const{
292 return Quaternion(v[0] + q.v[0] , v[1] + q.v[1] , v[2] + q.v[2] , v[3] + q.v[3] );
293
294 }
295 Quaternion operator-(const Quaternion &q) const{
296 return Quaternion(v[0] - q.v[0] , v[1] - q.v[1] , v[2] - q.v[2] , v[3] - q.v[3] );
297 }
298
300 Quaternion operator/(double s) const{
301 return Quaternion(v[0]/s,v[1]/s,v[2]/s,v[3]/s);
302 }
304 Quaternion operator*(double s) const{
305 return Quaternion(v[0]*s,v[1]*s,v[2]*s,v[3]*s);
306 }
307
309 Point_3d<T> cross(const Quaternion &q) const{
310 return (*this*q).to_point_3d();
311 }
312
314 T scalor(const Quaternion &q) const{
315 return v[1]*q.v[1] + v[2]*q.v[2] + v[3]*q.v[3];
316 }
317
319 Point_3d<T> to_point_3d() const{
320 return Point_3d<T>(v[1],v[2],v[3]);
321 }
322
324 SphericalPoint<T> to_SpericalPoint() const{
325 SphericalPoint<T> sp;
326 sp.cartisianTOspherical(v+1);
327 return sp;
328 }
329
330
332 T v[4];
334 T & operator[](int i){return v[i];}
335
337 static Quaternion q_x_rotation(T theta){
338 return Quaternion(cos(theta/2),sin(theta/2),0,0);
339 }
341 static Quaternion q_y_rotation(T theta){
342 return Quaternion(cos(theta/2),0,-sin(theta/2),0);
343 }
345 static Quaternion q_z_rotation(T theta){
346 return Quaternion(cos(theta/2),0,0,sin(theta/2));
347 }
348
349};
350
352bool intersect(const PosType a1[],const PosType a2[]
353 ,const PosType b1[],const PosType b2[]);
355int intersect(const std::vector<Point_2d> &curve);
356int intersections(const std::vector<Point_2d> &curve,std::vector<Point_2d> &intersections,std::vector<std::pair<int,int> > &segments);
357
365int orientation(const PosType p[],const PosType q[],const PosType r[]);
369bool onSegment(const PosType p[], const PosType q[], const PosType r[]);
370
372double AngleBetween2d(double v1[],double v2[]);
377//int incurve(PosType x[],std::vector<double *> &curve);
378
379}
380}
381
382namespace Utilities {
383namespace Geometry{
384
386template <typename T>
388 x[0] = r*cos(theta)*cos(phi);
389 x[1] = r*cos(theta)*sin(phi);
390 x[2] = r*sin(theta);
391}
392
394template <typename T>
396 return Point_3d<T>(r*cos(theta)*cos(phi)
397 ,r*cos(theta)*sin(phi),r*sin(theta) );
398}
399
401template <typename T>
403 r = sqrt( x[0]*x[0] + x[1]*x[1] +x[2]*x[2]);
404 theta = asin(x[2]/r);
405 phi = atan2(x[1],x[0]);
406}
407
408template <typename T>
410 r = sqrt( x[0]*x[0] + x[1]*x[1] +x[2]*x[2]);
411 theta = asin(x[2]/r);
412 phi = atan2(x[1],x[0]);
413}
414
415
421template <typename T>
423 const SphericalPoint<T> &central
424 ,T x[]
425) const{
426 double ct = cos(theta),st = sin(theta);
427 double cosphi = cos(phi - central.phi);
428 double so = sin(central.theta);
429 double co = cos(central.theta);
430
431 PosType k = 2/( 1 + so*st + co*ct*cosphi );
432
433 x[0] = k*(ct*sin(phi - central.phi));
434 x[1] = k*(co*st - so*ct*cosphi);
435}
436template <typename T>
438 const SphericalPoint<T> &central
439 ,Point_2d &x
440) const{
441 double ct = cos(theta),st = sin(theta);
442 double cosphi = cos(phi - central.phi);
443 double so = sin(central.theta);
444 double co = cos(central.theta);
445
446 PosType k = 2/( 1 + so*st + co*ct*cosphi );
447
448 x[0] = k*(ct*sin(phi - central.phi));
449 x[1] = k*(co*st - so*ct*cosphi);
450}
451
452template <typename T>
454 const SphericalPoint<T> &central
455) const{
456 double ct = cos(theta),st = sin(theta);
457 double cosphi = cos(phi - central.phi);
458 double so = sin(central.theta);
459 double co = cos(central.theta);
460
461 PosType k = 2/( 1 + so*st + co*ct*cosphi );
462
463 return Point_2d(k*(ct*sin(phi - central.phi)),k*(co*st - so*ct*cosphi));
464}
465
466
473template <typename T>
475 const SphericalPoint<T> &central
476 ,T x[]
477) const{
478 double ct = cos(theta),st = sin(theta);
479 double cosphi = cos(phi - central.phi);
480 double so = sin(central.theta);
481 double co = cos(central.theta);
482
483 x[0] = ct*sin(phi - central.phi);
484 x[1] = co*st - so*ct*cosphi;
485
486 if(st*so + ct*co*cosphi < 0 ){ // point is on the other hemosphere
487 double s = sqrt( x[0]*x[0] + x[1]*x[0] );
488 x[0] /=s;
489 x[1] /=s;
490 }
491}
492
493template <typename T>
495 const SphericalPoint<T> &central
496) const{
497 double c = cos(theta);
498 return Point_2d( c*sin(phi - central.phi),
499 cos(central.theta)*sin(theta) - sin(central.theta)*c*cos(phi - central.phi) );
500}
501
504template <typename T>
506 const SphericalPoint<T> &central
507 ,T const x[]
508){
509 PosType rho = sqrt(x[0]*x[0] + x[1]*x[1]);
510 PosType c = asin(rho);
511 r=1.0;
512 theta = asin( cos(c)*sin(central.theta) + x[1]*cos(central.theta) );
513 phi = central.phi + atan2(x[0] , cos(central.theta)*cos(c)
514 - x[1]*sin(central.theta) );
515}
516
517template <typename T>
519 const SphericalPoint<T> &central
520 ,const Point_2d &x
521){
522 PosType rho = sqrt(x[0]*x[0] + x[1]*x[1]);
523 PosType c = asin(rho);
524 r=1.0;
525 double at=cos(c)*sin(central.theta) + x[1]*cos(central.theta);
526 at = (at > 1) ? 1 : at;
527 at = (at < -1) ? -1 : at;
528 theta = asin( at );
529 phi = central.phi + atan2(x[0] , cos(central.theta)*cos(c)
530 - x[1]*sin(central.theta) );
531}
532
533template <typename T>
535 const SphericalPoint<T> &central
536){
537 return atan2( sin(central.theta) * sin(phi - central.phi)
538 , cos(phi - central.phi) );
539}
540
541template <typename T>
543 const SphericalPoint<T> &central
544){
545 return atan2( cos(central.theta) * cos(theta) + sin(central.theta) * sin(central.theta)
546 *cos(phi - central.phi)
547 , -sin(phi - central.phi) * sin(phi - central.phi) );
548}
549
551template <typename T>
553 const Point_2d &x
554){
555 PosType rho = sqrt(x[0]*x[0] + x[1]*x[1]);
556 if(rho==0) return *this;
557
558 PosType c = asin(rho);
559 T new_theta = asin( cos(c)*sin(theta) + x[1]*sin(c)*cos(theta)/rho );
560 T new_phi = phi + atan2(x[0]*sin(c),rho*cos(theta)*cos(c)
561 - x[1]*sin(theta)*sin(c) );
562
563 return SphericalPoint<T>(1,new_theta,new_phi);
564}
565
566template <typename T>
568 return Point_3d<T>(-sin(phi),cos(phi),0);
569}
570
571template <typename T>
573 return Point_3d<T>(-cos(phi)*sin(theta),-sin(theta)*sin(phi),cos(theta));
574}
575
577template <typename T>
579 ,const SphericalPoint<T> &p2){
580 T x1[3],x2[3];
581
582 p1.TOcartisian(x1);
583 p2.TOcartisian(x2);
584 return sqrt( (x1[0]-x2[0])*(x1[0]-x2[0]) + (x1[1]-x2[1])*(x1[1]-x2[1])
585 + (x1[2]-x2[2])*(x1[2]-x2[2]) );
586}
587
589template <typename T>
591 ,const SphericalPoint<T> &p2){
592 if(p1 == p2) return 0;
593 double ans = sin(p1.theta)*sin(p2.theta) + cos(p1.theta)*cos(p2.theta)*cos(p1.phi-p2.phi);
594 if(fabs(ans) > 1) return 0;
595 return acos(sin(p1.theta)*sin(p2.theta) + cos(p1.theta)*cos(p2.theta)*cos(p1.phi-p2.phi));
596}
597
598
600struct CYCLIC{
601 CYCLIC(long n):n(n){}
602
603 // returns the integer in bounds
604 long operator[](long i){
605 while(i<0) i+=n;
606 return i%n;
607 }
608
609 long n;
610};
611
612/* \brief finds the edge-wise concave hull of a complex curve
613
614 The returned curve will consist of segments of the edges of the original curve that form a closed
615 curve that does not cross itself and will enclose all the verticies.
616 */
617
618std::vector<Point_2d> DeInterset(const std::vector<Point_2d> &points);
619}
620}
621
622template <typename T>
623std::ostream &operator<<(std::ostream &os, Utilities::Geometry::SphericalPoint<T> const &p){
624 return os << "r: " << p.r << " theta: " << p.theta << " phi: " << p.phi;
625}
626
627
628#endif /* defined(__GLAMER__geometry__) */
represents a point in spherical coordinates, theta = 0 is equator
Definition geometry.h:30
Point_3d< T > unitPhi()
unit vector in phi direction
Definition geometry.h:567
void cartisianTOspherical(T const x[])
set the spherical coordinates of the point from the cartisian coordinates
Definition geometry.h:402
T OrthographicAnglePhi(const SphericalPoint &central)
the angle between the orthographic x-axis and the constant Phi curve
Definition geometry.h:542
T angular_separation(SphericalPoint &p)
angle between points. This uses the haversine formula that is more stable for small angles than the m...
Definition geometry.h:85
void OrthographicProjection(const SphericalPoint &central, T x[]) const
Calculates the orthographic projection of the point onto a plane.
Definition geometry.h:474
Point_3d< T > TOcartisian() const
output cartisian coordinates of the point
Definition geometry.h:395
Point_2d StereographicProjection(const SphericalPoint &central) const
Definition geometry.h:453
SphericalPoint< T > InverseOrthographicProjection(const Point_2d &x)
Definition geometry.h:552
void StereographicProjection(const SphericalPoint &central, Point_2d &x) const
Definition geometry.h:437
Point_3d< T > unitTheta()
unit vector in theta direction
Definition geometry.h:572
void StereographicProjection(const SphericalPoint &central, T x[]) const
Calculates the stereographic projection of the point onto a plane.
Definition geometry.h:422
void InverseOrthographicProjection(const SphericalPoint &central, T const x[])
Convert from an orthographic projection of the plane onto the unit sphere.
Definition geometry.h:505
void TOcartisian(T x[]) const
output Cartesian coordinates of the point
Definition geometry.h:387
T OrthographicAngleTheta(const SphericalPoint &central)
the angle between the orthographic x-axis and the constant theta curve
Definition geometry.h:534
Point_2d OrthographicProjection(const SphericalPoint &central) const
Definition geometry.h:494
void InverseOrthographicProjection(const SphericalPoint &central, const Point_2d &x)
Definition geometry.h:518
T AngleSeporation(const SphericalPoint< T > &p1, const SphericalPoint< T > &p2)
Angular seporation between points.
Definition geometry.h:590
T Seporation(const SphericalPoint< T > &p1, const SphericalPoint< T > &p2)
3 dimensional distance between points
Definition geometry.h:578
Definition utilities.h:39
Class for representing points or vectors in 2 dimensions. Not that the dereferencing operator is over...
Definition point.h:48
Class for representing points or vectors in 3 dimensions. Not that the dereferencing operator is over...
Definition point.h:883
used so that an index will not go out of bounds, ie. CYCLIC[0]=0, CYCLIC[n]=0, CYCLIC[-1]=n-1,...
Definition geometry.h:600