Skip to content

iwang2/GC1

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

70 Commits
 
 

Repository files navigation

Computer Graphics, Spring 2018

Table of Contents

DATE AIM
1/31 Peering into the depths of color (color depth, file formats)
2/2 Utilities (emacs, imagemagick)
2/5 Bresenham's Line Algorithm
2/12 Representing Image Data
2/13 Matrix Math in Graphics
2/26 Transformations (translation, dilation, rotation)
3/5 Parametrics
3/6 Curves (hermite, bezier)
3/13 3D Shapes (cube, sphere, torus)
3/20 Vector Math (dot product, cross product)
3/23 Rendering 3D Objects (wireframe, polygon)
3/28 Backface Culling
4/11 Relative Coordinate System (CS stack)
4/17 Filling in Triangles (scanline conversion)
4/19 Z-Buffering
4/26 Lighting (Phong reflection model)
5/7 Compilers (lexer, parser, semantic analyzer)
5/17 Animation
5/29 Shading Models (flat, Gourand)

5.29.18 - Shading Models

How and when you calculate the color (I) for each shape.

Flat Shading

Calculating I once per polygon (what we have right now).

Gourand Shading

Calculate I for each vertex of the polygon.
Interpolate I in scanline conversion and draw_line.

      /| It
     / |
 I0./__|.I1
   /   |
Im \   |
    \  |
     \ |
      \| Ib

Phong Shading Model

Calculate I once per pixel.
Instead of having 3 different values for I at each vertex (Gourand), have 3 different normal values at each vertex.
Interpolate the surface normal in scanline conversion and draw_line.

      /| Nt
     / |
 N0./__|.N1
   /   |
Nm \   |
    \  |
     \ |
      \| Nb

Calculating Normals for Gourand and Phong

  v0
  |\
  | \
A |  \ B
  |   \
  |____\
v1   C   v2

The way we calculate normals now, all 3 values at each vertex would be the same.

   _____
  |\    |
  | \ A |
  |  \  |
  | B \ |
  |____\|
  |\    |
  | \ C |
  |  \  |
  | D \ |
  |____\|

Vertex normals will instead be the combined value of all surface normals for polygons that share a commmon vertex.


5.17.18 - Animation

Generate multiple images in a sequence with small changes between each image.
We will apply transformations over time.

move 400 0 0
sphere 40 50 0 50
 __________                                                      __________
|          |                                                    |          |
|o         | -------------------------------------------------> |         o|
|__________|                                                    |__________|
 __________      __________      __________      __________      __________
|          |    |          |    |          |    |          |    |          |
|o         | -> |  o       | -> |     o    | -> |       o  | -> |         o|
|__________|    |__________|    |__________|    |__________|    |__________|
     0%              25%             50%            75%             100%

Knobs

These are applied to objects, not transformations.

move 400 0 0 0.00 |
     400 0 0 0.25 |
     400 0 0 0.50 | knob
     400 0 0 0.75 |
     400 0 0 1.00 |
		 
move 400 0 0 m0

Commands

Function Definition Example
vary knob, start frame, end frame, start value, end value compute and store the knob values for each frame vary m0, 0, 4, 0 1
frames number of frames defines number of frames in animation frames 5
basename name gif name basename rolling
-delay N delays animation by N/100 seconds between frames convert -delay 10
transformation args [knob] if there is a knob, look up its value in the symbol table and modify args by it move x y z m0

3-Pass Animation Framework

  1. Setup
    • Set frames if frame command is present.
    • set basename if basename command is present
    • stop if vary is present but not frames2.
  2. Vary - compiler errors
    • compute and store all knob values for every frame
    • stop if vary range is invalid
  3. Draw
    • repeat loop for each frame
    • update the knobs in the symbol table at the beginning of each loop
    • at the end of each loop, save the current frame
    • once the loop ends, stitch the frames together

vary - Structure for Storing Knob Values

knob       frames
 __    __ __ __ __ __
|m0|  |_1|_2|_3|_4|_5|
|__|
|__|
|__|
|__|
frames
 __
|_0| -> m0, 0 -> m1, 2.5
|_1|
|_2|
|_3|
|_4|

Organization may depend on the type of language used, but Mr. DW recommends frame major.
In C, an array of linked lists.

How do you deal with missing knob values?

     k
vary | 0 3 0 .5
vary | 4 6 .5 .8
vary | 9 11 .8 1

