Изменение 3D-системы координат с помощью Excel

У меня есть облако точек в электронной таблице в определенной системе координат, облако имеет следующий формат: Name X Y Z PT1 X1 Y1 Z1 PT2 X2 Y2 Z2 PT3 X3 Y3 Z3 PT4 X4 Y4 Z4 ... PTi Xi Yi Zi ... Я хочу использовать четыре первые точки в моем списке, чтобы построить новую систему координат и перенести все мои точки в новую систему координат.

Новая система координат должна быть определена как плоскость-линия-точка (или преобразование 3-2-1° как таковое:

  1. Самолет лучше всего подходит из (PT1, PT2, PT3, PT4). Я знаю, как построить уравнение плоскости, используя формулу Excel ЛИНЕЙН
  2. Линия/вектор От средней точки (PT1-PT2) до средней точки (PT3-PT4) линия/вектор легко построить в Excel
  3. Точка является средней точкой (PT1-PT2).

Подводя итог, начало координат (0,0,0) будет в средней точке (PT1-PT2). Новая ось X будет вектором от средней точки (PT1-PT2) до средней точки (PT3-PT4). Ось Y будет находиться в плоскости и перпендикулярна X. А Z будет перпендикулярна X и Y.

В настоящее время я могу найти уравнения плоскости и осей X, Y, Z.

Мой вопрос заключается в том, как построить матрицу преобразования на основе этих параметров и реализовать ее с помощью формул Excel.

Спасибо.


person Maxime    schedule 22.10.2015    source источник


Ответы (3)


Пытаюсь ответить, разделив задание на 5 частей. Я буду называть x,y,z старой осью с центром в O, а X,Y,Z вашей новой осью с центром в P.

Попробуйте сохранить частичный результат в пустых ячейках с первой попытки. Я не могу дать вам единственную уникальную формулу, которая ответит на ваш вопрос за 1 шаг.

а) Родовое преобразование — это ротоперевод. Вы нашли свое новое начало в точке P (координаты у вас есть). Предполагая, что ваш «старый источник» равен O = (0,0,0), я могу просто сказать, что перевод из старого источника в новый равен d = |P-O| = |П| евклидова норма вектора P в обеих системах, и ее довольно легко вычислить в excel (я не знаю, есть ли функция, я бы использовал теорему Пифагора). Кто-то пытается создать пользовательский макрос здесь

б) Теперь, когда у вас есть вектор смещения (t1,t2,t3), вы можете установить новое начало координат для старой оси, не поворачивая их. Обратите внимание на знак, но это простая формула перевода (см. пример: если x = x' + t1, то x' = x - t1) Подумайте, что такое x' и что такое x в вашем случае, попробуйте с простой точкой (1,0,0) и посмотрите, удачен ли ваш выбор. Сделайте перевод всех ваших точек (например: PT1_t, PT2_t...) Теперь у вас есть промежуточная система отсчета между xyz и XYZ. Назовем это "pqr"

