Когда мы строим ломаную или кривую, иногда необходимо вместо привычных декартовых X,Y-координат задавать точку кривой через угол и расстояние. Ни в GDI, ни в GDI+, нет инструментов, чтобы задать координаты точки по углу от произвольной прямой и расстоянию.
Зато координаты можно очень легко посчитать. Вот этим сейчас и займемся. А потом найдем угол между двумя прямыми.
Найти координаты по углу и расстоянию
Если прямая, от которой необходимо отложить угол, параллельна оси X, формулы для нахождения координат достаточно очевидны.
Рис1. Прямая отстоит на угол от оси X
Где:
L — расстояние, или длина прямой (P1, P2)
А — угол, на который отстоит прямая (P1, P2) от прямой (P0, P1). Отрицательное значение угла означает — против часовой стрелки.
Теперь придадим прямой (P0, P1) наклон.
A (синий) — это угол, на который отстоит (P1, P2) от прямой (P0, P1);
В (красный) — угол на между прямой (P0, P1) и осью X;
C (оранжевый) — угол на между прямой (P1, P2) и осью X.
Задача сводится к нахождению угла C. Как нетрудно убедится по рисунку:
Угол А нам известен. Угол B найдем через arctan2. Функция arctan2 есть во множестве языков. Возможно, будет называться atan2.
Таким образом, функция для нахождения координат точки выглядит так:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
// Посчитать координаты по углу и расстоянию // P0,P1 - прямая, точка считается от P1 // A - угол отклонения от (P0,P1), градусы // L - расстояние до точки function CalcPolarCoord(const P0, P1: TPointF; A, L: Single): TPointF; var B, C: Single; begin B := arctan2(p0.Y-p1.Y, p0.X-p1.x); C := A * PI/180 + B; Result.X := p1.X + cos(C) * L; Result.Y := p1.Y + sin(C) * L; end; |
И что, всегда работает? Всегда.
Найти угол по трем координатам
Рассмотрим процесс, обратный нахождению координаты по углу. Теперь будем находить угол между отрезками ломаной. Мы в плоскости работаем в декартовых координатах. Меняем мышкой координаты X, Y. А ситуация может возникнуть такая, что для предметной области важно хранить данные в полярных координатах.
Функция такая:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
// Нахождение угла между тремя точками в градусах // Точки заданы массивом из трех элементов function CalcPolarAngle(const pnt: Array of TPointF): Single; var a1, a2: Single; begin if Length(pnt)<3 then Exit; a1 := ArcTan2(pnt[0].y-pnt[1].y, pnt[0].x-pnt[1].x) * 180/PI; a2 := ArcTan2(pnt[2].y-pnt[1].y, pnt[2].x-pnt[1].x) * 180/PI; Result := (a2 - a1); end; |
Более продвинутую функцию можно найти в статье Пересечение прямых, угол и координаты пересечения.
Друзья, спасибо за внимание!
Оставляйте комментарии. Подписывайтесь на телегу.
В группе комментариев уже потихоньку становится интересно )))
есть местные координаты нужно найти точку отсчета на карте
Лично я с темой не знаком и в неведении своём знаю такую точку отсчёта: пересечение 0-го меридиана с экватором.
Думаю, про точку отсчёта и смещение местной системы координат лучше всего осведомлены в местной администрации.