There is no value for 7 and 8.

 ___ ___ ___ ___ ___ ___
|.5_|.65|.8_|_?_|_?_|.8_|
  4   5   6   7   8   9

You don't deal with it at all, throw a compiler warning instead and let the programmer deal with it.
Or you can default to 0, because that error should be easily seen in the animation.


5.7.18 - Compilers

source code --------------------------> image(s)  
source code ---------compiler---------> executeable code
    |                                            ^
    v                                            |
lexer -> syntatic -> semantic -> optimizer* ->  code
         analyzer    analyzer                 generator

Compiler Parts

Name Input Output
lexer source code (text) token list
parser token list syntax tree
semantic analyzer syntax tree operations list and symbol table
optimizer operations list optimized operations list
code generator optimized operations list and symbol table binary executeable

Lexer

Performs lexical analysis. "Knows" all the valid tokens in a language.

  • String literals
  • operators
  • formatting characters (semicolons, parentheses, brackets)
  • keywords (if, else)
  • numeric literals
  • identifiers (function names, variables)

Reads in source code and outputs a token list.

The types of errors a lexer will catch: bad character formatting, weird variable names (i.e. fro?)
Basically it only catches invalid tokens (NOT improper formatting).

Sample Code:

int main() {
  long x = 5 + 6;
  printf("%d", x);
  return x;
}

Sample Token List:

int
main
(
)
{
long
x
=
5
+
6
;
...

Tools

  • C: lex, flex (free lex)
  • java:

Parser

Performs syntax analysis, and checks the token list against the defined structure of the language.
Output is a syntax tree.

If the lexer checks for words, the parser checks for grammar.

Sample Syntax Tree:

               int main
       ____________|_____________
       =         printf      return
_______|___   _____|___        _|_
long x    +   "%d"    x         x
       ___|___
       5     6

Tools

  • C: yacc (yet another compiler compiler), bison
  • java: javacc

Semantic Analyzer

Evaluates the syntax tree and creates an operation list and symbol table (stores identifiers and associated information).
If the languaged is typed, type-checking will occur here.
The semantic analyzer does NOT evaluated expressions.

Tree Traversal Types

  • post: L -> R -> M
  • pre: M -> L -> R
  • in: L -> M -> R

Operation List

Number Operation Arguments
0 + 5 , 6
1 = x , (0)
2 return x

Symbol Table

Symbol Category Type?
main function int
x value long
printf function int

Optimizer

Runs through operations list and may replace functions in code to make it run faster.

For example: if ( x != 0 ) may turn into if ( x ), and if ( 1 ) may be removed completely.

We aren't making an optimizer, so this doesn't really matter.

Code Generator

Rather self-explanatory. Translates the operation list into binary assembly code.

Applying this to our graphics engine

image script -> token list -> syntax tree -> operations list -> image
                                              symbol table

Code Generator

  • call image
  • creation/manipulation functions

4.26.18 - Lighting

Colors are modeled based on:

  1. Color, intensity, and location of light.
  2. Reflective properties of objects.

Types of Light

Ambient Light: general lighting of an image

  • a single source - comes from all locations equally
  • represented by a normal color value

Point Light: comes from a specific location

  • can have many sources for an image
  • we will assume the light is from very far away
  • represented by a color and location

Phong Reflection Model

Models real world reflections by breaking them into 3 parts.
I (color, normalization) = ambient + diffuse + specular

  • diffuse and specular are point light

I = A·Ka + P·Kd · (N · L)

Ambient Light

  • A - Ambient Light (0->255)
  • Ka - constant of ambient reflection(0->1)
  • Ambient light = A·Ka

Diffuse Reflection

Reflection of a point light source. Reflected evenly in all directions. These are things that have a matte/dull finish.

Some important things

  • P - color of point light source
  • Kd - constant of diffuse reflection
 L    N
  \   |
   \  |
    \θ|
_____\|______

We can model the strength of the reflection with cosθ.

  • cosθ = N · L
  • diffuse = P · Kd · (N · L)

Specular Reflection

Reflects a point light source in a specific direction (shiny/glossy surfaces).

 L    N    R
 \_R__|__S_/   idk how to diagram it, but there is also another 
  \   T   /    view vector V between N and the x-axis.
   \  |  /     the angle between V and R is α
    \θ|θ/
_____\|/______
  • P - color of point light
  • Ks - constant of specular reflection
Component Value
R T + S
S T - L
R 2T - L
cosα R · V
T (N·C) · N
R 2(N·L)·N - L
cosα (2(N·L)·N - L) · V
        L
       /.
||L|| / .
     /  .
    /   .
   /θ___._N
   ||T||
  • cosθ = ||T|| / ||L||
  • cosθ = ||T|| (L is a normalized vector)
  • N · L = ||T||

Specular = P · Ks · [(2(N·L)·N - L) · V]x
power of x is to simulate a narrow reflection


4.19.18 - Z-Buffering

Keeping a separate set of z values corresponding to each point the color grid to draw only the most front-facing side of an object.

Z-BUFFER: 2D array of floating point values that directly correspond to the screen

  • check the z-buffer each time before updating the screen
  • initialize each z-value to the smallest possible value

Functions That Must Be Significantly Modified

  • plot must check/modify the z-buffer
  • draw_line must compute z-values
  • scanline must compute z-values

4.17.18 - Filling in Triangles

Given a triangle, how can we fill in its area?

  1. Fill with smaller and smaller triangles.
  2. Edge line fill (blending an edge to its opposite point; parallel lines to an edge)
  3. Scanline fill
  4. Flood fill (a single point, and plot its adjacent points; recursive)

Things that are good about scanline:

  • no double coverage
  • no weird spacing (horizontal lines only)
  • full coverage
  • takes advantage of the optimized draw_line

Scanline Conversion

Filling in a polygon by drawing consecutive horizontal (or vertical) lines.

  • Need to order vertices vertically for bottom, middle, and top, and find the endpoints of each scanline.
     top (T)
       /\
      /  \
  x0 /    \
    /    __\  middle
   /__---
bottom (B)
Value Pseudocode / Equivalent
y yB -> yT
y++
x0 on the line BT
xB -> xT
x0 += Δ0
Δ0 (xT - xB) / (yT - yB)
or
Δx / # of scanlines, aka Δy
x1 on the line BM until y = yM, then on MT
x1 += Δ1
Δ1 (xM - xB) / (yM - yB)
or
(xT - xM) / (yT - yM)

But...

What happens with a triangle where the middle has the same y-value as the top or bottom point?

    T
    /\
   /  \
  /    \
 /______\
B        M

Could possibly be dividing by 0, in which case you switch the order you draw each scanline. For example, instead of going from top to bottom, go from bottom to top (or vice versa).

If you flip, make sure to set x = xM to ensure that you cover the middle value.


4.11.18 - Relative Coordinate System

Currently transformations are applied to all shapes in the polygon/edge matrix.
In a RCS, we use transformations to modify the world in which we draw our shapes, rather than the shapes themselves.
Each shape can be drawn in a different world.

| 1 0 0 0 |   |  2  0  0  50  |
| 0 1 0 0 | · |  0  2  0  100 |
| 0 0 1 0 |   |  0  0  2  0   |
| 0 0 0 1 |   |  0  0  0  1   |
     A               B

Drawing

  1. Generate polygons/edges.
  2. Apply the current coordinate system to these points.
  3. Draw the polygons/edges to the image.

For Example: Drawing a sphere in the upper right.

sphere        rotate
rotate  ===>  move
move          sphere
apply

Everything must be done in reverse.

Coordinate System Stack

We will maintain a stack of coordinate systems.
The top will always be the most current system.
The bottom will always be the identity matrix (the global system).
All transformations modify the top, but none of the other matrices.
Push will push a copy of the top.

transformation · top vs. top · transformation

Command Stack
push I
I
move I
I · M1
box ""
push M1 · I
M1 · I
I
move I·M1·M2
I·M1
I
rotate I·M1·M2·R
I·M1
I
sphere ""
pop I·M1
I

3.28.18 - Backface Culling

Only drawing the polygons that are forward-facing.

Given a surface, take the surface normal (N), and a vector from the surface to the observer (V).
The angle between the two will tell us which way the surface is facing.

Step 1: Calculate N.

Taking 3 points (a triangle P0, P1, P2), two vectors A and B point away from the same point.

  • N = A x B
  • A = < P1 - P0 >
  • B = < P2 - P0 >

Step 2: Find θ.

  • N · V = || N || · || V || · cosθ
  • V = < 0, 0, 1 >
  • N = < x, y, z >
  • N · V = 0 + 0 + z

Step 3: If -90° < θ < 90°, draw.

Cosine is positive from -90 to 90, so if N · V > 0, draw.


3.23.18 - Rendering 3D Objects

Wireframe Mesh

Shape is defined by the edges that connect points on the surface.

add_box -> add_edge -> add_point
draw_lines -> draw_line

Disadvantages:

  • edges cannot be filled in
  • perspective is difficult to discern just by looking at the screen

Polygon Mesh

Shape is defined by the polygons that connect points on the surface (triangles).

add_box -> add_polygon -> add_point
new function (because draw_lines is no longer suitable): draw_polygons -> draw_line

    P0
    /\
P1 /__\ P2
      /\
     /__\
   P3    P4

Edge Matrix:

[ P0P1, P0P2, P1P2, ... ]

  • six edges

Polygon Matrix

[ P0P1P2, P2P3P4 ]

  • two triangles
  • points must be added in counter-clockwise order

3.20.18 - Vector Math "Review"

Vectors have direction and magnitude.

| ( x, y, z )     |  ^   < x, y, z >
|    ·            | /
|____________     |/____________

Given vector A, < x,y,z >, the magnitude || A || = sqrt( x2, y2, z2 ).

A normalized vector is a unit vector that preserves the direction of another vector.
A' = 1 / || A || * < Ax, Ay, Az >

Given vectors A and B, and angle θ between them:

Dot Product: A · B

  • || A || · || B || · cosθ
  • Ax · Bx + Ay · By + Az · Bz

Cross Product: A x B

Perpendicular to A and B.
Magnitude = area of the parallelogram formed by A and B.

  • || A || · || B || · sinθ
  • < AyBz - AzBy , AzBx - AxBz , AxBy - AyBy >

Finding a Vector between 2 Points

PQ: < Q-P >
QP: < P-Q >


3.13.18 - 3D Shapes

Box

Defining points: vertices
Given information: P0 (top, left, front), width (x), height (y), depth (z)

Sphere

Defining points: points on the surface
Given information: center, radius

Generate the defining points by drawing a circle and rotating it.
If you rotate about the z-axis, there is no 3D shape. Rotate about the x or y-axis.

| 1  0      0  |   | rcosθ |   | x |
| 0 cosϕ -sinϕ | · | rsinθ | = | y |
| 0 sinϕ  cosϕ |   |   0   |   | z |

θ = angle of circle creation
ϕ = angle of rotation (0 -> 2π)

There are a few ways to draw a sphere:

  1. Draw a circle and rotate it 180 degrees.
  2. Draw a semi-circle and rotate it 360 degrees (the better option).

Pseudocode

for (ϕ: 0 -> 2π) {
	for (θ: 0 -> π) { // Semicircle
		x = rcosθ + cx
		y = rsinθcosϕ + cy
		z = rsinθsinϕ + cz
	}
}

Torus

Defining points: points on the surface
Given information: R (radius of the whole torus), r (radius of cross section), center

Generate the image by translating a circle and rotating it.
If we move over x, rotate about y.
If we move over y, rotate about x.

    y-rotation          circle               torus
|  cosϕ  0  sinϕ |  | rcosθ + R |   |  cosϕ(rcosθ + R) + cx |   | x |
|   0    1    0  |  |   rsinθ   | = |      rsinθ + cy       | = | y |
| -sinϕ  0  cosϕ |  |     0     |   | -sinϕ(rcosθ + R) + cz |   | z |

θ = 0 -> 2π
ϕ = 0 -> 2π


3.6.18 - Splines

Curves that can be combined smoothly.
We will only draw cubics, and combine them to form these curves.

Hermite Curves

for t: 0->1, t += step

  • x = ax · t3 + bx · t2 + c · t + dx
  • y = ay · t3 + by · t2 + c · t + dy

Given Information

  • endpoints: P0, P1
  • rate of change at each endpoint: R0, R1
  • points on curve: f(t) = a · t3 + b · t2 + c · t + d
  • rates of change: f'(t) = 3a · t2 + 2b · t + c
When t = 0 When t = 1
f(t) = d : P0 f(t) = a + b + c + d : P1
f'(t) = c : R0 f'(t) = 3a + 2b + c : R1

H · C = G

| 0 0 0 1 |   | a |   | P0 |
| 1 1 1 1 | · | b | = | P1 |
| 0 0 1 0 |   | c |   | R0 |
| 3 2 1 0 |   | d |   | R1 |
     H          C       G

Unfortunately, we don't need to solve for G, because that is already given.

H-1 · G = C

|  2 -2  1  1  |   | P0 |   | a |
| -3  3 -2 -1  | · | P1 | = | b |
|  0  0  1  0  |   | R0 |   | c |
|  1  0  0  0  |   | R1 |   | d |

Bezier Curves

Defined by n + 1 points (n = degree of the equation).

Line

We will start with a line.

      . P1
     /
    /
   . Pt
  / 
 /
. P0
  • Pt moves along the line P0P1
  • Pt = (1 - t) · P0 + t · P1

Quadratic

Three points: P0, P1, P2.

Q0 moves along the line P0P1.
Q1 moves along the line P1P2.
Qt moves along the line Q0Q1.

Qt = (1 - t) · Q0 + t · Q1
= (1 - t)2 · P0 + 2t · (1 - t) · P1 + t2 · P2

Cubic

Rt moves along the line R0, R1.
R0 moves along the quadratic Q0, Q1.
R1 moves along the quadratc Q1, Q2.

Rt

= (1 - t) · R0 + t · R1
= (1 - t)2 · P0 + 3t · (1 - t)2 · P1 + 3 · t2 · (1 - t) · P2 + t3 · P3
= ( -P0 + 3P1 - 3P2 + P3 ) t3 + ( 3P0 - 6P1 + 3P2 ) t2 + ( -3P0 + 3P1 ) t + P0

a·t3 + b·t2 + c·t + d

  • a = -P0 + 3P1 - 3P2 + P3
  • b = 3P0 - 6P1 + 3P2
  • c = -3P0 + 3P1
  • d = 3P2
| -1  3 -3  1 |   | P0 |   | a |
|  3 -6  3  0 |   | P1 |   | b |
| -3  3  0  0 | · | P2 | = | c |
|  1  0  0  0 |   | P3 |   | d |

3.5.18 - Parametric Equations

Instead of defining a curve in which x and y are directly dependent on each other, they will be separately related to another variable.

Essentially, define a curve as a system of equations based on an independent variable (t).

  • for example: x = f(t), y = g(t), z = h(t)
  • For consistency, think of t as going from 0 to 1.

General Parametric Framework

for t : 0->1, t += increment
    x = f(t)
    y = g(t)
    add(x, y)

t will not be an integer (the smaller the value, the more precise the image, and the slower your program will be)

Line ( x0 , y0 ) -> ( x1 , y1 )

  • f(t) = x0 + t(Δx)
  • g(t) = y0 + t(Δy)

When t = 0, x = x0 and y = y0.
When t = 1, x = x1 and y = y1.

Circle ( xc , yc ), r

  • f(t) = r · cos(2π·t) + xc
  • g(t) = r · sin(2π·t) + yc
  • θ : 0 -> 2π

Because of floating point math on computers, when you write your code, it's better to have integer based controls. So if you want 100 steps, instead of making the increment 0.01, make t go from 0 to 100, and divide by 100 at the end.


2.26.18 - Transformations

Translation, dilation, rotation (affine transformations; preserves orientation and vertices).

  • E: edge matrix
  • T: transformation matrix
  • E · T or T · E ( i.e. 3x3 · 3xN = 3xN )

Translation

( x, y, z ) -> T(a, b, c) -> ( x+a, y+b, z+c );

| 1 0 0 a |   | x |   | x+a |
| 0 1 0 b | · | y | = | y+b |
| 0 0 1 c |   | z |   | z+c |
| 0 0 0 1 |   | 1 |   |  1  |
    4x4        4xN      4xN

Dilation

( x, y, z ) -> D(a, b, c) -> ( ax, by, cz )

| a 0 0 0 |   | x |   | ax |
| 0 b 0 0 | · | y | = | by |
| 0 0 c 0 |   | z |   | cz |
| 0 0 0 1 |   | 1 |   |  1 |
  D(a,b,c)

With this formula, the size of the object being drawn will be scaled, but so will the distance from the origin. To avoid this, you can translate the object to the origin, dilate, and then translate back.

Rotation

y
|  · (x1,y1)
|
|      · (x,y)
|
|______________ x

( x, y ) -> Rθ -> ( ? , ? )
θ is the angle between the two points
Φ is the angle between (x,y) and the original x-axis

Polar Coordinates

  • x = r·cos(Φ)
  • y = r·sin(Φ)
  • x1 = r·cos(Φ + θ)
    x1 = r·cos(Φ)cos(θ) - r·sin(Φ)sin(θ)
    x1 = x·cos(θ) - y·sin(θ)
  • y1 = r·sin(Φ + θ)
    y1 = y·cos(θ) + x·sin(θ)
| cos -sin  0  0 |   | x |   | xcos - ysin |
| sin  cos  0  0 |   | y |   | ycos + xsin |
|  0    0   1  0 | · | z | = |      z      |
|  0    0   0  1 |   | 1 |   |      1      |
     R(θ,z)

Rθ,x

    z
    |  · (y1,z1)
    |
    |      · (y,z)
    |
    |______________ y
   /
  /
 /
x

y = rcosθ, z = rsinθ
y1 = ycosθ - zsinθ
z1 = zcosθ + ysinθ

Rθ,y

    x
    |  · (z1,x1)
    |
    |      · (z,x)
    |
    |______________ z
   /
  /
 /
y

z1 = zcosθ - xsinθ
x1 = xcosθ + zsinθ

Combining Transformations

E0 (edges), T (translate), R (rotate), S (scale)

  • T · E0 = E1
  • R · E1 = E2
  • S · E2 = E3
  • E3 = ( S · R · T ) · E0

THIS IS ASSOCIATIVE
Read from right to left. Translate first, then rotate, then scale.


2.13.18 - Matrix Math in Graphics

[ P0 , P1 , P2 , P3 ... Pn ]

| x0 , x1 ... xn |
| y0 , y1 ... yn |
| z0 , z1 ... zn |

3 x N (3 rows, N columns)

Matrix multiplication: M·N

  • # of columns in M = # of rows in N
  • A x B · B x C = A x C
  • Non-commutative: M·N ≠ N·M

Some Matrix Multiplication Examples

            | a |
| 1 2 3 | · | b | = | 1a + 2b + 3c |
    1x3     | c |         1x1
             3x1
| 1 2 3 |   | a b |   | 1a+2c+3a 1b+2d+3f |
| 4 5 6 | · | c d | = | 4a+5c+6e 4b+5d+6f |
| 7 8 9 |   | e f |   | 7a+8c+9e 7b+8d+9f |
   3x3        3x2             3x2

Multiplicative Identity Matrix: M · I = M

  • square, diagonal of 1's, and 0's everywhere else
| 1 0 | . | a | = | a |
| 0 1 |   | b |   | b |

2.12.18 - Representing Image Data

Say you have a triangle. Each time you create the triangle, draw_line() must be called 3 times.
To store this triangle, you could create a list of the pairs of points.

  • [ p0, p1, p2 ] --> edge list
  • [ p0 p1 p2 ] [ p1, p2, p0 ]
  • [ p0, p1, p2, p0 ]
  • one list for points, another list for connections between points

Edge List

List of points in the image where every 2 points determines a line.

[ p0 , p1 , p2 , p3 ... pn ] --> ( p0 , p1 ), (p2 , p3) , (pn-1 , pn )
Triangle ABC --> [ A, B, B, C, C, A ]

This is essentially a two dimensional array.


2.5.18 - Bresenham's Line Algorithm

y = mx + b - This is nice, but won't work in graphics because everything is in pixels, and therefore INTEGERS.
When using a line algorithm, we are approximating the line (except with horizontal/vertical lines).

Bresenham's Line Algorithm

Find the pixels that best approximate a target line.

Assume:

  • ( x0 , y0 ) -> ( x1 , y1 ) are all integers (endpoints exist)
  • Only lines in octant I - 0 < m < 1
  • x0 < x1 - always start in the left and move to the right

For example:

 __ __ __ __ __ __
|__|__|__|__|__|__|
|__|__|__|__|__|██|
|__|__|__|__|__|__|
|__|1_|__|__|__|__|
|██|2_|__|__|__|__|

In picking the line between the two selected endpoints, we have 2 options for the next pixel:

  1. ( x + 1 , y + 1 )
  2. ( x + 1 , y )

To pick, use the midpoint ( x + 1 , y + 0.5 ).

  • If the midpoint is above the line, draw the lower pixel.
  • If the midpoint is below the line, draw the upper pixel.
  • If the midpoint is on the line, draw one or the other.

Testing the Midpoint

y = mx + b
0 = mx - y + b

m = Δy / Δx

0 = (Δy / Δx) x - y + b
  = xΔy -yΔx + bΔx
A = Δy, B = -Δx, C = bΔx
0 = Ax + By + C

f(x,y) = Ax + By + C
  • When the midpoint is directly on the line, f(x,y) = 0 (this is not really that important).
  • When the midpoint is above the line, f(x,y) < 0.
  • When the midpoint is below the line, f(x,y) > 0.

( x0 , y0 ) -> ( x1 , y1 )

First Draft Algorithm:

x = x0 ,  y = y1
d = f ( x + 1 , y + 0.5)
while x <= x1
    plot ( x , y )
    x++
    if d > 0 : y++
    d = f ( x + 1 , y + 0.5 )

Second Draft Algorithm:

if x++ : d += A
if y++ : d += B

d = f( x + 1 , y + 0.5)  
while x <= x1 
    plot ( x , y )  
    if d > 0  
        y++ 
        d += B
    x++  
    d += A
    
d = f ( x0 + 1 , y0 + 0.5 )  
  = A ( x0 + 1 ) + B ( y0 + 0.5 ) + C  
  = A x0 + B y0 + A + 0.5 B  
  = f (x0, y0) + A + 0.5B
  = A + 0.5B

Third Draft Algorithm

d = 2A + B
while x <= x1
 plot(x,y)
 if d > 0
   y++
   d += 2B
 x++
 d += 2A

Octant II

 __ __ __ __ __ __
|__|__|__|██|__|__|
|__|__|__|__|__|__|
|__|__|__|__|__|__|   //  1. ( x , y + 1 )
|1_|2_|__|__|__|__|   //  2. ( x + 1 , y + 1 )
|██|__|__|__|__|__|

MIDPOINT: ( x + 0.5 , y + 1 )

d = 2A + B      --> d = A + 2B
while x <= x1   --> y <= y1
  plot(x,y)
    if d > 0    --> d < 0
    x++         // swapped with 
    d += 2A
  y++
  d += 2B

Octant VIII

 __ __ 
|██|1_|  // ( x + 1 , y )
|__|2_|  // ( x + 1 , y - 1 )

MIDPOINT : ( x + 1 , y - 0.5 )

d0 : f ( x0 + 1 , y0 - 0.5 )
     2A - B
if d > 0

2.2.18 - Utilities

emacs

ctrl-C to convert between image and code

imagemagick

Program thing for ppm.

  • $ display image.ppm
  • $ convert image.ppm image.png

1.31.18 - Peering into the depths of color.

Color Depth

The amount of data used to represent a single pixel.

SIZE COLOR OPTIONS
1 bit 1 color; on/off
2 bit 1 color; on/off, plus 1 bit for intensity
3 bit Red, Green, Blue; on/off
4 bit RGB with intensity
6 bit RGB, each color with its own intensity (each one color has 2 bits)
3 byte 1 byte for each color; each with 256 possible intensities (~16 million combinations)

Other Color Spaces

We mostly just use RGB.

  • RGBA: Red, Green, Blue + Alpha (transparency)
  • HSB: Hue, Saturation, Brightness (cone diagram)

Image File Formats

Vector vs. Raster

Vector: represent images as a series of drawing instructions

  • They are infinitely scalable.
  • SVG (Scalable Vector Graphics)

Raster: represent images as a grid of pixels

Uncompressed vs. Compressed (Raster)

Uncompressed: contain data for each pixel

  • (i.e. BMP, TIFF, RAW)

Compressed: use a compression algorithm to minimize file size

  1. lossless - contain enough information to exactly recreate the original image
    • PNG (Portable Network Graphics), GIF (Graphics Interchange Format)
  2. lossy - do not retain all the details of the original image
    • JPEG (Joint Photographic Experts Group)

PPM (Portable PixMap)

Uncompressed raster format.
Pixel data is represented by RGB triplets in either ASCII or binary.
All whitespace is equivalent.

Example File:

P3    // file type
4 3   // dimensions
255   // maximum color value
// each group of 3 numbers is a single pixel
255 0 0  255 0 0  255 0 0  255 0 0
0 255 0  0 255 0  0 255 0  0 255 0
0 0 255  0 0 255  0 0 255  0 0 255

Number 1 Rule of Graphics:
DO NOT UPLOAD PPM FILES TO GITHUB

About

Computer Graphics, Spring 2018

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors