Страницы

Поиск по вопросам

воскресенье, 29 марта 2020 г.

Вычислить координаты ортогональной проекции точки на отрезок

#javascript #математика #геометрия


Проект для создания чертежей в svg, на нативном js. 

Столкнулся со следующей задачей:

Известны координаты 3х точек A B C на плоскости. Точки A B являются началом и концом
отрезка AB. Нужно найти координаты ортогональной проекции (точка D) точки С на отрезок
АВ. Как это сделать?
    


Ответы

Ответ 1



Проекцию можно найти, используя скалярное произведение векторов D = A + AB * Dot(AC, AB) / Dot(AB, AB) В псевдокоде: abx = B.X - A.X aby = B.Y - A.Y dacab = (C.X - A.X) * abx + (C.Y - A.Y) * aby dab = abx * abx + aby * aby t = dacab / dab D.X = A.X + abx * t D.Y = A.Y + aby * t Здесь немного другие обозначения (C=P, N=D) и пояснения

Ответ 2



Метод "пересечения": Если построить точку С' = (Cx - (By - Ay), Cy + (Bx - Ax)), то прямая CC' будет перпендикулярна прямой AB. Пересечение прямых AB и CC' даст вам точку D. Метод "тяжеловат" с вычислительной точки зрения из-за того, что использует пересечение двух прямых в качестве примитива. Но прост в реализации, если такой примитив уже есть под руками. Метод "расстояния": Если AA, BB и CC - коэффициенты уравнения прямой, содержащей отрезок AB (легко вычисляются через координаты точек A и B), то величина DD = AA * Cx + BB * Cy + CC даст вам знаковое расстояние от этой прямой до точки C, домноженное на |(AA, BB)|. Если к точке C прибавить вектор DD * (-AA, -BB), то мы получим точку, которая смещена относительно C в правильном направлении, но, условно выражаясь, "слишком далеко": расстояние превышает требуемое в |(AA, BB)|^2 раз. Достаточно разделить смещение на эту величину - мы получим требуемую точку D DD D = C + ------------ * (-AA, -BB) |(AA, BB)|^2 Этот метод тоже несколько громоздок из-за "лишних" вычислений уравнения прямой, но может быть полезен, если вы и так уже знаете/вычисляете уравнение прямой, а также если вам в дополнение к точке проекции нужно еще вычислять и расстояние от C до AB. Метод "скалярного произведения": Очевидно, что |(A, D)| D = A + -------- * (A, B) |(A, B)| При этом скалярное произведение вектора (A, C) на вектор (A, B) - это длина проекции (A, D), домноженная на |(A, B)|. (A, C)•(A, B) = |(A, D)| * |(A, B)| Тогда (A, C)•(A, B) D = A + ------------- * (A, B) |(A, B)|^2 (Можно показать, что если собрать все вычисления второго метода в одну формулу, то она "сократится" до третьего метода.)

Комментариев нет:

Отправить комментарий