translate; scale; translate;

I know that one can think of transformations acting on a (grand) fixed coordinate system or on a (local) moving coordinate system. I always thought in terms of a local coord system, because that way the OpenGL commands don’t appear to be reversed. It’s more logical to me.

But then i discovered a technique to scale (i guess it works for rotations too) an object around a specific point: translate the object so that the chosen point goes to (0;0;0), scale and then translate the back to the original position. While it seems to work, i have to think of it using a fixed coordinate system, which i don’t like (commands reversed, unintuitive).

Is there a sensible interpretation of those transformations using a local coord. system? It would make my understanding easier.

PS: I hope my post is not too confusing…

To me, it’s easiest to think about it exactly the way it’s done. Think about a sequence of multiplies on the matrix stack:

You start with load identity:
MV = I.

Then you multiply a matrix A:
MV = MV * A;

Then you multiply a matrix B:
MV = MV * B;

Taken together, you have:
MV = I * A * B

Now, say you pass a vertex postion P:
NewP = I * A * B * P

You see the reverse order?
NewP = (I * (A * (B * P)))

First P is multiplied by B, then that result is multiplied by A.

This holds true for all transformations, including the camera. The first thing you do is set the model view matrix before you start drawing. This model view matrix will also be the last matrix applied:
MV = I * MyCameraRotationsAndTranslations * A * B

which makes sense - transform the points in space, then move them into camera coordinates for drawing last. Once you get used to the reverse order bit, it’s easy and consistent; you’ll be able to view all transformations in exactly the same way - no special cases, no exceptions.

I hope this helps.

As long as you view only a single sequence of transformations in your code it doesn’t matter how you view it. But when you have a hierarchial structure with push/pop, the approach with the local coordinate system is much easier, not because you don’t have to reverse the transformations but becasue you don’t need to care about what transformations are outside of your local drawing function. Either you figure out the local coordinate system and then apply the transformations to the objects in reverse order, or you transform only the local coordinate system.

I don’t see it the way Portal described, I see it this way:
NewP = (((I * A) * B) * P)
which is mathematically identical.

It is just a matter of preference, and if you find it more logical this way, I don’t think it is a good idea to force yourself into the other…

About the concrete problem (and its solution using a local coordinate system):

When you have scales, you have to change the length of the base vectors. All numbers are always multiples of the length of them.

Think of a circle (2D because it is easier) with radius 1 and center (1,1). We want to scale it to double size around its center.

  1. Translate (1,1)
    Now it still has the same size but is centered at (2,2). The local origin is (1,1).
  2. Scale (2,2)
    The local origin is still (1,1), but the coordinate system is scaled to double size. The result is a circle with radius 2 and center (3,3).
  3. Translate (-1,-1)
    Now we move the local origin back one unit, but because the local coordinate system is double the size of the global one, the origin is now at global (-1,-1). This gives a circle centered at (1,1) with radius 2, as expected.

If you can’t figure it out, it really helps drawing each step on paper with the global and the local coordinate system. Don’t forget to draw the arrows of the local coordinate system exactly one unit long.

But when you have a hierarchial structure with push/pop, the approach with the local coordinate system is much easier

I’m not sure what you mean by a local coordinate system. If you mean isolated, then it still makes no difference how you look at it, it is never anything more than one or more matrices, regardless of the context. Pushing and popping the matrix stack has no bearing on the matrix math involved here, or the reading order.


I didn’t want to say your way of thinking about it is wrong. I only wanted to point out that there is another way to look at the transformations, and one of the two seems more logical, but which one is different for every person.

Of course push/pop doesn’t change the math behind it, but the way you think about it is different. But you are right, I should have stated more clearly that this is the way I (and obviously <qw>, judging from his post) find it easier to think about it, and not the only correct way.