Если желаемой точкой C может быть любая из бесконечно многих точек, соответствующих вашим требованиям, вот один из методов.
Выберите любой вектор, который не параллелен или антипараллелен вектору AB.Вы можете попробовать вектор (1, 0, 0)
, а если он параллельный, вы можете использовать (0, 1, 0)
.Затем возьмите перекрестное произведение вектора AB и выбранного вектора.Это перекрестное произведение перпендикулярно вектору AB.Разделите это произведение на его длину, затем умножьте на желаемую длину N. Наконец, растяните этот вектор из точки B, чтобы найти желаемую точку C.
Вот код в Python 3, который следует этому алгоритму.Этот код несколько непифоничен, чтобы его было легче конвертировать в другие языки.(Если бы я действительно сделал это для себя, я бы использовал модуль numpy
, чтобы полностью избежать координат и сократить этот код.) Но он действительно обрабатывает точки как кортежи из 3 значений: многие языки требуют, чтобы вы обрабатывали каждую координату отдельно.Любой реальный код должен был бы проверять «почти ноль», а не «ноль» и проверять, что вычисление sqrt
не приводит к нулю.Я оставлю эти дополнительные шаги для вас.Задайте вопрос, если у вас есть еще вопросы.
from math import sqrt
def pt_at_given_distance_from_line_segment_and_endpoint(a, b, dist):
"""Return a point c such that line segment bc is perpendicular to
line segment ab and segment bc has length dist.
a and b are tuples of length 3, dist is a positive float.
"""
vec_ab = (b[0]-a[0], b[1]-a[1], b[2]-a[2])
# Find a vector not parallel or antiparallel to vector ab
if vec_ab[1] != 0 or vec_ab[2] != 0:
vec = (1, 0, 0)
else:
vec = (0, 1, 0)
# Find the cross product of the vectors
cross = (vec_ab[1] * vec[2] - vec_ab[2] * vec[1],
vec_ab[2] * vec[0] - vec_ab[0] * vec[2],
vec_ab[0] * vec[1] - vec_ab[1] * vec[0])
# Find the vector in the same direction with length dist
factor = dist / sqrt(cross[0]**2 + cross[1]**2 + cross[2]**2)
newvec = (factor * cross[0], factor * cross[1], factor * cross[2])
# Find point c such that vector bc is that vector
c = (b[0] + newvec[0], b[1] + newvec[1], b[2] + newvec[2])
# Done!
return c
Полученный результат команды
print(pt_at_given_distance_from_line_segment_and_endpoint((1, 2, 3), (4, 5, 6), 2))
равен
(4.0, 6.414213562373095, 4.585786437626905)