June 93 - 3-D ROTATION USING A 2-D INPUT DEVICE
3-D ROTATION USING A 2-D INPUT DEVICE
MICHAEL CHEN
One essential part of any 3-D graphics application is the ability to turn an object so
that it can be viewed from different sides. This article describes a user interface
technique called the Virtual Sphere that allows you to perform continuous 3-D
rotation using a 2-D input device such as a mouse. For those who have played with my
Rotation Controller application and have been waiting for source code, here it is! For
others, this article is a good way to learn something about interactive 3-D graphics
and user interfaces for 3-D.
There are many situations in which users might want to view a 3-D graphics object
from different sides. They might want to do so while constructing an object or
rearranging objects in a scene. Or they may be viewing a multimedia document and
want to turn around a 3-D object that's embedded in the page. Whatever the context,
it's important to provide a simple, intuitive interface for the task that's available to a
wide user base.
The problem of 3-D rotation has been approached in many ways. Some people have
designed their applications to use higher-degrees-of-freedom input devices such as
3-D mice, 3-D trackballs, the 6-D Spaceball, and the 6-D Polhemus. These devices
let you control values forx, y, and z (and perhaps roll, pitch, and yaw) at the same
time. Unfortunately, these input devices incur extra cost and must be available on the
machine currently being used. The user must also learn how to use the device and
possibly learn a new interface paradigm.
Other applications have stayed with 2-D input devices because of their familiarity
and availability. However, many of these applications will let you perform rotation
only about thex, y, or z axis, while others will let you use the mouse to perform only
"2-D rotations," in which the user must specify an axis of rotation lying on, say,
thex-y plane. In both cases, the user needs to change tools or hold down modifier keys
(or mouse buttons) to specify rotations about other axes. This is cumbersome, but
many have accepted the fact that they have only two degrees of freedom when using a
device like a mouse.
The Virtual Sphere controller is a user interface tool developed to solve the problem
of 3-D rotation using a 2-D input device. The controller allows continuous rotation
about an arbitrary axis in three- dimensional space. Because the controller works
with a 2-D input device, the interface can be used on a wide range of machines with a
mouse, trackball, touch screen, or similar device. (This article will assume the use of
a mouse.) An important part of the design effort was user testing. Not only must the
controller be technologically sound, it must also be easy to learn and use. Testing
results will be discussed later.
Grayscale version
Dithered version
Figure 1 The Initial Window, in Grayscale and With Dithering
USING THE VIRTUAL SPHERE INTERFACE
Before getting into the design and implementation of the Virtual Sphere interface, let's
first play a bit with the sample application. You'll need to use a machine running
System 7 or a System 6 machine with 32-Bit QuickDraw. Find and launch the
application VirtualSphereSample, provided on this issue's CD. As shown in Figure 1,
you'll see a 3-D house enclosed by the circular Virtual Sphere controller (hereafter
called thecue).
You'll see a color, grayscale, or dithered rendering of the house, depending on your
monitor and bit depth. To rotate the house, move the pointer inside the cue and then
drag the pointer around. Observe what happens to the house when you drag in the
following directions:
• left and right, beginning with the pointer at the center of the cue
• up and down, beginning with the pointer at the center of the cue
• around the edge of or outside the cue
See if you can position the house in a desired orientation.
The Virtual Sphere controller simulates the mechanics of a physical 3-D trackball
that can freely rotate about any arbitrary axis in three-dimensional space. The user
can imagine the cue to be a glass sphere that's encasing the object to be rotated.
Rotation is a matter of rolling the sphere and therefore the object with the pointer.
Up-and-down and left-and-right movement at the center of the cue is equivalent to
"rolling" the imaginary sphere at its apex and produces rotation about an axis lying on
the plane of the screen. Movement along (or completely outside) the edge of the cue is
equivalent to rolling the sphere at the edge and produces rotation about the axis
perpendicular to the screen.
The Virtual Sphere is unusual in the sense that you seem to be able to squeeze an extra
degree of freedom out of a 2-D input device. The action of rolling the Virtual Sphere
lets you specify an arbitrary rotation axis in three-dimensional space, with the
advantage that you don't need to think about the rotation axis. You just roll, and the
object turns in the expected way.
To validate the usefulness of the Virtual Sphere interface, two colleagues and I designed
an experiment to compare the performance of different rotational interfaces in a
matching task. In the experiment, the computer displays a house at a certain
orientation, and the user has to use the given rotational interface to match that
orientation. The performance measurement is based on time and accuracy. The result
showed that the Virtual Sphere was indeed easy to use and was fastest for complex
rotations. If you're interested in the details of the other rotational interfaces and the
experiment, they're described in "A Study in Interactive 3-D Rotation Using 2-D
Control Devices" (see "Recommended Reading" at the end of this article). A version of
the rotation controllers and computer experiment is available on this issue's CD.
HOW THE VIRTUAL SPHERE INTERFACE WORKS
The general idea of this interface is that the Virtual Sphere cue is drawn around the
object to be rotated. The cue is centered over the object's center of rotation and should
be just large enough to enclose the object. When the user drags over the cue, the
successivex-y locations of the pointer are used to incrementally rotate the object. The
next few paragraphs delve into the mathematics of this process. Those of you with an
aversion to vectors and trigonometry may want to skip ahead to the next section.
The orientation of the object is represented in the sample code by a 4 x 4 rotation
matrix. At each movement of the pointer, an incremental rotation matrix is computed,
using the Virtual Sphere algorithm. This matrix is then concatenated with the object's
matrix, and the object is redisplayed. This process is repeated until the user releases
the mouse button.
The incremental rotation matrix is computed using the Virtual Sphere algorithm as
follows: Figure 2 shows a cue as it appears on the screen and also gives the
corresponding 3-D view. The cue is conceptually a hemisphere protruding from the
screen. When the pointer is moved from pointp to pointq on the screen, we think of it
as moving from pointp' to pointq' on the surface of the imaginary hemisphere. We
compute the pointsp' and q'by projecting pointsp and q upward (that is, straight out
from the screen) from the circle to the surface of the hemisphere. To simplify the
math, we'll assume that the cue and hemisphere each have a radius of 1.
Figure 2 The Virtual Sphere Cue and Its Corresponding 3-D Hemisphere
Figure 3 Computing the Axis of Rotation
where
The Virtual Sphere algorithm just described is an improvement over the one
described in the paper "A Study in Interactive 3-D Rotation Using 2-D Control
Devices." The paper used a three-step procedure to convert movement of a 2-D input
device into a 3-D rotation matrix. However, it turns out that if we first convert the
2-D input to 3-D, the Virtual Sphere calculation can be done much more efficiently.
IMPLEMENTING THE VIRTUAL SPHERE INTERFACE
The preceding description of the Virtual Sphere algorithm probably sounds more
complicated than it is. The actual implementation is really quite simple. In fact, the
VirtualSphere module contains only one externally visible routine:
pascal void VirtualSphere (Point p, Point q, Point cueCenter,
Integer cueRadius, Matrix4D rotationMatrix)
{
CPoint3D op, oq;

/* Project mouse points to 3-D points on the +z hemisphere of a
* unit sphere. */
PointOnUnitSphere (p, cueCenter, cueRadius, &op);
PointOnUnitSphere (q, cueCenter, cueRadius, &oq);

/* Consider the two projected points as vectors from the center
* of the unit sphere. Compute the rotation matrix that will
* transform vector op to oq. */
SetRotationMatrix (rotationMatrix, &op, &oq);
}
USING THE VIRTUAL SPHERE INTERFACE
Let's look at how we use the VirtualSphere routine to rotate a 3-D object
interactively.
void DoRotation (WindowPtr window, EventRecord *event, Matrix4D
objectMatrix)
{
Point p, q;
short dx, dy;
Point sphereCenter;
Integer sphereRadius;
Matrix4D tempMatrix;
Matrix4D rotationMatrix;

p = event->where;
GlobalToLocal (&p);
/* Get mouse-down point in local coordinates.*/

/* Figure out where to place the Virtual Sphere cue. */
sphereCenter.h = kSphereCenterH;
sphereCenter.v = kSphereCenterV;
sphereRadius = kSphereRadius;
while (StillDown()) {
GetMouse (&q);
dx = q.h - p.h;
dy = q.v - p.v;
if (dx != 0 || dy != 0) {
VirtualSphere (p, q, sphereCenter, sphereRadius,
rotationMatrix);
MultiplyMatrix (objectMatrix, rotationMatrix,
tempMatrix);
CopyMatrix (tempMatrix, objectMatrix);
DrawWindow (window); /* Update the window. */
p = q;
/* Remember previous mouse point for next iteration.*/
}
}
}
When DoRotation is called, the 3-D object's current matrix is passed in as
objectMatrix. In the sample application, the Virtual Sphere cue is always centered on
the window and has a fixed size. Thus, sphereCenter and sphereRadius are assigned
with constants. In a general application, you'll need to determine which object is
selected and figure out the size and location of the cue (in the window's coordinates) to
surround the object. In any case, while the mouse button is still down and the mouse
has moved, we call VirtualSphere to obtain the incremental rotation matrix. This
matrix is concatenated onto the 3-D object's current matrix using MultiplyMatrix and
CopyMatrix. We then redraw the window to display the object at its new orientation.
This process is repeated until the mouse button is released.
CREATING A SIMPLE 3-D GRAPHICS SYSTEM
The real point of this article and the sample code is to demonstrate the Virtual Sphere
interface. However, it turned out that a large part of the effort involved went into
creating a simple 3-D graphics system. It was much more work than the
implementation of the Virtual Sphere algorithm itself! I wanted to provide a simple
system that would be accessible by the majority of Macintosh programmers and would
allow even low-end Macintosh models to do interactive 3-D graphics.
The graphics system I came up with is based on Graf3D. Graf3D is a simple library for
drawing 3-D graphics using a fixed-point interface to QuickDraw's integer
coordinates. I chose Graf3D because it's included in the THINK C and MPW
environments. It uses fixed-point math and runs reasonably quickly even on a
Macintosh SE! This means that the sample code should be quite usable for
alldevelopreaders.
One major caveat is that the Graf3D library is unsupported. Most people doing 3-D
graphics on the Macintosh probably won't care about this point, because they write
their own 3-D software and will simply port the Virtual Sphere code to their system.
I've provided the sample code using Graf3D to show how the whole system works. Also,
it's nice to be able to show that Graf3D is not as brain dead as some people might think.
GRAPHICS SYSTEM SPECIFICATION
The graphics system we need is extremely simple. It needs to be able to display only
one relatively simple 3-D object at the center of a window. We'll assume that the
entire object is visible so that we won't have to worry about 3-D polygon clipping
(which, unfortunately, is left as an exercise for thestudents in most 3-D graphics
courses). The object should be displayed with perspective projection. The displayed
object can only be rotated. We predefine the center of rotation to be the center of the
object.
On the display screen, we define the origin of the 3-D coordinate system at the center
of the screen, thex axis as extending to the right, they axis as extending upward, and
thez axis as coming out of the screen toward the viewer. Note that in the QuickDraw
coordinate system, they axis extends in the opposite direction.
For the sake of cosmetics, the graphics system should adapt to the monitor bit depth so
that the graphics can be shown on color, grayscale, and black-and-white displays. The
system must use double buffering to eliminate screen flicker.
To make the Virtual Sphere implementation easier to understand, I've used
floating-point math to compute the axis of rotation, the angle of rotation, and the 4 x 4
rotation matrix. However, we'll take advantage of the fixed-point math used in Graf3D
to speed up graphics drawing.
SETTING UP GRAF3D
To implement our simple graphics system using Graf3D, we create and associate a
Port3D to the grafPort in which the 3-D object is to be displayed. We place the camera