# Transforms, Degree thesis for Art. De Chirico

PDF (56 KB)
8 pages
956Number of visits
Description
gfdgddhgfgh
20 points
this document
Preview3 pages / 8
Transforms.dvi

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.

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.

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

[

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.

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 ]

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.

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̂ = Âp̂ = (x′, y′, 1)T (2)

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

Â(αp̂) = α(Â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.

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);

CSC418 / CSCD18 / CSC2504 Transformations

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

glPopMatrix();