]> git.mxchange.org Git - simgear.git/blob - Math/fg_geodesy.cxx
Cygnus tools compatibility tweaks.
[simgear.git] / Math / fg_geodesy.cxx
1 // fg_geodesy.cxx -- routines to convert between geodetic and geocentric 
2 //                   coordinate systems.
3 //
4 // Copied and adapted directly from LaRCsim/ls_geodesy.c
5 //
6 // See below for the complete original LaRCsim comments.
7 //
8 // $Id$
9 // (Log is kept at end of this file)
10
11
12 #include <math.h>
13 #include <errno.h>
14
15 #include <Include/fg_constants.h>
16 #include <Math/fg_geodesy.hxx>
17 #include <Math/point3d.hxx>
18
19
20 // ONE_SECOND is pi/180/60/60, or about 100 feet at earths' equator
21 #define ONE_SECOND 4.848136811E-6
22
23
24 // fgGeocToGeod(lat_geoc, radius, *lat_geod, *alt, *sea_level_r)
25 //     INPUTS:  
26 //         lat_geoc     Geocentric latitude, radians, + = North
27 //         radius       C.G. radius to earth center (meters)
28 //
29 //     OUTPUTS:
30 //         lat_geod     Geodetic latitude, radians, + = North
31 //         alt          C.G. altitude above mean sea level (meters)
32 //         sea_level_r  radius from earth center to sea level at
33 //                      local vertical (surface normal) of C.G. (meters)
34
35
36 void fgGeocToGeod( double lat_geoc, double radius, double
37                    *lat_geod, double *alt, double *sea_level_r )
38 {
39     double t_lat, x_alpha, mu_alpha, delt_mu, r_alpha, l_point, rho_alpha;
40     double sin_mu_a, denom,delt_lambda, lambda_sl, sin_lambda_sl;
41
42     if( ( (FG_PI_2 - lat_geoc) < ONE_SECOND )        // near North pole
43         || ( (FG_PI_2 + lat_geoc) < ONE_SECOND ) )   // near South pole
44     {
45         *lat_geod = lat_geoc;
46         *sea_level_r = EQUATORIAL_RADIUS_M*E;
47         *alt = radius - *sea_level_r;
48     } else {
49         t_lat = tan(lat_geoc);
50         x_alpha = E*EQUATORIAL_RADIUS_M/sqrt(t_lat*t_lat + E*E);
51         double tmp = RESQ_M - x_alpha * x_alpha;
52         if ( tmp < 0.0 ) { tmp = 0.0; }
53         mu_alpha = atan2(sqrt(tmp),E*x_alpha);
54         if (lat_geoc < 0) mu_alpha = - mu_alpha;
55         sin_mu_a = sin(mu_alpha);
56         delt_lambda = mu_alpha - lat_geoc;
57         r_alpha = x_alpha/cos(lat_geoc);
58         l_point = radius - r_alpha;
59         *alt = l_point*cos(delt_lambda);
60
61         // check for domain error
62         if ( errno == EDOM ) {
63             cout << "Domain ERROR in fgGeocToGeod!!!!\n";
64             *alt = 0.0;
65         }
66
67         denom = sqrt(1-EPS*EPS*sin_mu_a*sin_mu_a);
68         rho_alpha = EQUATORIAL_RADIUS_M*(1-EPS)/
69             (denom*denom*denom);
70         delt_mu = atan2(l_point*sin(delt_lambda),rho_alpha + *alt);
71         *lat_geod = mu_alpha - delt_mu;
72         lambda_sl = atan( E*E * tan(*lat_geod) ); // SL geoc. latitude
73         sin_lambda_sl = sin( lambda_sl );
74         *sea_level_r = 
75             sqrt(RESQ_M / (1 + ((1/(E*E))-1)*sin_lambda_sl*sin_lambda_sl));
76
77         // check for domain error
78         if ( errno == EDOM ) {
79             cout << "Domain ERROR in fgGeocToGeod!!!!\n";
80             *sea_level_r = 0.0;
81         }
82     }
83
84 }
85
86
87 // fgGeodToGeoc( lat_geod, alt, *sl_radius, *lat_geoc )
88 //     INPUTS:  
89 //         lat_geod     Geodetic latitude, radians, + = North
90 //         alt          C.G. altitude above mean sea level (meters)
91 //
92 //     OUTPUTS:
93 //         sl_radius    SEA LEVEL radius to earth center (meters)
94 //                      (add Altitude to get true distance from earth center.
95 //         lat_geoc     Geocentric latitude, radians, + = North
96 //
97
98
99 void fgGeodToGeoc( double lat_geod, double alt, double *sl_radius,
100                       double *lat_geoc )
101 {
102     double lambda_sl, sin_lambda_sl, cos_lambda_sl, sin_mu, cos_mu, px, py;
103     
104     lambda_sl = atan( E*E * tan(lat_geod) ); // sea level geocentric latitude
105     sin_lambda_sl = sin( lambda_sl );
106     cos_lambda_sl = cos( lambda_sl );
107     sin_mu = sin(lat_geod);                  // Geodetic (map makers') latitude
108     cos_mu = cos(lat_geod);
109     *sl_radius = 
110         sqrt(RESQ_M / (1 + ((1/(E*E))-1)*sin_lambda_sl*sin_lambda_sl));
111     py = *sl_radius*sin_lambda_sl + alt*sin_mu;
112     px = *sl_radius*cos_lambda_sl + alt*cos_mu;
113     *lat_geoc = atan2( py, px );
114 }
115
116
117 /***************************************************************************
118
119         TITLE:  ls_geodesy
120         
121 ----------------------------------------------------------------------------
122
123         FUNCTION:       Converts geocentric coordinates to geodetic positions
124
125 ----------------------------------------------------------------------------
126
127         MODULE STATUS:  developmental
128
129 ----------------------------------------------------------------------------
130
131         GENEALOGY:      Written as part of LaRCSim project by E. B. Jackson
132
133 ----------------------------------------------------------------------------
134
135         DESIGNED BY:    E. B. Jackson
136         
137         CODED BY:       E. B. Jackson
138         
139         MAINTAINED BY:  E. B. Jackson
140
141 ----------------------------------------------------------------------------
142
143         MODIFICATION HISTORY:
144         
145         DATE    PURPOSE                                         BY
146         
147         930208  Modified to avoid singularity near polar region.        EBJ
148         930602  Moved backwards calcs here from ls_step.                EBJ
149         931214  Changed erroneous Latitude and Altitude variables to 
150                 *lat_geod and *alt in routine ls_geoc_to_geod.          EBJ
151         940111  Changed header files from old ls_eom.h style to ls_types, 
152                 and ls_constants.  Also replaced old DATA type with new
153                 SCALAR type.                                            EBJ
154
155         CURRENT RCS HEADER:
156
157 $Header$
158 $Log$
159 Revision 1.4  1998/11/20 01:00:36  curt
160 Patch in fgGeoc2Geod() to avoid a floating explosion.
161 point3d.hxx include math.h for FreeBSD
162
163 Revision 1.3  1998/11/11 00:18:36  curt
164 Check for domain error in fgGeoctoGeod()
165
166 Revision 1.2  1998/10/16 23:36:36  curt
167 c++-ifying.
168
169 Revision 1.1  1998/10/16 19:30:40  curt
170 Renamed .c -> .h so we can start adding c++ supporting routines.
171
172 Revision 1.6  1998/07/08 14:40:07  curt
173 polar3d.[ch] renamed to polar3d.[ch]xx, vector.[ch] renamed to vector.[ch]xx
174 Updated fg_geodesy comments to reflect that routines expect and produce
175   meters.
176
177 Revision 1.5  1998/04/25 22:06:23  curt
178 Edited cvs log messages in source files ... bad bad bad!
179
180 Revision 1.4  1998/01/27 00:47:59  curt
181 Incorporated Paul Bleisch's <pbleisch@acm.org> new debug message
182 system and commandline/config file processing code.
183
184 Revision 1.3  1998/01/19 19:27:12  curt
185 Merged in make system changes from Bob Kuehne <rpk@sgi.com>
186 This should simplify things tremendously.
187
188 Revision 1.2  1997/12/15 23:54:54  curt
189 Add xgl wrappers for debugging.
190 Generate terrain normals on the fly.
191
192 Revision 1.1  1997/07/31 23:13:14  curt
193 Initial revision.
194
195 Revision 1.1  1997/05/29 00:09:56  curt
196 Initial Flight Gear revision.
197
198  * Revision 1.5  1994/01/11  18:47:05  bjax
199  * Changed include files to use types and constants, not ls_eom.h
200  * Also changed DATA type to SCALAR type.
201  *
202  * Revision 1.4  1993/12/14  21:06:47  bjax
203  * Removed global variable references Altitude and Latitude.   EBJ
204  *
205  * Revision 1.3  1993/06/02  15:03:40  bjax
206  * Made new subroutine for calculating geodetic to geocentric; changed name
207  * of forward conversion routine from ls_geodesy to ls_geoc_to_geod.
208  *
209
210 ----------------------------------------------------------------------------
211
212         REFERENCES:
213
214                 [ 1]    Stevens, Brian L.; and Lewis, Frank L.: "Aircraft 
215                         Control and Simulation", Wiley and Sons, 1992.
216                         ISBN 0-471-61397-5                    
217
218
219 ----------------------------------------------------------------------------
220
221         CALLED BY:      ls_aux
222
223 ----------------------------------------------------------------------------
224
225         CALLS TO:
226
227 ----------------------------------------------------------------------------
228
229         INPUTS: 
230                 lat_geoc        Geocentric latitude, radians, + = North
231                 radius          C.G. radius to earth center, ft
232
233 ----------------------------------------------------------------------------
234
235         OUTPUTS:
236                 lat_geod        Geodetic latitude, radians, + = North
237                 alt             C.G. altitude above mean sea level, ft
238                 sea_level_r     radius from earth center to sea level at
239                                 local vertical (surface normal) of C.G.
240
241 --------------------------------------------------------------------------*/
242
243
244 // $Log$
245 // Revision 1.4  1998/11/20 01:00:36  curt
246 // Patch in fgGeoc2Geod() to avoid a floating explosion.
247 // point3d.hxx include math.h for FreeBSD
248 //
249 // Revision 1.3  1998/11/11 00:18:36  curt
250 // Check for domain error in fgGeoctoGeod()
251 //
252 // Revision 1.2  1998/10/16 23:36:36  curt
253 // c++-ifying.
254 //
255 // Revision 1.1  1998/10/16 19:30:40  curt
256 // Renamed .c -> .h so we can start adding c++ supporting routines.
257 //
258 // Revision 1.6  1998/07/08 14:40:07  curt
259 // polar3d.[ch] renamed to polar3d.[ch]xx, vector.[ch] renamed to vector.[ch]xx
260 // Updated fg_geodesy comments to reflect that routines expect and produce
261 //   meters.
262 //
263 // Revision 1.5  1998/04/25 22:06:23  curt
264 // Edited cvs log messages in source files ... bad bad bad!
265 //
266 // Revision 1.4  1998/01/27 00:47:59  curt
267 // Incorporated Paul Bleisch's <pbleisch@acm.org> new debug message
268 // system and commandline/config file processing code.
269 //
270 // Revision 1.3  1998/01/19 19:27:12  curt
271 // Merged in make system changes from Bob Kuehne <rpk@sgi.com>
272 // This should simplify things tremendously.
273 //
274 // Revision 1.2  1997/12/15 23:54:54  curt
275 // Add xgl wrappers for debugging.
276 // Generate terrain normals on the fly.
277 //
278 // Revision 1.1  1997/07/31 23:13:14  curt
279 // Initial revision.
280 //
281