# Trig Rotation

This topic is 2406 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

Need a little help with trig rotation following the website below:
http://www.kirupa.com/developer/actionscript/trig_multiple_axis.htm

For whatever reason, rotating around the center of the object using certain angles result in a flattening of the object.
Everything works good with two different axes rotations, but upon the introduction of the third, there's trouble.
If you have a solution, it has to be something simple I'm sure, any source would be much appreciated.

Thanks.

##### Share on other sites
Usually, any standard photo/image viewing software, such as the Windows Photo Gallery, will allow you to rotate an image by varying degrees. I believe you can right click the image in question and then select rotate clockwise/counter clockwise for the desired effect, and there is likely a way to adjust the exact degree you want to rotate by changing some options, but I don't know them off hand (Google). Hope this helped!

##### Share on other sites

Need a little help with trig rotation following the website below:
http://www.kirupa.com/developer/actionscript/trig_multiple_axis.htm

For whatever reason, rotating around the center of the object using certain angles result in a flattening of the object.
Everything works good with two different axes rotations, but upon the introduction of the third, there's trouble.
If you have a solution, it has to be something simple I'm sure, any source would be much appreciated.

Thanks.

Sounds like the problem could be due to Gimbal Lock .

You may be able to implement your three dimensional rotations as a matrix/quaternion instead of using Euler angles to solve this problem (if it is the problem I think it is). Do you have any screenshots/demo you could share?

##### Share on other sites

[quote name='oblivion_ocean' timestamp='1310840077' post='4836072']
Need a little help with trig rotation following the website below:
http://www.kirupa.com/developer/actionscript/trig_multiple_axis.htm

For whatever reason, rotating around the center of the object using certain angles result in a flattening of the object.
Everything works good with two different axes rotations, but upon the introduction of the third, there's trouble.
If you have a solution, it has to be something simple I'm sure, any source would be much appreciated.

Thanks.

Sounds like the problem could be due to Gimbal Lock .

You may be able to implement your three dimensional rotations as a matrix/quaternion instead of using Euler angles to solve this problem (if it is the problem I think it is). Do you have any screenshots/demo you could share?
[/quote]

If you could link me to some matrix/quaternion source that would be great, but using Euler angles is an attempt to keep things straight-forward.
I will definitely get some screenshots or make a small video illustrating the problem later this evening.

##### Share on other sites

[quote name='oblivion_ocean' timestamp='1310840077' post='4836072']
Need a little help with trig rotation following the website below:
http://www.kirupa.com/developer/actionscript/trig_multiple_axis.htm

For whatever reason, rotating around the center of the object using certain angles result in a flattening of the object.
Everything works good with two different axes rotations, but upon the introduction of the third, there's trouble.
If you have a solution, it has to be something simple I'm sure, any source would be much appreciated.

Thanks.

Sounds like the problem could be due to Gimbal Lock .

You may be able to implement your three dimensional rotations as a matrix/quaternion instead of using Euler angles to solve this problem (if it is the problem I think it is). Do you have any screenshots/demo you could share?
[/quote]

If you could link me to some matrix/quaternion source that would be great, but using Euler angles is an attempt to keep things straight-forward.
I will definitely get some screenshots or make a small video illustrating the problem later this evening.

Thanks again.

[/quote]

Could you use something like: Matrix3D?

there is also: Adobe ActionScript 3.0 * Working in three dimensions

