In order to do this week's homework (due Tuesday Oct 2), the following notes from class should be useful.
Please note:
At the end of the lecture I was kind of rushing
to get through things,
and I ended up saying something that was just
plain wrong.
Sorry about that!
No, you don't put the line drawing routines inside the doubly nested loops. The line drawing part only comes later, when you do the frame-by-frame animation of your transformed shapes. So please just forget about that confusing bit at the end of the lecture, and use the following notes as your reference. :-) |
The basic idea is that you are going to create your shape objects just once, when your program starts, and then render them at each animation frame by transforming each shape and drawing the transformed shape as a set of lines.
You probably will want to create an Java class Shape, that contains a transformation matrix, a vertices[] array, and a faces[] array (see below).
Your Shape object will also contain
two temporary arrays int px[]
and
NOTES ON REPRESENTING 3D SHAPES WITH POLYGONS
A shape can be represented as an object that contains:
double vertices[NVERTICES][6]
int faces[NFACES][]
For each latitude n, where 0 < n <= N, the location of vertex m is given by:
θ = 2 * π * m / M φ = π * n / N - π/2 x = cos θ cos φ y = sin θ cos φ z = sin φNotice that to march through the vertex values, you're going to need double nested
for
loops in order to iterate through all your values of m
and all your values of n
.
The sphere shape will have M * N rectangular faces.
θ = 2 * π * m / M φ = 2 * π * n / N x = (a + b * cos θ) * cos φ y = (a + b * sin θ) * cos φ z = b sin φwhere a and b refer to the major and minor radius, respectively.
If we let angle theta take on each of the N values around a circle:
θ = 2π i / N , where i = 0, 1, 2, .... N-1then we can create the central tube with 2N vertices (each with x,y,z and normal nx,ny,nz), where the first N vertices are:
[cosθ, sinθ, -1, cosθ, sinθ, 0]and the last N vertices are:
[cosθ, sinθ, +1, cosθ, sinθ, 0]Each of the faces of this central tube will have four sides, so the
face[][]
array needs to consist of:
The front cap will contain N+1 vertices, including the added central point [0,0,1, 0,0,1], and its faces will consist of N triangles. The back cap will also contain N+1 vertices, including the added central point [0,0,-1, 0,0,-1], and its faces will also consist of N triangles. I leave it as an exercise for you to create these two end caps. When you've built the complete cylinder, you should have 4N+2 vertices and 3N faces.
0 1 N+1 N 1 2 N+2 N+1 ... ... ... ... N-2 N-1 2N-1 2N-2 N-1 0 N 2N-1
Because we need to separately store vertices that have different normals, there will be 24 vertices; one for each corner of each face of the cube. For example, the cube's four vertices on its leftmost face (the face that points into negative x), are:
Notice that I have ordered these four vertices in counterclockwise order, if you are looking at this face of the cube from the outside. I leave it to you to create the vertices for the other five faces of the cube.
-1 -1 -1 -1 0 0 -1 -1 +1 -1 0 0 -1 +1 +1 -1 0 0 -1 +1 -1 -1 0 0
The face data for the cube is rather simple, as we discussed in class:
TRANSFORMING AND RENDERING SHAPES
0 1 2 3 4 5 6 7 ... ... ... ... 20 21 22 23
At every animation frame, for each shape in your scene you'll want to:
java.awt.Graphics
method
drawLine
between
the (px,py) that corresponds to
successive vertices in that face.
In your Shape object
you might want to maintain two arrays
int px[NV]
and
int py[NV]
into which you
can place your transformed and projected vertex data every frame.
How do I project my transformed vertex (x,y,z) onto a pixel (px,py)?
If we were using a real camera with perspective, you'd do something fancier, but for now I'd like you to do something simpler. Suppose your applet window is W pixels wide and H pixels high.
Then all you need to do is:
px = (int)(W/2 + x*W/2); py = (int)(H/2 - y*W/2);The above operations will ensure that your object will be centered at the middle of the image, and will be about the right size to fit in the image. If you find that your object is turning out really huge, so it's hard to see it in the applet image, then try scaling everything down by using your matrix scale operation.