z' -> (z*(zf + zn) -2*zf*zn ) / z*(zf - zn)

- z = zf: z' = 1
- z = zn: z' = -1
- z = (zf + zn) / 2. z'= (zf - zn) / (zf + zn)
As zn -> 0 what happens?

- What maps to z' = 0? z = 2*zf*zn / (zf + zn ) = 2 / (1/zf + 1/zn)
Note the possible numeric problems.

- z -> +0: z' = -2*zf*zn / \delta -> -infinity
- z -> -0: z' -> +infinity
- z -> infinity, z' = (zf + zn) / (zf - zn)

- Ordered sets of vertices, joined sequentially (and cyclically) by straight lines.
- Simple polygons
- convex or concave
- no line crossings
- no holes

Adding extra vertices removes the problems

- at the cost of adding degeneracies

- Polygons cover the surface of an object
- each polygon has a normal vector,
- usually pointing out
- polygonal "skin" is often called a mesh

Clipping a polygon reduces to clipping edges against

- lines in 2D
- planes in 3D

The clipping algorithm takes an ordered set of vertices [vi] and produces an ordered set of vertices [wi]. It relies on the following

- If one edge leaves the clipping region, a later edge must enter it.

The algorithm is

for each edge of clipping region for each edge of polygon // must be in sequence clip edge against region switch (result of clip) case "all inside" output leading vertex of edge case "all outside" do nothing case "cross edge leaving region" output crossing point case "cross entering region" output crossing point output leading vertex of edge

Exercise. Hand execute this algorithm on several cases to make sure that you understand exactly how it works.

Lines project to lines so projecting the vertices projects a polygon in 3D to a polygon on the view plane.

Sooner or later almost all polygons are converted to triangles

- there is not a unique way of doing so
- try to avoid long skinny triangles

Scan converting a polygon (in 2D)

sort vertices in direction perpendicular to the scan lines for each scan line if scan line contains the next vertex update and sort edge list inside = false for each pixel if on next edge inside = !inside if (inside) paint pixelt

Exercise. Expand "update and sort edge list" to make this a working algorithm.

Exercise. Hand execute your expanded algorithm on a triangle to make sure that you understand how it works.

Exercise. Hand execute your expanded algorithm on a non-convex polygon.

Every polygon, in 3D, has two sides

- the normal vector differentiates the sides
- different sides may have different properties

It is very convenient to assume that surfaces are closed

- Naturally open surfaces, e.g., a piece of paper, can be closed by adding polygons

Then we can say that every polygon has only a single side with visual properties

- The normal vector points away from this surface

Do not render any polygon with n.E < 0.

- On average this cuts the rendering effort in half.

Does not handle occlusion, so we need to finish off with one of the following algorithms

Sort polygons back to front, then render backmost first.

- simple, device-independent
- slow if there's lots of occlusion
- sorting may not be possible, which makes things hard.

Divide and conquer

- Start with whole window
- Divide into four subwindows
- Keep dividing into subwindows until
- the subwindow is a single pixel, OR
- there is a single polygon in the window

then paint the window

Warnock's algorithm is

- easy to implement, device independent
- slow, often O(p.n). p: number of pixels.

Use a second frame buffer with depth values stored in it

- Initalize depth-buffer to far plane distance
- If a pixel has z less than the current depth buffer value
- Write it, and
- Update the depth buffer

The depth buffer algorithm is

- easy to implement
- fast, O(n)
- no longer memory-intensive, though it used to be

Almost all graphics cards have hardware depth buffers.

Using the depth buffer may be hard the first time.

For assignment 3 you need to be able to rotate with the mouse

The virtual trackball

- vertical motion rotates about y
- horizontal motion rotates about x
- circular motion outside the trackball rotates about z

You need to modify the sample code.

For assignment 3 you need to be able to select graphical objects with the mouse

The simple principle

- Mouse gives (x, y).
- Render pixel at (x, y ) keeping track of the polygon it comes from.
- Associate polygon with object

For the assignment let GL do it for you.

- Associate names (unsigned integers) with objects that are drawn
- Get back a hit stack, with primitives `near' where the mouse clicked
- It's up to you how you handle the hit stack.

See the notes.