# Search in the document preview

CSC418 / CSCD18 / CSC2504 Transformations

**3 Transformations
**

**3.1 2D Transformations
**

Given a point cloud, polygon, or sampled parametric curve, we can use transformations for several purposes:

1. Change coordinate frames (world, window, viewport, device, etc).

2. Compose objects of simple parts with local scale/position/orientation of one part defined with regard to other parts. For example, for articulated objects.

3. Use deformation to create new shapes.

4. Useful for animation.

There are three basic classes of transformations:

1. **Rigid body **- Preserves distance and angles.

• Examples: translation and rotation.

2. **Conformal **- Preserves angles.

• Examples: translation, rotation, and uniform scaling.

3. **Affine **- Preserves parallelism. Lines remain lines.

• Examples: translation, rotation, scaling, shear, and reflection.

Examples of transformations:

• **Translation **by vector ~t: p̄1 = p̄0 + ~t.

• **Rotation **counterclockwise by θ: p̄1 =
[

cos(θ) − sin(θ) sin(θ) cos(θ)

]

p̄0.

Copyright c© 2005 David Fleet and Aaron Hertzmann 10

CSC418 / CSCD18 / CSC2504 Transformations

• **Uniform scaling **by scalar a: p̄1 =
[

a 0 0 a

]

p̄0.

• **Nonuniform scaling **by a and b: p̄1 =
[

a 0 0 b

]

p̄0.

• **Shear **by scalar h: p̄1 =
[

1 h 0 1

]

p̄0.

• **Reflection **about the y-axis: p̄1 =
[

−1 0 0 1

]

p̄0.

**3.2 Affine Transformations
**

An **affine transformation **takes a point p̄ to q̄ according to q̄ = F (p̄) = Ap̄ + ~t, a linear transfor-
mation followed by a translation. You should understand the following proofs.

Copyright c© 2005 David Fleet and Aaron Hertzmann 11

CSC418 / CSCD18 / CSC2504 Transformations

• The inverse of an affine transformation is also affine, assuming it exists.

Proof: Let q̄ = Ap̄+ ~t and assume A−1 exists, i.e. det(A) 6= 0. Then Ap̄ = q̄ − ~t, so p̄ = A−1q̄ − A−1~t. This can be rewritten as p̄ = Bq̄ + ~d, where B = A−1 and ~d = −A−1~t.

Note: The inverse of a 2D linear transformation is

A−1 =

[

a b c d

]

−1

= 1

ad− bc

[

d −b −c a

]

.

• Lines and parallelism are preserved under affine transformations.

Proof: To prove lines are preserved, we must show that q̄(λ) = F (l̄(λ)) is a line, where F (p̄) = Ap̄+ ~t and l̄(λ) = p̄0 + λ~d.

q̄(λ) = Al̄(λ) + ~t

= A(p̄0 + λ~d) + ~t

= (Ap̄0 + ~t) + λA~d

This is a parametric form of a line through Ap̄0 + ~t with direction A~d.

• Given a closed region, the area under an affine transformation Ap̄+ ~t is scaled by det(A).

Note:

**– **Rotations and translations have det(A) = 1.

**– **Scaling A =
[

a 0 0 b

]

has det(A) = ab.

**– **Singularities have det(A) = 0.

Example:

The matrix A =

[

1 0 0 0

]

maps all points to the x-axis, so the area of any closed

region will become zero. We have det(A) = 0, which verifies that any closed region’s area will be scaled by zero.

Copyright c© 2005 David Fleet and Aaron Hertzmann 12

CSC418 / CSCD18 / CSC2504 Transformations

• A composition of affine transformations is still affine.

Proof: Let F1(p̄) = A1p̄+ ~t1 and F2(p̄) = A2p̄+ ~t2. Then,

F (p̄) = F2(F1(p̄))

= A2(A1p̄+ ~t1) + ~t2

= A2A1p̄+ (A2~t1 + ~t2).

Letting A = A2A1 and ~t = A2~t1 + ~t2, we have F (p̄) = Ap̄ + ~t, and this is an affine transformation.

**3.3 Homogeneous Coordinates
**

