Go to most recent revision | Blame | Last modification | View Log | RSS feed
\documentclass[a4paper,landscape,twocolumn]{article}
\usepackage{listings}
\usepackage[isolatin]{inputenc}
\usepackage{makeidx,times}
\usepackage{fancyhdr}
\usepackage{graphicx}
\usepackage{float}
\usepackage{alltt}
%%\usepackage{doxygen}
\usepackage[pdftex,
pagebackref=true,
colorlinks=true,
linkcolor=blue
]{hyperref}
\makeindex
\lstset{tabsize=1,language=C++,basicstyle=\small}
\author{J. Andreas Bærentzen}
\title{CGLA usage}
\setcounter{tocdepth}{2}
\begin{document}
\maketitle
\tableofcontents
\section{Introduction}
CGLA is a set of numerical C++ vector and matrix classes and class
templates designed with computer graphics in mind. CGLA stands for
``Computer Graphics Linear Algebra''.
Let us get right down to the obvious question: Why create another
linear algebra package?
Well, CGLA evolved from a few matrix and vector classes because I
didn't have anything better. Also, I created CGLA to experiment with
some template programming techniques. This led to the most important
feature of CGLA, namely the fact that all vector types are derived
from the same template.
This makes it easy to ensure identical semantics: Since all vectors
have inherited, say, the * operator from a common ancestor, it works
the same for all of them.
It is important to note that CGLA was designed for Computer Graphics
(not numerical computations) and this had a number of
implications. Since, in computer graphics we mainly need small vectors
of dimension 2,3, or 4 CGLA was designed for vectors of low
dimensionality. Moreover, the amount of memory allocated for a vector
is decided by its type at compile time. CGLA does not use dynamic
memory. CGLA also does not use virtual functions, and most functions
are inline. These features all help making CGLA relatively fast.
Of course, other libraries of vector templates for computer graphics
exist, but to my knowledge none where the fundamental templates are
parametrized w.r.t. dimension as well as type. In other words, we have
a template (\texttt{ArithVec})that gets both type
(e.g. \texttt{float}) and dimension
(e.g. 3) as arguments. the intended use of this template is as
ancestor of concrete types such as \texttt{Vec3f} - a 3D floating
point type.
The use of just one template as basis is very important, I believe,
since it makes it extremely simple to add new types of
vectors. Another very generic template is \texttt{ArithMat} which is a
template for matrix classes. (and not necessarily NxN matrices).
From a users perspective CGLA contains a number of vector and matrix
classes, a quaternion and some utility classes. In summary, the most
important features are
\begin{itemize}
\item A number of 2, 3 and 4 d vector classes.
\item A number of Matrix classes.
\item A Quaternion class.
\item Some test programs.
\item Works well with OpenGL.
\end{itemize}
\subsection{Naming conventions}
Vectors in CGLA are named \texttt{VecDT} where \texttt{D} stands for
dimension at \texttt{T}
for type. For instance a 3D floating point vector is named
\texttt{Vec3f}. Other types are d (double), s (short), i (int), uc
(unsigned char), and usi (unsigned shourt int).
Matrices are similiarly named \texttt{MatDxDT}. For instance a 4D
\texttt{double} matrix is called \texttt{Mat4x4d}.
\subsection{How to use CGLA}
If you need a given CGLA class you can find the header file that
contains it in this document. Simply include the header file and use
the class. Remember also that all CGLA functions and classes live in
the CGLA namespace! Lastly, look at the example programs that came
with the code.
An important point is that you should never use the Arith... classes
directly. Classes whose names begin with Arith are templates used for
deriving concrete types. It is simpler, cleaner, and the intended
thing to do to only use the derived types.
In some cases, you may find that you need a vector or matrix class
that I haven't defined. If so, it is fortunate that CGLA is easy to
extend. Just look at, say, \texttt{Vec4f} if you need a \texttt{Vec5d}
class.
For some more specific help look at the next section where some of the
commonly used operations are shown.
\subsection{How to get CGLA}
If you have this document but not the code, look at\\
\href{http://www.imm.dtu.dk/~jab/software.html#cgla}
{http://www.imm.dtu.dk/~jab/software.html\#cgla}
\subsection{How to use this document}
This document is mostly autogenerated from Doxygen tags in the source
code. While this is the only way of creating documentation that
stands a reasonable chance of being updated every time the code is,
the method does have some drawbacks.
If you want to know whether a given class contains a given function,
first look at the class. If you don't find the function, look at its
ancestors. For instance, the class Vec3f certainly has a += operator
function but it is defined in the template class ArithVec.
Another problem is that since templates are used extensively in CGLA,
template syntax clutters this document. Unfortunately, that cannot be
helped.
\subsection{Help, bugs, contributions}
CGLA was written (mostly) by Andreas Bærentzen (jab{@}imm.dtu.dk), and
any bug fixes, contributions, or questions should be addressed to me.
\section{CGLA: Examples of Usage}
While this is mostly a reference manual some examples are probably
helpful. The examples below are by no means complete. Many things are
possible but not covered below. However, most of the common usage is
shown, so this should be enough to get you started. Note that in the
following we assume that you are \texttt{using namespace CGLA} and
hence don't prefix with \texttt{CGLA::}.
In short, to compile the examples below you would need the following
in the top of your file
\begin{lstlisting}{}
#include <iostream> // For input output
#include "CGLA/Vec3f.h"
#include "CGLA/Quaternion.h"
#include "CGLA/Mat4x4f.h"
using namespace std; // For input output
using namespace CGLA;
\end{lstlisting}
To begin with let us create 3 3D vectors. This is done as follows:
\begin{lstlisting}{}
Vec3f p0(10,10,10);
Vec3f p1(20,10,10);
Vec3f p2(10,20,10);
\end{lstlisting}
if we had left out the arguments the three vectors would have been
uninitialized, at least in release mode. If we compile in debug mode
they would have been initialized to ``Not a Number'' to aid
debugging. However, the $[10 10 10]^T$ vector could also have been
created differently, using
\begin{lstlisting}{}
Vec3f p0(10);
\end{}
A very common operation is to compute the normal of a triangle from
the position of its vertices. Assuming the three vectors represent the
vertices of a triangle, we can compute the normal by finding the
vector from the first vertex to the two other vertices, taking the
cross product and normalizing the result. This is a one-liner:
\begin{lstlisting}{}
Vec3f n = normalize(cross(p1-p0,p2-p0));
\end{lstlisting}
Quite a lot goes on in the snippet above. Observe that the - operator
also works for vectors. In fact almost all the arithmetic operators
work for vectors. You can also use assignment operators (i.e
\texttt{+=}) which is often faster. Then there is the function
\texttt{cross} which simply computes the cross product of its
arguments. Another frequently used function is \texttt{dot} which
takes the dot product. Finally the vector is normalized using the
function normalize.
Of course, we can print all or at least most CGLA entities. For
example
\begin{lstlisting}{}
cout << n << endl;
\end{lstlisting}
will print the normal vector just computed. We can also treat a vector
as an array as shown below
\begin{lstlisting}{}
float x = n[0];
\end{lstlisting}
here, of course, we just extracted the first coordinate of the
vector.
CGLA contains a number of features that are not used very frequently,
but which are used frequently enough to warrent inclusion. A good
example is assigning to a vector using spherical coordinates:
\begin{lstlisting}{}
Vec3f p;
p.set_spherical(0.955317, 3.1415926f/4.0f , 1);
\end{lstlisting}
CGLA also includes a quaternion class. Here it is used to construct a
quaternion which will rotate the x axis into the y axis.
\begin{lstlisting}{}
Quaternion q;
q.make_rot(Vec3f(1,0,0), Vec3f(0,1,0));
\end{lstlisting}
Next, we construct a $4\times 4$ matrix \texttt{m} and assign a translation
matrix to the newly constructed matrix. After that we ask the
quaternion to return a $4\times 4$ matrix corresponding to its
rotation. This rotation matrix is then multiplied onto \texttt{m}.
\begin{lstlisting}{}
Mat4x4f m = translation_Mat4x4f(Vec3f(1,2,3));
m *= q.get_mat4x4f();
\end{lstlisting}
Just like for vectors, the subscript operator works on
matrices. However, in this case there are two indices. Just using one
index will return the ith row as a vector as shown on the first line
below. On the second line we see that using two indices will get us an
element in the matrix.
\begin{lstlisting}{}
Vec4f v4 = m[0];
float c = m[0][3];
\end{lstlisting}
There is a number of constructors for vectors. The default constructor
will create a null vector as we have already seen. We can also specify
all the coordinates. Finally, we can pass just a single number
$a$. This will create the $[a\:a\:a]^T$ vector. For instance, below we
create the $[1\: 1\: 1]^T$ vector. Subsequently, this vector is
multiplied onto \texttt{m}.
\begin{lstlisting}{}
Vec3f p(1);
Vec3f p2 = m.mul_3D_point(p);
\end{lstlisting}
Note though that \texttt{m} is a $4\times
4$ matrix so ... how is that possible? Well, we use the function
\texttt{mul\_3D\_point} which, effectively, adds a $w=1$ coordinate to p
making it a 4D vector. This $w$ coordinate is stripped afterwards. In
practice, this means that the translation part of the matrix is also
applied. There is a similar function \texttt{mul\_3D\_vector} if we want
to transform vectors without having the translation. This function,
effectively, sets $w=0$.
Finally, CGLA is often used together with OpenGL although there is no
explicit tie to the OpenGL library. However, we can call the
\texttt{get} function of most CGLA entities to get a pointer to the
contents. E.g. \texttt{p.get()} will return a pointer to the first
float in the 3D vector \texttt{p}. This can be used with OpenGL's
``v'' functions as shown below.
\begin{lstlisting}{}
glVertex3fv(p.get());
\end{lstlisting}
\end{document}