Rotations flipping after 180 degree duplicate transform

I’ve got an object that I’m duplicating into a ring by moving it’s pivot point away on an axis and then duplicating to rotate around that point, and applying duplicate transform. I’ve also tried with duplicate special at 5 degrees and 71 instances. The object has it’s x axis at 180, y at 0 and z increments. For some reason when it passes 180, x becomes 0, y becomes 180 and z resets to 0. This continues til about 90 degrees where it flips to -90 degrees working it’s way back to 0 to complete the circle. It’d be great to either go to 270 degrees or -180 without the x and y being switched and starting from 0 on z…

I can do this manually, just confused why Maya is doing this. I can’t seem to find anything in settings and not had much luck on google. While it looks fine and correct visually in Maya, I’m exporting the transform data to a game engine which uses Quaternions and for this 90 degrees section it’s coming out wrong. I have noticed that if I take the z value and *-1 it’ll be correct. That’s not a condition I could easily recognize via code though, intending to use Maya as an editor for level layout for the game engine.

this behavior is not unique to maya, but you if know that you are rotating on only 1 axis, you could temporarily lock the other 2 axes while duplicating and rotating to force the rotation to go beyond 180.

Inside maya, this is actually a UI issue: the manipulations are done in matrices but then converted to eulers. Unfortunately the conversion between matrices and euler rotations is not deterministic (hence, all the damn Euler flip issues that plague maya animations). It’s based on conventions – that’s why we specify rotation order in Maya transforms – but even then a 0,0,0 rotation and a 0,0,720 rotation create the exact same matrix. So you can’t rely on the numbers that come out of constraints or IKs to behave the way you expect in Euler space.

Quaternions suffer from a related problem. Like matrices, they don’t represent actions: they represent orientations. Thus there is no quaternion equivalent of ‘900 degrees’.

You could achieve the visual result by iteratively applying your quaternion rotation to the same object, however: 10 90 degree relative rotations will be the same as a single 900 degree rotation.

The other complication is that not all matrix > euler or euler > matrix conversions are equal: in particular, if you send Maya data to another program your maya rotation order and the other programs euler conversion rotation order are different you’ll get visually similar results. If you’re sending the data yourself, matrices or quaternions are better than eulers because they don’t rely on other knowledge.

1 Like

[QUOTE=Theodox;27049]Inside maya, this is actually a UI issue: the manipulations are done in matrices but then converted to eulers. Unfortunately the conversion between matrices and euler rotations is not deterministic (hence, all the damn Euler flip issues that plague maya animations). It’s based on conventions – that’s why we specify rotation order in Maya transforms – but even then a 0,0,0 rotation and a 0,0,720 rotation create the exact same matrix. So you can’t rely on the numbers that come out of constraints or IKs to behave the way you expect in Euler space.

Quaternions suffer from a related problem. Like matrices, they don’t represent actions: they represent orientations. Thus there is no quaternion equivalent of ‘900 degrees’.

You could achieve the visual result by iteratively applying your quaternion rotation to the same object, however: 10 90 degree relative rotations will be the same as a single 900 degree rotation.

The other complication is that not all matrix > euler or euler > matrix conversions are equal: in particular, if you send Maya data to another program your maya rotation order and the other programs euler conversion rotation order are different you’ll get visually similar results. If you’re sending the data yourself, matrices or quaternions are better than eulers because they don’t rely on other knowledge.[/QUOTE]
The game uses Quaternions for rotations, when I took the euler values and converted to quaternions to put in the game, -90 degree to 180 degrees displays fine, it’s after 180 degrees that it switched x:180 y:0 to x:0 y:180, and reset z to 0 which increments to 90…So it’s effectively the same as as the first quarter of the circle/ring. If I manually fix the euler values it’ll convert fine, it’s just maya’s duplicate transforms that did this odd behaviour. Perhaps I didn’t convert euler to quaternion right? seems fine for everything else though.

def crop_rotation(angle):
if angle > 180:
return angle-360
elif angle < -180:
return angle+360
else:
return angle

def convert_to_radians(degrees):
return (degrees/180) * math.pi

def euler_to_quaternion(angle_x, angle_y, angle_z):
heading = convert_to_radians(angle_y)
attitude = convert_to_radians(angle_z)
bank = convert_to_radians(angle_x)

c1 = math.cos(heading/2)
c2 = math.cos(attitude/2)
c3 = math.cos(bank/2)
s1 = math.sin(heading/2)
s2 = math.sin(attitude/2)
s3 = math.sin(bank/2)
w = (c1 * c2 * c3) - (s1 * s2 * s3)
x = (s1 * s2 * c3) + (c1 * c2 * s3)
y = (s1 * c2 * c3) + (c1 * s2 * s3)
z = (c1 * s2 * c3) - (s1 * c2 * s3)
return Quaternion(w, x, y, z)

snippet of relevant code using the above functions

angles x/y are flipped to match the game engines correctly

angles are cropped to fit into -180 to 180 bounds, may not be necessary?

angleX = crop_rotation(cm.getAttr(selected+‘.rx’)-1)
angleY = crop_rotation(cm.getAttr(selected+‘.ry’)
-1)
angleZ = crop_rotation(cm.getAttr(selected+‘.rz’))

q = euler_to_quaternion(angleX, angleY, angleZ)

I tried @rgkovach123’s solution, locking x/y rotations and then shift+d after the first duplicate rotation to test this out, this was the result:

If I keep x/y at 0 degrees instead of one being 180 though, regardless if I lock the axis, everything is fine: