python + maya:沿向量旋转Y轴 [英] python + maya: Rotate Y axis to be along vector

查看:248
本文介绍了python + maya:沿向量旋转Y轴的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何旋转圆形,使其y轴沿着提供的矢量?此示例脚本中的矢量是使用场景中的两个定位器创建的.该代码分为3个部分.第一部分仅创建测试场景.第二部分收集向量.第三部分是我需要帮助的地方,以弄清楚如何使用向量来调整圆的旋转,使其Y轴指向收集的向量.谢谢你们.

How can I rotate the circle shape so it's y axis is along the supplied vector? The vector in this sample script is created using the two locators in the scene. The code is broken up into 3 sections. The first section just creates the test scene. The second part collects the vector. The third part is where I need help figuring out how to use the vector to adjust the rotation of the circle so it's Y axis is pointing along the collected vector. Thank you guys.

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,因为它不再需要额外的成本中心.

The power of using a package like Maya is in the fact that you don't need to do all of the stuff on your own. You can do it, but it will be slower and less efficient than working with Maya. In fact if you insist on doing it this way you should consider disposing Maya entirely, because its just a extra cost center you no longer need.

现在,maya为此提供了工具.在这种情况下,很明显的工具是构建钻机时的约束.调用现有工具没有错.您始终使用函数进行操作,为什么不使用Maya节点毕竟是函数呢?最明显的是直接在您希望法线指向nr选项用于此目的的位置上直接创建圆.但看起来您想要一些实际的索具:

Now maya offers tools for this. The obvious tool in this case is constraints if your building a rig. There's nothing wrong in calling an existing tool. You do it all the time with functions, why not with maya nodes they are functions after all. The most obvious is to create the circle directly in the position where you want the normal pointing the nr option is for this purpose. But looks like you want some actual rigging:

#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));

就是这样.但是,如果您想在代码中重现此内容或修改解决方案,则需要做一些解释,因为这不是没有问题的方法.目标节点的作用是根据3个向量手动构建矩阵,但是有无数种不同的方法可以实现此目的.在这种情况下,如果您的目标矢量指向向上的矢量方向,则极点矢量会有些问题.

That is it. However a bit of explanation should you want to ever reproduce this in code or to modify the solution, since this is not a problem free approach. What the aim node does is it builds manually a matrix from 3 vectors, but there is a infinite number ow ways you could do this differently. In this case the pole vector is a bit of a problem if your aim vector ever points in up vector direction your going to experience some problems.

现在,矩阵只是指向基本方向的一堆矢量,这是微不足道的. Maya在向量中存储的矩阵是行格式,因此沿向量指向y的矩阵,其中a标准化为单位长度,a看起来如下:

Now the matrix is just a bunch of vectors pointing in the cardinal direction is trivial. Maya stores matrices in in vectors are rows format so a matrix that points in y along a vector, where a is normalized to unit length, a would look as follows:

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

现在要解决这个问题,您需要为问题标记的向量提供任何正交值.输入向上矢量,在这种情况下,取与本地向上方向的叉积.并将其值放在x列中(向上向量用作未知向上向量的占位符),让我们将其称为b,您将得到:

Now for this to work out you need any orthogonal values for the question marked vectors. enter up vector, in this case take a cross product with the local up direction. and place its value in the x column (up vector applies as a placeholder for the unknown up vector), let us call this b and you get:

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

现在您可以重新计算up向量,因为它必须与a和b正交,因此将a跨过c即可得到:

Now you can recompute the up vector because it must be orthogonal to a and b so cross a b for c and you get:

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

您可以分解该矩阵以获得欧拉角.您可以通过加一个来获取该主题的变体,例如获取起搏器参考

You can decompose this matrix to get Euler angles. You could use variations of this theme by adding up to a to get the paceholder reference for example

这篇关于python + maya:沿向量旋转Y轴的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