Industrial Training




2D & 3D Transformations

  • the order we perform multiple transforms can matter
    • eg. translate + scale can differ from scale + translate
    • eg. rotate + translate can differ from translate + rotate
    • eg. rotate + scale can differ from scale + rotate (when scale_x differs from scale_y)
  • when does m1 + m2 = m2 + m1?

 m1

 m2

 translate

translate

scale

scale

rotate

rotate

scale (sx = sy)

rotate

  • to prove commutativity (or lack thereof), show that the composed transformation matrices are the same (or different).


combined form for 2d transforms

 | r11 r12 tx |
	m = | r21 r22 ty |
	| 0 0 1 |
  • upper 2 by 2 submatrix is a composite rotation & scale matrix;
    • t1 and t2 are composed translations
  • precise form of matrix expressions depends upon order of transforms


coordinate systems: local and global

  • with no transformations, there is one global coordinate system in which objects are drawn.
  • when you apply any transformation, this is equivalent to changing the coordinate system. you are defining a local coordinate system within the global system.
  • for example, if you set the scale to 0.5, and then draw a box, that box's coordinate system is 0.5 relative to the global coordinate system.
  • thinking of transformations as changing the coordinate systems is very useful conceptually, since in most scenes, objects transforms are defined relative to one, but the objects themselves are drawn without regard to the transforms applied to them. this is most easily imagined as if they had differing coordinate systems.


2d transforms: opengl implementation

  • opengl is immediate mode: graphics operations are applied 'instantly'
    • in terms of transformations, the user gives a rotate, translate, or scale command, and the matrix multiplication represented by that transform is immediately applied to a global transformation matrix
    • in other words, a 4 by 4 matrix of floating point values is maintained. it changes each time a single transformation is done. however, all the individual transformations used to derive these numeric values are not retained.


2d transforms: opengl

  • opengl transformation commands set up a 4 by 4 transformation matrix, in the way shown on previous overheads
    • can use glget(gl_modelview_matrix) to retrieve this matrix, and glloadmatrix to replace it with your own matrix.
  • we haven't talked about 3d transforms; however, note that homogeneous 3d transformation matrix is 4 by 4; 2d uses subset of it.
  • glrotate{fd} (type angle, type x, type y, type z)
    • type is f or d
    • rotates the current transformation matrix counterclockwise 'angle' degrees about a ray from the origin through the point (x, y, z)
    • eg. glrotatef(45.0, 0.0, 0.0, 1.0) rotates 45 degrees about the z-axis
    • (x,y,z) can be any direction. it will be automatically normalized if it isn't a unit vector.
  • gltranslate {fd} (type x, y, z)
    • translates by the amounts x, y, z
    • note: gltranslatef(): empty argument is the identity matrix
  • glscale {fd} (type x, y, z)
    • applies x, y, z scaling factors
    • eg. glscalef(2.0, -0.5, 1.0)


opengl: order of transformation operations

  • when giving opengltransformation commands, they are applied in the inverse order you give them.
	glscaled(1.0, 1.0, 3.0);
	glrotatef(45.0, 0.0, 1.0, 0.0);
	gltranslatef(3.0, 2.0, 0.0);
	draw_my_triangle();
  • the transformations occur in the reverse order
    • this is done to reflect the algebraic order of the matrix transforms:
      s * r * t * p = s * (r * (t * p) )


2d transformation inversions

t(dx, dy) * t(-dx, -dy) = 1

r( a) * r(- a) = 1

s(sx, sy) * s( 1/sx, 1/sy) = 1

to invert a sequence of transforms p' = m * p = (tr1 * tr2 * ... * trk) * p

m^(-1) * p = (tr1 * tr2 * ... * trk)^(-1) * p = trk^(-1) * ... * tr2^(-1) * tr1^(-1) * p

  • note how matrix/vector notation is useful here!


opengl: saving and restoring contexts

  • previously mentioned that opengl does not save individual transformations.
    • implies that application program must retain all the individual transformations, if one ever wants to "undo" them!
  • glpushmatrix(), glpopmatrix(): save and restore transformation matrices
    • you essentially modify & use top matrix on the stack
    • initialize to identity matrix with: glloadidentity()
    • using glpushmatrix() lets you save your current local coordinate system, by copying top (current) transformation matrix onto top of stack.
    • subsequent transformations manipulate top matrix in stack.
      --> transformations compound and accumulate into one general transformation.
    • glpopmatrix() then reverts back to previous local coordinate system.
      • equivalent to applying the inversions of all the transforms done in the meantime.
  • extremely useful when rendering hierarchical scenes


opengl matrix modes

  • opengl has separate transformation matrices for different graphics features
  • glmatrixmode(glenum mode), where mode is one of:
    • gl_modelview - for manipulating model in scene (stack of them for glpushmatrix)
    • gl_projection - perspective orientation
    • gl_texture - texture map orientation
  • make sure you specify glmatrixmode(gl_modelview) before proceeding with model transformations
  • likewise, specify glmatrixmode(gl_projection) when you set up your perspective view (in later topic)
  • glloadidentity(): loads a 4-by-4 identity matrix into the current matrix (whatever mode you're in)
    • always initialize with the identity; don't presume it is loaded for you
  • example 2d opengl program: sierpinski triangles and example output (level=7).
  • here's the output when transformations in wrong order.


properties of affine transformation matrix m

  • lines are preserved (ie. lines remain lines after transform)
  • parallelism is preserved
  • proportional distances are preserved
    • eg. if point p is a fraction f between points a and b before, it will remain so after the transform
  • the change in area of any object transformed is:
    • (area after transform) / (area before transform) = |determinant m |


2d transforms: shear transformations ("shearing")

 

 | 1 a 0 | | 1 0 0 |
	shx = | 0 1 0 | shy = | b 1 0 |
	| 0 0 1 | | 0 0 1 |
	
	x' = x + ay x' = x
	y' = y y' = bx + y
  • ... a proportional change in x as a function of y (and vice versa)


3d transforms

  • 3d space: add a z coordinate (x, y, z)
    • 3d homogeneous coordinates: 4 dimensions
  • text and opengl use a right-handed rotation system: grab the z axis with right hand, and curl fingers from +ve x axis to +ve y axis: thumb points out at you, which is direction of +ve z axis
    • implies that +ve z axis points at you when facing the screen with +ve y pointing up and +ve x pointing right


3d transforms

  • all transformations directly extend to 3d
  • translation:
 | 1 0 0 dx |
	t(dx,dy,dz) = | 0 1 0 dy |
	| 0 0 1 dz |
	| 0 0 0 1 |
  • scaling:
 | sx 0 0 0 |
	s(sx,sy,sz) = | 0 sy 0 0 |
	| 0 0 sz 0 |
	| 0 0 0 1 |
  • rotation:
 | 1 0 0 0 |
	rx(a) = | 0 cos a -sin a 0 |
	| 0 sin a cos a 0 |
	| 0 0 0 1 |
	
	| cos a 0 sin a 0 |
	ry(a) = | 0 1 0 0 |
	| -sin a 0 cos a 0 |
	| 0 0 0 1 |
	
	| cos a -sin a 0 0 |
	rz(a) = | sin a cos a 0 0 |
	| 0 0 1 0 |
	| 0 0 0 1 |
	

3d transforms

  • 2d rotations is given by z axis rotation matrix
  • note that rotation matrix about y axis uses "different' signs
    • reason: when you look down y axis, you have this:

z' = z cos a - x sin a

x' = z sin a + x cos a (as before)

--> but when you put these in matrix form, the x and z are in reversed order, hence the sign change

  • all these transformation matrices have inverses similar to 2d case


3d transforms

  • composing 3d transforms works same as 2d: write each transformation matrix in the order the transformation sequence is done
    • translation & rotations on same axes are additive, while scaling is multiplicative
    • however, note that rotations on different axis are not commutative!
  • general transform:
 | r11 r12 r13 tx |
	m = | r21 r22 r23 ty |
	| r31 r32 r33 tz |
	| 0 0 0 1 |
  • one trick: inverse of the top-left 3 x 3 submatrix: transpose it
 | r11 r12 r13 |
	r = | r21 r22 r23 |
	| r31 r32 r33 |
	
	| r11 -r21 r13 |
	r^(-1) = (1/det r)* | -r12 r22 -r32 |
	| r31 -r23 r33 |


3d transform properties

  • lines are preserved
  • parallelism is preserved
  • proportional distances are preserved
  • (volume after transformation) / (volume before) = | det m |
  • example 3d opengl program: sierpinski pyramids and example output


non-affine transform: fish-eye (angle halver)

  • entire x-y plane mapped to a circle
    • phi = tan^(-1)(|p|)
    • convert p to q: q = s * p (s = scaling factor)
    • where s = tan(tan^(-1)(|p|)/2)/(|p|) = |q|/|p| = tan(phi/2)/|p|
  • fish eye transformation setup(from [hill 1990])
  • example transformation (from [hill 1990])


non-affine transforms: inversion in a unit circle

  • map point p to inverse of its distance from origin
  • circles and lines that do not pass through origin map into circles
  • derivation:
    • sin(a) = x/(|p|)
    • so: x' = 1/(|p|) sin(a) = (1/(|p|))*(x/(|p|)) = x / (|p|^2)
    • q = 1/(|p|^2) * p
    • x' = 1/(|p|^2) * x
    • y' = 1/(|p|^2) * y

  • example unit circle inversions.(from [hill 1990])
  • circle inversion of a map of the world(from [hill 1990])


references

  • introduction to computer graphics , foley, van dam, et al, addison wesley, isbn 0-201-60921-5.
  • computer graphics, f.s. hill jr, macmillan 1990, isbn 0-02-354860-6. (source of non-affine transformation examples.)



Hi I am Pluto.