1 transformation jeff parker, 2011 based on lectures by ed angel

67
1 Transformation Jeff Parker, 2011 Based on lectures by Ed Angel

Post on 22-Dec-2015

217 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: 1 Transformation Jeff Parker, 2011 Based on lectures by Ed Angel

1

Transformation

Jeff Parker, 2011

Based on lectures by Ed Angel

Page 2: 1 Transformation Jeff Parker, 2011 Based on lectures by Ed Angel

2

Objectives

Introduce standard transformationsRotationTranslationScalingShear

Learn to build arbitrary transformation matrices from simple transformations

Look at some 2 dimensional examples, with an excursion to 3D

We start with a simple example to motivate this

Page 3: 1 Transformation Jeff Parker, 2011 Based on lectures by Ed Angel

3

Using transformations

void display(){ ... setColorBlue(); drawDisc();

setColorRed(); glTranslatef(8,0,0); drawDisc(); setColorGreen(); glTranslatef(-3,2,0); glScalef(2,2,2); drawDisc(); glFlush();}

Page 4: 1 Transformation Jeff Parker, 2011 Based on lectures by Ed Angel

4

General Transformations

Transformation maps points to other points and/or vectors to other vectors

Q=T(P)

v=T(u)

Page 5: 1 Transformation Jeff Parker, 2011 Based on lectures by Ed Angel

5

Non-Rigid Transformations

Page 6: 1 Transformation Jeff Parker, 2011 Based on lectures by Ed Angel

6

Ocean Sunfish

The Ocean Sunfish is the world's heaviest known bony fish Adapted from Thomas D'Arcy's

On Growth and Form

Page 7: 1 Transformation Jeff Parker, 2011 Based on lectures by Ed Angel

7

How many ways?

Although we can move a point to a new location in infinite ways, when we move many points there is usually only one way

object translation: every point displaced by same vector

Page 8: 1 Transformation Jeff Parker, 2011 Based on lectures by Ed Angel

8

Pipeline Implementation

transformation rasterizer

u

v

u

v

T

T(u)

T(v)

T(u)T(u)

T(v)

T(v)

vertices vertices pixels

framebuffer

Page 9: 1 Transformation Jeff Parker, 2011 Based on lectures by Ed Angel

9

Affine Transformations

We want our transformations to be Line PreservingCharacteristic of many physically important

transformationsRigid body transformations: rotation, translationScaling, shear

Importance in graphics is that we need only transform endpoints of line segmentsLet implementation draw line segment between

the transformed endpoints

Page 10: 1 Transformation Jeff Parker, 2011 Based on lectures by Ed Angel

10

Translation

Move (translate, displace) a point to a new location

Displacement determined by a vector dP’=P+d

P

P’

d

Page 11: 1 Transformation Jeff Parker, 2011 Based on lectures by Ed Angel

11

Not Commutative

While often A x B = B x A, transformations are not usually commutativeIf I take a step left, and then turn left, not the same asTurn left, take a step left

This is fundamental, and cannot be patched or fixed.

Page 12: 1 Transformation Jeff Parker, 2011 Based on lectures by Ed Angel

12

Rotations in 2D

We wish to take triplets (x, y) and map them to new points (x', y')While we will want to introduce operations that change scale, we will start

with rigid body translations Translation (x, y) (x + deltaX, y)Translation (x, y) (x + deltaX, y + deltaY)

Rotation (x, y) ?Insight: fix origin, and track (1, 0) and (0, 1) as we rotate through angle a

Page 13: 1 Transformation Jeff Parker, 2011 Based on lectures by Ed Angel

13

RotationsAny point (x, y) can be expressed in terms of (1, 0), (0, 1)

e.g. (12, 15) = 12*(1,0) + 15*(0, 1)These unit vectors form a basis

The coordinates of the rotation of T(1, 0) = (cos(a), sin(a))The coordinates of the rotation of T(0, 1) = (-sin(a), cos(a))

The coordinates of T (x, y) = (x cos(a) + y sin(a), -x sin(a) + y cos(a))Each term of the result is a dot product

(x, y) • ( cos(a), sin(a)) = (x cos(a) - y sin(a))(x, y) • (-sin(a), cos(a)) = (x sin(a) + y cos(a))

Page 14: 1 Transformation Jeff Parker, 2011 Based on lectures by Ed Angel

14

Matrices

Matrices provide a compact representation for rotations, and many other transformation

T (x, y) = (x cos(a) - y sin(a), x sin(a) + y cos(a))To multiply matrices, multiply the rows of first by the columns of second

cos(θ ) −sin(θ )

sin(θ ) cos(θ )

⎣ ⎢

⎦ ⎥x

y

⎣ ⎢

⎦ ⎥=

x cos(θ ) − ysin(θ )

x sin(θ )+ ycos(θ )

⎣ ⎢

⎦ ⎥

Page 15: 1 Transformation Jeff Parker, 2011 Based on lectures by Ed Angel

15

Determinant

If the length of each column is 1, the matrix preserves the length of vectors (1, 0) and (0, 1)

We also will look at the Determinant. Determinant of a rotation is 1.

a b

c d= ad − bc

cos(θ ) −sin(θ )

sin(θ ) cos(θ )= cos2(θ )+sin2(θ ) =1

Page 16: 1 Transformation Jeff Parker, 2011 Based on lectures by Ed Angel

16

3D Matrices

Can act on 3 spaceT (x, y, z) = (x cos(a) + y sin(a), -x sin(a) + y cos(a), z)

This is called a "Rotation about the z axis" – z values are unchanged

cos(θ ) −sin(θ ) 0

sin(θ ) cos(θ ) 0

0 0 1

⎢ ⎢ ⎢

⎥ ⎥ ⎥

x

y

z

⎢ ⎢ ⎢

⎥ ⎥ ⎥=

x cos(θ ) − ysin(θ )

x sin(θ )+ ycos(θ )

z

⎢ ⎢ ⎢

⎥ ⎥ ⎥

Page 17: 1 Transformation Jeff Parker, 2011 Based on lectures by Ed Angel

17

3D Matrices

Can rotate about other axesCan also rotate about other lines through the origin…Can perform rotations in orderAny rotation is the produce of three of these rotations

Euler AnglesNot unique

cos(θ ) 0 −sin(θ )

0 1 0

sin(θ ) 0 cos(θ )

⎢ ⎢ ⎢

⎥ ⎥ ⎥

1 0 0

0 cos(θ ) −sin(θ )

0 sin(θ ) cos(θ )

⎢ ⎢ ⎢

⎥ ⎥ ⎥

Euler Angles Wikipedia

Page 18: 1 Transformation Jeff Parker, 2011 Based on lectures by Ed Angel

18

Euler Angles

The Euler Angles for a rotation are not unique

Euler Angles Wikipedia

−1 0 0

0 −1 0

0 0 1

⎢ ⎢ ⎢

⎥ ⎥ ⎥

1 0 0

0 −1 0

0 0 −1

⎢ ⎢ ⎢

⎥ ⎥ ⎥

−1 0 0

0 1 0

0 0 −1

⎢ ⎢ ⎢

⎥ ⎥ ⎥=

1 0 0

0 1 0

0 0 1

⎢ ⎢ ⎢

⎥ ⎥ ⎥

Page 19: 1 Transformation Jeff Parker, 2011 Based on lectures by Ed Angel

19

Scaling

sx 0 0

0 sy 0

0 0 sz

⎢ ⎢ ⎢

⎥ ⎥ ⎥

S = S(sx, sy, sz) =

x’=sxxy’=syxz’=szx

p’=Sp

Expand or contract along each axis (fixed point of origin)

Page 20: 1 Transformation Jeff Parker, 2011 Based on lectures by Ed Angel

20

Reflection

Reflection corresponds to negative scale factorsExample below sends (x, y, z) (-x, y, z)Note that the product of two reflections is a rotation

originalsx = -1 sy = 1

sx = -1 sy = -1

sx = 1 sy = -1

−1 0 0

0 1 0

0 0 1

⎢ ⎢ ⎢

⎥ ⎥ ⎥

Page 21: 1 Transformation Jeff Parker, 2011 Based on lectures by Ed Angel

21

Limitations

We cannot define a translation in 2D space with a 2x2 matrixThere are no choices for a, b, c, and d that will move the

origin, (0, 0), to some other point, such as (5, 3) in the equation above

Further, we will see that perspective can not be handled by a matrix operation alone

We will find ways to get around each of these problems

a b

c d

⎣ ⎢

⎦ ⎥0

0

⎣ ⎢

⎦ ⎥= ? =

5

3

⎣ ⎢

⎦ ⎥

Page 22: 1 Transformation Jeff Parker, 2011 Based on lectures by Ed Angel

22

Image Formation

We can describe movement with a matrixOr implicitly, as below

Ask for what we want…

glTranslatef(8,0,0);

glTranslatef(-3,2,0);glScalef(2,2,2);

There are still some surprises

Page 23: 1 Transformation Jeff Parker, 2011 Based on lectures by Ed Angel

23

Using transformations

void display(){ ... setColorBlue(); drawDisc();

setColorRed(); glTranslatef(8,0,0); drawDisc(); setColorGreen(); glTranslatef(-3,2,0); glScalef(2,2,2); drawDisc(); glFlush();}

Page 24: 1 Transformation Jeff Parker, 2011 Based on lectures by Ed Angel

24

Absolute vs Relative movevoid display()

{

...

setColorBlue();

glLoadIdentity();

drawDisc();

setColorRed();

glLoadIdentity(); /* Not really needed... */

glTranslatef(8,0,0);

drawDisc();

setColorGreen();

glLoadIdentity(); /* Return to known position */

glTranslatef(5,2,0);

glScalef(2,2,2);

drawDisc();

glFlush();

}

void display(){ ... setColorRed(); glTranslatef(8,0,0); ... glTranslatef(-3,2,0); glScalef(2,2,2); drawDisc();

With absolute placement, don't need to remember where we were before

Page 25: 1 Transformation Jeff Parker, 2011 Based on lectures by Ed Angel

25

Order of Transformations

Note that matrix on the right is the first applied to the point pMathematically, the following are equivalent p’ = ABCp = A(B(Cp))We use column matrices to represent points. In terms of row matrices p’T = pTCTBTAT

That is, the "last" transformation is applied first.

We will see that the implicit transformations have the same order property

Page 26: 1 Transformation Jeff Parker, 2011 Based on lectures by Ed Angel

26

Rotation About a Fixed Point other than the Origin

Move fixed point to originRotateMove fixed point back

M = T(pf) R() T(-pf)

Page 27: 1 Transformation Jeff Parker, 2011 Based on lectures by Ed Angel

27

Instancing

In modeling, we often start with a simple object centered at the origin, oriented with the axis, and at a standard size

We apply an instance transformation to its vertices to Scale Orient (rotate)Locate (translate)

Page 28: 1 Transformation Jeff Parker, 2011 Based on lectures by Ed Angel

28

Example

void display(){

...setColorGreen();glLoadIdentity();glTranslatef(5,2,0);glRotatef(45.0, 0.0, 0.0, 1.0); /* z axis */glScalef(2,4,0);drawDisc();...

}

Page 29: 1 Transformation Jeff Parker, 2011 Based on lectures by Ed Angel

29

Match image to code

setColorGreen();

glLoadIdentity();

glRotatef(45.0, 0.0, 0.0, 1.0); /* z axis */

glTranslatef(5,2,0);

glScalef(2,4,0);

drawDisc();

setColorGreen();glLoadIdentity();glTranslatef(5,2,0);glRotatef(45.0, 0.0, 0.0, 1.0); glScalef(2,4,0);drawDisc();

setColorGreen();glLoadIdentity();glTranslatef(5,2,0);glScalef(2,4,0);glRotatef(45.0, 0.0, 0.0, 1.0); drawDisc();

The most recently applied transformation works first

Page 30: 1 Transformation Jeff Parker, 2011 Based on lectures by Ed Angel

30

Proper Order

setColorGreen();

glLoadIdentity();

glRotatef(45.0, 0.0, 0.0, 1.0); /* z axis */

glTranslatef(5,2,0);

glScalef(2,4,0);

drawDisc();

setColorGreen();glLoadIdentity();glTranslatef(5,2,0);glRotatef(45.0, 0.0, 0.0, 1.0); glScalef(2,4,0);drawDisc();

setColorGreen();glLoadIdentity();glTranslatef(5,2,0);glScalef(2,4,0);glRotatef(45.0, 0.0, 0.0, 1.0); drawDisc();

Page 31: 1 Transformation Jeff Parker, 2011 Based on lectures by Ed Angel

Example

Be sure to play with Nate Robin's Transformation example

Page 32: 1 Transformation Jeff Parker, 2011 Based on lectures by Ed Angel

Matrix Stack

It is useful to be able to save the current transformationWe can push the current state on a stack, and thenMake new scale, translations, rotations transformations

Then pop the stack and return to status quo ante

Page 33: 1 Transformation Jeff Parker, 2011 Based on lectures by Ed Angel

Example

Page 34: 1 Transformation Jeff Parker, 2011 Based on lectures by Ed Angel

Example

Image is made up of subimages

Page 35: 1 Transformation Jeff Parker, 2011 Based on lectures by Ed Angel

Ringsvoid display(){

int angle;glClear(GL_COLOR_BUFFER_BIT);for (angle = 0; angle < 360; angle = angle + STEP){

glPushMatrix(); /* Remember current state */glRotated(angle, 0, 0, 1);glTranslatef(0.0, 0.75, 0.0);glScalef(0.15, 0.15, 0.15);drawRing();glPopMatrix(); /* Restore orignal state */

}glFlush();

}

Page 36: 1 Transformation Jeff Parker, 2011 Based on lectures by Ed Angel

Rings/* Draw 12 rings */void display(){

int angle;// glClear(GL_COLOR_BUFFER_BIT);for (angle = 0; angle < 360; angle = angle + STEP){

glPushMatrix(); /* Remember current state */glRotated(angle, 0, 0, 1);glTranslatef(0.0, 0.75, 0.0);glScalef(0.15, 0.15, 0.15);drawRing();glPopMatrix(); /* Restore orignal state */

}glFlush();

}

Page 37: 1 Transformation Jeff Parker, 2011 Based on lectures by Ed Angel

drawRing/* Draw 12 triangles to form one ring */void drawRing(){

int angle;for (angle = 0; angle < 360; angle = angle + STEP){

glPushMatrix(); /* Remember current state */glRotated(angle, 0, 0, 1);glTranslatef(0.0, 0.75, 0.0);glScalef(0.2, 0.2, 0.2);glColor3f((float)angle/360, 0, 1.0-((float)angle/360));

drawTriangle();glPopMatrix(); /* Restore orignal state */

}glFlush();

}

Page 38: 1 Transformation Jeff Parker, 2011 Based on lectures by Ed Angel

Tree

This is harder to do from scratch

Jon Squire's fractalgl uses the Matrix Stack

Page 39: 1 Transformation Jeff Parker, 2011 Based on lectures by Ed Angel

39

Shear

Helpful to add one more basic transformationEquivalent to pulling faces in opposite directions

Page 40: 1 Transformation Jeff Parker, 2011 Based on lectures by Ed Angel

40

Shear Matrix

Consider simple shear along x axis

x’ = x + y cot y’ = yz’ = z

1 cot(θ) 0

0 1 0

0 0 1

⎢ ⎢ ⎢

⎥ ⎥ ⎥

H() =

Page 41: 1 Transformation Jeff Parker, 2011 Based on lectures by Ed Angel

41

3D Rotation example// Vertices of a unit cube centered at originpoint4 vertices[8] = { point4( -0.5, -0.5, 0.5, 1.0 ), point4( -0.5, 0.5, 0.5, 1.0 ), point4( 0.5, 0.5, 0.5, 1.0 ), point4( 0.5, -0.5, 0.5, 1.0 ), point4( -0.5, -0.5, -0.5, 1.0 ), point4( -0.5, 0.5, -0.5, 1.0 ), point4( 0.5, 0.5, -0.5, 1.0 ), point4( 0.5, -0.5, -0.5, 1.0 )};

Page 42: 1 Transformation Jeff Parker, 2011 Based on lectures by Ed Angel

42

Cube corners// generate 12 triangles: 36 vertices and 36 colorsvoid colorcube(){ quad( 1, 0, 3, 2 ); quad( 2, 3, 7, 6 ); quad( 3, 0, 4, 7 ); quad( 6, 5, 1, 2 ); quad( 4, 5, 6, 7 ); quad( 5, 4, 0, 1 );}

