private static ICoordinate GetV(ICoordinate p1, ICoordinate p2, double disNm) { return(EarthGeometry.GetV( p1.ToVector3D(), p2.ToVector3D(), disNm / EarthRadiusNm).ToLatLon()); }
/// <summary> /// Calculates the great circle path from x to y, and returns heading departing x. /// x and y should be unique. /// </summary> /// <exception cref="ArgumentException"></exception> public static double TrueHeading(ICoordinate x, ICoordinate y) { if (x.LatLonEquals(y)) { throw new ArgumentException(); } return(TrueHeading(GetW(x.ToVector3D(), y.ToVector3D()), x)); }
/// <summary> /// Calculates the true heading of the given vector, at the given coordinate. /// Return value is larger than 0 and smaller or equal to 360. Note: If v is /// orthogonal to the earth surface, the return value may be any number /// in that range. /// </summary> /// <exception cref="ArgumentException"></exception> public static double TrueHeading(Vector3D v, ICoordinate c) { if (v.R == 0) { throw new ArgumentException("Length of v cannot be 0."); } if (c.Lat >= 90.0) { return(180); } if (c.Lat <= -90.0) { return(360); } // Normal vector to tangent plane of earth at c var normal = c.ToVector3D(); // Projection of v onto the tangent plane var projection = ProjectOnPlane(v, normal); if (projection.R == 0) { return(360); } // vector that points towards north on the tangent plane var north = ProjectOnPlane(new Vector3D(0, 0, 1), normal).Normalize(); var east = (-normal).Cross(new Vector3D(0, 0, 1)).Normalize(); // Calculate angle var x = north.Dot(projection); var y = east.Dot(projection); var heading = Angles.ToDegree(Atan2(y, x)); var headingDeg = heading.Mod(360); return(headingDeg == 0.0 ? 360.0 : headingDeg); Vector3D ProjectOnPlane(Vector3D p, Vector3D unitNormalVec) { return(p - p.Dot(unitNormalVec) * unitNormalVec); } }
// delta: in degrees public double GetAirDistance(ICoordinate point1, ICoordinate point2, double delta = 1.0) { if (point1.LatLonEquals(point2, 1E-5)) { return(0.0); } v1 = point1.ToVector3D(); v2 = point2.ToVector3D(); double deltaAlpha = ToRadian(delta); // Total distance double r = EarthRadiusNm * SafeAcos(v1.Dot(v2)); // Total time required double time = Integrate(GetOneOverGS, 0.0, r, deltaAlpha * EarthRadiusNm); return(time * Ktas); }