An example given from that link:

 package { import flash.display.Sprite; import flash.display.Shape; import flash.display.Graphics; import flash.geom.*; public class Matrix3DTransformsExample extends Sprite { private var rect1:Shape; private var rect2:Shape; public function Matrix3DTransformsExample():void { var pp:PerspectiveProjection = this.transform.perspectiveProjection; pp.projectionCenter = new Point(275,200); this.transform.perspectiveProjection = pp; rect1 = new Shape(); rect1.x = -70; rect1.y = -40; rect1.z = 0; rect1.graphics.beginFill(0xFF8800); rect1.graphics.drawRect(0,0,50,80); rect1.graphics.endFill(); addChild(rect1); rect2 = new Shape(); rect2.x = 20; rect2.y = -40; rect2.z = 0; rect2.graphics.beginFill(0xFF0088); rect2.graphics.drawRect(0,0,50,80); rect2.graphics.endFill(); addChild(rect2); doTransforms(); } private function doTransforms():void { rect1.rotationX = 15; rect1.scaleX = 1.2; rect1.x += 100; rect1.y += 50; rect1.rotationZ = 10; var matrix:Matrix3D = rect2.transform.matrix3D; matrix.appendRotation(15, Vector3D.X_AXIS); matrix.appendScale(1.2, 1, 1); matrix.appendTranslation(100, 50, 0); matrix.appendRotation(10, Vector3D.Z_AXIS); rect2.transform.matrix3D = matrix; } } } 

Hope it helps!

##### Share on other sites
Thanks for the post, do you have it in C though?

It did happen again just now so, it's definitely something and it turned my 2D box into what looks like a toothpick.
I do think it is that Gimbal lock, which should be fine as long as it's rare and this does seem more difficult to replicate.
I am still playing with this, I'll let you know though ..and yes, C source if you have it, would be great.

##### Share on other sites

Thanks for the post, do you have it in C though?

It did happen again just now so, it's definitely something and it turned my 2D box into what looks like a toothpick.
I do think it is that Gimbal lock, which should be fine as long as it's rare and this does seem more difficult to replicate.
I am still playing with this, I'll let you know though ..and yes, C source if you have it, would be great.

Maybe this?

##### Share on other sites
[font=arial, verdana, tahoma, sans-serif][size=2]I can't imagine how gimbal lock can possibly result in flattening of the object. Perhaps you can post some of your code?[/font]

##### Share on other sites
Okay, I'll keep it simple and illustrate 2 formulas.
This formula works great, only thing is it's just 2 axis rotations.

mw.new_x = cos(degy)* x + sin(degy)*sin(degx)*y - sin(degy)*cos(degx)*z;
mw.new_y = 0 + cos(degx)*y + sin(degx)*z;
mw.new_z = sin(degy)*x + cos(degy)*-sin(degx) *y + cos(degy)*cos(degx)*z;
[/quote]

This is the one from the website (adjusted a bit) perhaps I'm implementing it wrong?
After I used a cube illustration, it's apparent gimbal lock isn't the problem.

mw.new_y = cos(anglex)*y - sin(anglex)*z;
mw.new_z = sin(anglex)*y + cos(anglex)*z;

mw.new_z = cos(angley)*mw.new_z - sin(angley)*x;
mw.new_x = sin(angley)*mw.new_z + cos(angley)*x;

mw.new_x = cos(anglez)*mw.new_x - sin(anglez)*mw.new_y;
mw.new_y = sin(anglez)*mw.new_x + cos(anglez)*mw.new_y;
[/quote]

##### Share on other sites
Gimbal lock may appear when performing several consecutive rotations. It means especially that, also performing 3 rotations, the 3rd rotation has no effect that could not be done with the 1st rotation already. So1. gimbal lock cannot be responsible for shape flattening, and
2. using matrices or quaternions doesn't prevent from gimbal lock.

The link in the OP doesn't work, so I haven't seen the effect on the shape. However, "flattening the object" sounds like scaling or perhaps shearing effect. That may happen in case that the coefficients of the rotation matrix are not set as is needed for pure rotations.

Furthermore, shape distortions will happen also simply when just enough consecutive rotations are performed. This is because of numerical inaccuracies. We are speaking of a few dozen matrix rotations and even more quaternion rotations. Hence I don't assume that the OP is based on this kind of problem, because the problem sounds to happen immediately with the 3rd partial rotation.

So could we get some code snippet to check?

EDIT: A more detailed post was made just during I wrote this answer. So please be patient ...

