Как рассчитать (или повернуть) четыре точки в плоскости, перпендикулярной линии - PullRequest
1 голос
/ 11 ноября 2019

Мне нужно сгенерировать четырехточечную квадратную «шапку» для трехмерного отрезка, который перпендикулярен упомянутой трехмерной линии. Теоретически линия может быть любой линией в трехмерном пространстве и описывается двумя точками в трехмерном пространстве.

image

До сих пор я был в состоянии правильно вращать точки вокруг оси Y (которая в Годо указывает вверх), изменяя их положения X и Z с помощью алгоритма 2D-вращенияно я не вижу способа включить вращение 3-го измерения.

Насколько я понимаю, требуется совершенно новый алгоритм для поворота точек в трехмерном пространстве (кватернионы?), Но я не нашел приложений кода этого, которые я могу понять.

Способдумать о том, что мне нужно сгенерировать квадратную плоскость из ее нормального. Точки должны образовывать квадрат со стороной «L», поэтому я не могу использовать алгоритмы, которые генерируют случайные точки.

Я благодарю вас за любую помощь, которую вы можете оказать.

Ответы [ 3 ]

2 голосов
/ 11 ноября 2019

Вы можете сделать это без матрицы вращения, просто с помощью векторного исчисления.

Точка S вдоль линии, проходящей через P и Q, вычисляется как P + t.PQ, где t - этоскалярТеперь возьмем любую точку в пространстве, пусть R и найдем ее ортогональную проекцию S на линию, решив RS.PQ = 0 или (RP + t.PQ).PQ = 0, или t = - RP.PQ / PQ.PQ.

Вектор RS определяетнаправление диагонали квадрата. Следовательно, мы находим первую вершину R' длиной L/√2 вдоль SR, применяя коэффициент L/√2|SR|.

Вторая вершина U такова, что U = S + R'S.

Оставшиеся две вершины V и W находятся путем построения вектора VS, ортогонального к RS, используя перекрестное произведение с направлением линии, R'S x PQ/|PQ|.

enter image description here

1 голос
/ 12 ноября 2019
func drawline(starting_point, finishing_point):

var width = 0.1

var diference_vector = finishing_point - starting_point
var diference_vector_norm = sqrt(pow(diference_vector[0],2.0) + pow(diference_vector[1],2.0) + pow(diference_vector[2],2.0))
var normalized_difference_vector

if diference_vector_norm != 0:
    normalized_difference_vector = Vector3(diference_vector[0]/diference_vector_norm, diference_vector[1]/diference_vector_norm, diference_vector[2]/diference_vector_norm)
else:
    normalized_difference_vector = Vector3(0,0,0)

var s1 = Vector3(0, width, -width)
var s2 = Vector3(0, width, width)
var s3 = Vector3(0, -width, width)
var s4 = Vector3(0, -width, -width)

var x_vec = Vector3(1,0,0)
var axis_vector = normalized_difference_vector.cross(x_vec)
var axis_vector_norm = sqrt(pow(axis_vector[0],2.0) + pow(axis_vector[1],2.0) + pow(axis_vector[2],2.0))

if axis_vector_norm != 0:
    var normalized_axis_vector = Vector3(axis_vector[0]/axis_vector_norm, axis_vector[1]/axis_vector_norm, axis_vector[2]/axis_vector_norm)
    var theta = acos(x_vec.dot(normalized_difference_vector))

    var matrix_0_0 = cos(theta) + (pow(normalized_axis_vector[0],2.0) * (1-cos(theta)))
    var matrix_0_1 = (normalized_axis_vector[0] * normalized_axis_vector[1] * (1-cos(theta))) - (normalized_axis_vector[2] * sin(theta))
    var matrix_0_2 = (normalized_axis_vector[0] * normalized_axis_vector[2] * (1-cos(theta))) + (normalized_axis_vector[1] * sin(theta))

    var matrix_1_0 = (normalized_axis_vector[1] * normalized_axis_vector[0] * (1-cos(theta))) + (normalized_axis_vector[2] * sin(theta))
    var matrix_1_1 = cos(theta) + (pow(normalized_axis_vector[1],2.0) * (1-cos(theta)))
    var matrix_1_2 = (normalized_axis_vector[1] * normalized_axis_vector[2] * (1-cos(theta))) - (normalized_axis_vector[0] * sin(theta))

    var matrix_2_0 = (normalized_axis_vector[2] * normalized_axis_vector[0] * (1-cos(theta))) - (normalized_axis_vector[1] * sin(theta))
    var matrix_2_1 = (normalized_axis_vector[2] * normalized_axis_vector[1] * (1-cos(theta))) - (normalized_axis_vector[0] * sin(theta))
    var matrix_2_2 = cos(theta) + (pow(normalized_axis_vector[2],2.0) * (1-cos(theta)))

    var matrix = Transform(Vector3(matrix_0_0, matrix_0_1, matrix_0_2), Vector3(matrix_1_0, matrix_1_1, matrix_1_2), Vector3(matrix_2_0, matrix_2_1, matrix_2_2), Vector3(0,0,0))

    var a1 = matrix.basis.xform(s1) + starting_point
    var a2 = matrix.basis.xform(s2) + starting_point
    var a3 = matrix.basis.xform(s3) + starting_point
    var a4 = matrix.basis.xform(s4) + starting_point

    var b1 = matrix.basis.xform(s1) + finishing_point
    var b2 = matrix.basis.xform(s2) + finishing_point
    var b3 = matrix.basis.xform(s3) + finishing_point
    var b4 = matrix.basis.xform(s4) + finishing_point
1 голос
/ 11 ноября 2019

Кватернионы интересны, но не обязательны. Здесь можно использовать матрицу вращения.

Схема алгоритма:

  • предположим, что p1 и p2 - трехмерные точки линии
  • пусть p1p2 будет нормализовановектор от p1 к p2 (нормализовать (p2-p1))
  • поместить четыре точки s1, s2, s3, s4 в (0,1,1), (0,1, -1), (0,-1, -1), (0, -1,1);это начальные положения точек, образующих квадрат, перпендикулярный оси X;если слишком мало, просто умножьте их на желаемый размер
  • пусть xvec будет единичным x-вектором (1, 0, 0)
  • пусть axis будет перекрестным продуктом p1p2 и xvec
  • если норма оси равна нулю, вращение не требуется -> пропустить шаги вращения, иначе:
    • theta = acos (dotproduct (xvec, p1p2))
    • build aматрица вращения, как в этой странице википедии с использованием тэты и оси
    • , умножьте s1, s2, s3, s4 на матрицу вращения
  • добавьте p1 кs1, s2, s3, s4, чтобы получить квадрат в позиции p1
  • , добавьте p2 к s1, s2, s3, s4, чтобы получить квадрат в позиции p2

PS: если вывыберите s1, s2, s3, s4 как (1,0,1), (1,0, -1), (-1,0, -1), (-1,0,1), вы можете сделать то же самоес yvec = (0,1,0)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...