0

I have been trying to get the Euler angles to each axis of a face normal vector but I haven't been successful so far. I tried using the direction cosines for each axis, but I haven't been successful as the returned value was completely off. Here's my code so far, I'm pretty sure there's a problem with my logic, specially in my math, but I cant really figure it out. I'm using python and the Maya for this. I'm modifying the manipulator pivot to check if the result. Thanks In advance! Here's my code:

import maya.cmds as cmds
import math as math

def Difference(a,b):
    return list(set(a)- set(b))

def VertPosition(vert, axis):
    return cmds.xform(vert,q = 1,ws = 1, t = 1)[axis]

def GetFaceNormal(face):
        cmds.select(face,r=1)
        faceNormal = cmds.polyInfo(fn=True)
        return faceNormal

def GetNumericNormalValue(normalInfoString):
    faceNormalDirection = [0,0,0]
    normalInfoString = str(normalInfoString).split(' ')
    faceNormalDirection[0] = float(normalInfoString[-3])
    faceNormalDirection[1] = float(normalInfoString[-2])
    faceNormalDirection[2] = float(normalInfoString[-1][:-5])
    return faceNormalDirection

def NormalizeVector(vector):
    vLength = VLength(vector)
    for axis in range(0,3):
        vector[axis] = vector[axis]/vLength
    return vector

def VLength(vector):
    vLength = 0
    for axis in range(0,3):
        vLength += pow(vector[axis],2)
    vLength = math.sqrt(vLength)
    return vLength

def GetAngleToAxis(vector):
    vLength = VLength(vector)
    angleToAxis = [0,0,0]
    for axis in range(0,3):
        angleToAxis[axis] += math.degrees(math.acos(vector[axis]/vLength))
    return angleToAxis

faceSelection = cmds.filterExpand(sm=34)
normal = GetNumericNormalValue(GetFaceNormal(faceSelection))
normal = NormalizeVector(normal)
normalAngles=GetAngleToAxis(normal)
cmds.manipPivot(o=normalAngles)

1 Answers1

0

There are a few ways to interpret the data but if given a vector you want the respective rotations per major axis you take the inverse tangents of the components of the vector. The choice of components determines the axis of rotation:

inVec = /(input vector)/
rotZ = atan(inVec.y/inVec.x)
rotY = atan(inVec.x/inVec.z)
rotX = atan(inVec.y/inVec.z)

results are in radians.

rebusB
  • 518
  • 5
  • 19
  • This is not a good solution for one it fails if inVec.z is 0. Not only that but it gives the wrong result for say the vector <1.0,1.0,1.0>, it gives the rotation of 45, 45, 45 but thats not the right answer. Euler angles just do not work like this. – joojaa Jun 07 '16 at 20:17
  • That was an error, now fixed, but you are right about not getting proper Eulers out of this. These would be the rotations of the vector projected down the axes. I think the closest Eulers are from conversion to spherical coord. – rebusB Jun 07 '16 at 22:28
  • Indeed, one vector does not define three Euler angles! [This Link about the subject may help.](http://stackoverflow.com/questions/21622956/how-to-convert-direction-vector-to-euler-angles) – rebusB Jun 07 '16 at 22:49
  • how about using aran2? – joojaa Jun 08 '16 at 14:45
  • not familiar with that... you mean [atan2(y,x)](https://docs.python.org/2/library/math.html#math.atan2)? That would work... – rebusB Jun 09 '16 at 15:31
  • Ah yes sorry typo. In a general you never want to use atan for angles like this but nearly always atan2 instead – joojaa Jun 09 '16 at 17:48