Проект для создания чертежей в svg
, на нативном js
.
Столкнулся со следующей задачей:
Известны координаты 3х точек A B C
на плоскости. Точки A B
являются началом и концом отрезка AB
. Нужно найти координаты ортогональной проекции (точка D)
точки С
на отрезок АВ
. Как это сделать?
Проекцию можно найти, используя скалярное произведение векторов
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) и пояснения
Метод "пересечения":
Если построить точку С' = (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
(Можно показать, что если собрать все вычисления второго метода в одну формулу, то она "сократится" до третьего метода.)
Виртуальный выделенный сервер (VDS) становится отличным выбором
Задан какой-то массив из цифр (JavaScript)Надо проверить,если удалить один элемент из массива,то станет ли массив упорядоченным? (Например - [1,4,2,3]...
Столкнулся с проблемой: при переходе по страницам через клавиши вперёд и назад браузера (Chrome), загружаемая страница распадается на кодТочнее...
Помогите пожалуйстаНужно, чтобы во время клика на кнопку в соседнем div-e выводился name этой кнопки
Есть запрос с подзапросом, который считает количество клиентов за сутки до текущей заявки: