# Rotate by normal align without maya viewport

 10 October 2012 AKovalev PRO   portfolio Aleksei Kovalev CG Artist Saint-Petersburg, Russia 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? share quote
 10 October 2012 zoharl A newbie   portfolio Zohar Wellington, New Zealand 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. share quote
 10 October 2012 AKovalev PRO   portfolio Aleksei Kovalev CG Artist Saint-Petersburg, Russia 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. share quote
 10 October 2012 zoharl A newbie   portfolio Zohar Wellington, New Zealand 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. share quote
10 October 2012
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)

return degree*(math.pi/180)

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)

``````

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
 rotate_by_normal.zip (7.1 KB, 13 views) rotate_by_normal.txt (2.3 KB, 11 views)

Last edited by AKovalev : 10 October 2012 at 12:31 PM.

 10 October 2012 zoharl A newbie   portfolio Zohar Wellington, New Zealand 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? share quote
 10 October 2012 AKovalev PRO   portfolio Aleksei Kovalev CG Artist Saint-Petersburg, Russia 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. share quote
 10 October 2012 CGTalk Moderation Expert 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. share quote

 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 vBulletinCopyright ©2000 - 2006, Jelsoft Enterprises Ltd.