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;
170 double rtmp = mECLoc.Magnitude(
eX,
eY);
173 if (0.0 == mECLoc.Magnitude())
192 double r = mECLoc.Magnitude();
198 double rtmp = mECLoc.Magnitude(
eX,
eY);
216 double rold = mECLoc.Magnitude();
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);
281void 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 };
367 mTl2ec = mTec2l.Transposed();
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;
This class implements a 3 element column vector.
double Magnitude(void) const
Length of the vector.
static constexpr double sign(double num)
void SetLongitude(double longitude)
Set the longitude.
const FGLocation & operator=(const FGColumnVector3 &v)
Sets this location via the supplied vector.
FGLocation(void)
Default constructor.
double GetRadius() const
Get the distance from the center of the earth in feet.
void SetPositionGeodetic(double lon, double lat, double height)
Sets the longitude, latitude and the distance above the reference spheroid.
double GetDistanceTo(double target_longitude, double target_latitude) const
Get the geodetic distance between the current location and a given location.
void SetRadius(double radius)
Set the distance from the center of the earth.
void SetPosition(double lon, double lat, double radius)
Sets the longitude, latitude and the distance from the center of the earth.
double GetSeaLevelRadius(void) const
Get the sea level radius in feet below the current location.
void SetLatitude(double latitude)
Set the GEOCENTRIC latitude.
void SetEllipse(double semimajor, double semiminor)
Sets the semimajor and semiminor axis lengths for this planet.
double GetHeadingTo(double target_longitude, double target_latitude) const
Get the heading that should be followed from the current location to a given location along the short...