public static double LineToPointDistance(CMGeoPoint point, CMGeoPoint RunwayBegin, CMGeoPoint RunwayEnd) { //поиск растояния от полосы до точки через высоту треугольника double a = CMGeoBase.GetDistance(RunwayEnd, point); double b = CMGeoBase.GetDistance(point, RunwayBegin); double c = CMGeoBase.GetDistance(RunwayBegin, RunwayEnd); double p = (a + b + c) / 2; double h = Math.Sqrt(p * (p - a) * (p - b) * (p - c)) * 2 / c; return(h); }
public static int GetZone(CMGeoPoint point, double Radius, int TakeoffSurfaceDirection, CMRunwayThreshold RunwayBegin, CMRunwayThreshold RunwayEnd) { double RunwayLength = GetDistance(RunwayBegin, RunwayEnd); List <PointLatLng> Plane1 = new List <PointLatLng>(); Plane1.Add(CMGeoBase.GetCoordinate(RunwayBegin, RunwayBegin.BackTrueCourse - 90, Radius).Coordinates); Plane1.Add(CMGeoBase.GetCoordinate(RunwayEnd, RunwayEnd.BackTrueCourse + 90, Radius).Coordinates); Plane1.Add(CMGeoBase.GetCoordinate(RunwayEnd, RunwayEnd.BackTrueCourse - 90, Radius).Coordinates); Plane1.Add(CMGeoBase.GetCoordinate(RunwayBegin, RunwayBegin.BackTrueCourse + 90, Radius).Coordinates); //Plane1.Add(CMGeoBase.OtstupVPP(Radius, 1, RunwayBegin.Coordinates)); //Plane1.Add(CMGeoBase.OtstupVPP(Radius, 1, RunwayEnd.Coordinates)); //Plane1.Add(CMGeoBase.OtstupVPP(Radius, 3, RunwayEnd.Coordinates)); //Plane1.Add(CMGeoBase.OtstupVPP(Radius, 3, RunwayBegin.Coordinates)); // ShowPolygonPoints(Plane1); if (CMGeoBase.IsPointInPolygon(Plane1, point.Coordinates)) { return(2); } else { //CMGeoPoint pointx = CMGeoBase.GetCoordinate(RunwayBegin,RunwayBegin. PointLatLng pointx = CMGeoBase.GetCoordinate(RunwayBegin.Coordinates, RunwayBegin.TrueCourse, RunwayLength / 2); PointLatLng LineBegin = CMGeoBase.GetCoordinate(pointx, RunwayBegin.TrueCourse + 90, Radius); PointLatLng LineEnd = CMGeoBase.GetCoordinate(pointx, RunwayBegin.TrueCourse - 90, Radius); //PointLatLng pointx_ = CMGeoBase.OtstupVPP(RunwayLength / 2, TakeoffSurfaceDirection, RunwayBegin.Coordinates); //PointLatLng LineBegin_ = CMGeoBase.OtstupVPP(Radius, 1, pointx); //PointLatLng LineEnd_ = CMGeoBase.OtstupVPP(Radius, 3, pointx); double dec = LineSide(point.Coordinates, LineBegin, LineEnd); if (dec <= 0) { return(TakeoffSurfaceDirection == 2 ? 3 : 1); } else { return(TakeoffSurfaceDirection == 2 ? 1 : 3); } } }
public static double GetDistance(CMGeoPoint StartPoint, CMGeoPoint FinishPoint) { //double U1 = Math.Atan((1 - alfa) * Math.Tan(StartPoint.LatRad)); // запихнуть в функцию //double U2 = Math.Atan((1 - alfa) * Math.Tan(FinishPoint.LatRad)); // запихнуть в функцию double U1 = GetU(StartPoint.LatRad); // запихнуть в функцию double U2 = GetU(FinishPoint.LatRad); // запихнуть в функцию double L = FinishPoint.LngRad - StartPoint.LngRad; double lambda = L; double sigma = 0; // растояние между двумя точками на дополнительной сфере double sin_sigma = 0; double cos_sigma = 0; double cos_asimutEq_quad = 0; double cos_2_sigmaM = 0; for (int i = 0; i < 20; i++) { sin_sigma = Math.Sqrt(Math.Pow(Math.Cos(U2) * Math.Sin(lambda), 2) + Math.Pow(Math.Cos(U1) * Math.Sin(U2) - Math.Sin(U1) * Math.Cos(U2) * Math.Cos(lambda), 2)); //sin_sigma = Math.Sqrt((Math.Pow((Math.Cos(U2) * Math.Sin(lambda)), 2)) + Math.Pow((Math.Cos(U1) * Math.Sin(U2) - Math.Sin(U2) * Math.Cos(U1) * Math.Cos(lambda)), 2)); cos_sigma = Math.Sin(U1) * Math.Sin(U2) + Math.Cos(U1) * Math.Cos(U2) * Math.Cos(lambda); sigma = Math.Atan(sin_sigma / cos_sigma); double sin_asimutEq = Math.Cos(U1) * Math.Cos(U2) * Math.Sin(lambda) / sin_sigma; cos_asimutEq_quad = 1.0 - Math.Pow(sin_asimutEq, 2); cos_2_sigmaM = cos_sigma - 2.0 * Math.Sin(U1) * Math.Sin(U2) / cos_asimutEq_quad; double C = alfa / 16.0 * cos_asimutEq_quad * (4.0 + alfa * (4.0 - 3.0 * cos_asimutEq_quad)); lambda = L + (1.0 - C) * alfa * sin_asimutEq * (sigma + C * sin_sigma * (cos_2_sigmaM + C * cos_sigma * (-1.0 + 2.0 * Math.Pow(cos_2_sigmaM, 2)))); } double u_quad = cos_asimutEq_quad * Math.Pow(e2, 2); //double A = 1 + u_quad / 16384 * (4096 + u_quad * (-768 + u_quad * (320 - 175 * u_quad))); double B = u_quad / 1024 * (256 + u_quad * (-128 + u_quad * (74 - 47 * u_quad))); double delta_sigma = B * sin_sigma * (cos_2_sigmaM + 1.0 / 4.0 * B * (cos_sigma * (-1 + 2 * Math.Pow(cos_2_sigmaM, 2) - 1 / 6 * B * cos_2_sigmaM * (-3 + 4 * Math.Pow(sin_sigma, 2) * (-3 + 4 * Math.Pow(cos_2_sigmaM, 2)))))); return(b * (1 + u_quad / 16384 * (4096 + u_quad * (-768 + u_quad * (320 - 175 * u_quad)))) * (sigma - delta_sigma)); //return b * A * (sigma - delta_sigma); }
public static double GetDistance(CMGeoPoint RPoint, int zone, CMGeoPoint RunwayBegin, CMGeoPoint RunwayEnd) { //TODO убрать в класс точки //GeoCoordinate test = new GeoCoordinate(); GeoCoordinate sCoord = new GeoCoordinate(RunwayBegin.Lat, RunwayBegin.Lng); GeoCoordinate eCoord = new GeoCoordinate(RunwayEnd.Lat, RunwayEnd.Lng); double Fdistance = 0; GeoCoordinate randCoord = new GeoCoordinate(RPoint.Lat, RPoint.Lng); //var KTACoord = new GeoCoordinate(GPKTA.Lat, GPKTA.Lng); switch (zone) { case 3: Fdistance = GetDistance(RunwayEnd.Coordinates, RPoint.Coordinates); //= eCoord.GetDistanceTo(randCoord); //HeigthPlaneB(Fdistance); break; case 1: Fdistance = GetDistance(RunwayBegin.Coordinates, RPoint.Coordinates); //Fdistance = sCoord.GetDistanceTo(randCoord); //HeigthPlaneB(Fdistance); break; case 2: { Fdistance = LineToPointDistance(RPoint, RunwayBegin, RunwayEnd); //HeigthPlaneB(Fdistance); break; } default: break; } return(Fdistance); }
/// <summary> /// Получение новой точки на основании начальной координаты, азимута и растояния /// </summary> /// <param name="StartPoint">Начальная точка</param> /// <param name="asimut">азимут</param> /// <param name="distance">растояние от начальной точки</param> /// <returns></returns> public static CMGeoPoint GetCoordinateRad(CMGeoPoint StartPoint, double asimut, double distance) { /* * S - distance , растояние */ CMGeoPoint FinishPoint = new CMGeoPoint(); //double a = 6378137; //большая полуось элипсоида //double alfa = 1 / 298.257223563;//коэфициент сжатия элипсоида //double ro = 206264.80624; //double b = a * (1 - alfa); //малая полуось элипсоида, ~ 6356752.314245179497 //double B = StartPoint.Coordinates.Lat; //геодезическая широта // убрать переменную использовать StartPoint.Coordinates.Lat //double e = Math.Sqrt((Math.Pow(a, 2) - Math.Pow(b, 2)) / Math.Pow(a, 2));// первый эксцентритет //double e2 = Math.Sqrt((Math.Pow(a, 2) - Math.Pow(b, 2)) / Math.Pow(b, 2)); //double N = (a / Math.Sqrt(1 - Math.Pow(e1, 2) * Math.Pow(Math.Sin(CMBaseGeoPoint.DegreeToRad(B)), 2))); //6387718.2645889279 //6387825.05301 double u = ((distance / N(StartPoint.Coordinates.Lat)) * Math.Cos(asimut)); double v = ((distance / N(StartPoint.Coordinates.Lat)) * Math.Sin(asimut)); double pb = u * (1 + Math.Pow(v, 2) / 3); double pc = v * (1 - Math.Pow(u, 2) / 6); double fi = (StartPoint.Coordinates.Lat + CMBaseGeoPoint.ShowDegreeFraction(0, 0, pb * ro)); double tau = pc * Math.Tan(CMBaseGeoPoint.DegreeToRad(fi)); double lambda = pc * (1 / Math.Cos(CMBaseGeoPoint.DegreeToRad(fi))); double t = tau * (1 - Math.Pow(lambda, 2) / 6 - Math.Pow(tau, 2) / 6) * ro; double l = lambda * (1 - Math.Pow(tau, 2)) * ro; double d = pc * tau / 2 * (1 - Math.Pow(lambda, 2) / 12 - Math.Pow(tau, 2) / 6); double deltafi = pb - d; double V = 1 + Math.Pow(e2, 2) * Math.Pow(Math.Cos(CMBaseGeoPoint.DegreeToRad(StartPoint.Coordinates.Lat)), 2); double deltaB = V * deltafi * (1 - 3.0 / 4.0 * Math.Pow(e2, 2) * Math.Sin(StartPoint.Coordinates.Lat * 2) * deltafi - Math.Pow(e2, 2) / 2 * Math.Cos(StartPoint.Coordinates.Lat * 2) * Math.Pow(deltafi, 2)) * ro; FinishPoint.Coordinates.Lat = StartPoint.Coordinates.Lat + CMBaseGeoPoint.ShowDegreeFraction(0, 0, deltaB); FinishPoint.Coordinates.Lng = StartPoint.Coordinates.Lng + CMBaseGeoPoint.ShowDegreeFraction(0, 0, l); return(FinishPoint); }
public static double GetAsimut(CMGeoPoint StartPoint, CMGeoPoint FinishPoint, int AsimutType = 0) { //double U1 = Math.Atan((1 - alfa) * Math.Tan(StartPoint.LatRad)); // запихнуть в функцию //double U2 = Math.Atan((1 - alfa) * Math.Tan(FinishPoint.LatRad)); // запихнуть в функцию double U1 = GetU(StartPoint.LatRad); double U2 = GetU(FinishPoint.LatRad); double L = FinishPoint.LngRad - StartPoint.LngRad; double lambda = L; double sigma = 0; // растояние между двумя точками на дополнительной сфере double sin_sigma = 0; double cos_sigma = 0; double cos_asimutEq_quad = 0; double cos_2_sigmaM = 0; for (int i = 0; i < 20; i++) { sin_sigma = Math.Sqrt(Math.Pow(Math.Cos(U2) * Math.Sin(lambda), 2) + Math.Pow(Math.Cos(U1) * Math.Sin(U2) - Math.Sin(U1) * Math.Cos(U2) * Math.Cos(lambda), 2)); //sin_sigma = Math.Sqrt((Math.Pow((Math.Cos(U2) * Math.Sin(lambda)), 2)) + Math.Pow((Math.Cos(U1) * Math.Sin(U2) - Math.Sin(U2) * Math.Cos(U1) * Math.Cos(lambda)), 2)); cos_sigma = Math.Sin(U1) * Math.Sin(U2) + Math.Cos(U1) * Math.Cos(U2) * Math.Cos(lambda); sigma = Math.Atan(sin_sigma / cos_sigma); double sin_asimutEq = Math.Cos(U1) * Math.Cos(U2) * Math.Sin(lambda) / sin_sigma; cos_asimutEq_quad = 1.0 - Math.Pow(sin_asimutEq, 2); cos_2_sigmaM = cos_sigma - 2.0 * Math.Sin(U1) * Math.Sin(U2) / cos_asimutEq_quad; double C = alfa / 16.0 * cos_asimutEq_quad * (4.0 + alfa * (4.0 - 3.0 * cos_asimutEq_quad)); lambda = L + (1.0 - C) * alfa * sin_asimutEq * (sigma + C * sin_sigma * (cos_2_sigmaM + C * cos_sigma * (-1.0 + 2.0 * Math.Pow(cos_2_sigmaM, 2)))); } double asimut12 = Math.Atan2((Math.Cos(U2) * Math.Sin(lambda)), (Math.Cos(U1) * Math.Sin(U2) - Math.Sin(U1) * Math.Cos(U2) * Math.Cos(lambda))); //азимут прямой с 1 на 2 double asimut21 = Math.Atan2((Math.Cos(U1) * Math.Sin(lambda)), (-Math.Sin(U1) * Math.Cos(U2) + Math.Cos(U1) * Math.Sin(U2) * Math.Cos(lambda))); //азимут обратный с 2 на 1 //asimut12 = Math.Atan((Math.Cos(U2) * Math.Sin(lambda)) / (Math.Cos(U1) * Math.Sin(U2) - Math.Sin(U1) * Math.Cos(U2) * Math.Cos(lambda))); //asimut21 = Math.Atan((Math.Cos(U1) * Math.Sin(lambda)) / (-Math.Sin(U1) * Math.Cos(U2) + Math.Cos(U1) * Math.Sin(U2) * Math.Cos(lambda))); //double a12 = asimut12 * 180 / Math.PI * 2; // double a21 = asimut21 * 180 / Math.PI; //return asimut12 * 180 / Math.PI * 2; double Asimut = 0.0; if (AsimutType == 0) { Asimut = asimut12 * 180 / Math.PI; } else { Asimut = asimut21 * 180 / Math.PI; Asimut += (Asimut >= 180) ? -180 : 180; } if (Asimut < 0) { Asimut = Asimut + 360; } return(Asimut); }