
Introduction to the Math of Computer Graphics - ingve
http://codeofthedamned.com/index.php/introduction-to-the-math-of
======
overgard
Small thing, but some of the examples have some pretty bad undefined behavior
bugs. For instance:

    
    
        Matrix& operator*( const double scalar,
                           const Matrix& rhs)
        {
          Matrix result(rhs);
          result *= scalar;
     
          return result;
        }
    

(Returning a reference to a stack variable is undefined behavior, but
realistically you're probably either looking at a hard crash or a really hard
to track down bug)

~~~
santaclaus
I wonder why they didn't simply nuke the reference and get move semantics? Or
better yet, use expression templates.

~~~
codeofthedamned
I have corrected the code by removing the reference.

The way the code is now structured will allow for the RVO (Return-value
optimization) to occur, so the new instance will be constructed in the
location of the receiving object.

Move semantics would not apply in this case, it would actually suffer from a
similar problem as the version that returned a reference, except the program
would not crash. Instead the return value would contain garbage.

(edit: added a link to details on how to use move semantics)
[http://codeofthedamned.com/index.php/c-r-value-
references](http://codeofthedamned.com/index.php/c-r-value-references)

I did not use expression templates, or try to optimize any of the
implementation because my intent is to demonstrate "how" to get started with
the math. I also wanted to make the code accessible to programmers that do not
use C++. For example, someone trying to learn WebGL.

------
djhworld
What I'm failing to understand is how do matrices relate to 3D graphics. What
is a matrix representing?

I think I get the idea of a vertex, as that can be used to represent a point
on a shape, like a 3d model.

~~~
barrkel
Matrices are a way of accumulating a bunch of separate transformations you
might want to perform on a point (in the lingo, points are vectors because
each coordinate of the point is an element of the vector).

Suppose figuring out where a world point (in a game map, for example) should
show up on screen (in pixels) looked like a bit like this function call
sequence (this is simplified):

    
    
        screenPoint = perspective(move(rotate(move(worldPoint))))
    

Think of a camera moving around the world; in virtual reality, this is exactly
equivalent to the camera staying put and the world moving around instead.
That's more or less how 3D graphics works. You have a virtual box that
logically lives behind your screen, with the same x and y coordinates as your
screen resolution, and z coordinates handled by a Z buffer that's used to
determine what overlaps what. A big chunk of the matrix work is about moving,
rotating and squishing the whole virtual world until the bit you want to look
at fits into the virtual box that lives behind the screen.

Each function (perspective, move (aka translate), rotate, scale, etc.) can be
expressed in the form of multiplication by a matrix. See [1], for example.
That turns it into something like this:

    
    
        screenPoint = perspectiveMatrix * moveMatrix * rotateMatrix * moveMatrix * worldPoint
    

But because matrix multiplication is associative, we can calculate a single
matrix to do all the work:

    
    
        transformMatrix = perspectiveMatrix * moveMatrix * rotateMatrix * moveMatrix
        screenPoint = transformMatrix * worldPoint
    

And this is much more efficient because there's fewer calculations that need
to be performed per point.

[1]
[https://en.wikipedia.org/wiki/Rotation_matrix](https://en.wikipedia.org/wiki/Rotation_matrix)

~~~
djhworld
Wonderful explanation, thanks

------
jarek-foksa
"The Matrix and Quaternions FAQ" is also worth reading:
[http://www.j3d.org/matrix_faq/matrfaq_latest.html](http://www.j3d.org/matrix_faq/matrfaq_latest.html)

~~~
moron4hire
I've been using quaternions for 15 years now and I still don't have a good
mental image of why they work. I've just learned to accept the operations and
what they do.

~~~
dtf
Visualising Quaternions is a book which goes into much beautiful depth about
what they represent and how they behave, if you fancy digging deeper than the
everyday practicality of them.

~~~
vive-la-liberte
I had never heard of quaternions so I Googled the book title you suggested. In
addition to the Amazon link [1], I also found a question on the gamedev SE
where they talk about building a mental model of quaternions [2], which I
found informative.

[1]: [http://www.amazon.com/Visualizing-Quaternions-Kaufmann-
Inter...](http://www.amazon.com/Visualizing-Quaternions-Kaufmann-Interactive-
Technology/dp/0120884003)

[2]: [http://gamedev.stackexchange.com/questions/4801/how-can-
you-...](http://gamedev.stackexchange.com/questions/4801/how-can-you-
visualize-a-quaternion)

------
kragen
This post is mistitled, and I really wish I knew where to find a thing that is
what this post claims to be.

From the title, I was hoping this would cover coordinate systems, the
Bresenham line algorithm and midpoint circle algorithm, Lambertian reflection,
perspective transformation, quaternions, Gouraud and Phong shading, rotation,
metaball approximation, parametric vs. implicit vs. explicit function
representation, splines, ray tracing, alpha compositing, and some basic
filtering. Instead, it consists only of basic linear algebra — it doesn't even
cover how to generate a rotation matrix! However, it does cover a lot of stuff
that basically doesn't come up at all in computer graphics, like multiplying
nonsquare matrices together, and as pandaman points out, adding matrices
together.

(Also, as overgard points out, the code contains basic novice errors:
[https://news.ycombinator.com/item?id=10812881](https://news.ycombinator.com/item?id=10812881))

(pandaman correctly points out that matrix-vector multiply is a special case
of multiplying nonsquare matrices. I still don't think you need to deal with
that in an introduction; it's easy to learn as a special case, and that's
probably how you'll have to code it anyway!)

Unfortunately, I don't know where to point people for a _real_ introduction to
the math of computer graphics. This is a shame; even without libraries and
hardware, you can do rotating 3-D shapes in just 15 lines of code
[http://canonical.org/~kragen/sw/netbook-misc-
devel/rotcube.p...](http://canonical.org/~kragen/sw/netbook-misc-
devel/rotcube.py) or ray-tracing in 186:
[http://canonical.org/~kragen/sw/aspmisc/my-very-first-
raytra...](http://canonical.org/~kragen/sw/aspmisc/my-very-first-
raytracer.html) or basic VR with your cellphone accelerometer in 114:
[http://canonical.org/~kragen/sw/81hacks/topopt-
ar/](http://canonical.org/~kragen/sw/81hacks/topopt-ar/)

(That last one is cheating a little bit since I didn't write the circle-
drawing algorithm myself, so it isn't included in the line count.)

Math is super powerful when you apply it to computer graphics. It empowers you
to make magic happen in only a few hours and a few dozen lines of code, and
the magic is visible even to people who can't program. You don't have to
understand _all_ that math stuff I mentioned in the first paragraph in order
to do these things.

~~~
pandaman
Matrix multiplication by vector and vice versa is a multiplication by at least
one non-square matrix. But matrix addition, on the other hand, is something I
have never seen come up in graphics.

~~~
codeofthedamned
Translation itself is not a linear transformation. To simply translate a
vertex is a matrix addition(subtraction) problem.

The only reason that it is possible in the transformation matrix is because of
the addition of the fourth parameter in a vertex [x y z 1] to create a
homogenous linear system. This allows the translation to become a part of the
transformation matrix.

~~~
pandaman
I am not sure what you mean. If by "matrix addition" you meant adding vectors
then it's obvious but adding actual matrices won't give you any translation
operators because no matter how many matrices you have added together you
still end up with a matrix, which, indeed, can only represent linear
operators.

~~~
codeofthedamned
I believe we are mincing words with the added confusion of two mathematical
meanings for the word vertex in this discussion.

The single row matrix, called a vertex, and a Euclidean vertex which we use to
represent the points in the geometry, and happen to store in a vertex
(matrix).

I do agree with your statement.

------
jetskindo
Got the good old hn hug.

Cached version:

[http://webcache.googleusercontent.com/search?q=cache:http://...](http://webcache.googleusercontent.com/search?q=cache:http://codeofthedamned.com/index.php/introduction-
to-the-math-of)

------
jheriko
too much maths, not enough understanding.

i worked out a lot of 3d stuff for myself early on, and the linear algebra
approach is quite confusing vs. taking an intuitive approach and noticing that
somethings are the same or special cases of...

... maybe i should write something about this.

