CIS-3012 Homework #2: Quaternions

Due: Wednesday, February 8, 2017

To support this assignment the primary reading in the text is chapter 7 on classes and chapter 14 on operator overloading.


Complex numbers have two components usually called the real and imaginary parts. This concept can be extended to numbers called quaternions that have four components. Quaternions were originally developed in the mid-1800s by William Hamilton. Today they have application in computer graphics, computer vision, flight dynamics, and satellite navigation where they can be used to elegantly describe rotations in three dimensions.

Let quaternion q = (a, b, c, d) be a tuple of four real numbers. The various arithmetic operations on quaternions are defined as follows.

Before the division of quaternions can be described it is necessary to define two additional operations. The conjugate of a quaternion is (a, -b, -c, -d), and the norm of a quaternion is sqrt(a*a* + b*b + c*c + d*d). Finally, the inverse of a quaternion q is conj(q)/(norm(q)*norm(q)). Notice that the norm of a quaternion is a scalar and so the previous division is just scalar multiplication of conj(q) by 1/(norm(q)*norm(q)).

There are now two different forms of quaternion division. Suppose we are trying to compute q1/q2. Left division is inv(q2)*q1. Right division is q1*inv(q2). Because quaternion multiplication is not commutative, these two values are, in general, different.

Class Quaternion

For this assignment you are to write a class Quaternion. Your class should satisfy the following requirements.

  1. Your class should provide a default constructor that initializes a Quaternion object to zero.

  2. Your class should provide a constructor that allows the values of a, b, c, and d to be set. Use type double for the components of your quaternion.

  3. Your class should provide accessor methods that return the individual components of the quaternion.

  4. Your class should provide overloaded operators +=, -=, and *= that do quaternion addition, subtraction, and multiplication. These operations take one quaternion parameter (by reference to const) and leave their result in the current object. For example

            q1 += q2;   // Same as q1.operator+=(q2); Computes q1 = q1 + q2
  5. Your class should provide an additional overloaded *= that does scalar multiplication. For example

            q1 *= 2.0;  // Same as q1.operator*=(2.0); Computes q1 = 2.0 * q1
  6. Provide free functions that are the overloaded binary operators +, -, and * that do quaternion addition, subtraction, and multiplication. These operations take two quaternions and return a new quaternion without changing either of their arguments. They should be written to take both parameters as references to const. For example

            q1 = q2 + q3;  // Same as q1 = operator+(q2, q3); Neither q2 nor q3 is modified.

    Hint: You can trivially implement the binary infix operators in terms of +=, -=, and *=. Do the computations in a local quaternion and return that result.

  7. Provide a free function for the overloaded binary * operator that allows scalar multiplication. For example

            q1 = 2.0 * q2; // Same as q1 = operator*(2.0, q2); q2 is not modified.
  8. Your class should provide a method conj that return the conjugate of the current object and a method norm that returns the norm of the current object. Neither of these methods should take any parameters.

  9. Provide free functions left_division and right_division that compute quaternion division. Do not overload the division operator!

  10. Provide a free function operator<< that allows a quaternion object to be written to an output stream.

Be sure to use const wherever it is appropriate.

Name your source files Quaternion.hpp and Quaternion.cpp and submit them in a zip archive. Be sure to include your name in both files.

Last Revised: 2017-01-30
© Copyright 2017 by Peter C. Chapin <>