aipdc@castle.ed.ac.uk (Paul D. Crowley) (11/30/90)
I'm writing a program that uses interactive graphics. It has a matrix M that represents the way you're facing, and applies it to every point in the scene before dividing by the depth and plotting the point on the screen. When I want to do a new rotation, I generate a matrix for that rotation which looks something like ( cos x sin x 0) A = (-sin x cos x 0) ( 0 0 1) I then do the matrix multiplication AM and place the result in M. My problem is that M is gradually getting further and further from being a rotation. Since the value for cos(x) is not exact, the matrix A is not exactly a rotation but a rotation followed by some other (small) transformation. But since M is multiplied by one of these very often, these small transformations build up, and the image becomes skewed in lots of nasty ways. What I'd like to do is apply some sort of process to M every so often that brings it back into line, ie that finds the rotation which M is closest to and changes it into that. But I have no idea what form what rotations will take. Incidentally, if it makes a difference, I lied a little bit up there: M is actually 4x4 since I'm operating on four-dimensional scenes. Solutions for three dimensions would also be appreciated, though. If anyone else is interested in this, mail me a "me too!" message. I'll forward everything I get to you, unless I get enough of them, in which case I'll summarise (and summarise properly, I promise) to the net. advaTHANKSnce -- \/ o\ Paul Crowley aipdc@uk.ac.ed.castle /\__/ "Trust me, I know what I'm doing" - Sledge Hammer
deb@elli.cs.cornell.edu (David Baraff) (12/01/90)
Try using unit quaternions to represent your rotations. After each multiplication, the quaternion is renormalized, preventing error from building up. I got this idea from the SIGGRAPH '88 paper "A modeling system based on dynamic constraints", by Ronen Barzel and Al Barr. Computer Graphics (Proc. SIGGRAPH), vol 22, pp. 179 - 188. I use this for my dynamic simulator and it works fine. David Baraff deb@graphics.cornell.edu
jcs@crash.cts.com (John Schultz) (12/01/90)
In <7386@castle.ed.ac.uk> aipdc@castle.ed.ac.uk (Paul D. Crowley) writes: [stuff deleted] >My problem is that M is gradually getting further and further from being >a rotation. Since the value for cos(x) is not exact, the matrix A is >not exactly a rotation but a rotation followed by some other (small) >transformation. But since M is multiplied by one of these very often, >these small transformations build up, and the image becomes skewed in >lots of nasty ways. >What I'd like to do is apply some sort of process to M every so often >that brings it back into line, ie that finds the rotation which M is >closest to and changes it into that. But I have no idea what form what >rotations will take. >Incidentally, if it makes a difference, I lied a little bit up there: M >is actually 4x4 since I'm operating on four-dimensional scenes. >Solutions for three dimensions would also be appreciated, though. If you consider your matrix as a set of orthonormal vectors, then all you need to do is restore the angles and lengths of the vectors so they are unit length and orthogonal to each other. There are many ways to do this. The simplest (and quickest) way is to normalize the first column of your matrix, then cross that vector with the next column, normalize the result, then cross the first column with the one you just normalized. The three resulting vectors make up your new matrix. For a 4x4 matrix, extend the process. Also, using this method, you don't need to do a complete matrix multiply, as the last column is completely interpolated. The column you pick as first to normalize will have the least angular error. I normalize cfi first, as the view is looking down z. Other methods include just renormalizing rows and columns on alternate passes, or a more complex (but more accurate method) is to find the matrix that is closest to the current matrix and is also orthonormal. The methods in this paragraph are described completely in "Graphics Gems", edited by Andrew Glassner [Academic Press]. John