Transformations



Transformations

10 0


Transformations

presentation available online here: http://visualcomputing.github.io/Transformations

On Github VisualComputing / Transformations

Themes

Set your presentation theme: Black (default) - White - League - Sky - Beige - Simple Serif - Blood - Night - Moon - Solarized

Transformations

Jean Pierre Charalambos

Index

Intro
  • Active vs pasive transformations
  • Shaders
Linear transformations
  • Scaling, rotation & shearing
Affine transformations
  • Homogeneous space
  • Translation
  • Scaling, rotation & shearing revisited
  • Matrix operations: orthogonality, inversion & composition

Index (part 2)

Modelling and view Projections
  • Orthographic
  • Perspective

Intro: Active vs pasive transformations

Active Transformation (standard basis) vs Passive Transformation (change of basis)

  • Standard = Canonical

Intro: Shaders

Vertex shader

Fragment shader

Intro: Shaders

Vertex shader: pseudo code

for (int i = 0; i < vertexCount; i++) {
  output = vertexShader(vertex[i]);
}

function vertexShader(vertex) {
  projPos = projection * modelview * vertex.position;
  litColor = lightColor * dot(vertex.normal, lightDirection);
  return (projPos, litColor);
}

Intro: Shaders

Vertex shader

uniform mat4 transform;
attribute vec4 vertex;
attribute vec4 color;
varying vec4 vertColor;

void main() {
   gl_Position = transform * vertex;
   vertColor = color;
}

Intro: Shaders

Vertex shader: glsl code for active transform

uniform mat4 transform;
attribute vec4 vertex;
attribute vec4 color;
varying vec4 vertColor;

void main() {
   gl_Position = transform * vertex;
   vertColor = color;
}
transform = projection

Intro: Shaders

Vertex shader: glsl code for passive transform

uniform mat4 transform;
attribute vec4 vertex;
attribute vec4 color;
varying vec4 vertColor;

void main() {
   gl_Position = transform * vertex;
   vertColor = color;
}
transform = projection * modelview transform = projection * view * model

(goto matrix composition and then to eye transform)

Intro: Shaders

Fragment shader: pseudo code

for (int i = 0; i < fragmentCount; i++) {
  screenBuffer[fragment[i].xy] = fragmentShader(fragment[i]);
}

function fragmentShader(fragment) {
  return fragment.litColor;
}

Intro: Shaders

Fragment shader: glsl code

varying vec4 vertColor;

void main() {
  gl_FragColor = vertColor;
}

Intro: Shaders

GLSL variable types

uniform: variables that remain constant for each vertex in the scene. Example: uniform mat4 transform

attribute: variables that change from vertex to vertex. Examples: attribute vec4 vertex, attribute vec4 color

varying: variables that are exchanged between the vertex and the fragment shaders. Example: varying vec4 vertColor

Intro: Shaders

Common GLSL uniform variables emitted by P5

Name Alias Type transform transformMatrix mat4 modelview modelviewMatrix mat4 projection projectionMatrix mat4 texture texMap sampler2D

Intro: Shaders

Common GLSL attribute variables emitted by P5

Name Type position (or, vertex) vec4 color vec4 normal vec3

Intro: Shaders

Processing shader API: PShader

Class that encapsulates a GLSL shader program, including a vertex and a fragment shader

Intro: Shaders

Processing shader API: loadShader()

Loads a shader into the PShader object

Method signatures

  loadShader(fragFilename)
  loadShader(fragFilename, vertFilename)

Example

  PShader unalShader;
  void setup() {
    ...
    //when no path is specified it looks in the sketch 'data' folder
    unalShader = loadShader("unal_frag.glsl", "unal_vert.glsl");
  }

Intro: Shaders

Processing shader API: shader()

Applies the specified shader

Method signature

  shader(shader)

Example

  PShader simpleShader, unalShader;
  void draw() {
    ...
    shader(simpleShader);
    simpleGeometry();
    shader(unalShader);
    unalGeometry();
  }

Intro: Shaders

Processing shader API: resetShader()

Restores the default shaders

Method signatures

  resetShader()

Example

    PShader simpleShader;
  void draw() {
    ...
    shader(simpleShader);
    simpleGeometry();
    resetshader();
    otherGeometry();
  }

Intro: Shaders

Processing shader API: PShader.set()

Sets the uniform variables inside the shader to modify the effect while the program is running

Method signatures for vector uniform variables vec2, vec3 or vec4:

  .set(name, x)
  .set(name, x, y)
  .set(name, x, y, z)
  .set(name, x, y, z, w)
  .set(name, vec)
  • name: of the uniform variable to modify
  • x, y, z and w: 1st, snd, 3rd and 4rd vec float components resp.
  • vec: PVector

Intro: Shaders

Processing shader API: PShader.set()

Sets the uniform variables inside the shader to modify the effect while the program is running

Method signatures for vector uniform variables boolean[], float[], int[]:

  .set(name, x)
  .set(name, x, y)
  .set(name, x, y, z)
  .set(name, x, y, z, w)
  .set(name, vec)
  • name: of the uniform variable to modify
  • x, y, z and w: 1st, snd, 3rd and 4rd vec (boolean, float or int) components resp.
  • vec: boolean[], float[], int[]

Intro: Shaders

Processing shader API: PShader.set()

Sets the uniform variables inside the shader to modify the effect while the program is running

Method signatures for mat3 and mat4 uniform variables:

  .set(name, mat) // mat is PMatrix2D, or PMatrix3D
  • name of the uniform variable to modify
  • mat PMatrix3D, or PMatrix2D

Intro: Shaders

Processing shader API: PShader.set()

Sets the uniform variables inside the shader to modify the effect while the program is running

Method signatures for vector uniform variables:

  .set(name, tex) // tex is a PImage

Intro: Shaders

Processing shader API: PShader.set()

Sets the uniform variables inside the shader to modify the effect while the program is running

Example:

  PShader unalShader;
  PMatrix3D projectionModelView1, projectionModelView2;
  void draw() {
    ...
    shader(unalShader);
    unalShader.set("unalMatrix", projectionModelView1);
    unalGeometry1();
    unalShader.set("unalMatrix", projectionModelView2);
    unalGeometry2();
  }

Linear transformations: Notion

Property 1 $$F(a+b)= F(a)+ F(b)$$

Property 2 $$F(\lambda a) = \lambda F(a)\rightarrow F(0) = 0$$

Observation 1: Matrix multiplication is always linear

Observation 2: Translation is a nonlinear transformation

Linear transformations: 2d scaling

$x'= sx*x$

$y'= sy*y$

$\begin{bmatrix} x' \cr y' \cr \end{bmatrix} = \begin{bmatrix} sx & 0 \cr 0 & sy \cr \end{bmatrix} \bullet \begin{bmatrix} x \cr y \cr \end{bmatrix} $

$P'= S(sx,sy) \bullet P$

  • mirroring and reflections are missed

Linear transformations: 3d scaling

$x'= sx*x$

$y'= sy*y$

$z'= sz*z$

$\begin{bmatrix} x' \cr y' \cr z' \cr \end{bmatrix} = \begin{bmatrix} sx & 0 & 0 \cr 0 & sy & 0 \cr 0 & 0 & sz \cr \end{bmatrix} \bullet \begin{bmatrix} x \cr y \cr z \cr \end{bmatrix} $

$P'= S(sx,sy,sz) \bullet P$

  • mirroring and reflections are missed

Linear transformations: 2d rotation

$x = rcos \alpha$

$y= rsin \alpha$

$x'= rcos (\alpha+\beta)$ $x'= rcos \alpha cos \beta - rsin \alpha sin \beta$

$y'= rsin (\alpha+\beta)$ $y'= rcos \alpha sin \beta - rsin \alpha cos \beta$

Linear transformations: 2d Rotation

$\begin{bmatrix} x' \cr y' \cr \end{bmatrix} = \begin{bmatrix} cos\beta & -sin \beta \cr sin\beta & cos \beta \cr \end{bmatrix} \bullet \begin{bmatrix} x \cr y \cr \end{bmatrix} $

$P'= R(\beta) \bullet P$

Linear transformations: 3d rotation

Euler angles (respect to z-axis)

$z' = z$

$\begin{bmatrix} x' \cr y' \cr z' \cr \end{bmatrix} = \begin{bmatrix} cos\beta & -sin \beta & 0 \cr sin\beta & cos \beta & 0 \cr 0 & 0 & 1 \cr \end{bmatrix} \bullet \begin{bmatrix} x \cr y \cr z \cr \end{bmatrix} $

$P'= R_z(\beta) \bullet P$

Linear transformations: 3d rotation

Euler angles (respect to x-axis)

$x' = x$

$\begin{bmatrix} x' \cr y' \cr z' \cr \end{bmatrix} = \begin{bmatrix} 1 & 0 & 0 \cr 0 & cos\beta & -sin \beta \cr 0 & sin\beta & cos \beta \cr \end{bmatrix} \bullet \begin{bmatrix} x \cr y \cr z \cr \end{bmatrix} $

$P'= R_x(\beta) \bullet P$

Linear transformations: 3d rotation

Euler angles (respect to y-axis)

$y' = y$

$\begin{bmatrix} x' \cr y' \cr z' \cr \end{bmatrix} = \begin{bmatrix} cos\beta & 0 & sin \beta \cr 0 & 1 & 0 \cr -sin\beta & 0 & cos \beta \cr \end{bmatrix} \bullet \begin{bmatrix} x \cr y \cr z \cr \end{bmatrix} $

$P'= R_y(\beta) \bullet P$

Linear transformations: 2d shearing

$x'= x + h*y$

$y'=y$

$\begin{bmatrix} x' \cr y' \cr \end{bmatrix} = \begin{bmatrix} 1 & h \cr 0 & 1 \cr \end{bmatrix} \bullet \begin{bmatrix} x \cr y \cr \end{bmatrix} $

$P'= D_y(h) \bullet P$

Linear transformations: 2d shearing

$x'= x$

$y'=y + h*x$

$\begin{bmatrix} x' \cr y' \cr \end{bmatrix} = \begin{bmatrix} 1 & 0 \cr h & 1 \cr \end{bmatrix} \bullet \begin{bmatrix} x \cr y \cr \end{bmatrix} $

$P'= D_x(h) \bullet P$

Linear transformations: 3d shearing

$x'=x+az$

$y'=y+bz$

$z'=z$

$\begin{bmatrix} x' \cr y' \cr z' \cr \end{bmatrix} = \begin{bmatrix} 1 & 0 & a \cr 0 & 1 & b \cr 0 & 0 & 1 \cr \end{bmatrix} \bullet \begin{bmatrix} x \cr y \cr z \cr \end{bmatrix} $

$P'= D_z(a,b) \bullet P$ (goto 2d translation)

Linear transformations: 3d shearing

...don't forget $P'= D_x(a,b) \bullet P$ and $P'= D_y(a,b) \bullet P$

Affine transformations

Non-linearity of translation

$x'= x + dx$

$y'=y + dy$

$\begin{bmatrix} x' \cr y' \cr \end{bmatrix} = \begin{bmatrix} dx \cr dy \cr \end{bmatrix} + \begin{bmatrix} x \cr y \cr \end{bmatrix} $

$P'= T(dx,dy) + P$

Affine transformations: Notion

Linear transformations $+$ Translation $\rightarrow P' = M\ast P + T $

Affine transformations: Homogeneous space $\rightarrow$ 2d

Homogeneous w-coordinate: $(x,y,w)$

Homogeneous space $\rightarrow$ 2d

$(x,y,1) \rightarrow (x,y)$, for $w=1$

In general: $(x,y,w) \rightarrow (x/w,y/w)$

Affine transformations: Homogeneous space $\rightarrow$ 3d

$(x,y,z,1) \rightarrow (x,y,z)$, for $w=1$

In general: $(x,y,z,w) \rightarrow (x/w,y/w,z/w)$

Affine transformations: Translation

$x'= x + dx$

$y'=y + dy$

$w'=w=1$

$\begin{bmatrix} x' \cr y' \cr w' \cr \end{bmatrix} = \begin{bmatrix} 1 & 0 & dx \cr 0 & 1 & dy \cr 0 & 0 & 1 \cr \end{bmatrix} \bullet \begin{bmatrix} x \cr y \cr w \cr \end{bmatrix} $

$P'= T(dx,dy) \bullet P$ (goto 3d shearing)

Affine transformations: Translation

$x'= x + dx$

$y'=y + dy$

$z'=z + dz$

$w'=w=1$

$\begin{bmatrix} x' \cr y' \cr z' \cr w' \cr \end{bmatrix} = \begin{bmatrix} 1 & 0 & 0 & dx \cr 0 & 1 & 0 & dy \cr 0 & 0 & 1 & dz \cr 0 & 0 & 0 & 1 \cr \end{bmatrix} \bullet \begin{bmatrix} x \cr y \cr z \cr w \cr \end{bmatrix} $

$P'= T(dx,dy,dz) \bullet P$

Affine transformations: Shearing (r)

$x'=x+az$

$y'=y+bz$

$z'=z$

$w'=w=1$

$\begin{bmatrix} x' \cr y' \cr z' \cr w' \cr \end{bmatrix} = \begin{bmatrix} 1 & 0 & a & 0 \cr 0 & 1 & b & 0 \cr 0 & 0 & 1 & 0 \cr 0 & 0 & 0 & 1 \cr \end{bmatrix} \bullet \begin{bmatrix} x \cr y \cr z \cr w \cr \end{bmatrix} $

$P'= D_z(a,b) \bullet P$

Affine transformations: Scaling (r)

$x'= sx*x$

$y'= sy*y$

$z'= sz*z$

$w'=w=1$

$\begin{bmatrix} x' \cr y' \cr z' \cr w' \cr \end{bmatrix} = \begin{bmatrix} sx & 0 & 0 & 0 \cr 0 & sy & 0 & 0 \cr 0 & 0 & sz & 0 \cr 0 & 0 & 0 & 1 \cr \end{bmatrix} \bullet \begin{bmatrix} x \cr y \cr z \cr w \cr \end{bmatrix} $

$P'= S(sx,sy,sz) \bullet P$

Affine transformations: 3d rotation (r)

Euler angles (respect to z-axis)

$z' = z$

$w'=w=1$

$\begin{bmatrix} x' \cr y' \cr z' \cr w' \cr \end{bmatrix} = \begin{bmatrix} cos\beta & -sin \beta & 0 & 0 \cr sin\beta & cos \beta & 0 & 0 \cr 0 & 0 & 1 & 0 \cr 0 & 0 & 0 & 1 \cr \end{bmatrix} \bullet \begin{bmatrix} x \cr y \cr z \cr w \cr \end{bmatrix} $

$P'= R_z(\beta) \bullet P$

Affine transformations: 3d rotation (r)

Euler angles (respect to x-axis)

$x' = x$

$w'=w=1$

$\begin{bmatrix} x' \cr y' \cr z' \cr w' \cr \end{bmatrix} = \begin{bmatrix} 1 & 0 & 0 & 0 \cr 0 & cos\beta & -sin \beta & 0 \cr 0 & sin\beta & cos \beta & 0 \cr 0 & 0 & 0 & 1 \cr \end{bmatrix} \bullet \begin{bmatrix} x \cr y \cr z \cr w \cr \end{bmatrix} $

$P'= R_x(\beta) \bullet P$

Affine transformations: 3d rotation (r)

Euler angles (respect to y-axis)

$y' = y$

$w'=w=1$

$\begin{bmatrix} x' \cr y' \cr z' \cr w' \cr \end{bmatrix} = \begin{bmatrix} cos\beta & 0 & sin \beta & 0 \cr 0 & 1 & 0 & 0 \cr -sin\beta & 0 & cos \beta & 0 \cr 0 & 0 & 0 & 1 \cr \end{bmatrix} \bullet \begin{bmatrix} x \cr y \cr z \cr w \cr \end{bmatrix} $

$P'= R_y(\beta) \bullet P$

Affine transformations: Matrix operations

Orthogonality

A matrix $$M = \begin{bmatrix} m_{11} & m_{12} & m_{13} \cr m_{21} & m_{22} & m_{33} \cr m_{31} & m_{32} & m_{33} \cr \end{bmatrix}$$

is orthogonal iff:

$$MM^{T} = I$$

This is equivalent to:

$$M^{-1} = M^{T}$$

Orthogonal matrix

Orthogonality: Geometric Interpretation

Let

$$r_{1} = \begin{bmatrix} m_{11} & m_{12} & m_{13} \end{bmatrix}$$ $$r_{2} = \begin{bmatrix} m_{21} & m_{22} & m_{23} \end{bmatrix}$$ $$r_{3} = \begin{bmatrix} m_{31} & m_{32} & m_{33} \end{bmatrix}$$

then

$$r_{1} \cdot r_{1} = r_{2} \cdot r_{2} = r_{3} \cdot r_{3} = 1 $$ $$r_{i} \cdot r_{j} = 0\ \ i=1,2,3 \ \ j=1,2,3 \ \ i\ne j$$

Orthogonal matrix

Orthogonality: Geometric Interpretation

We can conclude that:

  • Each row of the matrix must be a unit vector
  • The rows of the matrix must be mutually perpendicular
  • Vectors $r_{1}, \,r_{2}, \,r_{3}$ are orthonormals

Note 1: that $r_1$, $r_2$ and $r_3$ form a non-canonical basis

Note 2: that a rotation matrix is always orthogonal

  • Orthogonality is used in both: euler angles (composition) and rodrigues formula

Affine transformations: Matrix operations

Inversion

Let $M$ be an affine transformation matrix such that:

$$P'=MP$$

Let $M^{-1}$ be the inverse of $M$. Observe that:

$$M^{-1}P'=M^{-1}MP=(M^{-1}M)P=IP=P$$

Affine transformations: Matrix operations

Affine inverse matrices

Transformation Direct Inverted Translation $T(dx,dy,dz)$ $T(-dx,-dy,-dz)$ Shearing $D_z(a,b)$ $D_z(-a,-b)$ Scaling $S(sx,sy,sz)$ $S(1/sx,1/sy,1/sz)$ Rotation $R_z(\beta)$ $R_z(-\beta) (=R_z(\beta)^{T})$

Affine transformations: Matrix operations

Composition

Consider the following sequence of transformations:

$P_1=M_1P,$ $P_2=M_2P_1,$ $...,$ $P_n=M_nP_{n-1}$

which is the same as: $P_n=M_n^*P$, where $M_n^*=M_n...M_2M_1$

goto vertex shader

Mnemonic 1: The (right-to-left) $M_1M_2...M_n$ transformation sequence is performed respect to a world (fixed) coordinate system

Mnemonic 2: The (left-to-right) $M_n,...M_2M_1$ transformation sequence is performed respect to a local (mutable) coordinate system

Affine transformations: Matrix operations

Mnemonic 1 examples: Scaling respect to $(x_f,y_f)$

Affine transformations: Matrix operations

Mnemonic 1 examples: Scaling respect to $(x_f,y_f)$

$T(x_f,y_f)S(sx,sy)T(-x_f,-y_f)P$

Affine transformations: Matrix operations

Mnemonic 1 examples: Scaling respect to $(x_r,y_r)$

$T(x_f,y_f)S(sx,sy)T(-x_f,-y_f)$ Processing implementation

Affine transformations: Matrix operations

Mnemonic 1 examples: Rotation respect to $(x_r,y_r)$, $\beta$

Affine transformations: Matrix operations

Mnemonic 1 examples: Rotation respect to $(x_r,y_r)$, $\beta$

$T(x_r,y_r)R_z(\beta)T(-x_r,-y_r)P$

Affine transformations: Matrix operations

Mnemonic 1 examples: Rotation respect to $(x_r,y_r)$, $\beta$

$T(x_r,y_r)R_z(\beta)T(-x_r,-y_r)$ Processing implementation

Affine transformations: Matrix operations

Mnemonic 1 examples: Rotation respect to $(x_r,y_r)$, $\beta$

$T(x_r,y_r)R_z(\beta)T(-x_r,-y_r)$ Processing implementation: default shader (applyMatrix())

float xr=500, yr=250;
float beta = -QUARTER_PI;

void draw() {
  background(0);
  // We do the rotation as: T(xr,yr)Rz(β)T(−xr,−yr)
  // 1. T(xr,yr)
  applyMatrix(1, 0, 0, xr, 
              0, 1, 0, yr, 
              0, 0, 1, 0, 
              0, 0, 0, 1);
  // 2. Rz(β)
  applyMatrix(cos(beta), -sin(beta), 0, 0, 
              sin(beta), cos(beta),  0, 0, 
              0,         0,          1, 0, 
              0,         0,          0, 1);
  // 3. T(−xr,−yr)
  applyMatrix(1, 0, 0, -xr, 
              0, 1, 0, -yr, 
              0, 0, 1, 0, 
              0, 0, 0, 1);
  // drawing code follows
}

Affine transformations: Matrix operations

Mnemonic 1 examples: Rotation respect to $(x_r,y_r)$, $\beta$

$T(x_r,y_r)R_z(\beta)T(-x_r,-y_r)$ Processing implementation: default shader (translation() and rotation())

float xr=500, yr=250;
float beta = -QUARTER_PI;

void draw() {
  background(0);
  // 1. T(xr,yr)
  translate(xr, yr);
  // 2. Rz(β)
  rotate(beta);
  // 3. T(−xr,−yr)
  translate(-xr, -yr);
  // drawing code follows
}

Hence translate(), rotate(), applies the transformation to the current modelview

Affine transformations: Matrix operations

Mnemonic 1 examples: Rotation respect to $(x_r,y_r)$, $\beta$

$T(x_r,y_r)R_z(\beta)T(-x_r,-y_r)$ Processing implementation: simple shader

PShader simpleShader;

void setup() {
  size(700, 700, P3D);
  // simple custom shader
  simpleShader = loadShader("simple_frag.glsl", "simple_vert.glsl");
  shader(simpleShader);
}

Affine transformations: Matrix operations

Mnemonic 1 examples: Rotation respect to $(x_r,y_r)$, $\beta$

