You are on page 1of 5

Introduction to Computer Graphics, Midterm Cheat Sheet

Lecture 2: Linear Transformation


ˆ Point p̃, non-numerical
ˆ Vector ⃗v , non-numerical

ˆ Coordinate system f⃗t , bold means column vector, t means transposed


basis for vector; frame for point, non-numerical object
ˆ Coordinate vector c, numerical object
ˆ Vector space
 
h i c1
ci⃗bi = ⃗b1 ⃗b2 ⃗b3 c2  = b⃗t c
X
⃗v =
i c3

ˆ Linear transformation is notated by arrow.


X X
⃗v ⇒ L(⃗v ) = L( ci⃗bi ) = ci L(⃗bi )
i i
   
h i c1 h i c1
⃗b1 ⃗b2 ⃗b3 c2  ⇒ L(⃗b1 ) L(⃗b2 ) L(⃗b3 ) c2 
c3 c3
  
h i M11 M12 M13 c1
= ⃗b1 ⃗b2 ⃗b3 M21 M22 M23  c2 
M31 M32 M33 c3
Therefore, a vector undergoes a linear transformation as:

⃗v = b⃗t c ⇒ b⃗t M c
Where the matrix M depends on the linear transformation.

Lecture 3: Affine Transformation


ˆ Linear transformation
    
l t i t l 0
A= =
0 1 0 1 0 1
= TL

ˆ Rigid body transformation A = T R, where R is a rotation matrix.


RBT preserves dot product, handedness, and distance, i.e. geometric topology is maintained.
If we RBT’d a vector, then the fourth column becomes irrelevant; a vector cannot be translated.
ˆ A normal vector ⃗n is defined ⃗n · (p̃1 − p̃2 ) = 0.
When affine transformed, ⃗nt A−1 A(p̃1 − p̃2 ) = 0.
hence, transposing the expression, we get ⃗n′ = A−t⃗n = L−t⃗n
We need to normalize the vector after applying the inverse transpose linear transform.

1
Lecture 5: Respect
ˆ Left-of rule: Point is transformed w.r.t. the frame that appears immediately to the left of the
transform matrix.
f⃗t ⇒ f⃗t S
f⃗t is transformed by S with respect to f⃗t .
f⃗t = a⃗t A−1 ⇒ a⃗t SA−1 :
f⃗t is transformed by S with respect to a⃗t .
p̃ = f⃗t c ⇒ f⃗t Sc:
p̃ is transformed by S with respect to f⃗t .
p̃ = f⃗t c = a⃗t A−1 c ⇒ a⃗t SA−1 c = f⃗t ASA−1 c:
p̃ is transformed by S with respect to a⃗t .

Lecture 6: Frames in Graphics


⃗t
ˆ World frame w

ˆ Object frame o⃗t = w


⃗ tO

ˆ Eye frame e⃗t = w


⃗ tE
Eye matrix is specified by eye point p̃, view point q̃, and up vector ⃗u.
z = normalize(p − q), x = normalize(u × z), y = z × x

ˆ p̃ = o⃗t c = w
⃗ t Oc = e⃗t E −1 Oc

Lecture 8: Arcball
This is black magic

Lecture 9: Quaternion 2
 
ω
ˆ Quaternion , where ω is scalar and ĉ is 3D coordinate vector

   
ω αω
α =
ĉ αĉ
    
ω1 ω2 ω1 ω2 − ĉ1 · ĉ2
=
ĉ2 ĉ2 ω1 ĉ2 + ω2 ĉ1 + ĉ1 × ĉ2

cos( θ2 )
 
ˆ : rotation of angle θ about unit length axis k̂
sin( θ2 )k̂
−1
cos( θ2 ) cos( θ2 )
  
0
Rotation:
sin( θ2 )k̂ ĉ sin( θ2 )k̂
−1 
cos( θ2 ) cos( θ2 ) cos( −θ
   
2 )
where = =
sin( θ2 )k̂ −sin( θ2 )k̂ sin( −θ
2 )k̂

ˆ LERP and SLERP


cos( θ20 ) cos( θ21 )
   
LERP: (1 − α) + α , followed by normalization
sin( θ20 )k̂0 sin( θ21 )k̂1

2
1−α  α
cos( θ20 ) cos( θ21 )

SLERP: +
sin( θ20 )k̂0 sin( θ21 )k̂1
α
cos( θ2 ) cos( αθ
   
2 )
where =
sin( θ2 )k̂ sin( αθ
2 )k̂

cos( θ20 ) cos( θ21 )


   
Sphere-based SLERP: sin[(1−α)Ω] + sin(αΩ)
sin(Ω) sin( θ20 )k̂0 sin(Ω) sin( θ21 )k̂1

Lecture 10: Bezier Curves / Polar Forms


ˆ Polar form: n-affine, symmetric, and correspondence identity; f (t, · · · , t) = F (t)
1
there is unique polar form tk = n C
Q
k
ui1 · · · uik
You can get Bezier points using polar form.
 
n
ˆ Bernstein basis polynomials: Bi,n (t) = (1 − t)n−i ti
i
nonnegative, symmetric, partition of unity, resursion; Bi,n (t) = (1 − t)Bi,n−1 (t) + tBi−1,n−1 (t).
P
Bezier curve F (t) = Pi Bi,n (t)

ˆ Bezier control polygon has


Convex hull property: the curve lies within the convex hull
Variation diminishing property: number of intersection...
Affine invariance

Lecture 11: Splines


ˆ Cubic Hermite splines:
  
1 0 0 0 c0
3  0
 −1 0 0 ⃗v0 
t2

F (t) = 1 t t   
−3 −2 3 −1 c1 
2 1 −2 1 ⃗v1

ˆ Catmull-Rom splines: since c′ (i) = 3(di − ci ) and c′ (i + 1) = 3(ci+1 − ei ), we set


di = 61 (ci+1 − ci−1 ) + ci , ei = 61 (ci+2 − ci ) + ci+1
  
1 0 0 0 c−1
 −τ 0 τ 0 
  c0 
 
F (t) = 1 t t2 t3 

 2τ τ − 3 −2τ + 3 −τ   c1 
−τ −τ + 2 τ −2 τ c2

ˆ Catmull-Rom splines: since c′ (i) = 3(di − ci ) and c′ (i + 1) = 3(ci+1 − ei ), we set


di = 61 (ci+1 − ci−1 ) + ci , ei = 61 (ci+2 − ci ) + ci+1 , and more generally:
  
0 1 0 0 c−1
 −τ 0 τ 0 
  c0 
 
F (t) = 1 t t2 t3 

 2τ τ − 3 −2τ + 3 −τ   c1 
−τ −τ + 2 τ −2 τ c2
ˆ B-splines:
  
1 4 1 0 c−1
3 −3 0 3 0
  c0 
  
t2

F (t) = 1 t t 
3 6 3 0  c1 
−1 3 −3 1 c2

3
Lecture 12: Geometric Modeling
ˆ Implicit surface - torus: (x2 + y 2 + z 2 − R2 − a2 )2 − 4R2 (x2 + y 2 ) = 0
ˆ Catmull-Clark subdivision surface
a new vertex for each vertex, edge, and face in existing mesh, resulting in all faces are quads.
vf = m1f j vj , ve = 14 (v1 + v2 + vf 1 + vf 2 ), vv = nvn−2 v + n12 j vj + n12 j vf j
P P P
v v v

This is proven to converge to a G1 continuous surface.

OpenGL Example
struct Geometry {
GlBufferObject vbo, ibo;
int vboLen, iboLen;

Geometry(VertexPN *vtx, unsigned short *idx, int vboLen, int iboLen) {


this->vboLen = vboLen;
this->iboLen = iboLen;

// Now create the VBO and IBO


glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(VertexPN) * vboLen, vtx, GL_STATIC_DRAW);

glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(unsigned short) * iboLen, idx, GL_STATIC_DRAW);
}

void draw(const ShaderState& curSS) {


// Enable the attributes used by our shader
safe_glEnableVertexAttribArray(curSS.h_aPosition);
safe_glEnableVertexAttribArray(curSS.h_aNormal);

// bind vbo
glBindBuffer(GL_ARRAY_BUFFER, vbo);
safe_glVertexAttribPointer(curSS.h_aPosition, 3, GL_FLOAT, GL_FALSE, sizeof(VertexPN), FIELD_OFFSET(VertexPN, p));
safe_glVertexAttribPointer(curSS.h_aNormal, 3, GL_FLOAT, GL_FALSE, sizeof(VertexPN), FIELD_OFFSET(VertexPN, n));

// bind ibo
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);

// draw!
glDrawElements(GL_TRIANGLES, iboLen, GL_UNSIGNED_SHORT, 0);

// Disable the attributes used by our shader


safe_glDisableVertexAttribArray(curSS.h_aPosition);
safe_glDisableVertexAttribArray(curSS.h_aNormal);
}
};

static void drawStuff() {


// short hand for current shader state
const ShaderState& curSS = *g_shaderStates[g_activeShader];

// build & send proj. matrix to vshader


const Matrix4 projmat = makeProjectionMatrix();
sendProjectionMatrix(curSS, projmat);

// use the skyRbt as the eyeRbt


const Matrix4 eyeRbt = g_skyRbt;
const Matrix4 invEyeRbt = inv(eyeRbt);

4
const Cvec3 eyeLight1 = Cvec3(invEyeRbt * Cvec4(g_light1, 1)); // g_light1 position in eye coordinates
const Cvec3 eyeLight2 = Cvec3(invEyeRbt * Cvec4(g_light2, 1)); // g_light2 position in eye coordinates
safe_glUniform3f(curSS.h_uLight, eyeLight1[0], eyeLight1[1], eyeLight1[2]);
safe_glUniform3f(curSS.h_uLight2, eyeLight2[0], eyeLight2[1], eyeLight2[2]);

// draw ground
// ===========
//
const Matrix4 groundRbt = Matrix4(); // identity
Matrix4 MVM = invEyeRbt * groundRbt;
Matrix4 NMVM = normalMatrix(MVM);
sendModelViewNormalMatrix(curSS, MVM, NMVM);
safe_glUniform3f(curSS.h_uColor, 0.1, 0.95, 0.1); // set color
g_ground->draw(curSS);

// draw cubes
// ==========
MVM = invEyeRbt * g_objectRbt[0];
NMVM = normalMatrix(MVM);
sendModelViewNormalMatrix(curSS, MVM, NMVM);
safe_glUniform3f(curSS.h_uColor, g_objectColors[0][0], g_objectColors[0][1], g_objectColors[0][2]);
g_cube->draw(curSS);
}

static void display() {


glUseProgram(g_shaderStates[g_activeShader]->program);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // clear framebuffer color&depth

drawStuff();

glutSwapBuffers(); // show the back buffer (where we rendered stuff)

checkGlErrors();
}

You might also like