1 #include <cmath>
2 #include <map>
3 using namespace std;
4 
5 #include "xpUtil.h"
6 
7 #include "drawArc.h"
8 #include "drawCircle.h"
9 #include "libannotate/libannotate.h"
10 #include "libprojection/ProjectionRectangular.h"
11 
12 //  Given an value X and radius d, this routine draws a half-circle in
13 //  the plane where X is constant.
14 static void
drawAltitudeHalfCirc(ProjectionRectangular * rect,const double X,const double d,bool Z_positive,const unsigned char color[3],const int thickness,const double spacing,const double magnify,Planet * planet,View * view,ProjectionBase * projection,multimap<double,Annotation * > & annotationMap)15 drawAltitudeHalfCirc(ProjectionRectangular *rect,
16                      const double X, const double d, bool Z_positive,
17                      const unsigned char color[3], const int thickness,
18                      const double spacing, const double magnify,
19                      Planet *planet, View *view, ProjectionBase *projection,
20                      multimap<double, Annotation *> &annotationMap)
21 {
22     double Y = d;
23     double Z = (1 - X*X - Y*Y);
24     if (fabs(Z) < 1e-5) Z = 0;
25     Z = (Z_positive ? sqrt(Z) : -sqrt(Z));
26 
27     double lat = M_PI_2 - acos(Z);
28     double lon = atan2(Y, X);
29     rect->RotateXYZ(lat, lon);
30 
31     for (double sinY = 1; sinY >= -1; sinY -= 0.1)
32     {
33         double prevLat = lat;
34         double prevLon = lon;
35 
36         Y = sin(M_PI_2 * sinY) * d;
37         Z = (1 - X*X - Y*Y);
38         if (fabs(Z) < 1e-5) Z = 0;
39         Z = (Z_positive ? sqrt(Z) : -sqrt(Z));
40 
41         lat = M_PI_2 - acos(Z);
42         lon = atan2(Y, X);
43         rect->RotateXYZ(lat, lon);
44 
45         drawArc(prevLat, prevLon, 1, lat, lon, 1, color, thickness,
46                 spacing * deg_to_rad, magnify,
47                 planet, view, projection, annotationMap);
48     }
49 }
50 
51 // Draw a circle centered at lat, lon with angular radius rad
52 void
drawCircle(const double lat,const double lon,const double rad,const unsigned char color[3],const int thickness,const double spacing,const double magnify,Planet * planet,View * view,ProjectionBase * projection,multimap<double,Annotation * > & annotationMap)53 drawCircle(const double lat, const double lon, const double rad,
54            const unsigned char color[3], const int thickness,
55            const double spacing, const double magnify,
56            Planet *planet, View *view, ProjectionBase *projection,
57            multimap<double, Annotation *> &annotationMap)
58 {
59     ProjectionRectangular *rect = new ProjectionRectangular(1, 0, 0);
60 
61     rect->SetXYZRotationMatrix(0, lat, -lon);
62 
63     drawAltitudeHalfCirc(rect, cos(rad), sin(rad), true,
64                          color, thickness, spacing, magnify, planet, view,
65                          projection, annotationMap);
66 
67     drawAltitudeHalfCirc(rect, cos(rad), sin(rad), false,
68                          color, thickness, spacing, magnify, planet, view,
69                          projection, annotationMap);
70 
71     delete rect;
72 }
73