libgfx: Vector Math
Author: Michael Garland

## Vector Math

The `libgfx` vector math package provides classes that make it much more convenient to write vector equations. Two dimensional [Vec2], three dimensional [Vec3], and four dimensional [Vec4] vector classes are provided.

A vector consists of n numeric values. These vector types are actually implemented using template classes such as `TVec3<class T>` that allow the application to specify the type of value used to represent the vector elements. The standard classes described in this documentation (`Vec2`, `Vec3`, and `Vec4`) use double precision floating point values. Corresponding classes using single precision floating point values (`Vec2f`, `Vec3f`, and `Vec4f`) are also provided.

The elements of a vector are accessed with the standard bracket notation used for arrays. And like C++ arrays, vectors are indexed starting from 0. Thus the elements of a 3-vector can be assigned as follows:

        Vec3 v;

        v[0] = 1.0;
        v[1] = 0.0;
        v[2] = 2.0;

The default constructors (as used in the previous example) always initialize the vector elements to 0. All vector classes also provide constructors which accept the initial element values as arguments. Thus the previous example could be more succinctly written as:

        Vec3 v(1.0, 0.0, 2.0);

Vectors can also be automatically cast to `double` pointer types. Continuing the preceding example, the following is perfectly legal:

        double *w = v;     // w points to the first element of v
        w[1] = 3.14;       // Exactly equivalent to v[1] = 3.14

Warning: For efficiency reasons, accessors are not range checked. Thus you can legally write

        Vec3 v;
        v[42] = 3.14159;

and this will cause an invalid memory access beyond the bounds of the vector. This may cause a memory fault or it may just silently over-write other data. Therefore you must make sure that you only access valid elements of arrays.

### Arithmetic Operators

One of the primary goals of the vector package is to simplify the coding of vector equations. To accomplish this, it makes use of operator overloading.

Assignment Vectors can be assigned the values of other vectors or scalars. A vector assignment `v = w` copies the elements of `w` into the corresponding elements of `v`. A scalar assignment `v = 1.0` copies the given scalar, in this case `1.0`, into each of the elements of `v`.

Addition/Subtraction Vectors can be added together either with the binary addition operator (`u = v + w`) or the additive assignment operator (`u += v`). Subtraction operates similarly, using subtraction rather than addition operators.

Scalar Multiplication/Division Vectors can be multiplied by scalar values using either the binary operator (`v * 2.0`) or the accumulation operator (`v *= 2.0`). Scalar division operates similarly.

Inner Product The inner product (or dot product) of two vectors is written with the standard multiplication operator: `v * w`.

### Standard Vector Functions

All vector classes support a standard set of functions for performing common operations on vectors. These functions are:

        // Returns the squared length of the vector v
        inline double norm2(const Vec_& v);

        // Returns the length of the vector v
        inline double norm(const Vec_& v);

        // Adjusts v to have unit length.  Mostly equivalent to v/=norm(v)
        inline void unitize(Vec_& v);

Vector can also be read from and written to C++ iostreams using the standard `<<` and `>>` operators.