OOP Meets Algebra,
Suggesting New "Ways of Looking"

by Kirby Urner
First posted: Feb 24, 1999
Last modified: Feb 28, 1999

How does the OOP way of thinking affect already well-defined algebraic concepts, such as quaternions? To say "a quaternion is a kind of object" doesn't sound very controversial, but we need to remember that "objects" aren't "just data" but also define operations. What quaternions do is a part of what they are.

This way of thinking is a little different from writing a quaternion as [s,v] and explaining s is the "scalar part" and v the "vector part". So far, that's just explaining a data format, giving an idea like:

        q.s = 1.0; 
        q.v = new double[]{1,0,0}; 

where q is some quaternion object with properties (fields) s and v. But what about methods? In standard text books, operators float semi-independently of their arguments. q1q2 (two quaternions multiplied) implies an operation (multiplication) that accepts two quaternions as input. In pre-OOP computer language, we might have written:

        q3 = mult(q1,q2);
which indicates that the output is also a quaternion.

But in the OOP model, we have the option to think of operations as part of the definition of the objects themselves. Instead of writing q3 = mult(q1,q2), we instead write:

        q3 = q1.mult(q2);
meaning that the "mult" operation is internal to each and every quaternion object, because a part of the generic quaternion's class definition, i.e. a part of the template behind all the special case instantiatons of this class, each with its own s and v components.

Likewise, quaterions know how to spit out their own multiplicative inverses:

        qinv = q1.inv();
This approach has the effect of making quaternions, as objects, seem "more intelligent" than if we regard them as simply holding patterns for data, structures consisting of scalar and vector parts, but devoid of operational savvy.

Likewise, when we want to use a quaternion to rotate a vector around the x, y, or z axis, we come to see this in terms of passing parameters to the "quaternion constructor" i.e. in Java we might write:

        Quaternion qx = new Quaternion("X",20);
meaning qx will now have the effect of rotating a given vector v 20 degrees around the x-axis, if used in an expression such as:
        newv = qx.mult(v).mult(qx.inv());  // i.e. newv = qx v qx^-1

where v and newv are themselves quaternions, but with 0 for their scalar parts.

Click here to view the my Java code for my Quaternion class, the template for all my special case quaternion objects. Notice that dot and cross products, used in the text book definitions of quaternion multiplication, aren't even available outside of the quaternion objects, because are defined to be 'private' methods (internal use only).


If your browser supports Java 1.1 or above, you should see a rotating cube at right. Actually, because of the Necker effect, it may look like a weird trapezoidal thing until you mentally reverse front and back faces: a different "way of looking". Clicking on or near the cubes starts/stops its motion.

Three quaternions, paired with their inverses, apply to each of the cube's 8 corners, causing a 1 degree/cycle rotation around each of the three orthogonal axes (x,y and z). Then the code projects these points to a flat surface (the screen) and paints the 12 connecting edges. Check boxes control which of the 3 quaternion "rotors" get applied.

Here's some of the Java:

  public class Cubist extends Artist {
  // I'm a Cubist.  I live inside a Studio object as an Artist,
  // and I know something about Quaternions (at least I hope I do)

  double cube [ ][ ];
  Quaternion qx, qy, qz, qxinv, qyinv, qzinv;
  boolean xrotor, yrotor, zrotor;

  Cubist(){
    // my Constructor -- I set out these tools as soon as you
    // create me as an object
    noPoints = 8;
    s1 = new int[noPoints][2]; // screen coordinates for cube
    cube = new double[noPoints][3]; // array for cube points
    refcube();  // initialize the cube

    qx = new Quaternion("X",1); // rotate 1 degree around X
    qy = new Quaternion("Y",1); // rotate 1 degree around Y
    qz = new Quaternion("Z",1); // rotate 1 degree around Z

    // I need the inverse of each of the above -- Quaternions
    // know how to return their own inverses
    qxinv = qx.inv();
    qyinv = qy.inv();
    qzinv = qz.inv();

    xrotor = true;
    yrotor = true;
    zrotor = true;
  }

  public void rotateCube() {
      for ( int i=0; i<8; i++ ) {

      // I'm getting the vector part after rotating each
      // cube corner i.e. c = (q c q^-1).vector

        if (xrotor) cube[i] = qx.mult(cube[i]).mult(qxinv).vector;
        if (yrotor) cube[i] = qy.mult(cube[i]).mult(qyinv).vector;
        if (zrotor) cube[i] = qz.mult(cube[i]).mult(qzinv).vector;
      }
  }

The process cycles at high speed within a Flipbook, thanks to the quick work of a Studio-resident quanternion-savvy Cubist (a subclass of Artist) -- more Java objects which I dreamed up for this paper (and plan to reuse in other projects).

In sum, the OOP model has the effect of "stuffing more operational intelligence into the objects themselves" (in this case quaternions), by defining the methods internally, in contrast to having us conceptualize operations as "outside" or "independent of" the entities in question.

Again, the OOP paradigm is potentially imparting a "new spin" to our pre-OOP algebraic concepts. These effects may be subtle, but I suspect are quite real and, over the long haul, will probably make quite a difference, both in our pedagogical approach to the material, and in the shape of innovations to come.

For further reading:

Return to Topics for Exploration


oregon.gif - 8.3 K
Oregon Curriculum Network