в) Теперь ваши системы отсчета pqr и XYZ отличаются только углом поворота. Вы должны решить, какая ось будет вращаться первой, прежде чем строить матрицу вращения. Лучше работать с нормализованным вектором (разделить каждый вектор на его норму). Предположим, что вращение из системы pqr и XYZ представляет собой композицию (не более) 3 вращений вокруг фиксированной оси. Например

  1. вы повернете pqr вокруг Z, чтобы поместить versor p в плоскость XZ. вы получите «новую» систему pqr. Это делается с помощью матрицы вращения 3x3 RX (мы этого еще не знаем)
  2. вы будете вращать pqr' вокруг Y, чтобы выровнять versor p' с versor X, используя RY. Теперь у вас есть pqr''
  3. вы выровняете ось q по Y и ось r по Z, используя вращение вокруг X и матрицу RX. pqr''' полностью выровнен по XYZ

Полный оборот равен R = RX * RY * RZ, матричному произведению. Как найти вращение? (Следование моей последовательности вращения не является обязательным! Вы можете построить свою собственную последовательность, но наиболее известны XYZ, ZYX и ZXZ).

г) Каждой матрице нужен угол. Первый угол — это угол между p и его проекцией на плоскость XZ. Второй угол - это угол между p' (=RZ * p) и X, третий угол - между q'' (=RY * q' = RY * RX * q) и Y. Он должен быть равен (с ошибками) к углу между r'' и Z. Матрица может быть построена так (если A - общий угол)

RX = [1   0      0
      0 cos(A) -sin(A)
      0 sin(A) cos(A)]

проверьте RY и RZ по этой ссылке, но обратите внимание: как мы уже говорили ранее, A — это угол поворота в одном направлении, поэтому вам может понадобиться -A для вашего вращения. В общем (но проверьте это) A - это угол ОТ старой оси ДО новой, а положительный A - против часовой стрелки.

Чтобы вычислить угол A, используйте простую формулу приведенную здесь. В Excel есть все гониометрические формулы (косинус, арккосинус...), которые вам нужны.

e) Как только вы нашли три матрицы RX RY RZ, играющие с вращением старой оси pqr, каждая отдельная точка PTi' в вашей новой системе XYZ получается из PTi' = R * PTi_t. Вы можете просто создать матричный продукт с помощью функции Excel MMULT, объясненной здесь

Извините за длину, но это единственная система, которую я знаю как простой студент. Я надеюсь, что это может помочь вам.

person marcoresk    schedule 15.08.2016

Требуется команда от J6 до L16 ниже с помощью Ctrl+Shift+Enter для сброса координат до исходных значений

=RotpointsZ(RotpointsY(RotpointsX(AsArray($F$6:$H$16),$K$1),$K$2),$K$3)

Как я могу отредактировать код VBA, чтобы считывать разные повороты xyz для каждой повернутой строки вместо привязки к одному повороту, как показано здесь?

26/04/18 WORF на Mr.Excel только что ответил на мой вопрос о чтении разных поворотов xyz для каждой точки, которую нужно повернуть. Его ввод состоял в том, чтобы добавить следующий код к существующему коду:

Function Rot3D(ByVal rng1 As Range, ByVal rng2 As Range, ByVal rng3 As 
Range, ByVal rng4 As Range)
Rot3D = RotPointsX(RotPointsY(RotPointsZ(AsArray(rng1), rng2.Value), 
rng3.Value), rng4.Value)
End Function

Скопируйте следующую формулу:

=rot3d(b2:d2,h2,g2,f2)

в ячейки J2,K2,L2, используя Ctrl+Shift+Enter, а затем скопируйте вниз. Вращение координат xyz в столбцах B,C,D будет повернуто в соответствии с углами в столбцах F,G,H с выводом в столбцах J,K,L

Я поместил углы поворота в столбцы F, G, H, используя вырезание и вставку. Это, конечно, изменяет макет исходного листа, который отображается здесь.

person twa14    schedule 28.03.2018

Взгляните на этот код, который позволяет вращать диапазон точек, упорядоченных по строкам.

скр

Сначала три функции, которые принимают массив значений и применяют соответствующие повороты вокруг X, Y или Z.

Public Function RotPointsX(ByRef pts() As Variant, angle_rad As Double) As Variant()
    Dim n As Integer
    n = UBound(pts, 1)
    If UBound(pts, 2) <> 3 Then
        'Need Three Points
        Exit Function
    End If
    Dim tX As Double, tY As Double, tZ As Double
    Dim X As Double, Y As Double, Z As Double

    For i = 1 To n
        tX = pts(i, 1): tY = pts(i, 2): tZ = pts(i, 3)
        X = tX
        Y = tY * Cos(angle_rad) - tZ * Sin(angle_rad)
        Z = tY * Sin(angle_rad) + tZ * Cos(angle_rad)
        pts(i, 1) = X: pts(i, 2) = Y: pts(i, 3) = Z
    Next i

    RotPointsX = pts
End Function
Public Function RotPointsY(ByRef pts() As Variant, angle_rad As Double) As Variant()
    Dim n As Integer
    n = UBound(pts, 1)
    If UBound(pts, 2) <> 3 Then
        'Need Three Points
        Exit Function
    End If
    Dim tX As Double, tY As Double, tZ As Double
    Dim X As Double, Y As Double, Z As Double

    For i = 1 To n
        tX = pts(i, 1): tY = pts(i, 2): tZ = pts(i, 3)
        X = tZ * Sin(angle_rad) + tX * Cos(angle_rad)
        Y = tY
        Z = tZ * Cos(angle_rad) - tX * Sin(angle_rad)
        pts(i, 1) = X: pts(i, 2) = Y: pts(i, 3) = Z
    Next i

    RotPointsY = pts
End Function
Public Function RotPointsZ(ByRef pts() As Variant, angle_rad As Double) As Variant()
    Dim n As Integer
    n = UBound(pts, 1)
    If UBound(pts, 2) <> 3 Then
        'Need Three Points
        Exit Function
    End If
    Dim tX As Double, tY As Double, tZ As Double
    Dim X As Double, Y As Double, Z As Double

    For i = 1 To n
        tX = pts(i, 1): tY = pts(i, 2): tZ = pts(i, 3)
        X = tX * Cos(angle_rad) - tY * Sin(angle_rad)
        Y = tX * Sin(angle_rad) + tY * Cos(angle_rad)
        Z = tZ
        pts(i, 1) = X: pts(i, 2) = Y: pts(i, 3) = Z
    Next i

    RotPointsZ = pts
End Function

Далее мне нужна функция для преобразования диапазона в массив, и проще всего это сделать с помощью этой функции:

Public Function AsArray(ByVal r_pts As Range) As Variant()
    AsArray = r_pts.Value2
End Function

Наконец, на моем листе я выполняю повороты как вложенные функции и ввожу их с помощью Ctrl-Shift-Enter как функции массива.

скр

Таким образом, для вращения Эйлера на ZYX требуется следующий ввод

=RotPointsX(
     RotPointsY(
         RotPointsZ(
             AsArray(<range>),
         angle_z),
     angle_y), 
 angle_x)

Обратное вращение — это XYZ поворот отрицательных углов.

=RotPointsZ(
     RotPointsY(
         RotPointsX(
             AsArray(<range>),
         -angle_x),
     -angle_y), 
 -angle_z)

Я проверил это, восстановив исходные точки

скр

person John Alexiou    schedule 17.08.2016