找到四边形的旋转(4 点,平面)

Find the rotation of a quad (4 points, planar)

如何找到四边形的旋转? (它是平面的)
假设有一个未知的随机旋转四边形,如下所示:



最终的旋转值应该输出如下内容:

我找到了第一个向量 (y),但不确定如何完成它...

vec1 = pt2 - pt1
vec2 = pt3 - pt1

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

很容易得到表示该方向的矩阵;你可以从那个向后工作到轮换。

如果你确定四边形是平面的,你可以只使用面法线(它应该等同于任何顶点面法线)。如果没有,您可以像您在示例中尝试做的那样从交叉向量中导出它。如果几何图形真的是平面的,结果将是相同的。

到assemble矩阵,你只需要三个相互垂直的向量。使用图像暗示的 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 class 的专门化,可以为您处理诸如欧拉和四元数转换之类的事情。

为确保正确完成此操作,您可以制作一个定位器并使用矩阵设置其位置。你应该在你的图像中得到相同的排列:

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

如果您使用的单位不是厘米,则可能需要将 centroid 乘以换算系数;即,如果您以米为单位,则将 centroid 乘以 100。如果您的定位器看起来倾斜,您应该检查四边形上的点顺序以确保它符合您的预期。

一旦你的矩阵正确,得到欧拉或四元数就很简单了:

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

再检查 docs for TransformationMatrix