**Homogeneous coordinates **are another way to represent points to simplify the way in which we
express affine transformations. Normally, bookkeeping would become tedious when affine trans-
formations of the form Ap̄ + ~t are composed. With homogeneous coordinates, affine transforma-
tions become matrices, and composition of transformations is as simple as matrix multiplication.
In future sections of the course we exploit this in much more powerful ways.

With homogeneous coordinates, a point p̄ is augmented with a 1, to form p̂ =

[

p̄ 1

]

.

All points (αp̄, α) represent the same point p̄ for real α 6= 0.

Given p̂ in homogeneous coordinates, to get p̄, we divide p̂ by its last component and discard the last component.

Example: The homogeneous points (2, 4, 2) and (1, 2, 1) both represent the Cartesian point (1, 2). It’s the orientation of p̂ that matters, not its length.

Many transformations become linear in homogeneous coordinates, including affine transforma- tions:

[

qx qy

]

=

[

a b c d

] [

px py

]

+

[

tx ty

]

=

[

a b tx c d ty

]

px py 1

= [

A ~t ]

p̂

Copyright c© 2005 David Fleet and Aaron Hertzmann 13

CSC418 / CSCD18 / CSC2504 Transformations

To produce q̂ rather than q̄, we can add a row to the matrix:

q̂ =

[

A ~t ~0T 1

]

p̂ =

a b tx c d ty 0 0 1

p̂.

This is linear! Bookkeeping becomes simple under composition.

Example: F3(F2(F1(p̄))), where Fi(p̄) = Ai(p̄) + ~ti becomes M3M2M1p̄, where Mi = [

Ai ~ti ~0T 1

]

.

With homogeneous coordinates, the following properties of affine transformations become appar- ent:

• Affine transformations are associative. For affine transformations F1, F2, and F3,

(F3 ◦ F2) ◦ F1 = F3 ◦ (F2 ◦ F1).

• Affine transformations are *not *commutative.
For affine transformations F1 and F2,

F2 ◦ F1 6= F1 ◦ F2.

**3.4 Uses and Abuses of Homogeneous Coordinates
**

Homogeneous coordinates provide a different representation for Cartesian coordinates, and cannot
be treated in quite the same way. For example, consider the midpoint between two points p̄1 =
(1, 1) and p̄2 = (5, 5). The midpoint is (p̄1 + p̄2)/2 = (3, 3). We can represent these points
in homogeneous coordinates as p̂1 = (1, 1, 1) and p̂2 = (5, 5, 1). Directly applying the same
computation as above gives the same resulting point: (3, 3, 1). However, we can *also *represent
these points as p̂′

1 = (2, 2, 2) and p̂′

2 = (5, 5, 1). We then have (p̂′

1 + p̂′

2 )/2 = (7/2, 7/2, 3/2),

which cooresponds to the Cartesian point (7/3, 7/3). This is a different point, and illustrates that
we cannot blindly apply geometric operations to homogeneous coordinates. The simplest solution
is to **always convert homogeneous coordinates to Cartesian coordinates. **That said, there are
several important operations that can be performed correctly in terms of homogeneous coordinates,
as follows.

Copyright c© 2005 David Fleet and Aaron Hertzmann 14

CSC418 / CSCD18 / CSC2504 Transformations

**Affine transformations. **An important case in the previous section is applying an affine trans-
formation to a point in homogeneous coordinates:

q̄ = F (p̄) = Ap̄+ ~t (1)

q̂ = Âp̂ = (x′, y′, 1)T (2)

It is easy to see that this operation is correct, since rescaling p̂ does not change the result:

Â(αp̂) = α(Âp̂) = αq̂ = (αx′, αy′, α)T (3)

which is the same geometric point as q̂ = (x′, y′, 1)T

**Vectors. **We can represent a vector ~v = (x, y) in homogeneous coordinates by setting the last
element of the vector to be zero: v̂ = (x, y, 0). However, when adding a vector to a point, the point
must have the third component be 1.

q̂ = p̂+ v̂ (4)

(x′, y′, 1)T = (xp, yp, 1) + (x, y, 0) (5)

