Graphics by dffhrtcv3

VIEWS: 4 PAGES: 67

									                                1




    Transformation

      Jeff Parker, 2011
Based on lectures by Ed Angel
                 Objectives
Introduce standard transformations
    Rotation
    Translation
    Scaling
    Shear
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
   2
        Using transformations
void display()
{
    ...
    setColorBlue();
    drawDisc();

    setColorRed();
    glTranslatef(8,0,0);
    drawDisc();

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

    3
         General Transformations
Transformation maps points to other points and/or vectors to other vectors

                                               v=T(u)




                   Q=T(P)




    4
    Non-Rigid Transformations




5
       Ocean Sunfish




    The Ocean Sunfish is the world's
6   heaviest known bony fish           Adapted from Thomas D'Arcy's
                                           On Growth and Form
                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
    7
           Pipeline Implementation
                  T

                                                           frame
     u                          T(u)                       buffer
            transformation                rasterizer
      v                          T(v)                               T(v)

                                        T(v)
v
                                                       T(u)
       u                      T(u)
vertices                     vertices                   pixels

      8
        Affine Transformations
We want our transformations to be Line Preserving
Characteristic of many physically important
  transformations
   Rigid body transformations: rotation, translation
   Scaling, shear
Importance in graphics is that we need only
  transform endpoints of line segments
   Let implementation draw line segment between
     the transformed endpoints

   9
                            Translation

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


                                  d
                    P
Displacement determined by a vector d
    P’=P+d




    10
                Not Commutative
While often A x B = B x A, transformations are not usually commutative
If I take a step left, and then turn left, not the same as
Turn left, take a step left
      This is fundamental, and cannot be patched or fixed.




    11
                    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




    12
                            Rotations
Any 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))




    13
                            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


                                  
                 ) sin( ) x  cos( )  ysin( )
                cos(                      x
                                 
                                                             
               sin( ) cos( )  y x sin( )  y cos( )
                                  



     


    14
                       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
                            ad  bc
                       c d

           cos( ) sin( )
                             cos2 ( )  sin 2 ( )  1
            sin( ) cos( )
         

    15
                             3D Matrices
     Can act on 3 space
     T (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
                                
                ) sin( ) 0 x  cos( )  ysin( )
               cos(                     x     
                              
                                                     
                                                       
               sin( ) cos( ) 0 y  sin( ) y cos( )
                                    x
               0
                       0      
                              1 z  
                                 
                                               z         
                                                           







         16
                         3D Matrices
Can rotate about other axes
    Can also rotate about other lines through the origin…     Euler Angles Wikipedia
    Can perform rotations in order
    Any rotation is the produce of three of these rotations
         Euler Angles                                  
                                                        1    0           0 
                                                                             
             Not unique                                        
                                                        0 cos( ) sin( )
                                                       
                                                        sin( ) cos( ) 
                                                       
                                                        0                   


                                                           ) 0 sin( )
                                                          cos(
                                                                        
                                                            0    1   0 
                                                         sin( ) 0 cos( ) 
                                                                       
    17
                      Euler Angles
The Euler Angles for a rotation are not unique
                                                 Euler Angles Wikipedia



  1 0 0 1 0 0 1 0 0   0 0
                           1
        
                  
                                
 0 1 0 0 1 0  0 1 0   1 0
                             0
          
 0 0 1 0 0 1 0 0 1  0 1
        
                  
                    
                           0    




    18
                                  Scaling
Expand or contract along each axis (fixed point of origin)
                  x’=sxx
                  y’=syx
                  z’=szx

                  p’=Sp

                                x
                                s     0    0 
                                            
         S = S(sx, sy, sz) =
                               0    sy   0 
                               0
                                    0    sz 
                                              

       19
                          Reflection
Reflection corresponds to negative scale factors
Example below sends (x, y, z)  (-x, y, z)
Note that the product of two reflections is a rotation
 sx = -1 sy = 1                                                original



      
       1 0        0
                  
 sx = 0sy =1-1
      -1           0
      0 0
                 1
                    
                                                         sx = 1 sy = -1

    20
                      Limitations
                      
                 b0
                 a               
                                 5
                     ?   
                      
                 c
                 d 0
                               3
                                 
 We cannot define a translation in 2D space with a 2x2 matrix
    There 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
    21
               Image Formation
We can describe movement with a matrix
Or 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



   22
         Using transformations
void display()
{
    ...
    setColorBlue();
    drawDisc();

    setColorRed();
    glTranslatef(8,0,0);
    drawDisc();

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

    23
      Absolute vs Relative move
void display()                     void display()
                                   {
{                                      ...
    ...                                setColorRed();
                                       glTranslatef(8,0,0);
    setColorBlue();                    ...
    glLoadIdentity();                  glTranslatef(-3,2,0);
                                       glScalef(2,2,2);
    drawDisc();                        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();             With absolute placement, don't need
    glFlush();              to remember where we were before
    24
}
         Order of Transformations
Note that matrix on the right is the first applied to the point p
Mathematically, 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




    25
   Rotation About a Fixed Point
       other than the Origin
Move fixed point to origin
Rotate
Move fixed point back
M = T(pf) R() T(-pf)




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




    27
                  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();
   ...
}


   28
             Match image to code
                              The most recently applied
setColorGreen();              transformation works first
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();
    29
                     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();
    30
                       Example
Be sure to play with Nate Robin's Transformation example
                     Matrix Stack
It is useful to be able to save the current transformation
     We can push the current state on a stack, and then
     Make new scale, translations, rotations transformations
Then pop the stack and return to status quo ante
Example
                      Example
Image is made up of subimages
                          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();
}
                          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();
}
                       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();
}
Jon Squire's fractalgl uses the Matrix Stack
                                Tree




                       This is harder to do from scratch
                       Shear
Helpful to add one more basic transformation
Equivalent to pulling faces in opposite directions




   39
                        Shear Matrix
Consider simple shear along x axis

         x’ = x + y cot 

 1    cot( y 
         y’ =
       z’ = z 
 
               

 
               
                   
          H() =



     40
                                                41




         3D Rotation example
// Vertices of a unit cube centered at origin
point4 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 )
};
                                                 42




               Cube corners
// generate 12 triangles: 36 vertices and 36 colors
void 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 );
}
                                                     43




                    Colors
// RGBA olors
color4 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
};
                                                44


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

// RGBA olors
color4 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 vertices
int Index = 0;
void quad( int a, int b, int c, int d ) {
    colors[Index] = vertex_colors[a];
      points[Index] = vertices[a]; Index++;
                                                45


       Mixing color and corner
// quad generates two triangles for each face
// and assigns colors to the vertices
int 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++;
}
                                                    46


                         Spin
GLfloat 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();
}
                                    47


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

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

    glutPostRedisplay();
}

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


                   Change axis
// Array of rotation angles for each axis
GLfloat 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
                                                      49


                 Change axis
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;
   ...
// One button alternative
void mouse( int button, int state, int   x, int y )
{
  if ( state == GLUT_DOWN ) {
    Axis = Axis + 1;
    if (Axis == NumAxes)
      Axis = Xaxis;
  }
                                                     50


               Main Program
int 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;
}
                                51


              Fragment Shader

varying   vec4 color;

void main()
{
    gl_FragColor = color;
}
                                                      52


                Vertex Shader
attribute   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 );
                                                         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,          Euler Angles
                    s.y, 0.0, c.y, 0.0,           Wikipedia
                    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;
}
                                                       54
 Current scheme depends on speed of cpu
              Alternative timing
void spinCube() {              This one defines a timer…
  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);
                                                                                55



                   Fractals - Snowflake curve

The Koch Snowflake was discovered by Helge von Koch in 1904.
Start with a triangle inscribed in the unit circle
To build the level n snowflake, we replace each edge in the level n-1
   snowflake with the following pattern
The 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 curve
     Also what Jon Squire used for Fractal Tree
                                  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);
   }
}
                                                             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);
}
                                                                          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
     …
                                                                          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
                                                                                         60



                     How can we program this?

We could use a large array representing the turns
     RRL 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.
                              RRLRRLL
Start with a line
At every stage, we replace the line with a right angle
We 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
                                                             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);
}
                                                                                         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);
}
                                                                           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?
                                                                            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
From Previous class
Alex Chou's Pac Man




   65
                  Sample Projects
From last class




    66
                         Summary
We have played with transformations
    Spend today looking at movement in 2D
In OpenGL, transformations are defined by matrix operations
    In new version, glTranslate, glRotate, and glScale are deprecated
We have seen some 2D matrices for rotation and scaling
    You cannot define a 2x2 matrix that performs translation
         A puzzle to solve
The most recently applied transformation works first
You can push the current matrix state and restore later

Turtle Graphics provides an alternative




    67

								
To top