Rotating an objects axis

Started by
11 comments, last by AndyTX 18 years, 4 months ago
Hi I am kind of new to the world of 3d programing and I am still trying to get my head around everything. Anyway after looking at a few tutorials on the internet I have come up with the code listed below it works fine however I want to be able to rotate an object around its own axis not the global axis. The way it does the translations is in the following order x => y => z therefore if I rotate around the x axis then the object will roll fine, if for instance I had an aircraft the x axis will be the wings rolling. The y axis moves the nose left to right, and the z axis moves the nose up and down. If I rotate around the x axis 90 degrees however the y axis suddenly becomes the objects z axis therefore the y axis controls the pitch of the nose wheras the z axis controls the left to right rotation of the nose. This wouldnt be so complcated except because the x axis is always computed first the aircraft can roll correctly at any point reguardless of the rotation around the y and z axis or put another way the wings will always roll reguardless of the other axis, the y axis has priority over the z axis in a similar way except for when its at the mercy of the x axis. Therefore if I want the objects axis to rotate with the object I need to take into acount the rotation around the x axis in the case of y and the rotation around the x and y axis in the case of z. I can do this either when computing the vertices point in 3d space or when translating the inputs into the angles to rotate. The problem is that I am really strugling to maintain a grasp on whats happening as is so any tips will be most appreciated. The code below is in actionscript however it shouldnt be too disimilar to Java or C++. It is based heavily on code that was posted in a tutorial by a guy named senocar. p is the original point and does not change, r is the rotational transformation required for that point. Thanks - Ryan

	public function Transform3DPoints(p, r) {
		var sinx = Math.sin(r.x);
		var cosx = Math.cos(r.x);
		var siny = Math.sin(r.y);
		var cosy = Math.cos(r.y);
		var sinz = Math.sin(r.z);
		var cosz = Math.cos(r.z);

		var x = p.x;
		var y = p.y;
		var z = p.z;
		var xy = cosx*y-sinx*z; // cos(r.x) * y - sin(r.x)
		var xz = sinx*y+cosx*z; // sin(r.x) * y + cos(r.x) * z
		
		var yx = siny*xz+cosy*x; // sin(r.y) * (sin(r.x) * y + cos(r.x) * z) * x
		var yz = cosy*xz-siny*x; // cos(r.y) * (sin(r.x) * y + cos(r.x) * z) - sin(r.y) * x

		var zx = cosz*yx-sinz*xy; // cos(r.z) * sin(r.y) * (sin(r.x) * y + cos(r.x) * z) * x) - sin(r.z) * cos(r.x) * y - sin(r.x)
		var zy = sinz*yx+cosz*xy; // sin(r.z) * (sin(r.y) * (sin(r.x) * y + cos(r.x) * z) * x) + cos(r.z) * (cos(r.x) * y - sin(r.x))
		
		scaleRatio = focalLength/(focalLength+yz);
		x = zx*scaleRatio;
		y = zy*scaleRatio;
		z = yz;
		
		var transformed = make3DPoint(z,y,z);
		return transformed;
	}
Advertisement
I didn't study the code, but the problems you described are more or less unavoidable with Euler angles (e.g. yaw, pitch, and roll, like you're using). Sometimes you can get the behavior you want by reversing the order in which the rotations are applied, but for maximum flexibility you may want incremental local-axis rotations (as you suggested). To do this you need to maintain your rotation matrix (or quaternion) from frame to frame, orthogonalizing occasionally to prevent drift. To rotate about a local axis, you can construct an axis-angle matrix from the local axis and rotation angle and multiply on one side, or multiply by the corresponding global-axis rotation matrix on the other. Which side to multiply on depends on whether you're using row or column vectors.

That's just a brief overview, but maybe it will point you in the right direction.
Now I'm back to wondering about applying multiple rotations as a collective rotation where they basically all happen at the same time. What would happen if you interpolate the axes based on the angle? Completely unoptimized, say:
x:30°
y:45°
z:15°

The axis would be 30/45,45/45,15/45 the angle 45° and the result.. something. Hm, I'm pretty sure math books should have a formula to collapse rotations in an order independent way. But then, "looking" right for small to medium rotations would be fine enough.
f@dzhttp://festini.device-zero.de
You seem to be suffering from gimble lock.

One way around this is to use matricies or quaternions, by constructing a rotation matrix/quaternion with the eular angles relative to the objects axis and then multiplying the point by the given rotation matrix/quaternion.
Ok thanks for the help, I cant say I am perfectly clear on everything but I have some keywords to google for now.
Don't worry, the only think to keep in mind is: euler angles, aka "the dreadful let's-just-store-three-angles"-approach is usually worthless for anything but simple fps shooters. As you noticed, the order in which you applied all your rotations is important, but will be completely lost by storing just some angles.

Using a matrix is simple and straight forward. 3x3, with the parts of it being nothing but the right/up/fwd axes of the object. When you apply a rotation to it all axes are changed accordingly, so rotating around right (or x) will always rotate around whatever is "right" for the model/camera at this time. Plus, by applying it from the other side it basically happens "before" the rotations already applied and is hence using the global or world coordinate system.

Comment on Quaternions: don't. Unless you need to save every byte of memory you can. Some like them a lot because they look small and harmless (4 components compared to a matrix with 9). However, rotating a vector/point by a quaternion requires 2 quat. multiplications which require a) a lot more and b) less "intuitive" operations. Multiplying with a matrix is basically three dot products, screaming SSE. And funny enough, if you write out the two quat multiplications and break them down enough you get exactly the same as with converting back to a matrix and using that. Just with extra work for the conversion. The only advantage I can think of is that they might be a bit more robust when interpolating rotations close to 180° and concatenating them is 4 instead of 6 dot products (though probably not as nicely to use SSE for).

Have a look at them when you get around to it and have time, but if anyone claims they promise eternal life and happiness or can do things that matrices can't, then I would assume the person just doesn't know what matrices can do. Figure out where they are cheaper and where they are more expensive (and where the benefit justifies the hassle). They are a bit like pluecker coordinates. Looking really nice and cool for certain things, but also introducing extra work that may or may not negate whatver benefit they bring.
f@dzhttp://festini.device-zero.de
Quote:Original post by Trienco
Have a look at them when you get around to it and have time, but if anyone claims they promise eternal life and happiness or can do things that matrices can't, then I would assume the person just doesn't know what matrices can do. Figure out where they are cheaper and where they are more expensive (and where the benefit justifies the hassle). They are a bit like pluecker coordinates. Looking really nice and cool for certain things, but also introducing extra work that may or may not negate whatver benefit they bring.
Quoted for truth :)
Quote:Original post by Trienco
Have a look at them when you get around to it and have time, but if anyone claims they promise eternal life and happiness or can do things that matrices can't, then I would assume the person just doesn't know what matrices can do.

For sure: both matrices and quaternions are a complete description of orientation in 3D space. I wouldn't so quickly write off either though.

The advantages I see of quaternions:

1) Interpolation! Slerp is by far the biggest reason for using quaternions for animation, and I have seen no good derivation of it that uses matrices. Since it is so natural and cheap to do with quaternions, I also doubt that the matrix equivalent would be simpler OR faster.

2) Composing rotations is cheaper - with matrices it requires 9 (!) dot products, and quaternions only require a handlefull of mads.

3) Renormalizing a quaternion is much cheaper than reorthogonalizing a 3x3 matrix.

4) Their most natural geometric analog is the axis/angle representation, which is intuitive. Going between the two is very cheap for quaternions, and much more expensive for matrices.

5) Less storage/redundancy... not very significant in modern engines though.

Anyways I discount storage as a very valid comparison metric in most cases, and for the most part even performance is irrelivent (I've not yet come across a game engine that is CPU geometry transform limitted... maybe for software skinning, but that's probably better done in hardware nowadays).

That said I guess what it comes down to with quaternions is that there aren't many DISADVANTAGES of using them instead of rotation matrices. If you ever require the rotation matrix, they are readily converted cheaply. Composing quaternions is easy and cheap, renormalizing is very cheap, and most of all, with a nicely coded quaternion class, they are a drop-in replacement for 3x3 rotation matrices.

In any case I don't think it matters much which one you use, but I can see no compelling argument against using quaternions (even if you don't understand the math (which isn't really too difficult), there are plenty of FAQs that go as far as giving you the code to use...), and as far as I know, quaternions still have the interpolation card to play, which is huge once your engine stops just showing static scenes :)
Quote:Original post by AndyTX
Quote:Original post by Trienco
Have a look at them when you get around to it and have time, but if anyone claims they promise eternal life and happiness or can do things that matrices can't, then I would assume the person just doesn't know what matrices can do.

For sure: both matrices and quaternions are a complete description of orientation in 3D space. I wouldn't so quickly write off either though.

The advantages I see of quaternions:

1) Interpolation! Slerp is by far the biggest reason for using quaternions for animation, and I have seen no good derivation of it that uses matrices. Since it is so natural and cheap to do with quaternions, I also doubt that the matrix equivalent would be simpler OR faster.

2) Composing rotations is cheaper - with matrices it requires 9 (!) dot products, and quaternions only require a handlefull of mads.

3) Renormalizing a quaternion is much cheaper than reorthogonalizing a 3x3 matrix.

4) Their most natural geometric analog is the axis/angle representation, which is intuitive. Going between the two is very cheap for quaternions, and much more expensive for matrices.

5) Less storage/redundancy... not very significant in modern engines though.

Anyways I discount storage as a very valid comparison metric in most cases, and for the most part even performance is irrelivent (I've not yet come across a game engine that is CPU geometry transform limitted... maybe for software skinning, but that's probably better done in hardware nowadays).

That said I guess what it comes down to with quaternions is that there aren't many DISADVANTAGES of using them instead of rotation matrices. If you ever require the rotation matrix, they are readily converted cheaply. Composing quaternions is easy and cheap, renormalizing is very cheap, and most of all, with a nicely coded quaternion class, they are a drop-in replacement for 3x3 rotation matrices.

In any case I don't think it matters much which one you use, but I can see no compelling argument against using quaternions (even if you don't understand the math (which isn't really too difficult), there are plenty of FAQs that go as far as giving you the code to use...), and as far as I know, quaternions still have the interpolation card to play, which is huge once your engine stops just showing static scenes :)
Just wanted to comment quickly on the above. Just as an aside, you actually can interpolate rotation matrices just as you can with quats, but as you might expect it's a bit of a hack and, indeed, is neither simpler nor faster :)

Basically, pretty much everything you said in the above post it true, so I wanted to clarify why I suggested earlier that people not use quats, at least in certain circumstances. Part of the problem is the 'plenty of FAQs that go as far as giving you the code to use...' bit. It seems to me that any internet search for info on quaternions turns up as much misinformation and outright nonsense as it does useful material. My argument is that using quaternions rather than matrices should be an informed decision, based on a thorough understanding of the relative advantages and disadvantages of the degree evidenced in your post. It seems though that people often adopt quats without understanding them, which leads to, for example, the expectation of a magical cure for gimbal lock even when using Euler angles, or the misapplication of quats to a simple problem such as two-angle FPS camera movement. IMO this sort of ill-informed usage of quats does not help, and can be harmful in the sense that it perpetuates confusion and obscures the real issues involved.

So I just wanted to elaborate on that a little. But you're absolutely correct that for the informed user quats have many advantages over matrices.
Quote:Original post by AndyTX
1) Interpolation! Slerp is by far the biggest reason for using quaternions for animation, and I have seen no good derivation of it that uses matrices. Since it is so natural and cheap to do with quaternions, I also doubt that the matrix equivalent would be simpler OR faster.


Not faster, but getting the axis and angle and building a new rotation from the interpolated angle is still simple and intuitive.

Quote:
2) Composing rotations is cheaper - with matrices it requires 9 (!) dot products, and quaternions only require a handlefull of mads.


But seeing how many cross products are happening all over the place with quaternions it would be fair play to drop one axis and reduce it to a 2x3 matrix, only calculating the missing vector once when needed. So counting the ops it's 4 dots vs. 6, but the quat is wildly permutating it's components which might make it harder to get it done in parallel.

Quote:
3) Renormalizing a quaternion is much cheaper than reorthogonalizing a 3x3 matrix.


True, but shouldn't be necessary too often.

Quote:
4) Their most natural geometric analog is the axis/angle representation, which is intuitive. Going between the two is very cheap for quaternions, and much more expensive for matrices.


I wouldn't say much. 18 mults, 9 adds, 1 sin, 1 cos vs. 1 div, 3 mults, 1 sin, 1 cos.. if the compiler makes good use of SSE instructions the difference should be just a few ops.

Let's take a skeleton as a good use for quaternions because concatenating them is easier. Ignore hardware skinning, because with a variable number of bones per vertex it is pretty messy. Once you actually start transforming the vertices you can either stick with quats and probably spend more extra operations than you saved up to this time or you convert them all back to matrices, which will also eat up a good bit of time. With two boxes that return the same result if you feed them the same input they must be doing the same thing. And that means that if you break it down as far as you can and optimize away you will most likely end up with exactly the same formula/code.
f@dzhttp://festini.device-zero.de

This topic is closed to new replies.

Advertisement