next up previous contents
Next: Rendering Algorithm Up: Volrend User's Guide and Previous: Data Format

Virtual Trackball

The section documents the algorithm used with the virtual trackball. In order to keep all angles in the range , an orientation variable keeps track of which axis you are looking along, from the set {x+,x-,y+,y-,z+,z-}. There is also a face_orient variable that keeps track of the quadrant of rotations in the viewing plane, from the set {n,r,u,l} referring to rotations by and respectively.

The input to the trackball is effectively a unit stick attached to the virtual sphere, the endpoints of which are given by xcomp and ycomp. The third degree of freedom is stored in sinomega, representing where is the rotation around this ``stick''. The output of the virtual trackball routine is the box variable, which contains the projections of the x,y,z axes of the bounding box, as well as the projection of the origin.

The heart of the virtual trackball consists of constructing the rotation/projection matrix. Consider a set of rotations , and about the , and axes respectively. Explicitly, the rotation matrices are given by:

The full rotation matrix is given , or

 
Figure: Angle variables defining the virtual trackball

The unit stick is simply rotated, i.e. . From the above expression for , we find that

The bounding box is then calculated from the rotation/projection matrix from the bounding box axes (dims.x, dims.y and dims.z) and the origin offs.

The other major part of the algorithm requires keeping track of the bounding box's origin and face orientation. To do this, a transition table is used,

typedef enum  {up, right, down, left} transfers;

/* nextface[orientation][direction] */
ag_orient_t nextface[6][4]=
{{{zp,r},{yp,l},{zm,n},{ym,n}},   /* xp orientation */
 {{yp,n},{zp,n},{ym,r},{zm,l}},   /* xm orientation */
 {{xp,r},{zp,l},{xm,n},{zm,n}},   /* yp orientation */
 {{zp,n},{xp,n},{zm,r},{xm,l}},   /* ym orientation */
 {{yp,r},{xp,l},{ym,n},{xm,n}},   /* zp orientation */
 {{xp,n},{yp,n},{xm,r},{ym,l}}};  /* zm orientation */

inline transfers XFER(const transfers dir) 
{return (transfers) ((dir-face_orient)&3);}
and is used for example if we are flipping the cube to the right
new_orient = nextface[orientation][XFER(right)];
So if we are facing the x+ direction, and the face is in the r orientation, the new orientation becomes z+, in the r facial orientation.

With the new orientation calculated, we also need to compute where the unit stick goes. If we are moving to the right, the new stick will appear on the left hand face of the box. Similarly, moving up, the stick will appear on the bottom face. To calculate the new and , it is simply a matter of applying the Rotation/Project Matrix (for example moving right):

To calculate the new sinomega, we must apply a consistency relation. In the case of moving right, we must have , which implies , or in other words, .

The dimensions and origin of the box are handled by a reorient routine, which returns the permuted values from some absolute storage dims_abs and offs_abs. It should also be noticed that the sign of offs.z will depend on whether one is looking in the positive or negative direction along the z axis.



next up previous contents
Next: Rendering Algorithm Up: Volrend User's Guide and Previous: Data Format



Russell Standish
Mon Feb 20 17:13:01 EST 1995