[sci.math] 3D rotation -- world v. screen coordinates with a mouse

jroth@allvax.enet.dec.com (Jim Roth) (10/22/90)

In article <1990Oct22.032645.12473@rodan.acs.syr.edu>, gbnewby@rodan.acs.syr.edu (Gregory B. Newby) writes...
> 
>Hi, All.  I need the transformation equations to navigate through
>three dimensional space.  I am rotating data on world
>coordinates, but must have them stay consistent with viewer
>coordinates.

You should set up your viewing pipeline so that the object to be viewed
is first translated and scaled to be in a conceptual "box" at the origin
with some convenient size, say [-1..1] on all sides.

Use a righthanded coordinate system with X to the right, Y upward, and
Z pointing at the viewer.

Let N be a normalization matrix which sends the object being viewed to the
canonical box above, and let P be a projection matrix which lets you view
what is inside the box in your window, applying any perspective transformation
or whatever.

Now, let R be a rotation matrix, initially the identity.  The transformation
pipeline will then be P * R * N.

To do your view manipulation, measure your mouse strokes in the graphics window
and define a rotation axis orthogonal to the current mouse stroke, lying in
the XY plane, and define an angle scaled to be some convenient measure of the
length of the mouse stroke.

To be specific, suppose you have captured a mouse motion from (x_old,y_old)
to (x_new,y_new), so delta_x = x_new-x_old, etc, and its length will be
len = sqrt(delta_x^2 + delta_y^2).

Then your unit vector will have components (-delta_y/len, delta_x/len, 0),
lying in the XY plane, orthogonal to the mouse stroke just measured.

To do your rotation, make a rotation, S, about this axis with the
values to do a rotation about this axis and update your rotation matrix,
R, with

	R = S * R

and update your viewing pipe P * R * N.

You can populate S by the usual values for rotation about an axis (ux,uy,uz)
with sn = sin(angle), cs = cos(angle), dn = 1-cos(angle).

	| cs+ux^2*dn     ux*uy*dn-uz*sn ux*uz*dn+uy*sn 0 |
	| ux*uy*dn+uz*sn cs+uy^2*dn     uy*uz*dn-ux*sn 0 |
	| ux*uz*dn-uy*sn uy*uz*dn+ux*sn cs+uz*dn       0 |
	| 0              0              0              1 |

- Jim