394 |
jab |
1 |
\documentclass[a4paper]{article}
|
11 |
jab |
2 |
\usepackage{listings}
|
|
|
3 |
\usepackage[isolatin]{inputenc}
|
|
|
4 |
\usepackage{makeidx,times}
|
|
|
5 |
\usepackage{fancyhdr}
|
|
|
6 |
\usepackage{graphicx}
|
|
|
7 |
\usepackage{float}
|
|
|
8 |
\usepackage{alltt}
|
|
|
9 |
%%\usepackage{doxygen}
|
|
|
10 |
\usepackage[pdftex,
|
|
|
11 |
pagebackref=true,
|
|
|
12 |
colorlinks=true,
|
|
|
13 |
linkcolor=blue
|
|
|
14 |
]{hyperref}
|
|
|
15 |
\makeindex
|
|
|
16 |
\lstset{tabsize=1,language=C++,basicstyle=\small}
|
394 |
jab |
17 |
\author{J. Andreas B{\ae}rentzen}
|
11 |
jab |
18 |
\title{CGLA usage}
|
|
|
19 |
\setcounter{tocdepth}{2}
|
|
|
20 |
\begin{document}
|
|
|
21 |
\maketitle
|
|
|
22 |
\section{Introduction}
|
|
|
23 |
|
|
|
24 |
CGLA is a set of numerical C++ vector and matrix classes and class
|
|
|
25 |
templates designed with computer graphics in mind. CGLA stands for
|
394 |
jab |
26 |
``Computer Graphics Linear Algebra''. It is a part of the larger
|
|
|
27 |
package called GEL but deserves its own document since it is an important part.
|
11 |
jab |
28 |
|
|
|
29 |
Let us get right down to the obvious question: Why create another
|
|
|
30 |
linear algebra package?
|
|
|
31 |
Well, CGLA evolved from a few matrix and vector classes because I
|
|
|
32 |
didn't have anything better. Also, I created CGLA to experiment with
|
|
|
33 |
some template programming techniques. This led to the most important
|
|
|
34 |
feature of CGLA, namely the fact that all vector types are derived
|
|
|
35 |
from the same template.
|
|
|
36 |
|
|
|
37 |
This makes it easy to ensure identical semantics: Since all vectors
|
|
|
38 |
have inherited, say, the * operator from a common ancestor, it works
|
|
|
39 |
the same for all of them.
|
|
|
40 |
|
|
|
41 |
It is important to note that CGLA was designed for Computer Graphics
|
|
|
42 |
(not numerical computations) and this had a number of
|
|
|
43 |
implications. Since, in computer graphics we mainly need small vectors
|
|
|
44 |
of dimension 2,3, or 4 CGLA was designed for vectors of low
|
|
|
45 |
dimensionality. Moreover, the amount of memory allocated for a vector
|
|
|
46 |
is decided by its type at compile time. CGLA does not use dynamic
|
|
|
47 |
memory. CGLA also does not use virtual functions, and most functions
|
|
|
48 |
are inline. These features all help making CGLA relatively fast.
|
|
|
49 |
|
|
|
50 |
Of course, other libraries of vector templates for computer graphics
|
|
|
51 |
exist, but to my knowledge none where the fundamental templates are
|
|
|
52 |
parametrized w.r.t. dimension as well as type. In other words, we have
|
|
|
53 |
a template (\texttt{ArithVec})that gets both type
|
|
|
54 |
(e.g. \texttt{float}) and dimension
|
|
|
55 |
(e.g. 3) as arguments. the intended use of this template is as
|
|
|
56 |
ancestor of concrete types such as \texttt{Vec3f} - a 3D floating
|
|
|
57 |
point type.
|
|
|
58 |
|
|
|
59 |
The use of just one template as basis is very important, I believe,
|
|
|
60 |
since it makes it extremely simple to add new types of
|
|
|
61 |
vectors. Another very generic template is \texttt{ArithMat} which is a
|
|
|
62 |
template for matrix classes. (and not necessarily NxN matrices).
|
|
|
63 |
|
|
|
64 |
From a users perspective CGLA contains a number of vector and matrix
|
|
|
65 |
classes, a quaternion and some utility classes. In summary, the most
|
|
|
66 |
important features are
|
|
|
67 |
\begin{itemize}
|
|
|
68 |
\item A number of 2, 3 and 4 d vector classes.
|
|
|
69 |
\item A number of Matrix classes.
|
|
|
70 |
\item A Quaternion class.
|
|
|
71 |
\item Some test programs.
|
|
|
72 |
\item Works well with OpenGL.
|
|
|
73 |
\end{itemize}
|
|
|
74 |
|
|
|
75 |
|
|
|
76 |
\subsection{Naming conventions}
|
|
|
77 |
|
|
|
78 |
Vectors in CGLA are named \texttt{VecDT} where \texttt{D} stands for
|
|
|
79 |
dimension at \texttt{T}
|
|
|
80 |
for type. For instance a 3D floating point vector is named
|
|
|
81 |
\texttt{Vec3f}. Other types are d (double), s (short), i (int), uc
|
|
|
82 |
(unsigned char), and usi (unsigned shourt int).
|
|
|
83 |
|
|
|
84 |
Matrices are similiarly named \texttt{MatDxDT}. For instance a 4D
|
|
|
85 |
\texttt{double} matrix is called \texttt{Mat4x4d}.
|
|
|
86 |
|
|
|
87 |
\subsection{How to use CGLA}
|
|
|
88 |
|
|
|
89 |
If you need a given CGLA class you can find the header file that
|
|
|
90 |
contains it in this document. Simply include the header file and use
|
|
|
91 |
the class. Remember also that all CGLA functions and classes live in
|
|
|
92 |
the CGLA namespace! Lastly, look at the example programs that came
|
|
|
93 |
with the code.
|
|
|
94 |
|
|
|
95 |
An important point is that you should never use the Arith... classes
|
|
|
96 |
directly. Classes whose names begin with Arith are templates used for
|
|
|
97 |
deriving concrete types. It is simpler, cleaner, and the intended
|
|
|
98 |
thing to do to only use the derived types.
|
|
|
99 |
|
|
|
100 |
In some cases, you may find that you need a vector or matrix class
|
|
|
101 |
that I haven't defined. If so, it is fortunate that CGLA is easy to
|
|
|
102 |
extend. Just look at, say, \texttt{Vec4f} if you need a \texttt{Vec5d}
|
|
|
103 |
class.
|
|
|
104 |
|
|
|
105 |
For some more specific help look at the next section where some of the
|
|
|
106 |
commonly used operations are shown.
|
|
|
107 |
|
|
|
108 |
\subsection{How to get CGLA}
|
|
|
109 |
|
|
|
110 |
If you have this document but not the code, look at\\
|
394 |
jab |
111 |
\href{http://www2.imm.dtu.dk/projects/GEL/}{http://www2.imm.dtu.dk/projects/GEL/}
|
11 |
jab |
112 |
|
394 |
jab |
113 |
\subsection{Bugs etc.}
|
11 |
jab |
114 |
|
394 |
jab |
115 |
CGLA was written (mostly) by Andreas B{\ae}entzen (jab{@}imm.dtu.dk), and
|
11 |
jab |
116 |
any bug fixes, contributions, or questions should be addressed to me.
|
|
|
117 |
|
|
|
118 |
\section{CGLA: Examples of Usage}
|
|
|
119 |
|
394 |
jab |
120 |
The examples below are by no means complete. Many things are
|
11 |
jab |
121 |
possible but not covered below. However, most of the common usage is
|
|
|
122 |
shown, so this should be enough to get you started. Note that in the
|
|
|
123 |
following we assume that you are \texttt{using namespace CGLA} and
|
|
|
124 |
hence don't prefix with \texttt{CGLA::}.
|
|
|
125 |
|
|
|
126 |
In short, to compile the examples below you would need the following
|
|
|
127 |
in the top of your file
|
|
|
128 |
|
|
|
129 |
\begin{lstlisting}{}
|
|
|
130 |
#include <iostream> // For input output
|
|
|
131 |
#include "CGLA/Vec3f.h"
|
|
|
132 |
#include "CGLA/Quaternion.h"
|
|
|
133 |
#include "CGLA/Mat4x4f.h"
|
|
|
134 |
|
|
|
135 |
using namespace std; // For input output
|
|
|
136 |
using namespace CGLA;
|
|
|
137 |
\end{lstlisting}
|
|
|
138 |
|
|
|
139 |
To begin with let us create 3 3D vectors. This is done as follows:
|
|
|
140 |
\begin{lstlisting}{}
|
|
|
141 |
Vec3f p0(10,10,10);
|
|
|
142 |
Vec3f p1(20,10,10);
|
|
|
143 |
Vec3f p2(10,20,10);
|
|
|
144 |
\end{lstlisting}
|
|
|
145 |
if we had left out the arguments the three vectors would have been
|
|
|
146 |
uninitialized, at least in release mode. If we compile in debug mode
|
|
|
147 |
they would have been initialized to ``Not a Number'' to aid
|
|
|
148 |
debugging. However, the $[10 10 10]^T$ vector could also have been
|
|
|
149 |
created differently, using
|
|
|
150 |
\begin{lstlisting}{}
|
|
|
151 |
Vec3f p0(10);
|
115 |
jab |
152 |
\end{lstlisting}
|
11 |
jab |
153 |
|
|
|
154 |
A very common operation is to compute the normal of a triangle from
|
|
|
155 |
the position of its vertices. Assuming the three vectors represent the
|
|
|
156 |
vertices of a triangle, we can compute the normal by finding the
|
|
|
157 |
vector from the first vertex to the two other vertices, taking the
|
|
|
158 |
cross product and normalizing the result. This is a one-liner:
|
|
|
159 |
|
|
|
160 |
\begin{lstlisting}{}
|
|
|
161 |
Vec3f n = normalize(cross(p1-p0,p2-p0));
|
|
|
162 |
\end{lstlisting}
|
|
|
163 |
|
|
|
164 |
Quite a lot goes on in the snippet above. Observe that the - operator
|
|
|
165 |
also works for vectors. In fact almost all the arithmetic operators
|
|
|
166 |
work for vectors. You can also use assignment operators (i.e
|
|
|
167 |
\texttt{+=}) which is often faster. Then there is the function
|
|
|
168 |
\texttt{cross} which simply computes the cross product of its
|
|
|
169 |
arguments. Another frequently used function is \texttt{dot} which
|
|
|
170 |
takes the dot product. Finally the vector is normalized using the
|
|
|
171 |
function normalize.
|
|
|
172 |
|
|
|
173 |
Of course, we can print all or at least most CGLA entities. For
|
|
|
174 |
example
|
|
|
175 |
|
|
|
176 |
\begin{lstlisting}{}
|
|
|
177 |
cout << n << endl;
|
|
|
178 |
\end{lstlisting}
|
|
|
179 |
|
|
|
180 |
will print the normal vector just computed. We can also treat a vector
|
|
|
181 |
as an array as shown below
|
|
|
182 |
|
|
|
183 |
\begin{lstlisting}{}
|
|
|
184 |
float x = n[0];
|
|
|
185 |
\end{lstlisting}
|
|
|
186 |
|
|
|
187 |
here, of course, we just extracted the first coordinate of the
|
|
|
188 |
vector.
|
|
|
189 |
|
|
|
190 |
CGLA contains a number of features that are not used very frequently,
|
|
|
191 |
but which are used frequently enough to warrent inclusion. A good
|
|
|
192 |
example is assigning to a vector using spherical coordinates:
|
|
|
193 |
|
|
|
194 |
\begin{lstlisting}{}
|
|
|
195 |
Vec3f p;
|
|
|
196 |
p.set_spherical(0.955317, 3.1415926f/4.0f , 1);
|
|
|
197 |
\end{lstlisting}
|
|
|
198 |
|
|
|
199 |
CGLA also includes a quaternion class. Here it is used to construct a
|
|
|
200 |
quaternion which will rotate the x axis into the y axis.
|
|
|
201 |
|
|
|
202 |
\begin{lstlisting}{}
|
|
|
203 |
Quaternion q;
|
|
|
204 |
q.make_rot(Vec3f(1,0,0), Vec3f(0,1,0));
|
|
|
205 |
\end{lstlisting}
|
|
|
206 |
|
|
|
207 |
Next, we construct a $4\times 4$ matrix \texttt{m} and assign a translation
|
|
|
208 |
matrix to the newly constructed matrix. After that we ask the
|
|
|
209 |
quaternion to return a $4\times 4$ matrix corresponding to its
|
|
|
210 |
rotation. This rotation matrix is then multiplied onto \texttt{m}.
|
|
|
211 |
|
|
|
212 |
\begin{lstlisting}{}
|
|
|
213 |
Mat4x4f m = translation_Mat4x4f(Vec3f(1,2,3));
|
|
|
214 |
m *= q.get_mat4x4f();
|
|
|
215 |
\end{lstlisting}
|
|
|
216 |
|
|
|
217 |
Just like for vectors, the subscript operator works on
|
|
|
218 |
matrices. However, in this case there are two indices. Just using one
|
|
|
219 |
index will return the ith row as a vector as shown on the first line
|
|
|
220 |
below. On the second line we see that using two indices will get us an
|
|
|
221 |
element in the matrix.
|
|
|
222 |
|
|
|
223 |
\begin{lstlisting}{}
|
|
|
224 |
Vec4f v4 = m[0];
|
|
|
225 |
float c = m[0][3];
|
|
|
226 |
\end{lstlisting}
|
|
|
227 |
|
|
|
228 |
There is a number of constructors for vectors. The default constructor
|
|
|
229 |
will create a null vector as we have already seen. We can also specify
|
|
|
230 |
all the coordinates. Finally, we can pass just a single number
|
|
|
231 |
$a$. This will create the $[a\:a\:a]^T$ vector. For instance, below we
|
|
|
232 |
create the $[1\: 1\: 1]^T$ vector. Subsequently, this vector is
|
|
|
233 |
multiplied onto \texttt{m}.
|
|
|
234 |
|
|
|
235 |
\begin{lstlisting}{}
|
|
|
236 |
Vec3f p(1);
|
|
|
237 |
Vec3f p2 = m.mul_3D_point(p);
|
|
|
238 |
\end{lstlisting}
|
|
|
239 |
|
|
|
240 |
Note though that \texttt{m} is a $4\times
|
|
|
241 |
4$ matrix so ... how is that possible? Well, we use the function
|
|
|
242 |
\texttt{mul\_3D\_point} which, effectively, adds a $w=1$ coordinate to p
|
|
|
243 |
making it a 4D vector. This $w$ coordinate is stripped afterwards. In
|
|
|
244 |
practice, this means that the translation part of the matrix is also
|
|
|
245 |
applied. There is a similar function \texttt{mul\_3D\_vector} if we want
|
|
|
246 |
to transform vectors without having the translation. This function,
|
|
|
247 |
effectively, sets $w=0$.
|
|
|
248 |
|
|
|
249 |
Finally, CGLA is often used together with OpenGL although there is no
|
|
|
250 |
explicit tie to the OpenGL library. However, we can call the
|
|
|
251 |
\texttt{get} function of most CGLA entities to get a pointer to the
|
|
|
252 |
contents. E.g. \texttt{p.get()} will return a pointer to the first
|
|
|
253 |
float in the 3D vector \texttt{p}. This can be used with OpenGL's
|
|
|
254 |
``v'' functions as shown below.
|
|
|
255 |
|
|
|
256 |
\begin{lstlisting}{}
|
|
|
257 |
glVertex3fv(p.get());
|
|
|
258 |
\end{lstlisting}
|
|
|
259 |
\end{document}
|