Rotate by normal align without maya viewport

Become a member of the CGSociety

Connect, Share, and Learn with our Large Growing CG Art Community. It's Free!

THREAD CLOSED
 
Thread Tools Search this Thread Display Modes
Old 10 October 2012   #1
Rotate by normal align without maya viewport

Rotate by normal align without maya viewport

Hi! Maybe can you help me. I need to rotate transform so that it aligns to a surface normal. And i must do that only with math, without maya viewport tools. I have done this (with binormal and normal matrix). But only put my object on face normal. But how can I rotate it on random angle along, for example, Y axis?
 
Old 10 October 2012   #2
Two ways:

1. MQuaternion, which can be accessed through open maya python, can receive two vectors and return a rotation matrix.

2. First apply to your transform its inverse that would set it to Euler angles (0,0,0), then apply the rotation that would take it to your destination. The multiplication of these two matrices would give you the matrix you are looking for.
 
Old 10 October 2012   #3
Originally Posted by zoharl: Two ways:

1. MQuaternion, which can be accessed through open maya python, can receive two vectors and return a rotation matrix.

2. First apply to your transform its inverse that would set it to Euler angles (0,0,0), then apply the rotation that would take it to your destination. The multiplication of these two matrices would give you the matrix you are looking for.


Thanks for reply. I wrote (whith google help) this script (I've got already: centerP, tangent, binormal, normal) :





a=0

def getOrient(centerP, tangent, binormal, normal, a):

    #rotation formula
    x1 = normal[0]*normal[1]*(1-math.cos(a)) - normal[2]*math.sin(a)
    x2 = math.cos(a)+normal[1]*normal[1]*(1-math.cos(a))
    x3 = normal[2]*normal[1]*(1-math.cos(a))+normal[0]*math.sin(a)
        
    y1=normal[0]
    y2=normal[1]
    y3=normal[2]
    

    matrix  = OpenMaya.MMatrix()
    
    OpenMaya.MScriptUtil.setDoubleArray(matrix[0], 0, x1)
    OpenMaya.MScriptUtil.setDoubleArray(matrix[0], 1, x2)
    OpenMaya.MScriptUtil.setDoubleArray(matrix[0], 2, x3)
    OpenMaya.MScriptUtil.setDoubleArray(matrix[0], 3, 0)
    OpenMaya.MScriptUtil.setDoubleArray(matrix[1], 0, y1)
    OpenMaya.MScriptUtil.setDoubleArray(matrix[1], 1, y2)
    OpenMaya.MScriptUtil.setDoubleArray(matrix[1], 2, y3)
    OpenMaya.MScriptUtil.setDoubleArray(matrix[1], 3, 0)
    

    tmMatrix = OpenMaya.MTransformationMatrix(matrix)
    rotate   = tmMatrix.eulerRotation().reorder(OpenMaya.MEulerRo  tation.kXYZ)
    RAD_to_DEG    = (180/math.pi)
    return [rotate[0]*RAD_to_DEG, rotate[1]*RAD_to_DEG, rotate[2]*RAD_to_DEG]

    


a=a+0.1


#some parameters are not used, they just for tests

test = getOrient([centerP.x,centerP.y,centerP.z], [tangent.x,tangent.y,tangent.z], [binormal.x,binormal.y,binormal.z], [normal.x,normal.y,normal.z], a)

cmds.rotate(test[0],test[1],test[2])



It rotates object by axis ("normal") on angle "a". But something not ok, because the object is tilted. If I put "binormal" in this part:

x1=binormal[0]
x2=binormal[1]
x3=binormal[2]

It puts object exactly on normal. But how can I rotate it on custom angle of axis Y? Maybe can you help me with my code? My brain explode.

Last edited by AKovalev : 10 October 2012 at 04:45 PM.
 
Old 10 October 2012   #4
Please supply a script that creates an example scene (if it's a too complicated scene, then please attach one). On this example scene tell me how to manually do (or approximately do) what you need, and I'll try to help you with the code that do that.
 
Old 10 October 2012   #5
Originally Posted by zoharl: Please supply a script that creates an example scene (if it's a too complicated scene, then please attach one). On this example scene tell me how to manually do (or approximately do) what you need, and I'll try to help you with the code that do that.



zoharl, thanks. Here the test scene (look attachment):

Just open it and run this code (it generates some useful data such as normal, binormal, centerP and tangent) and def getOrient - it rotates cube:


PS: Forum breaks the code after copying in maya, there will have to be corrected in line 28: tangents (the word breaks into two parts), line 34: binormals (word breaks into two parts) and line 84 MEulerRotation (the word breaks into two parts). I attached .txt file with this part of code for just in case.




import maya.cmds as cmds
import maya.OpenMaya as OpenMaya
import math
import random

cmds.select ("pPlane1")

selList = OpenMaya.MSelectionList()
OpenMaya.MGlobal.getActiveSelectionList(selList)
selListIter = OpenMaya.MItSelectionList(selList)

dagPath = OpenMaya.MDagPath()
component = OpenMaya.MObject()

selListIter.getDagPath(dagPath, component)
myMesh=OpenMaya.MFnMesh(dagPath)

faceIter=OpenMaya.MItMeshPolygon( dagPath, component)

centerP=faceIter.center(OpenMaya.MSpace.kWorld)

normal=OpenMaya.MVector()

faceIter.getNormal(0,normal,OpenMaya.MSpace.kWorld  )

tangents=OpenMaya.MFloatVectorArray()

myMesh.getFaceVertexTangents(faceIter.index(),tang  ents,OpenMaya.MSpace.kWorld)

tangent=tangents[0]

binormals=OpenMaya.MFloatVectorArray()

myMesh.getFaceVertexBinormals(faceIter.index(),bin  ormals,OpenMaya.MSpace.kWorld)

binormal=binormals[0]

cmds.select(cl=True)

def DegreesToRads(degree):
	return degree*(math.pi/180)
	
def radsToDegrees(rads):
	return rads * 180.0 / math.pi		


a=0


#function for rotate:

def getOrient(centerP, tangent, binormal, normal, a):
    
    cmds.select ("pCube1")
    
    #rotation formula
    x1 = normal[0]*normal[1]*(1-math.cos(a)) - normal[2]*math.sin(a)
    x2 = math.cos(a)+normal[1]*normal[1]*(1-math.cos(a))
    x3 = normal[2]*normal[1]*(1-math.cos(a))+normal[0]*math.sin(a)
    
    #if uncomment this, cube will stand on normal
    #x1 = binormal[0]
    #x2 = binormal[1]
    #x3 = binormal[2]
        
    y1=normal[0]
    y2=normal[1]
    y3=normal[2]
    

    matrix  = OpenMaya.MMatrix()
    
    OpenMaya.MScriptUtil.setDoubleArray(matrix[0], 0, x1)
    OpenMaya.MScriptUtil.setDoubleArray(matrix[0], 1, x2)
    OpenMaya.MScriptUtil.setDoubleArray(matrix[0], 2, x3)
    OpenMaya.MScriptUtil.setDoubleArray(matrix[0], 3, 0)
    OpenMaya.MScriptUtil.setDoubleArray(matrix[1], 0, y1)
    OpenMaya.MScriptUtil.setDoubleArray(matrix[1], 1, y2)
    OpenMaya.MScriptUtil.setDoubleArray(matrix[1], 2, y3)
    OpenMaya.MScriptUtil.setDoubleArray(matrix[1], 3, 0)
    

    tmMatrix = OpenMaya.MTransformationMatrix(matrix)
    rotate   = tmMatrix.eulerRotation().reorder(OpenMaya.MEulerRo  tation.kXYZ)
    RAD_to_DEG    = (180/math.pi)
    return [rotate[0]*RAD_to_DEG, rotate[1]*RAD_to_DEG, rotate[2]*RAD_to_DEG]



Then run this (just hold right enter or run it multiple times) and you will see that cube is rotate by pPlane1 normal, but it is not exactly on it, not parallel to the normal:


#a - angle which varies
a=a+0.1

test = getOrient([centerP.x,centerP.y,centerP.z], [tangent.x,tangent.y,tangent.z], [binormal.x,binormal.y,binormal.z], [normal.x,normal.y,normal.z], a)

cmds.rotate(test[0],test[1],test[2])


I hope my code will work for you, i tested on maya 2012 and it works.

I need possible to rotate object parallel to normal of "ground" by custom angle ("a" in my case). If you can help me it will be great!
Attached Files
File Type: zip rotate_by_normal.zip (7.1 KB, 13 views)
File Type: txt rotate_by_normal.txt (2.3 KB, 11 views)

Last edited by AKovalev : 10 October 2012 at 12:31 PM.
 
Old 10 October 2012   #6
What did you mean by holding the 'right enter'? As soon as I press the right enter in the script editor, the script disappears and executes, so I need to continue copy-pasting it.

Anyway, I'm not entirely sure I understand what you need, and you are mixing definitions. There is pPlane1, which has a normal 'n'. Do you want to rotate the cube around this vector in an angle of 'a'?
First, you rotate something around a vector, and usually we don't use the term parallel for two vectors unless they are pointing in the opposite direction. If two vectors are parallel (and point to the same direction) they are the same.
Second, if it is indeed the problem that I wrote, then I don't think that you need the binormals or all the other stuff. In pure math you have:

http://en.wikipedia.org/wiki/Rotati...xis_and_angl e

which is the matrix form of Rodrigues' formula. Meaning, just plug the numbers to the formula, and you have the rotation matrix. 'n' is 'u', 'a' is theta. Note that the rotation is around the origin, so you might need to translate your pivot to the origin first (and back afterwards).

But maya has the MQuaternion class, which takes an axis and an angle:

MQuaternion (double angle, const MVector &axisb)


which can be converted later to a matrix: asMatrix ().

Or you meant something else?
 
Old 10 October 2012   #7
zoharlб yes, you are right - I want to rotate my cube around vector "n" (normal vector) in an angle of "a". Cube must rotates on pPlane1 and stand on normal of pPlane1. Well, thank you for your link and other info, I will try to fix my script with new formula.
 
Old 10 October 2012   #8
Thread automatically closed

This thread has been automatically closed as it remained inactive for 12 months. If you wish to continue the discussion, please create a new thread in the appropriate forum.
__________________
CGTalk Policy/Legalities
Note that as CGTalk Members, you agree to the terms and conditions of using this website.
 
Thread Closed share thread



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
CGSociety
Society of Digital Artists
www.cgsociety.org

Powered by vBulletin
Copyright 2000 - 2006,
Jelsoft Enterprises Ltd.
Minimize Ads
Forum Jump
Miscellaneous

All times are GMT. The time now is 01:35 PM.


Powered by vBulletin
Copyright ©2000 - 2017, Jelsoft Enterprises Ltd.