python + maya: Завъртете оста Y, за да бъде по вектора

Как мога да завъртя формата на кръга, така че оста 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 )

person JokerMartini    schedule 07.04.2014    source източник
comment
Много предпочитам да използвам ограничения, отколкото да преоткривам твърдата математика в кода. Възможно ли е ограничение на целта във вашия случай?   -  person mhlester    schedule 08.04.2014
comment
ако тръгна по този път. Ще направя фиктивен локатор и ще го подравня с помощта на ограничението и ще избегна да се забърквам с действителния кръг. След това подравнете трансформацията на кръга към манекена. Ако случаят е такъв, има ли бърз и мръсен начин за подравняване на един възел към друг по отношение на трансформацията?   -  person JokerMartini    schedule 08.04.2014
comment
@mhlester не е трудна математика, доста тривиална всъщност. Както и да е, моля, не пишете векторни функции по подразбиране сами. Вземете ги от някакъв пакет, това е просто източник на грешка, която е ненужно неефективна.   -  person joojaa    schedule 08.04.2014
comment
Наистина @joojaa, не е много трудно в този случай. Има обаче много случаи, в които това не е така, и аз съм виждал хора да отиват твърде дълбоко, преоткривайки нещо, което може да бъде просто ограничение за цел/нагоре. Добре е да сме сигурни, че сме запознати с вградените инструменти   -  person mhlester    schedule 08.04.2014


Отговори (1)


Силата на използването на пакет като Maya е във факта, че не е необходимо да правите всички неща сами. Можете да го направите, но ще бъде по-бавно и по-малко ефективно от работата с 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

Сега, за да се получи това, ви трябват някакви ортогонални стойности за векторите с въпросителна маркировка. въведете вектор нагоре, в този случай вземете кръстосано произведение с локалната посока нагоре. и поставете стойността му в колоната x (векторът нагоре се прилага като контейнер за неизвестния вектор нагоре), нека наречем това b и получавате:

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

Сега можете да преизчислите вектора нагоре, защото той трябва да е ортогонален на a и b, така че пресечете a b за c и получавате:

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

person joojaa    schedule 08.04.2014
comment
Въпреки че аз самият бих го направил с ограничение на целта, това е правилната математика. вместо да разлагам матрицата обаче, просто бих поставил превода в долните леви 3 единици на матрицата и бих го приложил с xform(matrix=joojas_matrix_from_vectors) - person theodox; 09.04.2014
comment
@theodox да, напълно забравих за това. Основно мислех за изграждане на възел или ако нямате Maya на разположение, което не винаги е така, тогава е добре да знаете името на операцията за целите на търсенето. - person joojaa; 09.04.2014