如何使用Python将三维向量转换为Maya中的欧拉旋转
有一个三维向量。
我想把这个向量转换成一个旋转,这样可以让立方体的一个局部轴(比如X轴)对齐到这个向量的方向。
我准备了两张图片,但因为我的声望不够,无法贴出来。我还是个新手。
我尝试了很多次,但还是没能成功。我觉得这可能和我旋转立方体时的旋转顺序有关。
3 个回答
我建议使用NumPy或者类似的库来处理数学运算,因为它们经过高度优化,提供了各种函数和运算符。
在Python中解决矩阵和向量相乘的问题,我们可以假设:
- 向量是1维的列表,视作列向量
- 矩阵是2维的列表,其中m[R][C]表示第R行第C列的元素
那么旋转矩阵和某个向量相乘的结果是
[
sum([m * v for m, v in zip(m_column, some_vector)])
for m_column in rotation_matrix
]
一些实用的链接:zip - 手册,Python 列表推导
正如@theodox所说,使用约束是完全有效的,使用xform也是可以的。我只是提供一些其他的信息(下面的附录中还有更多信息)。
不过,Maya里有一个叫decomposeMatrix的节点,如果你只是想做这个转换,它可以帮你完成。Maya API里也有一个用于分解的函数:
import maya.OpenMaya as om
util = om.MScriptUtil()
mat = om.MMatrix()
util.createMatrixFromList(
[
1., 0., 0., 0.,
0., 1., 0., 0.,
0., 0., 1., 0.,
0., 0., 0., 1.
], mat)
rot = om.MEulerRotation.decompose(mat, om.MEulerRotation.kXYZ)
# result in radians which in this are is known but my example is just a placeholder
print rot.x, rot.y, rot.z
不过你最好还是使用节点,因为它们会在你需要更新的时候自动更新,除非你在做一些静态的东西,比如不需要动画的内容,或者你在做一个导出器。
无论如何,将来你可能会在Maya之外做这个,或者使用不同的组合顺序来处理缩放和剪切等情况,这时候我建议你去看看Christoph Gohlke的主页,里面有Transformations.py和transformations.c,它们提供了很多关于矩阵数学的信息和原始资料的参考,比如在这个案例中,Ken Shoemake对旋转的出色分析。
附注:这是一个近似重复的问题,里面也包含了一些关于矩阵数学的信息,就像@theodox的回答一样。
你可以通过使用目标约束来实现你想要的效果。如果你只想一次性操作(不想在场景中保持这个约束),你可以直接这样做:
lc = cmds.aimConstraint( 'your_object_here', 'target_object_here')
cmds.delete(*lc)
不过,如果你想通过代码来进行数学计算,而不使用欧拉角的话,也是可以的。因为欧拉角的组合方式很多,对于同一个方向都有很多有效的组合,所以构建起来比较复杂。直接设置对象的矩阵,让它的局部轴线指向你想要的方向会更简单。
在Maya中,矩阵是这样工作的:
Xx Xy Xz 0
Yx Yy Yz 0
Zx Zy Zz 0
Tx Ty Tz 1
其中
- (Xx, Xy, Xz) 是矩阵的局部X向量
- (Yx, Yy, Yz) 是矩阵的局部Y向量
- (Zx, Zy, Zz) 是矩阵的局部Z向量
- (Tx, Ty, Tz) 是矩阵的平移部分
如果有缩放的话,缩放信息就包含在这些向量的大小里;对于一个缩放为1且没有旋转的矩阵,这些向量是标准化的,所以矩阵会是:
1 0 0 0
0 1 0 0
0 0 1 0
0 0 0 1
你可以使用Pymel来创建一个矩阵,方法是用4个元组来表示矩阵的行:
import pymel.core as pm
# in practice these vectors would reflect the orientation you want
new_mat = pm.core.matrix (
( 1, 0, 0, 0),
( 0, 1, 0, 0),
( 0, 0, 1, 0),
( 0, 0, 0, 1)
)
然后可以通过xform命令将这个矩阵应用到一个对象上:
pm.xform(my_object, matrix = new_mat)