Rotating an instance with the y axis
Try to rotate a MovieClip instance named my_mc 80 degrees with the y axis. The trace() function in the code below displays information in the [Output] panel as follows:
80.00003182368921 1.3962639570236206
var nRotationY:Number = 80; my_mc.rotationY = 0; var myMatrix3D:Matrix3D = my_mc.transform.matrix3D; myMatrix3D.prependRotation(nRotationY, Vector3D.Y_AXIS); trace(my_mc.rotationY, myMatrix3D.decompose()[1].y);

Then change the number of degrees in the variable, nRotationY, to 100. The code seems to rotate an instance 100 degrees. However, the number of degrees shown in the [Output] panel is still 80.
80.00003182368921 1.3962639570236206
var nRotationY:Number = 100; // 80; my_mc.rotationY = 0; var myMatrix3D:Matrix3D = my_mc.transform.matrix3D; myMatrix3D.prependRotation(nRotationY, Vector3D.Y_AXIS); trace(my_mc.rotationY, myMatrix3D.decompose()[1].y);

The following code reveals the reason.
0 80.00003182368921 0
Vector3D(0, 1.3962639570236206, 0)
180.00000500895632 80.00003182368921 180.00000500895632
Vector3D(3.1415927410125732, 1.3962639570236206, 3.1415927410125732)
var mySprite:Sprite = new Sprite();
var axis:Vector3D = Vector3D.Y_AXIS; // Vector3D.X_AXIS // Try to change this
mySprite.rotationY = 0;
var myMatrix3D:Matrix3D = mySprite.transform.matrix3D;
myMatrix3D.prependRotation(80, axis);
xTrace(mySprite);
myMatrix3D.prependRotation(20, axis);
xTrace(mySprite);
function xTrace(targetSprite:Sprite):void {
trace(targetSprite.rotationX, targetSprite.rotationY, targetSprite.rotationZ);
trace(targetSprite.transform.matrix3D.decompose()[1]);
}
When the Matrix3D.prependRotation() method rotates an instance 100 degrees with y axis, it is only rotated 80 degrees but is flipped with x and z axes.
The appearance of the instance is all right. But the number of degrees is not good. Besides, 100 degrees can be set with x or z axis. It means that the result of y axis is not consistent. Therefore, I suspect that this is a bug.
4 Comments
I suspect it is not, it is just that multiple rotationX/Y/Z combinations describe the same orientation. This is not that unexpected, if you think about it; that’s the case even in 2D case, where there is only one rotation. E.g., run this code:
rotation = 800; trace (rotation); // traces 80 (10 times less
That is because values 80, 440, 800 etc all represent the same orientation, and you can only return one of these values when asked for it.
Thank you for your comment, makc.
I will still evaluate this issue as a bug. First, the operation with the y axis should not affect other axes. Second, rotation with x or z axis results the value between -180 and 180 degrees. However, the value with y axis can be set between -90 and 90 degrees. It is very difficult to explain mathematically its reason.
You are both right
The fact that its a bug can be demonstrated by manually setting the rotation of the object to 0,100,0 and 180,80,180. Visually, they do not represent the same orientation.
But makc is right that there are many multiples of different x,y,z rotations which can express the same orientation. That’s one reason why people like Quaternions or axis/Angle representations. The matrix (and therefore the decompose method) has no knowledge of what exact sequence of changes you made resulted in this orientation, it has to pick a plausible one. It seems to be returning the wrong values here, but you should not expect that it necessarily has to return 0,100,0 as the value.
To understand what we’re doing under the hood, the algorithm is based on graphics gems 3, III.3, “decomposing linear and affine transformations”
hi,
i looked into this and might give some insight. you will notice that setting the rotation (for any a) to (0,a,0) and (180,180-a,180) will always result in the same rotation. flash internally uses a 4×4 matrix to describe the rotation. Setting it with rotation angles creates one of those. decompose does no longer know about those angles but will return some angles that would result in the same matrix if plugged back in. it can not know if you got to the matrix the (0,a,0) or the (180,180-a,180) way. Quite frankly, using three angles for rotation (they are also called Euler angles for reference) gets complicated and confusing very quickly and should only be used for simple cases. For easier to follow math you should use 4×4 matrices directly.