Office hours: Wednesday, 4-5pm
Text: Class notes (so make sure you come to class!), will be posted on-line after each lecture.
Graders:
Jonathan Tompson, Bowen Zhang, Weitao (Vito) Wang, Jianxing (Morgan) Chen
Discussion list:
TBA
Lectures:
Introductory lecture (January 26)
Simple applets and 2D matrix transformations
3D matrix transformations
Modeling shapes with polygons
Perspective and animation hierarchy
Better animation hierarchy + Splines
Ray tracing 1
Ray tracing 2
Ray tracing 3
Ray tracing 3
Z-buffers, part 1
Z-buffers, part 2
Advanced topics (if there is time)
Setting up a homepage and access to computers:
Most of you have the homepage and computers thing already figured out. But just to make sure you have at least one way to show your work on line, your NYU webpage can be activated and modified as follows:
To post assignments for this class, you should set up a subdirectory of your web site (preferably your NYU web site). Name this subdirectory "graphics". It should have a main "index.html" file, and that file should link to the various homework assignments. After the first class, you will send the grader an email, with subject line "graphics", telling him the URL.
Your homework, due before the start of the next class,
is to write an essay saying why you are taking this
class and what you hope to get out of it.
The essay should be posted to the graphics/ web page
that you will create for this class.
Send an email to grader Jonathan Tompson telling him
the URL of that web page, as we discussed in class.
To compile and run from the command line,
you can use the latest version of the
Java Development Kit (JDK), which
you can download from
http://www.oracle.com/technetwork/java/javase/downloads
To compile all of your java files, you can just type in the command line:
You can also develop from an
Integrated Development Environment
(IDE) such as Eclipse.
You can download Eclipse from
the
Eclipse Downloads page.
Be sure to download Eclipse IDE for Java Developers.
Installing Eclipse is
slightly more involved if you are on Windows than
if you are on a Mac. So if you are on Windows, you
can read this
Tutorial for installing Eclipse on Windows.
To get your Java applet running from the Web, or in appletviewer
from the command line, you need an html file that contains an applet tag.
The simple test1.html file I used in class looked like this:
After going through some example programs, in class
we started to discuss matrix transformations, beginning with
two dimensional transformations -- which are done using 3×3 matrices.
Consider any point (x,y) on the 2D plane.
We can represent a any point on the plane in homogeneous coordinates
as a column vector:
For points at infinity (that is, direction vectors) we can let w = 0.
For example, consider the two column vectors below. The first represents the point at location
(1,0) and the second represents the positive x direction:
We can build more complex transformations by multiplying
together transformation matrices:
For example, first translating by (1,0) and then rotating by π/2 does not
produce the same transformation as
first rotating by π/2 and then translating by (1,0):
Next week we will cover other sorts of matrix transformations,
such as scaling, skewing and perspective,
and we will talk about 3D matrix transformations.
Your homework,
due next February 9 before class starts,
will be to build upon the simple applets that I showed in class,
to make your own cool animated scene.
You are encouraged to be creative, to have fun with it.
Show me your imagination!
Remember, you can draw onto the Graphics object using
any method found in the API for the
You should create a subfolder for each homework
assignment, inside
the main folder on your class website that contains your index.html
page. This will make things a lot easier as the semester goes along.
Link to this assignment from your main index.html page.
Graders should be able to see your applet
running after they click on the link.
For this and other assignments, you should put up links to
all of your Java source files on the assignment page,
so the graders can see your actual code.
3D Transformation Matrices:
Here are the basic
3D matrix primitives (not including perspective):
Approximating curved shapes with vertices and polygonal faces
Because computers are better at
solving simple problems,
a very effective approach is to
break any curved surface down
into a collection of little flat surfaces.
This exploits the fact that people are
much more sensitive to shading than to
silhouettes. As long as we can shade
a flat polygon so that it reacts to light
in a way that makes it look curved, we
can get away with approximating curves
surfaces by such polygons.
There are two parts to representation of
a shape:
- an array of vertices. Each vertex has an x,y,z coordinate
- an array of faces. Each face is an ordered array of vertex indices.
Our represention needs to distinguish (1) adjoining faces
that are being used to approximate
a single curved surface from
(2) adjoining faces that are supposed
to have a visible edge between them.
To do this we will adopt the following convention:
(1) if two faces index into the same vertex,
then this indicates a single smooth curved surface.
(2) if two faces index into different vertices
that just happen to have the same x,y,z position,
this indicates an edge.
For example, the first example below is
a very coarse approximation to a smooth sphere
using an octahedral arrangement of vertices.
The second example is is an octahedron, with
eight faces and twelve edges.
double vertices[][] = {
{-1, 0, 0}, { 1, 0, 0}, { 0,-1, 0}, { 0, 1, 0}, { 0, 0,-1}, { 0, 0, 1},
};
int faces[][] = {
{0,2,5}, {0,5,3}, {0,3,4}, {0,4,2}, {1,5,2}, {1,3,5}, {1,4,3}, {1,2,4},
};
// OCTAHEDRON -- NEEDS 24 VERTICES, THREE FOR EACH OF THE EIGHT FACES.
double vertices[][] = {
{ 0, 0,-1}, { 0,-1, 0}, {-1, 0, 0},
{ 1, 0, 0}, { 0,-1, 0}, { 0, 0,-1},
{-1, 0, 0}, { 0, 1, 0}, { 0, 0,-1},
{ 0, 0,-1}, { 0, 1, 0}, { 1, 0, 0},
{-1, 0, 0}, { 0,-1, 0}, { 0, 0, 1},
{ 0, 0, 1}, { 0,-1, 0}, { 1, 0, 0},
{ 0, 0, 1}, { 0, 1, 0}, {-1, 0, 0},
{ 1, 0, 0}, { 0, 1, 0}, { 0, 0, 1},
};
int faces[][] = {
{0,1,2}, {3,4,5}, {6,7,8}, {9,10,11}, {12,13,14}, {15,16,17}, {18,19,20}, {21,22,23},
};
I leave it to you to figure out
the vertices and faces arrays for a cube.
In fact, that's part of your homework assignment
for this week.
In general, you can create a Java class
// OTHER CODE AND DATA GO HERE
}
To create different kinds of shapes,
you can add methods to your Geometry class
that fill in the vertices and faces values
in various useful and interesting ways.
For example, as we discussed in class,
some shapes can be described parametrically.
As two parameters each vary from a minimum to a maximum
value, we evaluate some function that returns
the (x,y,z) coordinates of the point on the surface
associated with those parameter values.
One example of this is the
description of a unit sphere as a
latitude/longitude globe generated
by two parameters:
with the associated function
Another example is the parametric description of a unit torus
(a "unit torus" is a torus centered on the origin,
whose large ring diameter is 1.0).
The torus is generated by two parameters:
with the associated function
where "r" is the radius of the tube thickness.
When dealing with such a shape,
we want to create a set of vertices that form
a rectangular mesh.
The user of our modeler should be able to specify
how many steps to take from the lowest to the
highest values of each of the two parameters.
For example, we might implement a method
As we discussed in class, a shape that forms a rectangular mesh contains
((m+1) * (n+1)) vertices, and (m * n) faces, where each face indexes four vertices.
The vertex whose value of θ is (2π * i / m)
and whose value of φ is (-&pi/2 + &phi * j / n),
is stored in vertices[i + (m + 1) * j].
For example, a sphere with m == 3 and n == 3 will have
16 vertices, that we can think of as being arranged
in a 4×4 grid:
and its nine faces will be:
An interesting hybrid shape is a cylinder.
The tubular sides of the cylinder form a kind
of mesh that can be parametrized by θ and z,
where:
HOMEWORK, DUE BEFORE CLASS STARTS, THURSDAY FEBRUARY 23
Implement a geometry class.
Add methods that generate a sphere,
a cylinder and a cube.
Once you have these three shapes,
you can model approximations to lots of different objects,
such as people, molecules, cars, robots, trees, houses, chairs,
and lots of other things,
by creating multiple Geometry objects
and using matrices to transform them.
Build a scene using models created from your shapes.
Be creative.
If you'd like, feel free to generate other primitive shapes,
For now, you can render all of your transformed
shapes by drawing the edges of the faces
using the g.drawLine command,
just as you did for last week's assignment.
I strongly recommend you do not wait
until the last minute to complete this
week's assignment. You won't be able to get it
done at the last moment.
Please read over both of those pages of notes carefully.
Your homework assignment, which will be due before
the start of class on March 1,
is described at the bottom of the notes about Transformation Hierarchy.
As we discussed in class,
the way you did animation
in the previous assignment
was limited, since the animation
hierarchy was "baked in" to the code.
It's much better to do this hierarchy
as data, rather than code, so that
users can make changes to the hierarchy
during run-time.
In class I explained how my little
example of a one-armed man,
shown in the old style as
scenetest1.java,
can be more elegantly expressed using
the new style, as in
scenetest2.java.
To support this,
you can add some data structures to your
Geometry object that support
an interface something like the following:
Note that you do not need to maintain an explicit matrix stack.
Instead, you can keep a separate globalMatrix inside
each Geometry object, which contains the result,
in each animation frame, of multiplying
the parent object's globalMatrix by the
object's relative matrix.
After you have computed the value an object's globalMatrix
for the current animation frame, you can then use that
globalMatrix to transform the vertices of the object,
placing the transformed vertices into a working array
(don't modify the values of the Geometry object's
original vertices array).
You can then render the Geometry object by
using the faces together with the transformed vertex
locations in this working array.
Your homework,
which will be
due before class on Thursday March 22 (after Spring break),
will consist of two parts:
(1) Change over to the better way of maintaining
a matrix/object hierarchy, and
(2) Doing animation by implementing splines as we discussed in class.
For the first part
of your homework -- changing to the improved method
of specifying a hierarchical scene --
you can use the same scene and object hierarchy
that you used in the previous assignment, or
you can create something new.
I leave that choice up to you -- but it's more
fun to try something new.
For the course notes and assignment
for the second part of the homework,
here is a link to an
introduction to animating with splines.
In class this coming Thursday,
I will repeat the small amount of math
I showed you for intersecting a ray
with a sphere.
That was just a taste, to give you the
general idea of how it works.
Your homework is to complete the ray tracing assignments.
People who had already completed them by April 12 will
get extra credit.
For those of you who are feeling confident
and ambitious (and have gotten everything else
done), here are some
notes from this week's lecture on texturing.
Introductory lecture (January 26)
General overview of computer graphics,
interactive demonstration of the sort of system
you will be implementing this semester.
Delineated the basic elements of
graphics you will learn in this course:
Simple applets and 2D matrix transformations
In class on Feb 2 we showed how to
create a simple java applet, by extending
my java class
BufferedApplet.java.
Example applets we built in class were
test1.java
and
test2.java.
Feel free to download these and to use
them as a basis to start your homework.
javac *.java
<applet code=test1 width=640 height=480>
</applet>
If you have test1.html in your current directory,
you can either type into the command line:
appletviewer test1.html
or you can click on test1.html from a finder window,
to launch the applet in a browser.
x
y
w
to represent the point at position (x/w, y/w).
For most points, we can just let w = 1.
1 1
0 0
1 0
This representation lets us use matrices to transform both points and directions by matrix-vector multiplication:
The identity matrix transforms every point to itself:
x' m0,0 m0,1 m0,2 x
y' ← m1,0 m1,1 m1,2 × y
w' m2,0 m2,1 m2,2 w
A translation matrix moves every point by a fixed amount (dx,dy):
x 1 0 0 x
y ← 0 1 0 × y
w 0 0 1 w
A rotation matrix rotates every point about the origin by a fixed angle θ:
x+dx 1 0 dx x
y+dy ← 0 1 dy × y
w 0 0 1 w
(x cosθ - y sinθ) cosθ -sinθ 0 x
(x sinθ + y cosθ) ← sinθ cosθ 0 × y
w 0 0 1 w
But we need to be careful, because matrix math is not
commutative -- the order that we perform these rotations matters.
(a0,0b0,0+a0,1b1,0+a0,2b2,0) (a0,0b0,1+a0,1b1,1+a0,2b2,1) (a0,0b0,2+a0,2b1,2+a0,2b2,2) a0,0 a0,1 a0,2 b0,0 b0,1 b0,2
(a1,0b0,0+a1,1b1,0+a1,2b2,0) (a1,0b0,1+a1,1b1,1+a1,2b2,1) (a1,0b0,2+a1,1b1,2+a1,2b2,2) ← a1,0 a1,1 a1,2 × b1,0 b1,1 b1,2
(a2,0b0,0+a2,1b1,0+a2,2b2,0) (a2,0b0,1+a2,1b1,1+a2,2b2,1) (a2,0b0,2+a2,1b1,2+a2,2b2,2) a2,0 a2,1 a2,2 b2,0 b2,1 b2,2
0 -1 0 0 -1 0 1 0 1
1 0 1 ← 1 0 0 × 0 1 0
0 0 1 0 0 1 0 0 1
0 -1 1 1 0 1 0 -1 0
1 0 0 ← 0 1 0 × 1 0 0
0 0 1 0 0 1 0 0 1
java.awt.Graphics
object class.
You can find the API documentation page on the web by doing a Google search for java Graphics
.
3D Matrices
In class this week we discussed
using 4×4 matrices to do
linear coordinate transformations.
After reviewing the form of the basic matrix
primitives, below, do the
this week's homework assignment.
That assignment page contains
extensive notes and hints about implementation.
identity:
1 0 0 0
0 1 0 0
0 0 1 0
0 0 0 1
translationMatrix(a,b,c):
1 0 0 a
0 1 0 b
0 0 1 c
0 0 0 1
xRotationMatrix(θ):
1 0 0 0
0 cos(θ) -sin(θ) 0
0 sin(θ) cos(θ) 0
0 0 0 1
yRotationMatrix(θ):
cos(θ) 0 sin(θ) 0
0 1 0 0
-sin(θ) 0 cos(θ) 0
0 0 0 1
zRotationMatrix(θ):
cos(θ) -sin(θ) 0 0
sin(θ) cos(θ) 0 0
0 0 1 0
0 0 0 1
scaleMatrix(a,b,c):
a 0 0 0
0 b 0 0
0 0 c 0
0 0 0 1
Modeling shapes with polygons
// VERY COARSE APPROXIMATION OF A SPHERE USING EIGHT VERTICES:
//
// 3
// | 4
// |/
// 0-----+-----1
// /|
// 5 |
// 2
A unit cube can be described using this vertices/faces description
as six faces and 24 vertices (four vertices for each
of its six faces).
Because the cube contains edges between adjoining faces,
the faces cannot share vertices. Hence the need
(as we discussed in class) for 24 vertices, rather than 8.
Geometry
that contains these two
data structures:
public class Geometry
{
double vertices[][];
int faces[][];
0 <= θ <= 2π
-π/2 <= φ <= π/2
f(θ,φ) = (cosθ cosφ , sinθ cosφ , sinφ)
0 <= θ <= 2π
0 <= φ <= 2π
f(θ,φ) = ( (1 + r cosφ) cosθ , (1 + r cosφ) sinθ , r sinφ )
globe(int m, int n)
within the Geometry class, which fills the geometry object's vertices and faces array
with values that form the shape of a sphere, taking m steps
in longitude (from 0 to 2π) and n steps in latitute (from -π/2 to π/2).
12 13 14 15
8 9 10 11
4 5 6 7
0 1 2 3
{
{ 0, 1, 5, 4}, { 1, 2, 6, 5}, { 2, 3, 7, 6},
{ 4, 5, 9, 8}, { 5, 6,10, 9}, { 6, 7,11,10},
{ 8, 9,13,12}, { 9,10,14,13}, {10,11,15,14},
};
0 <= θ <= 2π
-1 <= z <= 1
with the associated function:
f(θ,z) = ( cosθ , sinθ , z )
The end-cap in positive z can be parameterized by angle and radius:
0 <= θ <= 2π
0 <= r <= 1
with the associated function:
f(θ,z) = ( r cosθ , r sinθ , 1.0 )
The end-cap in negative z needs to circle around the other way,
so that the vertices of the resulting polygons will be
oriented counterclockwise
when seen from the outside of the cylinder:
f(θ,z) = ( r cos(-&theta); , r sin(-&theta); , -1.0 )
Perspective and animation hierarchy
We covered two topics on February 23:
Better animation hierarchy + Splines
Better animation hierarchy
public class Geometry
{
...
public Matrix getMatrix() { ... } // access to this geometry object's matrix
public void add(Geometry child) { ... } // add a child geometry object
public void remove(Geometry child) { ... } // remove a child geometry object
public int getNumChildren() { ... } // find out how many children there are
public Geometry getChild(int index) { ... } // get the ith child
...
}
The matrix of a Geometry object contains the object's
transformation relative to its parent object.
These structures allow the objects in your scene to form a hierarchical
tree.
You should make a special object called
world
,
which forms the root of this tree.
Your renderer will traverse the tree, starting at this root
world
object,
to find all the objects in your scene.
Ray tracing 1
In class on March 22
we started to talk about ray tracing,
but there is no assignment yet. Just finish
up the hierarchy/splines assignment for
Thursday, March 29.
Ray tracing 2
Notes (and homework) for the March 29 class about ray
tracing are here.
Ray tracing 3
Notes (and homework) for the April 5 class about ray
tracing are here.
Ray tracing 3
We went over the math for ray tracing very very carefully.
Z-buffers, part 1
The notes and assignment for this
week are here.
Z-buffers, part 2
The notes and assignment for
the second part of the z-buffer algorithm are
here.