46 #include "FGLocation.h"
55 : mECLoc(1.0, 0.0, 0.0), mCacheValid(false)
60 mLon = mLat = mRadius = 0.0;
61 mGeodLat = GeodeticAltitude = 0.0;
75 mLon = mLat = mRadius = 0.0;
76 mGeodLat = GeodeticAltitude = 0.0;
81 double sinLat = sin(lat);
82 double cosLat = cos(lat);
83 double sinLon = sin(lon);
84 double cosLon = cos(lon);
85 mECLoc = { radius*cosLat*cosLon,
93 : mECLoc(lv), mCacheValid(false)
98 mLon = mLat = mRadius = 0.0;
99 mGeodLat = GeodeticAltitude = 0.0;
108 : mECLoc(l.mECLoc), mCacheValid(l.mCacheValid)
115 mEllipseSet = l.mEllipseSet;
123 if (!mCacheValid)
return;
132 mGeodLat = l.mGeodLat;
133 GeodeticAltitude = l.GeodeticAltitude;
141 mCacheValid = l.mCacheValid;
142 mEllipseSet = l.mEllipseSet;
151 if (!mCacheValid)
return *
this;
160 mGeodLat = l.mGeodLat;
161 GeodeticAltitude = l.GeodeticAltitude;
182 mECLoc(eX) = rtmp*cos(longitude);
183 mECLoc(eY) = rtmp*sin(longitude);
200 double fac = r/rtmp*cos(latitude);
204 mECLoc(eX) = r*cos(latitude);
207 mECLoc(eZ) = r*sin(latitude);
220 mECLoc *= radius/rold;
229 double sinLat = sin(lat);
230 double cosLat = cos(lat);
231 double sinLon = sin(lon);
232 double cosLon = cos(lon);
234 mECLoc = { radius*cosLat*cosLon,
235 radius*cosLat*sinLon,
246 double slat = sin(lat);
247 double clat = cos(lat);
248 double RN = a / sqrt(1.0 - e2*slat*slat);
250 mECLoc(eX) = (RN + height)*clat*cos(lon);
251 mECLoc(eY) = (RN + height)*clat*sin(lon);
252 mECLoc(eZ) = ((1 - e2)*RN + height)*slat;
275 double cosLat = cos(mLat);
276 return a*ec/sqrt(1.0-e2*cosLat*cosLat);
281 void FGLocation::ComputeDerivedUnconditional(
void)
const
291 double sinLon, cosLon;
297 sinLon = mECLoc(eY)/rxy;
298 cosLon = mECLoc(eX)/rxy;
299 mLon = atan2(mECLoc(eY), mECLoc(eX));
303 double sinLat, cosLat;
304 if (mRadius == 0.0) {
310 GeodeticAltitude = -a;
314 mLat = atan2( mECLoc(eZ), rxy );
325 double s0 = fabs(mECLoc(eZ));
327 double c0 = ec * rxy;
328 double c02 = c0 * c0;
329 double s02 = s0 * s0;
330 double a02 = c02 + s02;
331 double a0 = sqrt(a02);
332 double a03 = a02 * a0;
333 double s1 = zc*a03 + c*s02*s0;
334 double c1 = rxy*a03 - c*c02*c0;
335 double cs0c0 = c*c0*s0;
336 double b0 = 1.5*cs0c0*((rxy*s0-zc*c0)*a0-cs0c0);
338 double cc = ec*(c1*a03-b0*c0);
339 mGeodLat = sign(mECLoc(eZ))*atan(s1 / cc);
340 double s12 = s1 * s1;
341 double cc2 = cc * cc;
342 double norm = sqrt(s12 + cc2);
344 sinLat = sign(mECLoc(eZ)) * s1 / norm;
345 GeodeticAltitude = (rxy*cc + s0*s1 - a*sqrt(ec2*s12 + cc2)) / norm;
348 sinLat = mECLoc(eZ)/mRadius;
349 cosLat = rxy/mRadius;
359 mTec2l = { -cosLon*sinLat, -sinLon*sinLat, cosLat,
360 -sinLon , cosLon , 0.0 ,
361 -cosLon*cosLat, -sinLon*cosLat, -sinLat };
392 double target_latitude)
const
395 double delta_lat_rad = target_latitude - mLat;
396 double delta_lon_rad = target_longitude - mLon;
398 double distance_a = pow(sin(0.5*delta_lat_rad), 2.0)
399 + (cos(mLat) * cos(target_latitude)
400 * (pow(sin(0.5*delta_lon_rad), 2.0)));
402 return 2.0 *
GetRadius() * atan2(sqrt(distance_a), sqrt(1.0 - distance_a));
422 double target_latitude)
const
425 double delta_lon_rad = target_longitude - mLon;
427 double Y = sin(delta_lon_rad) * cos(target_latitude);
428 double X = cos(mLat) * sin(target_latitude)
429 - sin(mLat) * cos(target_latitude) * cos(delta_lon_rad);
431 double heading_to_waypoint_rad = atan2(Y, X);
432 if (heading_to_waypoint_rad < 0) heading_to_waypoint_rad += 2.0*M_PI;
434 return heading_to_waypoint_rad;