Copyright 1995

A C++ math library

The page describes software for internal use at the GRASP and HMS labs of the University of Pennsylvania.
1. Introduction
2. Vectors
3. Rotational matrices
4. Transformation matrices
5. Geometry
6. Compiling

1

Introduction

This page describes the C++ math library written as part of the teleprogramming project. It includes code for vector operations, transformation math and some simple geometry. I've tried to make the code simple and elegant - hope that you agree!

You're welcome to browse through the code - its in:

~tele/iris/src/maths/*.[ch] on grip.cis
2

Vectors

The ptVector class defines a range of operations for vectors composed of exactly 3 real numbers:
    [x,y,z]
It is thus more efficient, but less general, than standard vector libraries which must handle vectors of arbitrary length.

All of the standard vector operations are supported (most with overloaded operators) so you can add, subtract, and scale vectors as well as taking the cross product, finding magnitudes and normalizing. You can also compare and print them.

For example, here's some code using the ptVector class which invokes the dot product operator to compute a.b and prints the final answer.

#include "ptMathLib.h"
ptVector a(0,0,3), b(0.5, 0.5, 3.0);

ptReal c = a*b;

cout << "a=" << a << " b=" << b << " a*b =" << c << "\n";
In writing the code I've attempted to keep things simple. Here's an example of the code the library uses to compute vector dot-products:
inline ptReal operator*( const ptVector& a, const ptVector& b )
{
  return a.x()*b.x() + a.y()*b.y() + a.z()*b.z();
}
In addition to ptVector there is also a ptNormal class. Every normal "isa" vector. The only distinction is that the magnitude of a ptNormal is guaranteed to always be 1.0. This allows some functions to be more efficient; for example, to test equality of two normals the system only needs to look at the first two elements.

A complete list of the available functions for both vectors and normals is in the ptVector.h file.

3

Rotational matrices

The ptRotation class defines a set of operations for 3x3 rotational matrices of the following form:
       /  n.x  o.x  a.x  \
       |  n.y  o.y  a.y  |
       \  n.z  o.z  a.z  /
You can create such matrices either by specifying all 9 real numbers, or by specifying 3 vectors, or by specifying an axis and angle of rotation.

You may decompose rotational matrices by using n(), o() and a() to get the columns or x(), y() and z() to get the rows.

The standard operations are supported so you can compute dot products of vectors and matrices, as well as taking the transpose, inverse, converting to RPY or Euler coordinates, comparing equality and printing results.

Here's the code the library uses to compute the dot product of a 3x3 rotational matrix with a vector - note how it makes use of the prior code for computing vector dot products.

ptVector operator*(const ptRotation& r, const ptVector& v)
{
  return ptVector(r.x() * v,
		  r.y() * v,
		  r.z() * v );
}
Here's an example which uses the library to rotate a normal by 45 degrees about the plus Z axis:
#include "ptMathLib.h"
ptNormal a(1,0,0);
cout << "result=" << ptRotation( ptNORM_PLUS_Z, 45*ptDEG_TO_RAD)*a << "\n";
A complete list of the available functions is in the ptRotation.h file.

4

Transformation matrices

The ptTransform class defines operations for 4x4 transformation matrices of the following form:
       /  n.x  o.x  a.x  p.x \
       |  n.y  o.y  a.y  p.y  |
       |  n.z  o.z  a.z  p.z  |
       \   0    0    0    1   /
The n,o and a vectors form a 3x3 rotational matrix (see previous section). You can construct a transform from 12 numbers, or 4 vectors, or a rotational matrix and a p vector.

They may be decomposed into rotational and translational components by using rot() and trans(), or into vectors by using n(), o() a() and p(). The standard operations of dot product, inversion, equality and output are supported. The standard robotics notation is adopted, thus when you take the dot product of a transform and a vector the vector is extended to a 1x4 by appending a 1 while when you take the dot product of a transform with a normal the normal is extended to a 1x4 by appending a 0. The result is that vectors are transformed while normals are rotated.

Since the transform math is written using the vector and rotation classes it can be very elegant. For example, here is the code the library uses for computing the dot product of a transformation matrix with a vector and a normal:

ptVector ptTransform::operator*(const ptVector& v) const
{ 
  return rot() * v + trans();
}

ptNormal ptTransform::operator*(const ptNormal& n) const
{ 
  return rot() * n;
}
A complete list of the available functions is in the ptTransform.h file.

5

Geometry

The ptGeometry.[ch] files define a set of classes for performing simple geometry. They define the following (all of which exist in 3-D Cartesian space):
ptPoint
A point
ptLine
An infinite line
ptLineSegment
A line between two points
ptPlane
An infinite 2-D plane
ptSurface
A convex 2-D polygon
ptCircle
A circle
Then there are sets of functions which operate on combinations of these classes, for example you can use ptDistance(x,y) to compute Cartesian distances between objects and ptIntersection(x,y) to compute the intersection (if any) between two objects. Not all combinations have been implemented (see .h file for full list).

Here's an example which computes the distance from the origin to a circle with radius 5 centered at [0,0,10] lying on the y-z plane.

#include "ptMathLib.h"
ptCircle circle(ptPoint(0,0,10), 5, ptNORM_PLUS_X);
ptPoint  origin(0,0,0);

cout << "Distance =" << ptDistance(origin,circle) << "\n";
6

Compiling

The library has been written and tested using an initial CFront-based C++ compiler and, more recently using the Delta C++ (DCC) compiler on the SGI machines. At this time the DCC compiler is by far the best available on any of the machines in the lab and it is strongly recommended that you use it.

To compile with the library you'll need to add ~tele/iris/inc to your include path and then link with libptMath.so

Here's an example:

DCC -fullwarn -g -I/home/tele/iris/inc test.c -o test /home/tele/iris/libptMath.so -lm
The library is compiled as a dynamically shared object file (see man DSO). When you execute a program compiled with it you'll need to set LD_LIBRARY_PATH to ~tele/iris/lib.



Craig Sayers (sayers@grip.cis.upenn.edu) May 1995