Hello,
I'm trying to figure out the best way to store linnear and angular velocity in my for-fun game engine. I currently have somewhat of a scene graph, where every node can have any number of children. I have a scene node at the top with a variable number of child nodes, and so on and so forth...
Anyway, each node has a relative and also an absolute 4x4 transformation matrix. The relative matrix stores the position and rotation of each node relative to its parent, and to calculate the absolute matrix for each node, I simply start at the top and recurse through each node in the tree, multiplying relative matrices as I go. And of course, the absolute matrix stores the node's position and rotation in absolute worldspace coordinates.
I tried using a scheme similar to this for velocity, but quickly realized that the rotation values in a matrix are clamped between -pi and pi. If I want to set the angular velocity to 2pi, it simply rolls over to zero and there's no rotation. Quaternions seem to suffer the same effect and Euler angles suffer from gimbal lock, so that leaves me with axis-angle format. If I do go with such though, how can I calculate the absolute linnear and angular velocities from the relative velocities that each node stores? I'll certainly need to do this, so my sound engine can query any of my sound nodes velocities (and the camera's) so that Doppler effects can be properly calculated.
Oh, and yes, I am new here. Although fewer, the articles here are much more up-to-date than those at gamedev, and the community seems friendly, so I thought I'd register myself an account and check it out. Maybe I can even give some help in return:).
Angular Velocity
Started by JoeCoder, Apr 02 2006 04:20 AM
7 replies to this topic
#1
Posted 02 April 2006 - 04:20 AM
#2
Posted 02 April 2006 - 04:07 PM
If you want robust angular velocities that always work store them as angle/axis. All other representations are just hacks (as you most probably already found out).
#3
Posted 03 April 2006 - 03:02 AM
Well, that solves one problem, but how can I derrive the absolute worldspace velocity and angular velocity further down in my tree? If that doesn't make sense, how can I apply a series of linnear and angular velocities and calculate my final ones from each of those, using the axis angle representation for angular velocity?
#4
Posted 03 April 2006 - 03:34 AM
The easiest way to concatenate two axis-angle rotation representations, as far as I am aware, is to convert them both to quaternions and multiply them, then convert back to axis-angle. The conversions are reasonably well-defined and are detailed here.
reedbeta.com - developer blog, OpenGL demos, and other projects
#5
Posted 03 April 2006 - 03:38 AM
That's simple enough and the library I wrote already supports it, but what stops the quaternions from having their rotation values clamped between -pi and pi? If I set an angular velocity of 2pi/sec it rolls over to 0pi/sec.
Edit: After thinking about it a little more, I could store very small angular velocities in a Matrix and call them say, the amount of rotation over 1/10^6th of a second, and then just multiply up from there when I actually apply the rotations. Even still, I'd be more comfortable with a real solution instead of a hack.
Edit: After thinking about it a little more, I could store very small angular velocities in a Matrix and call them say, the amount of rotation over 1/10^6th of a second, and then just multiply up from there when I actually apply the rotations. Even still, I'd be more comfortable with a real solution instead of a hack.
#6
Posted 03 April 2006 - 06:19 AM
Hang on. Now that I think about it, angular velocity is just a vector, not an axis-angle pair - the direction of the vector is the axis about which to rotate, and its magnitude is the speed of the rotation. You then integrate the velocity over time to get an actual rotation: if you're using quats for rotations, the equation is q' = 1/2 wq where q is the current rotation, q' is the derivative of the rotation, and w is the angular velocity vector (considered as a quaternion with scalar part 0); and if you're using rotation matrices, the equation is R' = w*R where R is the current rotation matrix, R' is the derivative of the matrix, and w* is the matrix
(The above is from David Baraff, Unconstrained Rigid Body Dynamics. In case you haven't heard of him, Baraff is one of the seminal researchers in the field of computational physics.)
However, I don't think you're going to be able to concatenate angular velocities directly. Although it's true that the concatenation of two rotations is another rotation, the same doesn't necessarily hold true for derivatives of rotational motions. You can see by thinking of a rotating propeller on an airplane that's yawing slowly; the motion of the propeller relative to the world can't be described by a single angular velocity.
Nevertheless, you should be able to come up with a linear velocity for any point on any body, taking into account both linear and rotational motion all the way up the tree. The basic equation is v = cross(w, r) where v is the velocity of a point on a rotating body, w is the angular velocity of the body, and r is a perpendicular vector from the axis of rotation to the point in question. So you should be able to calculate Doppler shifts for point sources located on rotating bodies without too much trouble
[ 0 -w.z w.y ] [ w.z 0 -w.x ] [ -w.y w.x 0 ]
(The above is from David Baraff, Unconstrained Rigid Body Dynamics. In case you haven't heard of him, Baraff is one of the seminal researchers in the field of computational physics.)
However, I don't think you're going to be able to concatenate angular velocities directly. Although it's true that the concatenation of two rotations is another rotation, the same doesn't necessarily hold true for derivatives of rotational motions. You can see by thinking of a rotating propeller on an airplane that's yawing slowly; the motion of the propeller relative to the world can't be described by a single angular velocity.
Nevertheless, you should be able to come up with a linear velocity for any point on any body, taking into account both linear and rotational motion all the way up the tree. The basic equation is v = cross(w, r) where v is the velocity of a point on a rotating body, w is the angular velocity of the body, and r is a perpendicular vector from the axis of rotation to the point in question. So you should be able to calculate Doppler shifts for point sources located on rotating bodies without too much trouble
reedbeta.com - developer blog, OpenGL demos, and other projects
#7
Posted 09 April 2006 - 05:55 PM
I used the cross product you mentioned above to great effect--but how can I cascade it? For example, If I have one rotating object attached a certain distance away from another rotating object, etc.?
Specifically, once I calculate the velocity of one, how do I "sum" it with the velocity of it's parent? Simply adding the vectors together fails in most situations.
Here's an illustration of why it doesn't work:
A--------B---------C
A is rotating. B is attached to A. B doesn't rotate. C is attached to B.
I can calculate the linnear velocity of B perfectly. Since B doesn't rotate, C's velocity relative to B is zero. But if I add the velocity of B to that relative velocity of C, then I come out with a result that shows C's linnear velocity is the same as B's--and that's not the case.
Specifically, once I calculate the velocity of one, how do I "sum" it with the velocity of it's parent? Simply adding the vectors together fails in most situations.
Here's an illustration of why it doesn't work:
A--------B---------C
A is rotating. B is attached to A. B doesn't rotate. C is attached to B.
I can calculate the linnear velocity of B perfectly. Since B doesn't rotate, C's velocity relative to B is zero. But if I add the velocity of B to that relative velocity of C, then I come out with a result that shows C's linnear velocity is the same as B's--and that's not the case.
#8
Posted 09 April 2006 - 07:17 PM
When adding in relative velocities due to rotation, you have to take into account the location of the body for which relative velocity is being added. Since B and C are at different points in A's coordinate frame, they will recieve different linear velocities relative to the world as a result of A's rotation. I think the easiest way to think of this is not as velocities propogating down the tree from the root node, but up the tree from the leaves. To find out C's velocity with respect to the root node (world), you first calculate its velocity relative to B (zero) and then its velocity relative to A (zero); to get its velocity relative to the world, you have to use the cross product formula for A's rotation, considering that the point in question ("r") is C and not B.
reedbeta.com - developer blog, OpenGL demos, and other projects
1 user(s) are reading this topic
0 members, 1 guests, 0 anonymous users