##### Share on other sites
Yep: The problem occurs probably because you override variables at moments where they must be still conserved:

 mw.new_z = cos(degy)*mw.new_z - sin(degy)*x; mw.new_x = sin(degy)*mw.new_z + cos(degy)*x; mw.new_x = cos(degz)*mw.new_x - sin(degz)*mw.new_y; mw.new_y = sin(degz)*mw.new_x + cos(degz)*mw.new_y; 
* In the 1st line the variable mw.new_z is overridden, although its "old" value is still needed in the 2nd line.
* In the 3rd line the variable mw.new_x is overridden, although its "old" value is still needed in the 4th line.

##### Share on other sites

Yep: The problem occurs probably because you override variables at moments where they must be still conserved:

Awesome, you saved me a lot of headache!
There is still one bug remaining however, x and z rotations work correctly, something else needs adjusting for y.

mw.new_y = cos(degx)*y - sin(degx)*z;
mw.new_z = sin(degx)*y + cos(degx)*z;

mw.new_z = cos(degy)*mw.new_z - sin(degy)*x;
mw.new_x = sin(degy)*z + cos(degy)*x;

mw.new_x = cos(degz)*mw.new_x - sin(degz)*mw.new_y;
mw.new_y = sin(degz)*x + cos(degz)*mw.new_y;
[/quote]

##### Share on other sites

mw.new_y = cos(degx)*y - sin(degx)*z;
mw.new_z = sin(degx)*y + cos(degx)*z;

mw.new_z = cos(degy)*mw.new_z - sin(degy)*x;
mw.new_x = sin(degy)*z + cos(degy)*x;

mw.new_x = cos(degz)*mw.new_x - sin(degz)*mw.new_y;
mw.new_y = sin(degz)*x + cos(degz)*mw.new_y;

This is not correct because now you conserve some values too long. Inside each individual rotation the values must be conserved, but not in-between the individual rotations. Something like

 mw.new_y = cos(degx)*y - sin(degx)*z; mw.new_z = sin(degx)*y + cos(degx)*z; temp = cos(degy)*mw.new_z - sin(degy)*mw.new_x; mw.new_x = sin(degy)*mw.new_z + cos(degy)*mw.new_x; mw.new_z = temp; temp = cos(degz)*mw.new_x - sin(degz)*mw.new_y; mw.new_y = sin(degz)*mw.new_x + cos(degz)*mw.new_y; mw.new_x = temp; 
should do the job (but I haven't checked whether the signs, cosines and sines are used as needed).

##### Share on other sites
Got it going! Very much appreciated.

##### Share on other sites
After looking at the implementation w.r.t. the formulas itself I have some more comments. The link provided in the OP is not working now, so I have no insight into the intent and hence I have to formulate some comments in a general way...

1. It seems me that the rotation directions are not consistent. Shouldn't the Y rotation be

 temp = cos(degy)*mw.new_z + sin(degy)*mw.new_x; mw.new_x = -sin(degy)*mw.new_z + cos(degy)*mw.new_x; mw.new_z = temp; 
instead (notice the both negated sine terms)?

2. The order of rotations as is implemented with the shown code is X, followed by Y, and completed by Z. This means in terms of local axis rotations, that the order is Z, then Y, then X. That is not wrong, and its exact meaning depends on what axes corresponds to the forward and up directions. The usual order is yaw (around UP, often Y), then pitch (around SIDE, often X), then roll (around FORWARD, often Z), what in summary would mean YXZ. So, please check whether the order is actually what you want.

3. It is common in programming languages that sin(a) and cos(a) are to be invoked with angles in radians. From the nomenclature of your variables it seems me that the angles are given in degrees. Please make sure that there isn't a unit mismatch.

4. Remember that Euler rotations used to manage an orientation are ever a source of problems. Switch to a more appropriate representation if possible.

Just from looking at the few lines of code I don't see any other issues.

##### Share on other sites
Another possible issue: There is perhaps a missing line of code.

 mw.new_x = x; // <<<< mw.new_y = cos(degx)*y - sin(degx)*z; mw.new_z = sin(degx)*y + cos(degx)*z;