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);
}