Page 3: Composition

CS559 Spring 2023 Sample Solution

Now that we’ve learned scale and translate, let’s try to put them together!

The idea of putting transformations together is a very important part of computer graphics. It’s important to understand it in the simple case (scale and translate), so that when we get to more complex transformations and more complex combinations, you will be able to appreciate what is happening.

As a reminder, you should be looking at the code for each of these examples.

Box 1: Scale and Translate

We can apply transformations one after the other. For example, here we can scale (in the X direction) and then translate (also in the X direction). This box is 03-03-01.html and 03-03-01.js.

Notice the difference in behavior. If we translate first, then the scale only applies to the object (we stretch the coordinate axes after we’ve moved the origin). If we scale first, then the translation applies in that stretched coordinate system.

We can think about this as functions being applied to positions (transformation). Let the position of the point be x, the translation be t and the scale be s. The translate transformation is T(x,y) => (x+t,y), and the scale transformation is S(x,y) => (sx,y).

If we translate first, and then scale it is T(S(x,y)) = T(sx,y) = (sx+t,y).

If we scale first, and then translate then it is S(T(x,y)) = S(x+t,y) = (sx+st,y).

Remember, that translate and scale apply to the coordinate system. The coordinate system then affects the points, because the points are interpreted in the coordinate system. To use the pen and paper analogy, the transformation commands (translate and scale) move and stretch the paper we draw on.

We can view the operations as applying to the points, but this requires us to read backwards. If we translate then scale, that means first scale the object then move it. If we scale then translate, we can think about first moving the object, then scaling the object (in its new position).

This may be a good time to look at the 2D Transform Toy (default demos) - there are examples “translate scale” and “scale translate” (and a third one that does both - with a save/restore - so you can compare). The transforms toy allows you to “run the code backwards” (click the “run the transformations in reverse order” checkbox and start at the end).

A warning: most programs cannot be run backwards. It is a special trick we can do in the 2D Transform Demos. Use it to understand how transformations work going forward. Don’t try to write code this way.

Understanding what happens when we scale first is important (and might be easiest if you look at the “Scale then Translate” demo). When we scale first, we make the coordinate system “bigger”. The translate is in the coordinate system, so we translate a larger amount than if we did the translate before we did the scale.

Box 2: Scale about the Center

Suppose we want to scale around the center of an object, not the center of the coordinate system.

To do this, we move the object so its center is at the origin, scale it, then move the object back to its original position.

Here, the center of the square is at (40,40). So we need to translate(-40,-40) to place its center at the origin, then scale, then do a translation to put the center back where it belongs. But when we look at the code ( 03-03-02.html and 03-03-02.js):

context.translate(40, 40);
context.scale(sc, sc);
context.translate(-40, -40);
context.fillRect(30, 30, 20, 20);

The order of transforms may seem backwards. The transformation that applies first to the object is closest to the object. However, when we think of the transformations as being things that change the coordinate system, they occur in the correct order. We can read the code as: (1) move the center of the coordinate system to where the center of the object will be; (2) scale the coordinate system; (3) move the center of the coordinate system back so that the object’s center position is where the object’s center position should be.

Note that we cannot do a save/restore to undo the first translation because that would also get rid of the scale.

This is an important example to understand. Combining transformations this way to control the center is a common thing. Understanding how we use ordered transformations is very important. There is an example “Center of Scaling” in 2D Transform Toy (default demos) that may help - you can even try “running the code backwards”.

A warning: most programs cannot be run backwards. It is a special trick we can do in the 2D Transform Demos. Use it to understand how transformations work going forward. Don’t try to write code this way.

Box 3: Exercise 2, Another Example

The original box with a triangle function puts the box at the origin. Suppose we want to make a grid of them (on the same (20,20) spacing), but with the boxes being half size.

Oh wait, the scale is missing :-) You need to fix the code - add the appropriate scaling, save and restore to make the lower box (canvas) canvas2 look like the upper one. You can find this code in 03-03-03.html and 03-03-03.js. You should add lines inside of the loop.

Box 4: Do a Flip

With Canvas, we’ve gotten used to the idea that the coordinate system starts in the upper left corner, the x axis goes to the right and the y axis goes down. The initial coordinate system has the Y axis scaled such that one unit in the y coordinate is one “html pixel” downward, but we can change that using scale.

In math classes, we usually put the origin in the lower left corner and have y going upwards. We can now change the coordinate system so that Canvas works like we’re used to! We need to scale the y axis and translate the origin. Or we can translate the origin and scale the y axis.

Here’s three pictures - the first with the regular canvas coordinate system, the second scaling and translating, and the third translating and scaling. Read the code ( 03-03-04.html and 03-03-04.js) and notice how the values for the translation change depending on the order. If you want, you can make a more interesting picture.

Box 5: Exercise 3, One more

In computer graphics, we often like to have a coordinate system with the origin in the center of the “window” (in our case, the Canvas we’re working in), and the x and y coordinates ranging from -1 to 1. That way, we can draw things with the same coordinates no matter how big the window is.

Unfortunately, this is a bad idea in Canvas for many reasons. One problem is that some browsers do some of the drawing using integer arithmetic. So, for this exercise, we’ll go from -100 to 100 instead.

You can create the coordinate system for canvas using a translation and a scale (in either order). In 03-03-05.html and 03-03-05.js, add something to the “picture” function to set the coordinate system so it goes from -100 to 100 in x and y. The picture is a diamond shape that touches the edges, a plus at the center, and a T near the top left. You should only add translate and scale commands to set the coordinate system. If you do it correctly, you will fill each of the boxes below in a similar way.

When you’re done, it should look like

HINTS: you can access canvas.width and canvas.height. You only need to add two lines of code to the picture function in function part5. The picture has a T in the top left corner, and a red plus in the middle - you cannot see the T and can see only part of the plus in the initial code.

Summary: Composing transformations

Composing transformations is a key concept in computer graphics. It is important to understand it now, when the transformations are simple (2D translate and scale). In the future, the transformations will become more complex, but the basic idea of composition will be the same.

In fact, on the next page, we’ll consider rotations - which might really make your head spin.

Next: Rotation

Page 3 Rubric (6 points total)
Points (6):
Box 03-03-03
3 pt
add appropriate transformations to make both images look the same
Box 03-03-05
3 pt
define the canvas coordinate systems as specified