]> git.mxchange.org Git - simgear.git/blob - simgear/math/SGGeoc.hxx
b7d0a191cf695055820fba972aeec95ae1dde86b
[simgear.git] / simgear / math / SGGeoc.hxx
1 #ifndef SGGeoc_H
2 #define SGGeoc_H
3
4 #include <simgear/constants.h>
5  
6 // #define SG_GEOC_NATIVE_DEGREE
7
8 /// Class representing a geocentric location
9 class SGGeoc {
10 public:
11   /// Default constructor, initializes the instance to lat = lon = lat = 0
12   SGGeoc(void);
13   /// Initialize from a cartesian vector assumed to be in meters
14   /// Note that this conversion is relatively expensive to compute
15   SGGeoc(const SGVec3<double>& cart);
16   /// Initialize from a geodetic position
17   /// Note that this conversion is relatively expensive to compute
18   SGGeoc(const SGGeod& geod);
19
20   /// Factory from angular values in radians and radius in ft
21   static SGGeoc fromRadFt(double lon, double lat, double radius);
22   /// Factory from angular values in degrees and radius in ft
23   static SGGeoc fromDegFt(double lon, double lat, double radius);
24   /// Factory from angular values in radians and radius in m
25   static SGGeoc fromRadM(double lon, double lat, double radius);
26   /// Factory from angular values in degrees and radius in m
27   static SGGeoc fromDegM(double lon, double lat, double radius);
28
29   /// Return the geocentric longitude in radians
30   double getLongitudeRad(void) const;
31   /// Set the geocentric longitude from the argument given in radians
32   void setLongitudeRad(double lon);
33
34   /// Return the geocentric longitude in degrees
35   double getLongitudeDeg(void) const;
36   /// Set the geocentric longitude from the argument given in degrees
37   void setLongitudeDeg(double lon);
38
39   /// Return the geocentric latitude in radians
40   double getLatitudeRad(void) const;
41   /// Set the geocentric latitude from the argument given in radians
42   void setLatitudeRad(double lat);
43
44   /// Return the geocentric latitude in degrees
45   double getLatitudeDeg(void) const;
46   /// Set the geocentric latitude from the argument given in degrees
47   void setLatitudeDeg(double lat);
48
49   /// Return the geocentric radius in meters
50   double getRadiusM(void) const;
51   /// Set the geocentric radius from the argument given in meters
52   void setRadiusM(double radius);
53
54   /// Return the geocentric radius in feet
55   double getRadiusFt(void) const;
56   /// Set the geocentric radius from the argument given in feet
57   void setRadiusFt(double radius);
58
59 private:
60   /// This one is private since construction is not unique if you do
61   /// not know the units of the arguments, use the factory methods for
62   /// that purpose
63   SGGeoc(double lon, double lat, double radius);
64
65   /// The actual data, angles in degree, radius in meters
66   /// The rationale for storing the values in degrees is that most code places
67   /// in flightgear/terragear use degrees as a nativ input and output value.
68   /// The places where it makes sense to use radians is when we convert
69   /// to other representations or compute rotation matrices. But both tasks
70   /// are computionally intensive anyway and that additional 'toRadian'
71   /// conversion does not hurt too much
72   double _lon;
73   double _lat;
74   double _radius;
75 };
76
77 inline
78 SGGeoc::SGGeoc(void) :
79   _lon(0), _lat(0), _radius(0)
80 {
81 }
82
83 inline
84 SGGeoc::SGGeoc(double lon, double lat, double radius) :
85   _lon(lon), _lat(lat), _radius(radius)
86 {
87 }
88
89 inline
90 SGGeoc::SGGeoc(const SGVec3<double>& cart)
91 {
92   SGGeodesy::SGCartToGeoc(cart, *this);
93 }
94
95 inline
96 SGGeoc::SGGeoc(const SGGeod& geod)
97 {
98   SGVec3<double> cart;
99   SGGeodesy::SGGeodToCart(geod, cart);
100   SGGeodesy::SGCartToGeoc(cart, *this);
101 }
102
103 inline
104 SGGeoc
105 SGGeoc::fromRadFt(double lon, double lat, double radius)
106 {
107 #ifdef SG_GEOC_NATIVE_DEGREE
108   return SGGeoc(lon*SGD_RADIANS_TO_DEGREES, lat*SGD_RADIANS_TO_DEGREES,
109                 radius*SG_FEET_TO_METER);
110 #else
111   return SGGeoc(lon, lat, radius*SG_FEET_TO_METER);
112 #endif
113 }
114
115 inline
116 SGGeoc
117 SGGeoc::fromDegFt(double lon, double lat, double radius)
118 {
119 #ifdef SG_GEOC_NATIVE_DEGREE
120   return SGGeoc(lon, lat, radius*SG_FEET_TO_METER);
121 #else
122   return SGGeoc(lon*SGD_DEGREES_TO_RADIANS, lat*SGD_DEGREES_TO_RADIANS,
123                 radius*SG_FEET_TO_METER);
124 #endif
125 }
126
127 inline
128 SGGeoc
129 SGGeoc::fromRadM(double lon, double lat, double radius)
130 {
131 #ifdef SG_GEOC_NATIVE_DEGREE
132   return SGGeoc(lon*SGD_RADIANS_TO_DEGREES, lat*SGD_RADIANS_TO_DEGREES,
133                 radius);
134 #else
135   return SGGeoc(lon, lat, radius);
136 #endif
137 }
138
139 inline
140 SGGeoc
141 SGGeoc::fromDegM(double lon, double lat, double radius)
142 {
143 #ifdef SG_GEOC_NATIVE_DEGREE
144   return SGGeoc(lon, lat, radius);
145 #else
146   return SGGeoc(lon*SGD_DEGREES_TO_RADIANS, lat*SGD_DEGREES_TO_RADIANS,
147                 radius);
148 #endif
149 }
150
151 inline
152 double
153 SGGeoc::getLongitudeRad(void) const
154 {
155 #ifdef SG_GEOC_NATIVE_DEGREE
156   return _lon*SGD_DEGREES_TO_RADIANS;
157 #else
158   return _lon;
159 #endif
160 }
161
162 inline
163 void
164 SGGeoc::setLongitudeRad(double lon)
165 {
166 #ifdef SG_GEOC_NATIVE_DEGREE
167   _lon = lon*SGD_RADIANS_TO_DEGREES;
168 #else
169   _lon = lon;
170 #endif
171 }
172
173 inline
174 double
175 SGGeoc::getLongitudeDeg(void) const
176 {
177 #ifdef SG_GEOC_NATIVE_DEGREE
178   return _lon;
179 #else
180   return _lon*SGD_DEGREES_TO_RADIANS;
181 #endif
182 }
183
184 inline
185 void
186 SGGeoc::setLongitudeDeg(double lon)
187 {
188 #ifdef SG_GEOC_NATIVE_DEGREE
189   _lon = lon;
190 #else
191   _lon = lon*SGD_RADIANS_TO_DEGREES;
192 #endif
193 }
194
195 inline
196 double
197 SGGeoc::getLatitudeRad(void) const
198 {
199 #ifdef SG_GEOC_NATIVE_DEGREE
200   return _lat*SGD_DEGREES_TO_RADIANS;
201 #else
202   return _lat;
203 #endif
204 }
205
206 inline
207 void
208 SGGeoc::setLatitudeRad(double lat)
209 {
210 #ifdef SG_GEOC_NATIVE_DEGREE
211   _lat = lat*SGD_RADIANS_TO_DEGREES;
212 #else
213   _lat = lat;
214 #endif
215 }
216
217 inline
218 double
219 SGGeoc::getLatitudeDeg(void) const
220 {
221 #ifdef SG_GEOC_NATIVE_DEGREE
222   return _lat;
223 #else
224   return _lat*SGD_DEGREES_TO_RADIANS;
225 #endif
226 }
227
228 inline
229 void
230 SGGeoc::setLatitudeDeg(double lat)
231 {
232 #ifdef SG_GEOC_NATIVE_DEGREE
233   _lat = lat;
234 #else
235   _lat = lat*SGD_RADIANS_TO_DEGREES;
236 #endif
237 }
238
239 inline
240 double
241 SGGeoc::getRadiusM(void) const
242 {
243   return _radius;
244 }
245
246 inline
247 void
248 SGGeoc::setRadiusM(double radius)
249 {
250   _radius = radius;
251 }
252
253 inline
254 double
255 SGGeoc::getRadiusFt(void) const
256 {
257   return _radius*SG_METER_TO_FEET;
258 }
259
260 inline
261 void
262 SGGeoc::setRadiusFt(double radius)
263 {
264   _radius = radius*SG_FEET_TO_METER;
265 }
266
267 /// Output to an ostream
268 template<typename char_type, typename traits_type>
269 inline
270 std::basic_ostream<char_type, traits_type>&
271 operator<<(std::basic_ostream<char_type, traits_type>& s, const SGGeoc& g)
272 {
273   return s << "lon = " << g.getLongitudeDeg()
274            << ", lat = " << g.getLatitudeDeg()
275            << ", radius = " << g.getRadiusM();
276 }
277
278 #endif