Достаточно просто получить матрицу, которая представляет эту ориентацию;Вы можете работать в обратном направлении от этого к вращению.
Если вы уверены, что четырехугольник плоский, вы можете просто использовать нормаль грани (которая должна быть эквивалентна любой из нормалей грани вершины).Если нет, вы можете вывести его из перекрестных векторов, как вы пытались сделать в своем примере.Если геометрия действительно плоская, результаты будут одинаковыми.
Чтобы собрать матрицу, вам просто понадобятся три вектора, которые являются нормальными друг к другу.Используя порядок 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 , чтобы узнать больше.