Vector3d:
---------

This class encapsulates both 3-d point and vector methods, with
overloaded operators for simple arithmetic. A vector is represented
using homogeneous coordinates, where the last coordinate is 0. Rather
than defining a separate class Point3d, we typedef Point3d to Vector3d
just reuse all the methods (without any error checking). All valid
combinations of points and vectors "should" work properly (up to
small floating point roundoff errors).

------------------------------------------------------------------------
WARNING! WARNING! WARNING! WARNING! WARNING! WARNING! WARNING!
------------------------------------------------------------------------

This class defines two types, Vector3d and Point3d, but they are
in fact exactly the same object (we typedef Point3d to be Vector3d).
The only means of distinguishing them is by looking at the last
coordinate. If it is a 0, the object is a vector (even if it is
declared to be a Point3d). If it is a 1, the object is a point (even
if it is declared to be a Vector3d). If it is anything else, then
the object is undefined. (You're on your own.)

There are two ways to define a point or vector object, either by
giving all four coordinates or by calling the functions Vector or
Point. The latter two functions automatically set the fourth
coordinate. For example:

  Vector3d u(1, 2, 3, 0);               // OK: this is a vector
  Point3d p(1, 2, 3, 1);                // OK: this is a point
  Vector3d v = Geom::Vector(1, 2, 3);   // OK: this is a vector (w = 0)
  Point3d q = Geom::Point(1, 2, 3);     // OK: this is a point (w = 1)

  Point3d r(1, 2, 3, 0);                // WARNING: This is a vector!
  Vector3d w = Geom::Point(1, 2, 3);    // WARNING: This is a point!

------------------------------------------------------------------------
Summary of methods: (x,y,z,w,s are scalars and v and u are vectors)
------------------------------------------------------------------------

    Vector3d()                  create vector (0,0,0)
    Vector3d(x,y,z,w)           create vector (x,y,z,w)
                                [w = 0 for vector, w = 1 for point]
    Vector3d(v)                 create a copy of vector v
    u = v                       vector assignment
    u += v                      u = u + v
    u -= v                      u = u - v
    u *= s                      u = u * s
    u /= s                      u = u / s
    u + v                       returns u + v
    u - v                       returns u - v
    s * u                       returns s * u
    u * s                       returns u * s
    u / s                       returns u / s
    u.length()                  returns u's length
    u.clamp(min, max)           clamp each coord to interval [min,max]
    u.clampLength(min, max)     clamp length to interval [min,max]
    u.normalize()               normalize u's length to unity
    Vector3d::normalize(u)      returns unit vector in u's direction
                                (u is not modified)
    Vector3d::dot(v,u)          returns (v . u)
    Vector3d::cross(v,u)        returns cross product (v x u)
    Vector3d::parProject(v,u)   returns parallel part of projection
                                of v onto u
    Vector3d::orthProject(v,u)  returns orthogonal part of
                                projection of v onto u
    Vector3d::cartesianToSpherical(v) return conversion of v from
                                Cartesian to Spherical coords
    Vector3d::sphericalToCartesian(v) return conversion of v from
                                Spherical to Cartesian coords
    Vector3d::zero()            return vector (0,0,0)
    Vector3d::xUnit()           return vector (1,0,0)
    Vector3d::yUnit()           return vector (0,1,0)
    Vector3d::zUnit()           return vector (0,0,1)

    Geom::Point(x, y, z)        return point (x, y, z, 1)
    Geom::Vector(x, y, z)       return vector (x, y, z, 0)

    Geom::affineComb(a, p, q)   returns (1-a)*p + a*q
    Geom::distance(p, q)        returns distance from p to q
    checkMe(GeomType t)         check that I'm of type "t"

    cout << u                   output u
