找到四边形的旋转(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()
如何找到四边形的旋转? (它是平面的)
假设有一个未知的随机旋转四边形,如下所示:
最终的旋转值应该输出如下内容:
我找到了第一个向量 (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()