python+;maya:沿矢量旋转Y轴

python+;maya:沿矢量旋转Y轴,python,vector,maya,Python,Vector,Maya,如何旋转圆形状,使其y轴沿提供的向量?此示例脚本中的向量是使用场景中的两个定位器创建的。代码分为3个部分。第一部分只是创建测试场景。第二部分收集向量。第三部分是我需要帮助解决如何使用向量来调整圆的旋转,使其Y轴指向收集的向量。谢谢你们 import maya.cmds as cmds import random import math cmds.select(all=True) cmds.delete() #------------------------------TEST SCEN

如何旋转圆形状,使其y轴沿提供的向量?此示例脚本中的向量是使用场景中的两个定位器创建的。代码分为3个部分。第一部分只是创建测试场景。第二部分收集向量。第三部分是我需要帮助解决如何使用向量来调整圆的旋转,使其Y轴指向收集的向量。谢谢你们

import maya.cmds as cmds
import random
import math

cmds.select(all=True)   
cmds.delete()

#------------------------------TEST SCENE SETUP

def genPos():
    x = random.uniform(-5,5)
    y = random.uniform(0,5)
    z = random.uniform(-5,5)
    return (x, y, z)

a = cmds.spaceLocator(n='ctrl_00')
b = cmds.spaceLocator(n='ctrl_00')

cmds.xform(a, t=(genPos()) )
cmds.xform(b, t=(genPos()) )

cmds.createDisplayLayer(name="Ctrls")
cmds.editDisplayLayerMembers('Ctrls', a, b)
cmds.setAttr('Ctrls.color' ,14)

cmds.select(clear=True)


#-----------------------THE SCRIPT
def normlizedVector(vecA,vecB,offset):

    nX = vecB[0] - vecA[0]
    nY = vecB[1] - vecA[1]
    nZ = vecB[2] - vecA[2]

    #vectorLength = distance vecA vecB
    # find the distance between the two supplied point3 values
    distX = pow( (vecA[0] - vecB[0] ) , 2.0 ) 
    distY = pow( (vecA[1] - vecB[1] ) , 2.0 ) 
    distZ = pow( (vecA[2] - vecB[2] ) , 2.0 )

    vecLength = math.sqrt(distX + distY + distZ)

    # the normalized vector is calculated by dividing the X, Y and Z coordinates by the length
    calcX = nX / vecLength
    calcY = nY / vecLength
    calcZ = nZ / vecLength

    # project point along vector, offset by a given value
    ptX = vecB[0] + (calcX * offset)
    ptY = vecB[1] + (calcY * offset)
    ptZ = vecB[2] + (calcZ * offset)

    return (ptX, ptY, ptZ)


posA = cmds.xform(a,q=1,ws=1,rp=1)  
posB = cmds.xform(b,q=1,ws=1,rp=1)  

pt = normlizedVector(posA,posB,10)

#--------MOVE AND ALIGN CIRCLE
cir = cmds.circle( nr=(0, 0, 1), c=(0, 0, 0) )
cmds.xform(cir, t=posB )

使用Maya之类的软件包的强大之处在于,您不需要自己完成所有工作。您可以这样做,但与使用Maya相比,这样做会更慢、效率更低。事实上,如果你坚持这样做,你应该考虑完全处置玛雅,因为它只是一个额外的成本中心,你不再需要。 现在maya为此提供了工具。在这种情况下,最明显的工具是约束,如果您正在构建装备。调用现有工具没有什么错。您一直都在使用函数,为什么不使用maya节点呢?毕竟它们是函数。最明显的方法是直接在需要法线指向的位置创建圆。nr选项用于此目的。但看起来你需要一些实际的装备:

#aim 00 to 01 swap if you need the other way around
cmds.aimConstraint("ctrl_01", "ctrl_00", 
                   aimVector=(0, 1, 0), upVector=(0, 0, 1), 
                   worldUpType="vector", worldUpVector=(0, 1, 0));
就是这样。但是,如果您希望在代码中重现此问题或修改解决方案,请给出一些解释,因为这不是一种无问题的方法。aim节点所做的是从3个向量手动构建一个矩阵,但是有无数种不同的方法可以做到这一点。在这种情况下,极向量是一个问题,如果你的目标向量指向上向量方向,你会遇到一些问题

现在矩阵只是一组指向基数方向的向量,这很简单。Maya以“向量是行”格式存储矩阵,因此沿向量指向y的矩阵,其中a被规格化为单位长度,a将如下所示:

?   ?   ?   ?
a.x a.y a.z a.w=0 
?   ?   ?   ? 
0   0   0   1
现在,为了解决这个问题,需要为带问号的向量提供任何正交值。输入up vector,在本例中,取局部向上方向的叉积。并将其值放在x列中(上方向向量用作未知上方向向量的占位符),我们将其称为b,得到:

b.x b.y b.z b.w=0
a.x a.y a.z a.w=0 
?   ?   ?   ? 
0   0   0   1
b.x b.y b.z b.w=0
a.x a.y a.z a.w=0 
c.x c.y c.z c.w=0 
0   0   0   1
现在可以重新计算上方向向量,因为它必须与a和b正交,所以将a和b交叉,得到:

b.x b.y b.z b.w=0
a.x a.y a.z a.w=0 
?   ?   ?   ? 
0   0   0   1
b.x b.y b.z b.w=0
a.x a.y a.z a.w=0 
c.x c.y c.z c.w=0 
0   0   0   1

你可以分解这个矩阵得到欧拉角。你可以使用这个主题的变体,通过加上a来获得paceholder参考,例如

我更喜欢使用约束,而不是在代码中重新设计硬数学。目标约束是你的选择吗?如果我走那条路。我将制作一个虚拟定位器,并使用约束将其对齐,避免与实际圆混淆。然后将圆的变换与虚拟对象对齐。如果是这样的话,是否有一种快速而肮脏的方法可以将一个节点与另一个节点按转换方式对齐?@mhlester这不是一个难的数学问题,事实上相当简单。无论如何,请不要自己编写默认向量函数。从某个包中获取它们——这只是一个错误源,非常不可靠。事实上@joojaa,在这种情况下并不难。然而,在很多情况下,情况并非如此,我看到人们过于深入地重新创造了一些可能只是目标/提升约束的东西。很好,确保我们知道内置的工具。当我自己使用aimsconstraint时,这是正确的数学。不过,我没有分解矩阵,而是将转换放在矩阵左下角的3个单元中,并用xform应用它(矩阵=joojas_matrix_from_vectors)@theodox yes完全忘记了这一点。我主要考虑的是节点构建,或者如果您没有maya可用(可能并非始终如此),那么最好知道查找操作的名称。