Newsgroups: comp.graphics
Path: utzoo!utgpu!watserv1!watdragon!rose!ccplumb
From: ccplumb@rose.uwaterloo.ca (Colin Plumb)
Subject: Re: 2 3D Vectors: Get a 3rd perp. to 1st?
Message-ID: <1991Jan15.233218.7646@watdragon.waterloo.edu>
Sender: daemon@watdragon.waterloo.edu (Owner of Many System Processes)
Organization: University of Waterloo
References: <6613@crash.cts.com> <22365@well.sf.ca.us> <6660@crash.cts.com>
Date: Tue, 15 Jan 91 23:32:18 GMT
Lines: 51

jcs@crash.cts.com (John Schultz) wrote:
>In <22365@well.sf.ca.us> levine@well.sf.ca.us (Ron Levine) writes:
>>In article <6613@crash.cts.com> jcs@crash.cts.com (John Schultz) writes:
>>>  Given two 3D vectors, compute a third vector normal to the first
>>>and in the plane of both. The two given vectors are unit length, and
>>>the result must be unit length. I've come up with two solutions:
>>>
>>>  Given unit vectors A and B, result is C:
>>>
>>>  2. C = (A*(A dot B) - B) / (sin(acos(A dot B))), [6 muls, 5 add/subs,
>>>                                                    2 table lookups,
>>>  Method two is much faster, and produces correct results with error
>>>increasing as the angle between A and B decreases. ...
>>>... Method one has much less error. Is there a faster
>>>way to do this, or with less error?

Why two table lookups?  sin(acos(x)) = sqrt(1-x^2) and the
division can be done in one lookup or, if you prefer,
near x=0, 1/sqrt(1-x^2) =

            2        4         6    35  8    63  10    231  12    429  14
   1 + 1/2 x  + 3/8 x  + 5/16 x  + --- x  + --- x   + ---- x   + ---- x
                                   128      256       1024       2048

           6435  16   12155  18    46189  20    88179  22    676039  24
        + ----- x   + ----- x   + ------ x   + ------ x   + ------- x
          32768       65536       262144       524288       4194304

          1300075  26    5014575  28      30
        + ------- x   + -------- x   + O(x  )
          8388608       33554432

This is similar to a problem I'm trying to solve.  I want to do very
fast (real-time animation) incremental rotation of an orthonormal basis
in 3-space.  E.g. rotate 1/20 degree up, then 1/20 degree right, then
1/20 degree right, etc.  The user has a joystick, and is flying over a
surface I'm texture-mapping.  The step size is always the same (1/20
degree is about right) but just multiplying by the matrix doesn't work
if you're composing it 10,000+ times.  I have to correct so the vectors
stay orthonormal.

In my application, accuracy is not important, as long as I don't get
sudden jumps in any of the vectors, and they never drift too far from
perpendicular.  Does anyone know a recurrence that takes an almost
orthonormal basis and returns a more nearly orthonormal basis that I
can execute once per step or something?  (If it matters, I'm using
scaled integers, not floating point.)

Your help is greatly appreciated.
-- 
	-Colin
