Обсудить в форуме Комментариев 29Редактировать в вики
Угловая засечка — это нахождение положения точки по координатам двух исходных пунктов и значениям азимутов направлений с этих пунктов на определяемую точку.
Содержание |
В качестве модели Земли принимается сфера с радиусом R, равным среднему радиусу земного эллипсоида. Аналогом прямой линии на плоскости является геодезическая линия на поверхности. На сфере геодезическая линия — дуга большого круга.
Введём следующие обозначения:
Линейное расстояние по дуге большого круга s связано со сферическим расстоянием σ формулой s = R σ.
Решение любого вида засечек сводится к нахождению полярных координат искомой точки, т.е. начального направления и расстояния на неё с одного из исходных пунктов. На конечном этапе координаты находятся из решения прямой геодезической задачи. Поскольку в угловой засечке направления α₁₃ и α₂₃ уже заданы, остаётся определить расстояние σ₁₃ или σ₂₃.
На рисунке синим цветом выделены заданные элементы сферических треугольников, красным цветом неизвестные, зелёным — вспомогательные элементы. Очевидно, в треугольнике Q₁Q₂Q₃ нет ни одного известного элемента. Однако из решения обратной геодезической задачи для пунктов Q₁, Q₂ могут быть получены расстояние σ₁₂, а также азимуты α₁₂ и α₂₁, после чего углы β₁ и β₂ вычисляются как разности азимутов при соответствующих пунктах. Далее из решения треугольника Q₁Q₂Q₃ найдём сторону σ₁₃.
Последовательность действий:
Действия по первому и последнему пунктам рассмотрены в статьях Задачи на сфере: обратная геодезическая задача и Задачи на сфере: прямая геодезическая задача.
Углы β₁, β₂ и длина σ₁₃ вычисляются по формулам:
Правда, до вычисления длины σ₁₃ необходимо проанализировать полученные значения углов β₁ и β₂. Ниже в коде функции можно увидеть пример такого анализа:
Здесь необходимо пояснить, что на сфере две несовпадающие геодезические линии всегда пересекаются в двух точках-антиподах. В традиционной постановке задачи направление на нужное пересечение задаётся явно. Если же прямое и обратное направления по условию равнозначны, возникает вопрос выбора одного из антиподов: φ₃, λ₃ или φ₃′ = −φ₃, λ₃′ = λ₃ ± 180°.
Пример функции SphereAngular на языке Си, реализующей вышеизоложенный алгоритм:
/* * Решение угловой засечки * * Аргументы исходные: * pt1 - {широта, долгота} пункта Q1 * pt2 - {широта, долгота} пункта Q2 * azi13 - азимут направления Q1-Q3 * azi23 - азимут направления Q2-Q3 * * Аргументы определяемые: * pt3 - {широта, долгота} точки Q3 */ int SphereAngular(double pt1[], double pt2[], double azi13, double azi23, double pt3[]) { double azi12, dist12, azi21, dist13; double cos_beta1, sin_beta1, cos_beta2, sin_beta2, cos_dist12, sin_dist12; SphereInverse(pt2, pt1, &azi21, &dist12); SphereInverse(pt1, pt2, &azi12, &dist12); cos_beta1 = cos(azi13 - azi12); sin_beta1 = sin(azi13 - azi12); cos_beta2 = cos(azi21 - azi23); sin_beta2 = sin(azi21 - azi23); cos_dist12 = cos(dist12); sin_dist12 = sin(dist12); if (sin_beta1 == 0. && sin_beta2 == 0.) // Решение - любая точка return -1; // на большом круге Q1-Q2. else if (sin_beta1 == 0.) { pt3[0] = pt2[0]; // Решение - точка Q2. pt3[1] = pt2[1]; return 0; } else if (sin_beta2 == 0.) { // Решение - точка Q1. pt3[0] = pt1[0]; pt3[1] = pt1[1]; return 0; } else if (sin_beta1 * sin_beta2 < 0.) { // Лучи Q1-Q3 и Q2-Q3 направлены if (fabs(sin_beta1) >= fabs(sin_beta2)) { // в разные полусферы. cos_beta2 = -cos_beta2; // Выберем ближайшее решение: sin_beta2 = -sin_beta2; // развернём луч Q2-Q3 на 180°; } else { // иначе cos_beta1 = -cos_beta1; // развернём луч Q1-Q3 на 180°. sin_beta1 = -sin_beta1; } } dist13 = atan2(fabs(sin_beta2) * sin_dist12, cos_beta2 * fabs(sin_beta1) + fabs(sin_beta2) * cos_beta1 * cos_dist12); SphereDirect(pt1, azi13, dist13, pt3); return 0; }
Этот код находится в архиве Sph.zip в файле sph.c. Кроме того, в файл sph.h включены следующие определения:
#define A_E 6371.0 // радиус Земли в километрах #define Degrees(x) (x * 57.29577951308232) // радианы -> градусы #define Radians(x) (x / 57.29577951308232) // градусы -> радианы
Теперь напишем программу, которая обращается к функции SphereAngular для решения угловой засечки:
#include <stdio.h> #include <stdlib.h> #include "sph.h" int main(int argc, char *argv[]) { char buf[1024]; double pt1[2], pt2[2], pt3[2]; double lat1, lon1, lat2, lon2, azi13, azi23; while (fgets(buf, 1024, stdin) != NULL) { sscanf(buf, "%lf %lf %lf %lf %lf %lf", &lat1, &lon1, &lat2, &lon2, &azi13, &azi23); pt1[0] = Radians(lat1); pt1[1] = Radians(lon1); pt2[0] = Radians(lat2); pt2[1] = Radians(lon2); if (SphereAngular(pt1, pt2, Radians(azi13), Radians(azi23), pt3)) puts("\t"); /* Бесконечно много решений на большом круге Q1-Q2 */ else printf("%f\t%f\n", Degrees(pt3[0]), Degrees(pt3[1])); } return 0; }
В архиве Sph.zip этот код находится в файле ang.c. Создадим исполняемый модуль ang компилятором gcc:
$ gcc -o ang ang.c sph.c -lm
Впрочем, в архиве есть Makefile. Для MS Windows готовую программу ang.exe можно найти в архиве Sph-win32.zip.
Программа читает данные из стандартного ввода консоли и отправляет результаты на стандартный вывод. Для чтения и записи файлов используются символы перенаправления потока «>» и «<» соответственно. Из каждой строки ввода программа считывает координаты первого и второго пунктов φ₁, λ₁, φ₂, λ₂, начальные азимуты α₁₃ и α₂₃ в градусах; решает угловую засечку; выводит в строку вывода координаты третьей точки φ₃, λ₃ в градусах.
Создадим файл ang.dat, содержащий одну строку данных:
30 0 60 30 44.80406 110.389945
После запуска программы
$ ang < ang.dat
получим φ₃, λ₃:
52.000000 54.000000
В архиве Sph-py.zip находится код на языке Питон. Выполнение скрипта в командной консоли:
$ python ang.py ang.dat
Обсудить в форуме Комментариев 29Редактировать в вики
Последнее обновление: 2014-06-21 09:41
Дата создания: 11.03.2014
Автор(ы): ErnieBoyd
© GIS-Lab и авторы, 2002-2021. При использовании материалов сайта, ссылка на GIS-Lab и авторов обязательна. Содержание материалов - ответственность авторов. (подробнее).