Emma (hearthand) wrote in algorithms,

Computer Graphics - Java

Some backstory for those willing to kindly help me interpret the below java code.

The class is Computer Graphics. What we did in the class was to basically reinvent the wheel; well, the java Graphics2D and Graphics3D API (except... badly) In our projects we managed to master (dun dun DUN!) 3D cubes and viewpoints, hidden surfaces, shaded surfaces and hidden line removal (ta da!) and an insane amount of inheritance. For this question we have to discuss how we might represent a class to represent a cylinder using flat surfaces (where Surface3D inherits from many simple classes: Drawing3D, Line3D to Point3D) to approximate to the figure. 

So far I have established that the paramaters used to specify the cylinder will be: center point, diameter, length and position. An ArrayList data structure will be appropriate for the cylinder and how I will do the class in English. I had a look at the sample answer and I found some java code which I've since been puzzling over because I'm not 100% sure what on earth it's doing.

double cylinder_length = 4; will allow us to specify the length of the cylinder, the length between the two symetrical circles on the axis
double oldx = 1; old x and y co-ordinates that can be saved so we do calculations on previous co-ordinates not the first co-ords.
double oldy = 0;
int n = 32; the set number of points I want around the circle, can be increased to create a smoother surface.

 for (int i = n; i>=0; i--){

double theta = (double)(((double)i/n)*Math.PI *2); 
double x = (double)Math.cos (theta); 
double y = (double)Math.sin (theta); 

Surface3D temp = new Surface3D(); this is us creating a new surface of type surface3D. The "base surface"
cylinder.addGItem(temp);  hierarchy crap that I don't understand but know to do
temp.addPoint(oldx,oldy,0); we are adding the old x, y (0 on the z-axis because the cylinder will start on the xy corords, we aren't rotating it around z) to the circle... making the circle?
temp.addPoint(x,y,0); now adding the next points x and y on the circle calculated above ^
temp.addPoint(x,y,cylinder_length); adding the points x and y identically to the second circle down the z-axis (toward us or away from us depending on the view point)
temp.addPoint(oldx,oldy,cylinder_length); adding the second point on the z-axis that reflects the old xy and y coords
oldx = x; sex new co-ordinates x and y to the old so the new calulations can be done on the new co-ords not the first
oldy = y;

}//for i

Surface3D cylinder_front = new Surface3D(); defining the front of the cylinder that will be able to be seen as a new surface
Surface3D cylinder_back = new Surface3D(); same to the back that should be invisible
cylinder.addGItem(cylinder_front); adding both front and back to cylinder


* which is all fine and well... but then...eh?

for (int i = n; i>=0; i--){

double theta = (double)(((double)i/n)*Math.PI *2);
double x = (double)Math.cos (theta);
double y = (double)Math.sin (theta);

System.out.println("theta: " +theta + ", x:"+x+", y:"+y); just printing the values of theta, x and y

cylinder_front.addPoint(x,y,0); I have no idea why we're doing this.... connecting the back co-ords to the front, perhaps? to create the cylinder?

oldx = x;
oldy = y;

}//for i

I'm not sure if I'm understanding it correctly or not and I'm quite inexperienced in understanding code by others mainly because I doubt that I'll get it or not.

Thanks in advance for reading!
  • Post a new comment


    Anonymous comments are disabled in this journal

    default userpic

    Your reply will be screened

    Your IP address will be recorded 

  • 1 comment
"double theta = (double)(((double)i/n)*Math.PI *2);
double x = (double)Math.cos (theta);
double y = (double)Math.sin (theta); "

This is literally calculating 2 points x and y representing a point on the circle circumference in 2D - you can visualise that as looking down on a 3D shape from the top so nothing else is visible.

The centre of the shape is 0,0 with x and y both going from -1 to +1.

(I guess you knew that bit)

"Surface3D temp = new Surface3D(); "

for the purpose of this I am going to assume some stuff as I haven't looked up the Java API but think of it as a 2D peice of canvas that you can place in 3D space and manipulate, 32 peices of this canvas make up a big part of the whole cylinder each connected until they form a complete circle in 3D.

This is done using the following code


Assuming cylinder is the object representing the entire cylinder shape we are adding each of the 32 pieces of canvas (the 3D surface object) on each iteration of the loop.

The canvas has 4 points, it has been bent in this case like a rectangle on a slight curve in 3D, the four points that are added are the top left, top right, bottom left, bottom right (very simply), this is called a quad in 3D geometry programming and is a good way to construct shapes (known as meshes).

The quad runs from the top (z=0) to the bottom (z=4). After drawing each quad on the rectangular canvas, that is bent slightly in 3D you can visualise a single quad as a thin strip running from the top to the bottom of the cylinder with a width of 11.25 degrees of the 360 degrees needed to do the curved side of a cylinder.

After each iteration the starting 2 points for the next segment is moved to the ending 2 points of the next segment (represented by Surface3D and visualised as an 11 degree strip)

So strip one { {z=0 cm, xy=0 degrees around the circumference},{z=0, xy=11 degrees around the circumference},{z=4 cm, xy=11},{z=4, xy=11 degrees}

" oldx = x;
oldy = y; "

The next strip starts at 11 degrees and does the same but drawing from 11 to 22 degrees around the circumference and so on.

" Surface3D cylinder_front = new Surface3D();
Surface3D cylinder_back = new Surface3D();
cylinder.addGItem(cylinder_front); adding both front and back to cylinder
cylinder.addGItem(cylinder_back); "

This is creating 2 new 'canvases', called formally surfaces that will be part of the cylinder (using addGItem). we have created the circumference with a length of 4 but have to end caps for the cylinder, so now we've created a canvas to place in 3D space we can go through the next peice of code.

In the next loop the following loops through 32 steps again, calculating 32 points on the circumference of a circle as before, going from -1 to +1 in the x and y directions.

These are calculated the same as before

"double theta = (double)(((double)i/n)*Math.PI *2);
double x = (double)Math.cos (theta);
double y = (double)Math.sin (theta); "

So we have a can of food with no lid and bottom, with the circumference made from 32 strips of canvas, each held in place at 4 corners at the top of the can z=0 and the bottom of the can z=4, each strip is approx 11 degrees wide.

As we visualised before the centre of the can on the x and y axis is x=0, y=0, the top of the can is x=0,y=0,z=0 the bottom of the can is x=0,y=0,z=4

" cylinder_front.addPoint(x,y,0);
cylinder_back.addPoint(x,y,cylinder_length); "

TO create the caps we are creating triangles this time instead of quads (and all 32 triangles will be on the same canvas (surface) not on 32 unique surfaces.

The loop incrementally draws triangles for each quad on the circumference connecting the centre point of the can to the 2 points at the top of the quad, it also does this for the bottom of the can.

In 3D these are called indices, and from these you can create triangles which you can render visually.

Hope this helps and is not stating the obvious.