Найти вращение четырехугольника (4 точки, плоскость) - PullRequest
0 голосов
/ 11 декабря 2018

Как мне найти вращение четырехугольника?(это плоско)
Допустим, есть неизвестный случайным образом повернутый четырехугольник, подобный этому:

enter image description here

Окончательные значения вращения должны выводить что-то вроде этого: enter image description here

Я нашел первый вектор (y), но не уверен, как это закончить ...

vec1 = pt2 - pt1
vec2 = pt3 - pt1

cross1 = vec1.cross(vec2).normal()
angle = pm.angleBetween(euler=1, v1=(0,-1,0), v2=cross1)

1 Ответ

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

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

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

Чтобы собрать матрицу, вам просто понадобятся три вектора, которые являются нормальными друг к другу.Используя порядок XYZ, подразумеваемый вашим изображением, он будет работать следующим образом:

import pymel.core as pm
from pymel.core.datatypes import Matrix, Vector, TransformationMatrix

points = [Vector(pm.xform('pPlane1.vtx[%i]' % i, q=True, t=True, ws=True))  for i in range(4)]

local_x = (points[1] - points[0]).normal()
local_z = (points[2] - points[0]).normal()
local_y = local_x.cross(local_z).normal()

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

centroid = sum(points) / 4.0

Теперь мы строим фактическую матрицу.Чтобы было понятнее, вот несколько скучный способ сложения:

 matrix = TransformationMatrix (
               local_x.x, local_x.y, local_x.z, 0,
               local_y.x, local_y.y, local_y.z, 0,
               local_z.x, local_z.y, local_z.z, 0,
               centroid.x, centroid.y, centroid.z, 1
     )

Обратите внимание, что вам нужен pymel.datatypes.TransformationMatrix, который является специализацией класса Matrix, который обрабатывает такие вещи, как eulerи кватернионные преобразования для вас.

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

locator = pm.spaceLocator()
pm.xform(locator, m=matrix, ws=True)

Если вы работаете в единицах, отличных от сантиметров, вам может понадобиться умножить centroid на коэффициент преобразования;то есть, если вы находитесь в метрах, вы умножите centroid на 100. Если ваш локатор выглядит перекошенным, вы должны проверить порядок точек на своем квадре, чтобы убедиться, что это то, что вы ожидаете.

Если ваша матрица верна, получить эйлера или кватернион просто:

eulers = matrix.getRotation()
quat = matrix.getRotationQuaternion()

Проверьте документацию для TransformationMatrix , чтобы узнать больше.

...