Как найти точку в 3D на произвольной перпендикулярной линии по заданному расстоянию до точки - PullRequest
0 голосов
/ 31 декабря 2018

У меня есть строка AB.Я хотел бы нарисовать линию BC, перпендикулярную AB.Я знаю xyz из точек A и B, я также знаю расстояние N между B и C. Как я могу найти произвольную точку C, которая соответствует заданным параметрам?Расчеты должны быть выполнены в 3-D.Любая точка, перпендикулярная AB, может быть точкой C, если ее расстояние до B равно N.

Здесь задается почти идентичный вопрос, но я хотел бы знать, как то же самое делается в 3-D: Как найти точку на заданном перпендикулярном расстоянии от линии?

Расчет, который работает для меня в 2-D, был дан по ссылке выше:

dx = A.x-B.x
dy = A.y-B.y
dist = sqrt(dx*dx + dy*dy)
dx /= dist
dy /= dist
C.x = B.x + N*dy
C.y = B.y - N*dx

Я попытался добавить к нему ось Z следующим образом:

dz = A.z - B.z 
dist = sqrt(dx*dx + dy*dy + dz*dz) 
dz /=dist 
C.z = .... at this point it becomes a mystery to me

Если я добавлю что-то вроде "Cz - N * dz" в Cz, расстояние будет точным только в некоторых углах поворота, я быхотел бы узнать правильное решение.Я могу представить, что в 3-х измерениях она рассчитывается совершенно по-другому.

Разъяснение

  • Точка C не уникальна.Это может быть любая точка на круге с центром в точке B и радиусом N. Круг перпендикулярен AB

1 Ответ

0 голосов
/ 31 декабря 2018

Если желаемой точкой 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)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...