2014-04-07 3 views
0

y 축이 제공된 벡터를 따라 원 모양을 회전시키는 방법은 무엇입니까? 이 샘플 스크립트의 벡터는 장면의 두 위치 지정자를 사용하여 작성됩니다. 코드는 세 부분으로 나뉩니다. 첫 번째 섹션에서는 테스트 장면을 만듭니다. 두 번째 부분은 벡터를 수집합니다. 세 번째 부분은 벡터를 사용하여 원의 회전을 조정하여 Y 축이 수집 된 벡터를 따라 가리키는 방법을 찾는 데 도움이 필요한 부분입니다. 고마워.python + maya : 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) 
+0

코드에서 어려운 수학을 다시 작성하는 것보다 제약 조건을 사용하는 것이 훨씬 더 좋습니다. 귀하의 경우 목표 제한이 옵션입니까? 내가 그 길로 가면 – mhlester

+0

. 더미 로케이터를 만들어 제약 조건을 사용하여 정렬하고 실제로 원을 그리는 것을 피합니다. 그런 다음 원의 변형을 더미에 맞 춥니 다. 그런 경우에 한 노드를 다른 노드로 정렬하는 것이 현명하고 신속한 방법일까요? – JokerMartini

+0

@mhlester 그것의 어려운 수학, 꽤 사소한 사실. 어쨌든 wirte 기본 벡터 함수를 직접 사용하지 마십시오. 그 (것)들을 얻으십시오 unpackcesrily 불발성 인 과실의 다만 근원을 약간 포장하십시오. – joojaa

답변

2

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

그게 전부입니다. 그러나 문제의 자유로운 접근 방식이 아니기 때문에 이것을 코드로 재현하거나 솔루션을 수정하고 싶다면 약간의 설명이 필요합니다. 목표 노드는 3 개의 벡터로부터 행렬을 수동으로 생성하지만,이 방법을 다르게 수행 할 수있는 방법은 무한합니다. 이 경우 극 벡터는 목표 벡터가 상향 벡터 방향을 가리키면 문제가 발생하는 문제입니다.

이제 행렬은 추기경 방향을 가리키는 벡터들의 묶음 일뿐입니다. 마야 상점은 그래서 벡터를 따라 Y을 가리키는 행렬은 단위 길이에 정규화 는 다음 보일 것 같은 벡터되는 행 형식의 행렬 :

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

지금이 당신을 해결하기 위해 물음표 표시된 벡터에 대한 직각 값이 필요합니다. 이 경우에는 로컬 업 방향으로 교차 제품을 사용하십시오. 및 (벡터 미지의 위쪽 벡터에 대한 자리로 적용까지) 우리가이 B 부르 자,는 x 열에서 그 가치를 배치하고 당신이 얻을 : 그것은 직교해야하기 때문에

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

는 이제 위쪽 벡터를 다시 계산 할 수 있습니다 a와 b에 이르기 때문에 C와 X를 교차하면 다음과 같이됩니다.

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를 더하여이 테마의 변형을 사용할 수 있습니다.

+0

나는 aimconstraint 자신과 함께 할 것이지만, 이것은 올바른 수학이다. 행렬을 분해하는 것이 아니라 행렬의 왼쪽 아래 3 단위에 변환을 넣고 xform (matrix = joojas_matrix_from_vectors) – theodox

+0

과 함께 적용합니다. @theodox는 완전히 그것을 잊었습니다. 주로 노드 구축을 생각하고 있었거나, maya를 사용할 수 없다면 항상 검색의 목적으로 작업의 이름을 알면 좋을 것입니다. – joojaa