$T(x_r,y_r)R_z(\beta)T(-x_r,-y_r)$ Processing implementation: simple shader

simple_vert.glsl:

uniform mat4 transform;
attribute vec4 vertex;
attribute vec4 color;
varying vec4 vertColor;

void main() {
  gl_Position = transform * vertex;
  vertColor = color;
}

Since here we use the default uniforms (transform) and attributes (vertex, color) the rest of the sketch remains the same

Affine transformations: Matrix operations

Mnemonic 1 examples: Rotation respect to $(x_r,y_r)$, $\beta$

$T(x_r,y_r)R_z(\beta)T(-x_r,-y_r)$ Processing implementation: unal shader

PShader unalShader;
PMatrix3D modelview;

void setup() {
  size(700, 700, P3D);
  // unal custom shader
  unalShader = loadShader("unal_frag.glsl", "unal_vert.glsl");
  shader(unalShader);
  modelview = new PMatrix3D();
}

Affine transformations: Matrix operations

Mnemonic 1 examples: Rotation respect to $(x_r,y_r)$, $\beta$

$T(x_r,y_r)R_z(\beta)T(-x_r,-y_r)$ Processing implementation: unal shader

void draw() {
  background(0);
  //load identity
  modelview.reset();
  // 1. T(xr,yr)
  modelview.translate(xr, yr);
  // 2. Rz(β)
  modelview.rotate(beta);
  // 1. T(-xr,-yr)
  modelview.translate(-xr, -yr);
  emitUniforms();
  // drawing code follows
}
void emitUniforms() {
  //hack to retrieve the Processing projection matrix
  PMatrix3D projectionTimesModelview = new PMatrix3D(((PGraphics2D)g).projection);
  projectionTimesModelview.apply(modelview);
  //GLSL uses column major order, whereas processing uses row major order
  projectionTimesModelview.transpose();
  unalShader.set("unalMatrix", projectionTimesModelview);
}

Affine transformations: Matrix operations

Mnemonic 1 examples: Rotation respect to $(x_r,y_r)$, $\beta$

$T(x_r,y_r)R_z(\beta)T(-x_r,-y_r)$ Processing implementation: unal shader

unal_vert.glsl:

uniform mat4 unalMatrix;
attribute vec4 vertex;
attribute vec4 color;
varying vec4 unalVertColor;

void main() {
  gl_Position = unalMatrix * vertex;
  unalVertColor = color;
}

Note the use of the custom uniform unalMatrix instead of the default transform

The Shader Programming for Computational Arts and Design paper discusses API simplicity and flexibility in shader programming

Affine transformations: Matrix operations

Mnemonic 1 examples: 3D Rotation respect to $u$, $\beta$

let $v = p_2 - p_1$

$u = v / |v| = (a, b, c)$

$a = (x_2 - x_1) / |v|$

$b = (y_2 - y_1) / |v|$

$c = (z_2 - z_1) / |v|$

Affine transformations: Matrix operations

Mnemonic 1 examples: 3D Rotation respect to $u$, $\beta$

$T(x_1,y_1,z_1) * R_x(-\alpha) * R_y(-\lambda) * R_z(\beta) * R_y(\lambda) * R_x(\alpha) * T(-x_1,-y_1,-z_1)$

Affine transformations: Matrix operations

Mnemonic 1 examples: 3D Rotation respect to $u$, $\beta$

Step 2

$u = (a, b, c)$

$u'= (0,b,c)$

$\cos \alpha = (u' \bullet u_z) / ( |u'| |u_z| )$, note that $|u_z| = 1$

$\cos \alpha = c/d$, where $d = |u'| = \sqrt{(b^2 + c^2)}$

since $\cos ^ 2 \alpha + \sin ^ 2 \alpha = 1$

$\sin \alpha = b/d$

Affine transformations: Matrix operations

Mnemonic 1 examples: 3D Rotation respect to $u$, $\beta$

Step 3

$u = (a, b, c)$

$u'= (0,b,c)$

$u''=(a,0,d)$, $d = sqrt{(b^2+c^2)}$

$\cos \lambda = (u'' \bullet u_z) / ( |u''| |u_z| )$

since $|u''|=|u_z|=1$

$\cos \lambda = d$

since $\cos ^ 2 \lambda + \sin ^ 2 \lambda = 1$ and $|u| = 1$

$\sin \lambda = a$, note that the actual angle we need is $-\lambda$

$\sin -\lambda = -a$ (unlike $\cos$, $\sin$ is an odd function)

Affine transformations: Matrix operations

Mnemonic 1 examples: 3D Rotation respect to $u$, $\beta$

Using orthogonality to compute $R_y(\lambda) * R_x(\alpha)$

Suppose $u$ is part of a non-canonical basis $x', y', z'$

Affine transformations: Matrix operations

Mnemonic 1 examples: 3D Rotation respect to $u$, $\beta$

Using orthogonality to compute $R_y(\lambda) * R_x(\alpha)$

$ R_y(\lambda) * R_x(\alpha) = \begin{bmatrix} u_{x'1} & u_{x'2} & u_{x'3} & 0 \cr u_{y'1} & u_{y'2} & u_{y'3} & 0 \cr u_{z'1} & u_{z'2} & u_{z'3} & 0 \cr 0 & 0 & 0 & 1 \cr \end{bmatrix} $

where

$u_{z'}=u$

$u_{x'}$ is any orthogonal vector to $u_{z'}$

$u_{y'} = u \times u_{x'}$

missing:

Affine transformations: Rotation: use orthogonality to compute R_y(\lambda) * R_x(\alpha) Affine transformations: Rotation: Quaternions magic Affine transformations: Rotation: Rodrigues' rotation formula

Modelling and view: Frame notion

Mnemonic 2: The (left-to-right) $M_n,...M_2M_1$ transformation sequence is performed respect to a local (mutable) coordinate system

Local coordinate systems are commonly referred to as "frames"

Modelling and view: Frame notion

Consider the function axes() which draws the X (horizontal) and Y vertical) axes:

void axes() {
  pushStyle();
  // X-Axis
  strokeWeight(4);
  stroke(255, 0, 0);
  fill(255, 0, 0);
  line(0, 0, 100, 0);//horizontal red X-axis line
  text("X", 100 + 5, 0);
  // Y-Axis
  stroke(0, 0, 255);
  fill(0, 0, 255);
  line(0, 0, 0, 100);//vertical blue Y-axis line
  text("Y", 0, 100 + 15);
  popStyle();
}

Modelling and view: Frame notion

let's first call the axes() function to see what it does:

void draw() {
  background(50);
  axes();
}

Modelling and view: Frame notion

now let's call it again, but pre-translating it first:

void draw() {
  background(50);
  axes();
  translate(300, 180);//translation
  axes();//2nd call
}

Modelling and view: Frame notion

let's add a rotation to the second axes() call:

void draw() {
  background(50);
  axes();
  translate(300, 180);
  rotate(QUARTER_PI / 2);//rotation after translation
  axes();//2nd call
}

Modelling and view: Frame notion

let's do something similar with a third axes() call:

void draw() {
  background(50);
  axes();
  translate(300, 180);
  rotate(QUARTER_PI/2);
  axes();
  translate(260, -180);
  rotate(-QUARTER_PI);
  scale(1.5);//even scaling it
  axes();//3rd call
}

Modelling and view: Frame notion

see the result when we animate only the first rotation;

void draw() {
  background(50);
  axes();
  translate(300, 180);
  rotate(QUARTER_PI/2 * p.frameCount);//animation line
  axes();
  translate(260, -180);
  rotate(-QUARTER_PI);
  scale(1.5);
  axes();
}

Modelling and view: Frame notion

and now see the result when we animate only the second rotation;

void draw() {
  background(50);
  axes();
  translate(300, 180);
  rotate(QUARTER_PI/2);
  axes();
  translate(260, -180);
  rotate(-QUARTER_PI * p.frameCount);//animation line
  scale(1.5);
  axes();
}

Modelling and view: Frame notion

A frame is defined by an affine (composed) transform: $M_i^*, 1 \leq i \leq 3$ read in left-to-right order (goto mnemonic 2)

Modelling and view: Scene-graph

A scene-graph is a directed acyclic graph (DAG) of frames which root is the world coordinate system

Modelling and view: Scene-graph

Eyeless example

 World
  ^
  |
 L1
  ^
  |\
 L2  L3
void drawModel() {
  // define a local frame L1 (respect to the world)
  pushMatrix();
  affineTransform1();
  drawL1();
  // define a local frame L2 respect to L1
  pushMatrix();
  affineTransform2();
  drawL2();
  // "return" to L1
  popMatrix();
  // define a local coordinate system L3 respect to L1
  pushMatrix();
  affineTransform3();
  drawL3();
  // return to L1
  popMatrix();
  // return to World
  popMatrix();
}

Modelling and view: Scene-graph

Eyeless example

Modelling and view: Scene-graph

View transform (eye-frame)

 World
  ^
  |\
... Eye
  ^
  |\
... ...

Let the eye frame transform be defined, like it is with any other frame, as: $M_{eye}^*$

The eye transform is therefore: $\left.M_{eye}^{*}\right.^{-1}$ (goto vertex shader)

For example, for an eye frame transform: $M_{eye}^*=T(x,y,z)R(\beta)S(s)$

The eye transform would be: $\left.M_{eye}^{*}\right.^{-1}=S(1/s)R(-\beta)T(-x,-y,-z)$

$M_{eye}^*$ would position (orient, scale, ...) the eye frame in the world, but want it to be the other way around (i.e., draw the scene from the eye point-of-view)

Modelling and view: Scene-graph

View example

 World
  ^
  |\
 L1 Eye
  ^
  |\
 L2  L3
void draw() {
  // the following sequence would position (orient, scale, ...) the eye frame in the world:
  // translate(eyePosition.x, eyePosition.y);
  // rotate(eyeOrientation);
  // scale(eyeScaling)
  // drawEye();
  scale(1/eyeScaling);
  rotate(-eyeOrientation);
  translate(-eyePosition.x, -eyePosition.y);
  drawModel();
}

Modelling and view: Scene-graph

View example

Projections: Orthographic

View volume: Eye and Clip spaces

Orthographic Volume and Normalized Device Coordinates (NDC)

Let $P_e$ be a point in eye space and $P_c$ a point in clip space, we seek:

$$P_e = [x_e,y_e,z_e]\xrightarrow{\text{map}}P_c = [x_c,y_c,z_c]$$

$$x_e \in [l,r] \rightarrow x_c \in [-1,1], y_e \in [b,t] \rightarrow y_c \in [-1,1], z_e \in [n,f] \rightarrow z_c \in [-1,1]$$

Projections: Orthographic

View volume: Re-mapping a variable among ranges (general case)

            |---------------*---------|          ->           |-------------------*--------------|
           min              u        max                     min'                 u'            max'

The linear conversion is given by:

$$u' = min'+(u-min)(\Delta u')/(\Delta u)$$

where $\Delta u=max-min$, and $\Delta u'=max'-min'$

which may be re-written as:

$$u' = uS_u + T_u$$ $$S_u=\Delta u'/\Delta u$$ $$T_u=(min'\Delta u - min\Delta u')/\Delta u$$

Projections: Orthographic

View volume: Re-mapping a variable among ranges (our case)

            |---------------*---------|          ->           |-------------------*--------------|
           min              u        max                     -1                   u'             1

$$u' = uS_u + T_u$$ $$S_u=2/(max-min)$$ $$T_u=-(max+min)/(max-min)$$

Projections: Orthographic

Matrix form: formulation

$$u' = uS_u + T_u$$

$$[x_e,y_e,z_e]\xrightarrow{\text{map}}[x_c,y_c,z_c]$$ $$x_e \in [l,r] \rightarrow x_c \in [-1,1], y_e \in [b,t] \rightarrow y_c \in [-1,1], z_e \in [n,f] \rightarrow z_c \in [-1,1]$$

$\begin{bmatrix} x_c \cr y_c \cr z_c \cr w_c \cr \end{bmatrix} = \begin{bmatrix} S_{x_e} & 0 & 0 & T_{x_e} \cr 0 & S_{y_e} & 0 & T_{y_e} \cr 0 & 0 & S_{z_e} & T_{z_e} \cr 0 & 0 & 0 & 1 \cr \end{bmatrix} \bullet \begin{bmatrix} x_e \cr y_e \cr z_e \cr w_e(=1) \cr \end{bmatrix} $

$P_c = Ortho(S_{x_e/y_e/z_e},T_{x_e/y_e/z_e}) \bullet P_e$

Projections: Orthographic

Matrix form: solution

$$u' = uS_u + T_u$$ $$S_u=2/(max-min)$$ $$T_u=-(max+min)/(max-min)$$

$$[x_e,y_e,z_e]\xrightarrow{\text{map}}[x_c,y_c,z_c]$$ $$x_e \in [l,r] \rightarrow x_c \in [-1,1], y_e \in [b,t] \rightarrow y_c \in [-1,1], z_e \in [n,f] \rightarrow z_c \in [-1,1]$$

$\begin{bmatrix} x_c \cr y_c \cr z_c \cr w_c \cr \end{bmatrix} = \begin{bmatrix} 2 \above 1pt (r-l) & 0 & 0 & -(r+l) \above 1pt (r-l) \cr 0 & 2 \above 1pt (t-b) & 0 & -(t+b) \above 1pt (t-b) \cr 0 & 0 & -2 \above 1pt (f-n) & -(f+n) \above 1pt (f-n) \cr 0 & 0 & 0 & 1 \cr \end{bmatrix} \bullet \begin{bmatrix} x_e \cr y_e \cr z_e \cr w_e(=1) \cr \end{bmatrix} $

$P_c = Ortho(l,r,b,t,n,f) \bullet P_e$

Projections: Orthographic

Matrix form: Symmetrical viewing volume ($l=-r$ and $b=-t$)

$$u' = uS_u + T_u$$ $$S_u=2/(max-min)$$ $$T_u=-(max+min)/(max-min)$$

$$[x_e,y_e,z_e]\xrightarrow{\text{map}}[x_c,y_c,z_c]$$ $$x_e \in [-r,r] \rightarrow x_c \in [-1,1], y_e \in [-t,t] \rightarrow y_c \in [-1,1], z_e \in [n,f] \rightarrow z_c \in [-1,1]$$

$\begin{bmatrix} x_c \cr y_c \cr z_c \cr w_c \cr \end{bmatrix} = \begin{bmatrix} 1 \above 1pt r & 0 & 0 & 0 \cr 0 & 1 \above 1pt t & 0 & 0 \cr 0 & 0 & -2 \above 1pt (f-n) & -(f+n) \above 1pt (f-n) \cr 0 & 0 & 0 & 1 \cr \end{bmatrix} \bullet \begin{bmatrix} x_e \cr y_e \cr z_e \cr w_e(=1) \cr \end{bmatrix} $

$P_c= Ortho(r,t,n,f) \bullet P_e$

Projections: Perspective

View volume

Perspective Frustum and Normalized Device Coordinates (NDC)

Let $P_e$ be a point in eye space and $P_n$ a point in NDC, we seek:

$$P_e = [x_e,y_e,z_e,w_e(=1)]\xrightarrow{\text{map}}P_c = [x_c,y_c,z_c,w_c(\neq 1)]$$

$$P_c = [x_c,y_c,z_c,w_c(\neq 1)]\xrightarrow[\text{divide}]{\text{perspective}}P_n = [x_n(=x_c/w_c),y_n(=y_c/w_c),z_n(=z_c/w_c),1]$$

Projections: Perspective

Near plane projection of $x_e,y_e \xrightarrow {\text{onto}} x_p,y_p$

Top view of frustum

$${x_p\above 1pt x_e}= {-n\above 1pt z_e}$$ $$x_p= {nx_e\above 1pt -z_e}$$

Projections: Perspective

Near plane projection of $x_e,y_e \xrightarrow {\text{onto}} x_p,y_p$

Side view of frustum

$${y_p\above 1pt y_e}= {-n\above 1pt z_e}$$ $$y_p= {ny_e\above 1pt -z_e}$$

Projections: Perspective

Near plane projection of $x_e,y_e \xrightarrow {\text{onto}} x_p,y_p$

$$x_p= {nx_e\above 1pt -z_e},y_p= {ny_e\above 1pt -z_e}$$

which means ${\color{red} {w_c}}=-z_e$

$$\begin{bmatrix} x_c \cr y_c \cr z_c \cr w_c \cr \end{bmatrix} = \begin{bmatrix} . & . & . & . \cr . & . & . & . \cr . & . & . & . \cr 0 & 0 & {\color{red} {-1}} & 0 \cr \end{bmatrix} \bullet \begin{bmatrix} x_e \cr y_e \cr z_e \cr w_e(=1) \cr \end{bmatrix} $$

Projections: Perspective

$x_e$,$y_e$ coordinate mapping (using our ortho matrix)

$${\color{green} {x_p}}= {nx_e\above 1pt -z_e},{\color{green} {y_p}}= {ny_e\above 1pt -z_e},w_c=-z_e$$

$$\begin{bmatrix} {\color{blue} {x_n}} \cr {\color{blue} {y_n}} \cr z_c \cr w_c \cr \end{bmatrix} = \begin{bmatrix} 2 \above 1pt (r-l) & 0 & 0 & -(r+l) \above 1pt (r-l) \cr 0 & 2 \above 1pt (t-b) & 0 & -(t+b) \above 1pt (t-b) \cr . & . & . & . \cr . & . & . & . \cr \end{bmatrix} \bullet \begin{bmatrix} {\color{green} {x_p}} \cr {\color{green} {y_p}} \cr z_e \cr w_e(=1) \cr \end{bmatrix} $$

solving for ${\color{blue} {x_n,y_n}}$ we get: ${\color{blue} {x_n}}= {2{\color{green} {x_p}}\above 1pt r-l}-{r+l\above 1pt r-l},{\color{blue} {y_n}} = {2{\color{green} {y_p}}\above 1pt t-b}-{t+b\above 1pt t-b}$

since ${\color{blue} {x_n}}={x_c\above 1pt w_c}$ and ${\color{blue} {y_n}}={y_c\above 1pt w_c}$ , solving for ${\color{red} {x_c,y_c}}$ in terms of $x_e,y_e,z_e$ , we get: ${\color{red} {x_c}}= {2nx_e\above 1pt r-l}+{(r+l)z_e\above 1pt r-l},{\color{red} {y_c}}= {2ny_e\above 1pt t-b}+{(t+b)z_e\above 1pt t-b}$

Projections: Perspective

$x_e$,$y_e$ coordinate mapping

$${\color{red} {x_c}}= {2nx_e\above 1pt r-l}+{(r+l)z_e\above 1pt r-l},{\color{red} {y_c}}= {2ny_e\above 1pt t-b}+{(t+b)z_e\above 1pt t-b},w_c=-z_e$$

$\begin{bmatrix} x_c \cr y_c \cr z_c \cr w_c \cr \end{bmatrix} = \begin{bmatrix} 2n \above 1pt r-l & 0 & r+l \above 1pt r-l & 0 \cr 0 & 2n \above 1pt t-b & t+b \above 1pt t-b & 0 \cr . & . & . & . \cr 0 & 0 & -1 & 0 \cr \end{bmatrix} \bullet \begin{bmatrix} x_e \cr y_e \cr z_e \cr w_e(=1) \cr \end{bmatrix} $

Projections: Perspective

$z_e$ coordinate mapping

$\begin{bmatrix} x_c \cr y_c \cr z_c \cr w_c \cr \end{bmatrix} = \begin{bmatrix} 2n \above 1pt r-l & 0 & r+l \above 1pt r-l & 0 \cr 0 & 2n \above 1pt t-b & t+b \above 1pt t-b & 0 \cr 0 & 0 & {\color{green} A} & {\color{green} B} \cr 0 & 0 & -1 & 0 \cr \end{bmatrix} \bullet \begin{bmatrix} x_e \cr y_e \cr z_e \cr w_e(=1) \cr \end{bmatrix} $

$z_n=z_c/w_c={Az_e+Bw_e\above 1pt -z_e}={Az_e+B\above 1pt -z_e}$

To find $A$ and $B$, use the map relation $z_e \in [n,f] \rightarrow z_n \in [-1,1]$ and replace them above (twice)

Projections: Perspective

$z_e$ coordinate mapping

$\begin{bmatrix} x_c \cr y_c \cr z_c \cr w_c \cr \end{bmatrix} = \begin{bmatrix} 2n \above 1pt r-l & 0 & r+l \above 1pt r-l & 0 \cr 0 & 2n \above 1pt t-b & t+b \above 1pt t-b & 0 \cr 0 & 0 & -(f+n) \above 1pt f-n & -2fn \above 1pt f-n \cr 0 & 0 & -1 & 0 \cr \end{bmatrix} \bullet \begin{bmatrix} x_e \cr y_e \cr z_e \cr w_e(=1) \cr \end{bmatrix} $

$P_c = Persp(l,r,b,t,n,f) \bullet P_e$

Projections: Perspective

Alternative form: Symmetrical viewing volume ($l=-r$ and $b=-t$)

$$l=-r$$ $$b=-t$$ $$aspectRatio=screenWidth/screenHeight$$ $fovy:$ vertical field-of-view (in radians)

$\begin{bmatrix} x_c \cr y_c \cr z_c \cr w_c \cr \end{bmatrix} = \begin{bmatrix} 1 \above 1pt \tan (fovy/2)aspectRatio & 0 & 0 & 0 \cr 0 & \tan (fovy/2) & 0 & 0 \cr 0 & 0 & -(f+n) \above 1pt f-n & -2fn \above 1pt f-n \cr 0 & 0 & -1 & 0 \cr \end{bmatrix} \bullet \begin{bmatrix} x_e \cr y_e \cr z_e \cr w_e(=1) \cr \end{bmatrix} $

$P_c = Persp(fovy,aspectRatio,n,f) \bullet P_e$

References

Acknowledgements

Themes Set your presentation theme: Black (default) - White - League - Sky - Beige - Simple Serif - Blood - Night - Moon - Solarized