Introduction
Solutions for session 7.
Exercises
Source code for all solutions.
Exercise 1: projecting 3D coordinates onto a 2D plane
The equation of a line in 3D given two points p0 and p1 is:
p = p0 + t*(p1-p0)
with t being a real number. The intersection of this line with the plane z = d then equals:
x = ( (d - z0) / (z1 - z0) ) * (x1 - x0) + x0 y = ( (d - z0) / (z1 - z0) ) * (y1 - y0) + y0 z = ( (d - z0) / (z1 - z0) ) * (z1 - z0) + z0 = d
Scaling and translating to screen coordinates gives:
x = (int)( (( (x1-x0)*(d - z0))/(z1 - z0) + x0) * width + width/2); y = (int)( ((-(y1-y0)*(d - z0))/(z1 - z0) + y0) * height + height/2);
Negating the y-coordinate is necessary to mirror the figure along the Y-axis (on our Processing screen, the y-coordinates increase from the top, in our 3D world model it is the other way around). The point (x0,y0,z0) is considered the viewpoint. The projection is defined as follows:
// in Point3D class: Point3D project(Point3D eye, double zoom) { double newx = (x - eye.x)*(zoom - eye.z) / (z - eye.z) + eye.x; double newy = (y - eye.y)*(zoom - eye.z) / (z - eye.z) + eye.y; double newz = zoom; return new Point3D(newx,newy,newz); } // in Polygon class: void draw(Point3D eye, double zoom) { noFill(); beginShape(); for (int i=0; i < vertices.length; i++) { Point3D p = vertices[i].project(eye, zoom); int x = (int) ( p.x * width + width/2 ); int y = (int) ( -p.y * height + height/2 ); vertex(x,y); } endShape(CLOSE); }
Exercise 2: Perspective Projection of a cube
Cube construction:
Figure makeCube() { Point3D a = new Point3D(0,0,0); Point3D b = new Point3D(1,0,0); Point3D c = new Point3D(1,1,0); Point3D d = new Point3D(0,1,0); Point3D e = new Point3D(0,0,1); Point3D f = new Point3D(1,0,1); Point3D g = new Point3D(1,1,1); Point3D h = new Point3D(0,1,1); Polygon[] faces = new Polygon[6]; faces[0] = makeQuad(a,b,f,e); faces[1] = makeQuad(b,c,g,f); faces[2] = makeQuad(c,g,h,d); faces[3] = makeQuad(a,d,h,e); faces[4] = makeQuad(e,f,g,h); faces[5] = makeQuad(a,b,c,d); return new Figure(faces); }
Exercise 3: Rotation
Rotation of a 3D point with coordinates (x,y,z):
Point3D rotateX(double angle) { double cos = Math.cos(angle); double sin = Math.sin(angle); double nx = x; double ny = y * cos + z * sin; double nz = - y * sin + z * cos; return new Point3D(nx,ny,nz); } Point3D rotateY(double angle) { double cos = Math.cos(angle); double sin = Math.sin(angle); double nx = x * cos - z * sin; double ny = y; double nz = x * sin + z * cos; return new Point3D(nx,ny,nz); } Point3D rotateZ(double angle) { double cos = Math.cos(angle); double sin = Math.sin(angle); double nx = x * cos + y * sin; double ny = - x * sin + y * cos; double nz = z; return new Point3D(nx,ny,nz); }
Exercise 4: Perspective Projection of a tetrahedron
Tetrahedron construction:
Figure makeTetrahedron() { Point3D a = new Point3D(0,0,0); Point3D b = new Point3D(0,1,1); Point3D c = new Point3D(1,0,1); Point3D d = new Point3D(1,1,0); Polygon[] faces = new Polygon[4]; faces[0] = makeTriangle(a,b,c); faces[1] = makeTriangle(a,b,d); faces[2] = makeTriangle(b,c,d); faces[3] = makeTriangle(c,a,d); return new Figure(faces); }
Exercise 5: Scaling
public void zoomIn(double distance) { ZOOM += distance; EYE.z += distance; } public void zoomOut(double distance) { ZOOM -= distance; EYE.z -= distance; }
Exercise 6: Translation
Point3D translate(double xofs, double yofs, double zofs) { return new Point3D(x + xofs, y + yofs, z + zofs); }