/// <summary> /// Находит кратчайшее расстояние (длина перпендикуляра) между точкой и заданной линией (высота не учитывается) /// Работает на малых расстояниях (считается, что поверхность плоская) /// </summary> public static double PerpendicularLength(GeoPoint lineX, GeoPoint lineY, GeoPoint p) { var azimuth = lineX.Azimuth(lineY) - lineX.Azimuth(p); var d = Distance(lineX, p); return(Math.Abs(d * Math.Sin(azimuth * Math.PI / 180))); }
/// <summary> /// Находит точку на заданной линии, являющуюся пересечением перпендикуляра опущенного из заданной точки к прямой (высота не учитывается) /// Работает на малых расстояниях (считается, что поверхность плоская) /// </summary> public static GeoPoint IntersectionLineAndPerpendicularFromPoint(GeoPoint lineX, GeoPoint lineY, GeoPoint p) { var azimuth = DegreesToRadians(lineX.Azimuth(lineY) - lineX.Azimuth(p)); var d = Distance(lineX, p); var h = Math.Abs(d * Math.Cos(azimuth)); return(lineX.RadialPoint(h, lineX.Azimuth(lineY))); }
private async Task <double> GoToPointUntilReachAzimuth(GeoPoint point, double azimuth, double precisionMet, double precisionDegr, CancellationToken cancel, int attemptsCnt = 1) { _logger.Info($"GoTo point {point}"); await GoToGlobAndWait(point, CallbackProgress <double> .Default, precisionMet, cancel).ConfigureAwait(false); _logger.Info("Start circling"); var attempts = 0; while (!cancel.IsCancellationRequested) { var location = GlobalPosition.Value; var currentAzimuth = point.Azimuth(location); _logger.Info($"Azimuth relative to the point {currentAzimuth:F1} deg"); if (IsInAzimuthLimits(currentAzimuth, azimuth, precisionDegr)) { attempts++; if (attempts >= attemptsCnt) { return(GeoMath.Distance(location, point)); } await Task.Delay(TimeSpan.FromMilliseconds(1500), cancel).ConfigureAwait(false); } await Task.Delay(TimeSpan.FromMilliseconds(250), cancel).ConfigureAwait(false); } return(0); }
/// <summary> /// Находит точку, являющуюся пересечением перпендикуляра опущенного от заданной точки к прямой, проходящей на заданном углу (высота не учитывается) /// Работает на малых расстояниях (считается, что поверхность плоская) /// </summary> public static GeoPoint IntersectionLineAndPerpendicularFromPoint(GeoPoint lineX, GeoPoint lineY, double alpha) { var azimuth = lineX.Azimuth(lineY) + alpha; var b = Distance(lineX, lineY); var c = Math.Abs(b / Math.Cos(DegreesToRadians(alpha))); return(lineX.RadialPoint(c, azimuth)); }
public static IEnumerable <GeoPoint> SplitIntoGeoPoints(GeoPoint startLocation, GeoPoint endLocation, int stepCount) { var dist = startLocation.DistanceTo(endLocation) / stepCount; stepCount = stepCount == 0 ? 1 : Math.Abs(stepCount); var vAlt = 0.0; if (startLocation.Altitude.HasValue && endLocation.Altitude.HasValue) { vAlt = (double)((endLocation.Altitude - startLocation.Altitude) / stepCount); } var a = startLocation.Azimuth(endLocation); for (var i = 0; i <= stepCount; i++) { yield return(startLocation.RadialPoint(i * dist, a).AddAltitude(vAlt * i)); } }
/// <summary> /// Возвращает точку, которая находится на луче, начало которого в точке <paramref name="p1"/> /// Луч проходит через точку p2. Расстояние между p1 и возвращаемой точкой равно указанному <paramref name="distance"/> /// <param name="distance"> Расстояние в метрах</param> /// </summary> public static GeoPoint VectorMove(this GeoPoint p1, GeoPoint p2, int distance) { return(p1.RadialPoint(distance, p1.Azimuth(p2))); }
public static double AngleBetween(this GeoPoint a, GeoPoint b) { return(a.Azimuth(b)); }