Page 43: 1 Transformation Jeff Parker, 2011 Based on lectures by Ed Angel

43

Colors// RGBA olorscolor4 vertex_colors[8] = { color4( 0.0, 0.0, 0.0, 1.0 ), // black color4( 1.0, 0.0, 0.0, 1.0 ), // red color4( 1.0, 1.0, 0.0, 1.0 ), // yellow color4( 0.0, 1.0, 0.0, 1.0 ), // green color4( 0.0, 0.0, 1.0, 1.0 ), // blue color4( 1.0, 0.0, 1.0, 1.0 ), // magenta color4( 1.0, 1.0, 1.0, 1.0 ), // white color4( 0.0, 1.0, 1.0, 1.0 ) // cyan};

Page 44: 1 Transformation Jeff Parker, 2011 Based on lectures by Ed Angel

44

Mixing color and corner// Vertices of a unit cube centered at originpoint4 vertices[8] = { point4( -0.5, -0.5, 0.5, 1.0 ), ...

// RGBA olorscolor4 vertex_colors[8] = { color4( 0.0, 0.0, 0.0, 1.0 ), // black ...

// quad generates two triangles for each face // and assigns colors to the verticesint Index = 0;void quad( int a, int b, int c, int d ) { colors[Index] = vertex_colors[a];

points[Index] = vertices[a]; Index++;

Page 45: 1 Transformation Jeff Parker, 2011 Based on lectures by Ed Angel

45

Mixing color and corner// quad generates two triangles for each face // and assigns colors to the verticesint Index = 0;void quad( int a, int b, int c, int d ) { colors[Index] = vertex_colors[a];

points[Index] = vertices[a]; Index++; colors[Index] = vertex_colors[b];

points[Index] = vertices[b]; Index++; colors[Index] = vertex_colors[c];

points[Index] = vertices[c]; Index++; colors[Index] = vertex_colors[a];

points[Index] = vertices[a]; Index++; colors[Index] = vertex_colors[c];

points[Index] = vertices[c]; Index++; colors[Index] = vertex_colors[d];

points[Index] = vertices[d]; Index++;}

Page 46: 1 Transformation Jeff Parker, 2011 Based on lectures by Ed Angel

46

SpinGLfloat Theta[NumAxes] = { 0.0, 0.0, 0.0 };GLuint theta;// The location of the "theta"

// shader uniform variable... theta = glGetUniformLocation( program, "theta" );...

void display( void ){ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glUniform3fv( theta, 1, Theta ); glDrawArrays( GL_TRIANGLES, 0, NumVertices );

glutSwapBuffers();}

Page 47: 1 Transformation Jeff Parker, 2011 Based on lectures by Ed Angel

47

Delta Spinvoid idle( void ){ Theta[Axis] += 0.01;

if ( Theta[Axis] > 360.0 ) { Theta[Axis] -= 360.0; } glutPostRedisplay();}

