#java #algorithm #math #trigonometry
#java #алгоритм #математика #тригонометрия
Вопрос:
У меня есть вариант использования, когда мне нужно сгенерировать координаты GPS для покрытия определенной области (отмеченной списком координат GPS).
Итак, мне нужно сгенерировать координаты. У меня протестированы и реализованы следующие функции:
//determines wether a Waypoint is inside the specified area
public boolean isInsideArea(Waypoint waypoint)
public double distanceInKmBetweenGPSCoordinates(Waypoint from, Waypoint to)
public double[] calculateCoordinatesAfterMove(Waypoint waypoint, double dx, double dy)
Вот моя наивная реализация того, как генерировать координаты для квадрата (или приблизительно квадрата):
public static List<drone.Waypoint> addAutoGeneratedWaypoints(List<Waypoint> polygon_lat_long_pairs) {
List<Waypoint> waypoints = new ArrayList<>();
AreaTester tester = new GPSPolygonTester(polygon_lat_long_pairs);
GPSCoordinateCalculator coordinateCalculator = new GPSCoordinateCalculator();
CustomGPSMapper mapper = new CustomGPSMapper();
boolean finish = false;
String mode = "r";
Waypoint prev = polygon_lat_long_pairs.get(0);
int count = 0;
double distanceDown = mapper.distanceInKmBetweenGPSCoordinates(polygon_lat_long_pairs.get(2), polygon_lat_long_pairs.get(3));
double travelledDown = 0;
while (!finish) {
if (mode.equals("r")) {
double[] nextA = coordinateCalculator.calculateCoordinatesAfterMove(prev.getPosition().getLatitude(), prev.getPosition().getLongitude(), 5.0, 0.0);
Waypoint next = new DefaultWaypoint(nextA[0], nextA[1]);
if (tester.isInsideArea(next)) {
System.out.println("Waypoint was in area");
waypoints.add(next);
prev = next;
} else {
System.err.println("Left area, switching position");
mode = "l";
double[] nextB = coordinateCalculator.calculateCoordinatesAfterMove(prev.getPosition().getLatitude(), prev.getPosition().getLongitude(), 0.0, -3.0);
Waypoint next2 = new DefaultWaypoint(nextB[0], nextB[1]);
waypoints.add(next2);
travelledDown = mapper.distanceInKmBetweenGPSCoordinates(prev, next);
prev = next2;
}
count ;
} else {
double[] nextA = coordinateCalculator.calculateCoordinatesAfterMove(prev.getPosition().getLatitude(), prev.getPosition().getLongitude(), -5.0, 0.0);
Waypoint next = new DefaultWaypoint(nextA[0], nextA[1]);
if (tester.isInsideArea(next)) {
waypoints.add(next);
prev = next;
} else {
System.out.println("Left are, switching");
mode = "r";
double[] nextB = coordinateCalculator.calculateCoordinatesAfterMove(prev.getPosition().getLatitude(), prev.getPosition().getLongitude(), 0.0, -3.0);
Waypoint next2 = new DefaultWaypoint(nextB[0], nextB[1]);
waypoints.add(next2);
travelledDown = mapper.distanceInKmBetweenGPSCoordinates(prev, next);
prev = next2;
}
count ;
}
if (travelledDown >= distanceDown) {
finish = true;
}
}
List<de.dhbw.drone.waypoints.Waypoint> mapped = waypoints.stream().map(p -> new de.dhbw.drone.waypoints.Waypoint(p)).collect(Collectors.toList());
return mapped;
Я останавливаю алгоритм, когда он перемещается по правой / левой стороне квадрата.
Однако я испытываю трудности, если форма отмеченной области не является квадратной и имеет наклонные линии.
Поэтому мне пришлось бы двигаться по азимуту, как показано на этом изображении:
Когда я мог бы добавить этот угол к своему перемещению, я мог бы использовать этот алгоритм для каждой формы области, в результате чего получился следующий путь:
Кто-нибудь может мне помочь, как переместить расстояние в метрах под этим конкретным углом и как рассчитать этот угол между двумя координатами GPS и как рассчитать угол после поворота в сторону? (справа налево вместо слева направо и наоборот). Или это можно решить путем вычисления угла (point1, point2) и angle (point2, point1)?
Ответ №1:
Чтобы вычислить азимут от одной координаты к другой и указать точку на заданном расстоянии, вы можете использовать формулы из latlong page ( bearing
и destination point
разделов)
Вы можете использовать тот же подход, который обычно реализуется при растеризации 2d-полигонов.
Горизонтальные линии изображения непрерывны в памяти, поэтому заполнение горизонтальных линий является наиболее надежным способом.
В вашем случае вы можете использовать, например, линии на постоянной широте.
Отсортируйте вершины вашего земного многоугольника по широте и разделите диапазоны между значениями широты вершин, затем заполните полученные «трапеции» последовательностями точек (пример с плоскостью)
Иногда (сложный многоугольник и т.д.) Было бы проще использовать метод отклонения — генерировать точки сетки в выписанном прямоугольнике и игнорировать те, которые находятся за пределами многоугольника.