Path: utzoo!utgpu!jarvis.csri.toronto.edu!clyde.concordia.ca!uunet!wuarchive!zaphod.mps.ohio-state.edu!uwm.edu!lll-winken!arisia!sgi!shinobu!odin!victoria.esd.sgi.com!robert From: robert@victoria.esd.sgi.com (Robert Skinner) Newsgroups: comp.graphics Subject: Re: Errors in rotations Keywords: ROTATIONS Message-ID: <2496@odin.SGI.COM> Date: 5 Jan 90 19:25:09 GMT References: <47d784ba.20b6d@apollo.HP.COM> <1990Jan2.163405.24094@ibmpcug.co.uk> Sender: news@odin.SGI.COM Reply-To: robert@victoria.esd.sgi.com (Robert Skinner) Organization: Silicon Graphics, Inc. Lines: 57 In article <47d784ba.20b6d@apollo.HP.COM>, oj@apollo.HP.COM (Ellis Oliver Jones) writes: > I faced this problem some years ago on an E&S Picture System II. > I used a compromise solution (hack) as follows. > (1) The rotation matrix was kept separate, and was not composed > with translation or perspective matrices. > (2) A good rotation matrix (as opposed to a malformed one) is > unitary. This means that its determinant is one, obviously, > but it also means that each of the rows taken by itself > is a unit vector. Ditto for the columns. > (3) Every nth rotation cycle (1 perform a normalization step. Adjust the rotation matrix > such that each of the rows or columns, considered separately, > are unit vectors. This works well if you alternate > between rows and columns in successive normalization > steps. If you just normalize columns (or just rows) > the rotation will deteriorate into a skew. In practice > the alternation prevents this deterioration. > (4) The implementation of the normalization step was > carefully coded, using integer multiplies and > a decent integer Newton-Raphson-method square root. > See earlier postings in this newsgroup for some ideas. > > /Ollie Jones (speaking for myself, not necessarily for HP Apollo, nor for UCSF's > computer graphics lab, where I worked when I did this). Ollie is correct on (1), (2), and (4), but step (3) depends on luck for the corrections applied to rows to correctly cancel out the corrections applied to columns. Remember that rotation matrices are not only unitary, but are also orthogonal -- which means that each row (column) vector is orthogonal to all other row (column) vectors. You can use this fact to get a correct rotation matrix without switching between rows and columns. Here's how: starting with the first row vector (which I will call X, because this is what a unit vector on the X axis gets transformed into), normalize it to obtain X'. Then obtain the correct Z direction by finding the cross product of X' and Y and normalizing: Z' = norm( X' x Y ) Now you can find the correct Y by using the cross product again: Y' = Z' x X' (no need to normalize, because X' and Z' are unit length and orthogonal). The matrix is now a real rotation matrix, unitary and orthonormal. You still need a fast square-root for the normalization. Of course, this sort of assumes that X is correct each time. You could start with Y or Z other times, but my guess is that you probably won't notice any difference in sticking with X first, because the matrix is now correct. Robert Skinner robert@sgi.com