int main( int argc, char **argv ){ ... glutIdleFunc( idle );

Page 48: 1 Transformation Jeff Parker, 2011 Based on lectures by Ed Angel

48

Change axis// Array of rotation angles for each axisGLfloat Theta[NumAxes] = { 0.0, 0.0, 0.0 };enum { Xaxis = 0, Yaxis = 1, Zaxis = 2, NumAxes = 3 };int Axis = Xaxis;

void mouse( int button, int state, int x, int y ){ if ( state == GLUT_DOWN ) { switch( button ) { case GLUT_LEFT_BUTTON: Axis = Xaxis; break; case GLUT_MIDDLE_BUTTON: Axis = Yaxis; break; case GLUT_RIGHT_BUTTON: Axis = Zaxis; break; } }}

The Euler Angles do not give the rotations you might expect

Page 49: 1 Transformation Jeff Parker, 2011 Based on lectures by Ed Angel

49

Change axisvoid mouse( int button, int state, int x, int y ){ if ( state == GLUT_DOWN ) { switch( button ) { case GLUT_LEFT_BUTTON: Axis = Xaxis; break; case GLUT_MIDDLE_BUTTON: Axis = Yaxis; break; case GLUT_RIGHT_BUTTON: Axis = Zaxis; break; ...// One button alternativevoid mouse( int button, int state, int x, int y ){ if ( state == GLUT_DOWN ) { Axis = Axis + 1; if (Axis == NumAxes) Axis = Xaxis; }

Page 50: 1 Transformation Jeff Parker, 2011 Based on lectures by Ed Angel

50

Main Programint main( int argc, char **argv ) { glutInit( &argc, argv ); glutInitDisplayMode( GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH ); glutInitWindowSize( 512, 512 ); glutCreateWindow( "Color Cube" );

init();

glutDisplayFunc( display ); glutKeyboardFunc( keyboard ); glutMouseFunc( mouse ); glutIdleFunc( idle );

glutMainLoop(); return 0;}

Page 51: 1 Transformation Jeff Parker, 2011 Based on lectures by Ed Angel

51

Fragment Shader

varying vec4 color;

void main() { gl_FragColor = color;}

Page 52: 1 Transformation Jeff Parker, 2011 Based on lectures by Ed Angel

52

Vertex Shaderattribute vec4 vPosition;attribute vec4 vColor;varying vec4 color;

uniform vec3 theta;

void main() { // Compute sines and cosines of theta for each of // the three axes in one computation. vec3 angles = radians( theta ); vec3 c = cos( angles ); vec3 s = sin( angles );

Page 53: 1 Transformation Jeff Parker, 2011 Based on lectures by Ed Angel

53

Rotation mat4 rx = mat4( 1.0, 0.0, 0.0, 0.0,

0.0, c.x, s.x, 0.0, 0.0, -s.x, c.x, 0.0, 0.0, 0.0, 0.0, 1.0 );

mat4 ry = mat4( c.y, 0.0, -s.y, 0.0, 0.0, 1.0, 0.0, 0.0, s.y, 0.0, c.y, 0.0,

0.0, 0.0, 0.0, 1.0 ); ... mat4 rz = mat4( c.z, -s.z, 0.0, 0.0,

s.z, c.z, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0 );

color = vColor; gl_Position = rz * ry * rx * vPosition;}

Euler AnglesWikipedia

Page 54: 1 Transformation Jeff Parker, 2011 Based on lectures by Ed Angel

54

Alternative timingvoid spinCube() { theta[axis] += 1.0; if( theta[axis] > 360.0 ) theta[axis] -= 360.0; glutPostRedisplay();}

static void timerCallback (int value) { /* Do timer processing */ spinCube(value); /* call back again after elapsedUSecs have passed */ glutTimerFunc (50, timerCallback, value);}

/* Main program */int main(int argc, char **argv) { ... glutTimerFunc (50, timerCallback, 1);

Current scheme depends on speed of cpu

This one defines a timer…

Page 55: 1 Transformation Jeff Parker, 2011 Based on lectures by Ed Angel

55

Fractals - Snowflake curve

The Koch Snowflake was discovered by Helge von Koch in 1904. Start with a triangle inscribed in the unit circleTo build the level n snowflake, we replace each edge in the level n-1

snowflake with the following patternThe perimeter of each version is 4/3 as long

Infinite perimeter, but snowflake lies within unit circle, so has finite area

We will use Turtle Geometry to draw the snowflake curveAlso what Jon Squire used for Fractal Tree

Page 56: 1 Transformation Jeff Parker, 2011 Based on lectures by Ed Angel

56

Recursive Step

void toEdge(int size, int num) {

if (1 >= num)turtleDrawLine(size);

else {toEdge(size/3, num-1);turtleTurn(300);toEdge(size/3, num-1);turtleTurn(120);toEdge(size/3, num-1);turtleTurn(300);toEdge(size/3, num-1);

}}

Page 57: 1 Transformation Jeff Parker, 2011 Based on lectures by Ed Angel

57

Turtle Library

/** Draw a line of length size */

void turtleDrawLine(GLint size)

glVertex2f(xPos, yPos);

turtleMove(size);

glVertex2f(xPos, yPos);

}

int turtleTurn(int alpha) {

theta = theta + alpha;

theta = turtleScale(theta);

return theta;

}

/** Move the turtle. Called to move and by DrawLine */

void turtleMove(GLint size) {

xPos = xPos + size * cos(DEGREES_TO_RADIANS * theta);

yPos = yPos + size * sin(DEGREES_TO_RADIANS * theta);

}

Page 58: 1 Transformation Jeff Parker, 2011 Based on lectures by Ed Angel

58

Dragon Curve

The Dragon Curve is due to Heighway

One way to generate the curve is to start with a folded piece of paper

We can describe a curve as a set of turtle directions

The second stage is simply

Take one step, turn Right, and take one step

The next stage is

Take one step, turn Right, take one step

Turn Right

Perform the original steps backwards, or

Take one step, turn Left, take one step

Since the step between turns is implicit, we can write this as RRL

The next stage is

Page 59: 1 Transformation Jeff Parker, 2011 Based on lectures by Ed Angel

59

Dragon Curve

The Dragon Curve is due to Heighway

One way to generate the curve is to start with a folded piece of paper

We can describe a curve as a set of turtle directions

The second stage is simply

Take one step, turn Right, and take one step

The next stage is

Take one step, turn Right, take one step

Turn Right

Perform the original steps backwards, or

Take one step, turn Left, take one step

Since the step between turns is implicit, we can write this as RRL

The next stage is

RRL R RLL

Page 60: 1 Transformation Jeff Parker, 2011 Based on lectures by Ed Angel

60

How can we program this?

We could use a large array representing the turnsRRL R RLL

To generate the next level, append an R and walk back to the head, changing L’s to R’s and R’s to L’s and appending the result to end of array

But there is another way.

Start with a lineAt every stage, we replace the line with a right angleWe have to remember which side of the line to decorate (use variable “direction”)One feature of this scheme is that the “head” and “tail” are fixed

R R L R R L L

Page 61: 1 Transformation Jeff Parker, 2011 Based on lectures by Ed Angel

61

Dragon Curve

void dragon(int size, int level, int direction, int alpha)

{

/* Add on left or right? */

int degree = direction * 45;

turtleSet(alpha);

if (1 == level) {

turtleDrawLine(size);

return;

}

size = size/scale; /* scale == sqrt(2.0) */

dragon(size, level - 1, 1, alpha + degree);

dragon(size, level - 1, -1, alpha - degree);

}

Page 62: 1 Transformation Jeff Parker, 2011 Based on lectures by Ed Angel

62

Dragon Curve

When we divide an int (size) by a real (sqrt(2.0)) there is roundoff error, and the dragon slowly shrinks

The on-line version of this program precomputes sizes per level and passes them through, as below

int sizes[] = {0, 256, 181, 128, 90, 64, 49, 32, 23, 16, 11, 8, 6, 4, 3, 2, 2, 1, 0};

...

dragon(sizes[level], level, 1, 0);

...

void dragon(int size, int level, int direction, int alpha)

{

...

/* size = size/scale; */

dragon(size, level - 1, 1, alpha + degree);

dragon(size, level - 1, -1, alpha - degree);

}

Page 63: 1 Transformation Jeff Parker, 2011 Based on lectures by Ed Angel

63

Pen And Paper

Write routines to decide if a circle intersects a line or a line segment

How much harder would it be to find the point of intersection?

Page 64: 1 Transformation Jeff Parker, 2011 Based on lectures by Ed Angel

64

Task

Write a program that displays an image, and uses user input to update the image. Don't worry about logic behind the display

Page 65: 1 Transformation Jeff Parker, 2011 Based on lectures by Ed Angel

65

From Previous classAlex Chou's Pac Man

Page 66: 1 Transformation Jeff Parker, 2011 Based on lectures by Ed Angel

66

Sample Projects

From last class

Page 67: 1 Transformation Jeff Parker, 2011 Based on lectures by Ed Angel

67

Summary

We have played with transformationsSpend today looking at movement in 2D

In OpenGL, transformations are defined by matrix operationsIn new version, glTranslate, glRotate, and glScale are deprecated

We have seen some 2D matrices for rotation and scalingYou cannot define a 2x2 matrix that performs translation

A puzzle to solveThe most recently applied transformation works firstYou can push the current matrix state and restore later

Turtle Graphics provides an alternative