The result is clearly incorrect if the third component of the vector is not 0.

Aside:
Homogeneous coordinates are a representation of points in **projective geometry.
**

**3.5 Hierarchical Transformations
**

It is often convenient to model objects as hierarchically connected parts. For example, a robot arm might be made up of an upper arm, forearm, palm, and fingers. Rotating at the shoulder on the upper arm would affect all of the rest of the arm, but rotating the forearm at the elbow would affect the palm and fingers, but not the upper arm. A reasonable hierarchy, then, would have the upper arm at the root, with the forearm as its only child, which in turn connects only to the palm, and the palm would be the parent to all of the fingers.

Each part in the hierarchy can be modeled in its own local coordinates, independent of the other parts. For a robot, a simple square might be used to model each of the upper arm, forearm, and so on. Rigid body transformations are then applied to each part relative to its parent to achieve the proper alignment and pose of the object. For example, the fingers are positioned to be in the appropriate places in the palm coordinates, the fingers and palm together are positioned in forearm coordinates, and the process continues up the hierarchy. Then a transformation applied to upper arm coordinates is also applied to all parts down the hierarchy.

Copyright c© 2005 David Fleet and Aaron Hertzmann 15

CSC418 / CSCD18 / CSC2504 Transformations

**3.6 Transformations in OpenGL
**

OpenGL manages two 4 × 4 transformation matrices: the *modelview matrix*, and the *projection
matrix*. Whenever you specify geometry (using glVertex), the vertices are transformed by the
current modelview matrix and then the current projection matrix. Hence, you don’t have to perform
these transformations yourself. You can modify the entries of these matrices at any time. OpenGL
provides several utilities for modifying these matrices. The modelview matrix is normally used to
represent geometric transformations of objects; the projection matrix is normally used to store the
camera transformation. For now, we’ll focus just on the modelview matrix, and discuss the camera
transformation later.

To modify the current matrix, first specify which matrix is going to be manipulated: use glMatrixMode(GL MODELVIEW)
to modify the modelview matrix. The modelview matrix can then be initialized to the identity with
glLoadIdentity(). The matrix can be manipulated by directly filling its values, multiplying it
by an arbitrary matrix, or using the functions OpenGL provides to multiply the matrix by specific
transformation matrices (glRotate, glTranslate, and glScale). Note that these transforma-
tions **right-multiply **the current matrix; this can be confusing since it means that you specify
transformations in the reverse of the obvious order. Exercise: why does OpenGL right-multiply
the current matrix?

OpenGL provides a **stacks **to assist with hierarchical transformations. There is one stack for the
modelview matrix and one for the projection matrix. OpenGL provides routines for pushing and
popping matrices on the stack.

The following example draws an upper arm and forearm with shoulder and elbow joints. The current modelview matrix is pushed onto the stack and popped at the end of the rendering, so, for example, another arm could be rendered without the transformations from rendering this arm affecting its modelview matrix. Since each OpenGL transformation is applied by multiplying a matrix on the right-hand side of the modelview matrix, the transformations occur in reverse order. Here, the upper arm is translated so that its shoulder position is at the origin, then it is rotated, and finally it is translated so that the shoulder is in its appropriate world-space position. Similarly, the forearm is translated to rotate about its elbow position, then it is translated so that the elbow matches its position in upper arm coordinates.

glPushMatrix();

glTranslatef(worldShoulderX, worldShoulderY, 0.0f); drawShoulderJoint(); glRotatef(shoulderRotation, 0.0f, 0.0f, 1.0f); glTranslatef(-upperArmShoulderX, -upperArmShoulderY, 0.0f); drawUpperArmShape();

glTranslatef(upperArmElbowX, upperArmElbowY, 0.0f);

Copyright c© 2005 David Fleet and Aaron Hertzmann 16

CSC418 / CSCD18 / CSC2504 Transformations

drawElbowJoint(); glRotatef(elbowRotation, 0.0f, 0.0f, 1.0f); glTranslatef(-forearmElbowX, -forearmElbowY, 0.0f); drawForearmShape();

glPopMatrix();

Copyright c© 2005 David Fleet and Aaron Hertzmann 17