Учитывая две 2D-точки (p1 и p2), мне нужно найти точку (p3), которая (с точки зрения p1) находится по другую сторону от p2, и в то же время она должна иметь заданное расстояние до p2.
С большим заданным расстоянием это могло бы выглядеть так:
^
|
| p1
| p2
|
| p3
<-|---------------------------->
v
Или вот так с меньшим заданным расстоянием:
^
|
|
| p3
| p2
|p1
<-|---------------------------->
v
Как я могу рассчитать эту точку (p3)?
Я предпочитаю JavaScript, но я не прошу ответа строго на JavaScript. Если вы можете объяснить это способом, который можно перевести в код, или если вы напишете псевдокод, это будет нормально.
Это была моя последняя попытка (очевидно, это не сработает):
calculate_point_on_other_side_of_p2(p1, p2, distance_p2_to_p3) {
deltaX = p1.x-p2.x
deltaY = p1.y-p2.y
distance_p1_to_p2 = sqrt(deltaX*deltaX + deltaY*deltaY)
if (deltaX < 0)
p3.x = p2.x+distance_p2_to_p3
else
p3.x = p1.x-distance_p2_to_p3
if (deltaY < 0)
p3.y = p2.y+distance_p2_to_p3
else
p3.y = p1.y-distance_p2_to_p3
return p3
}
Ну конечно; естественно. Исправил это.
Я думаю, что в вашем заявлении else вам нужно сделать p3.x = p2.x-distance_p2_to_p3
и p3.y = p2.y-distance_p2_to_p3
т.е. вычесть из p2, а не p1
Может, не знаю. но добавление / вычитание расстояния p2_to_p3 по x и y в любом случае не может быть решением.
находятся ли p1, p2 и p3 на одной линии?
Да, они должны быть на одной теоретической прямой.
Одна из версий правильного алгоритма будет следующей (это даже не псевдокод, но он должен объяснять, что делать):
Обратите внимание на знак минус, потому что дельты являются компонентами вектора от p2 до p1, но p2p3 антиколлинеарен p2p1
calculate_point_on_other_side_of_p2(p1, p2, distance_p2_to_p3) {
deltaX = p1.x-p2.x
deltaY = p1.y-p2.y
distance_p1_to_p2 = sqrt(deltaX*deltaX + deltaY*deltaY)
scale = distance_p2_to_p3 / distance_p1_to_p2
p3.x = p2.x - deltaX * scale
p3.y = p2.y - deltaY * scale
return p3
}
Предположим, все три строки находятся в строке. Тогда наклон - deltaY/deltaX
. Если p3 находится на расстоянии x
от p2 по горизонтали, то он находится на расстоянии deltaY/deltaX * x
от p2 по вертикали. distance_p2_to_p3^2 = x^2 + (deltaY/deltaX * x)^2
, решите для x
. Затем добавьте / вычтите x
из p2.x
и прибавьте. Вычтите deltaY/deltaX * x
из p2.y.
Использование уклонов обычно является неправильным подходом в компьютерной геометрии (представьте себе вертикальную линию).
@MBo хороший момент. Я думаю, мы можем позаботиться о граничном случае, прежде чем вычислять наклон, но мне нравится ваш ответ об использовании отношения
Это простая проблема, если вы понимаете, как работают 2D-векторы.
Вычислите единичный вектор от p1 до p2:
(nx, ny) = ((p2x - p1x)*i + (p2y-p1y)*j)/sqrt((p2x-p1x)^2 + (p2y-p1y)^2)
Где i и j - единичные векторы в направлениях x и y соответственно.
Теперь вы можете вычислить (p3x, p3y) на любом расстоянии d от p1:
(p3x, p3y) = (p1x, p1y) + (d*nx, d*ny)
Вы хотели извлечь квадратный корень из distance_p1_to_p2?