Computer Graphics

Lab Exercise 5: Parallel Projection

This week we construct a class for the simplest kind of projection: orthographic parallel projection. This is the kind of projection used in engineering drawings, to produce "plan views". The projection is as follows: Given a point (x,y,z) the projection of that point is (x,y). (Alternatively, one could map to (x,z) or (y,z) depending on what kind of plan view is required).

In 3d computer graphics, the projection process (without clipping) from 3d points to 2d pixels on screen is usually divided into three parts:

In a simple orthographic parallel projection, the world and camera coordinates are the same, so the first two transformations are trivial.

The values aX, bX, aY, bY are used in viewport transformation. In other words, if (x,y) is a point on the view plane, and (x',y') the corresponding point on the screen, then x' = aX + bX*x, and y' = aY + bY*y. These values are defined exactly as in the notes on 2D viewing below.

Your program will be assessed as part of your coursework (10%).

Here is an example of the parallel camera.

Camera.java
 
public class Camera
{
  public Vector3D getVPN(){/*return a vector that points towards the viewer. Used for face orientation*/}
 
  protected Point3D cameraTransform(final Point3D p){}
 
  protected Point3D projectionTransform(final Point3D p){} 
 
  private final Point3D viewportTransform(final Point3D p){}
 
  public final Point3D project(final Point3D p){
    Point3D temp=cameraTransform(p);
    temp=projectionTransform(temp);
    return viewportTransform(temp);
  }
 
  public Camera(double xmin_, double xmax_, double ymin_, double ymax_){}
 
  public void setViewport(int width, int height){/*calculate ax, bx, ay, by*/}
 
  public String toString(){/* Make it look nice to save your debugging time! */}
 
  private double xmin, xmax, ymin, ymax;
  private double fcp, bcp;  //NOT USED: front & back clippling planes
  private double ax, bx, ay, by;
}
Scene.java

Back face elimination is required before drawing polygons. See Lab 3 for how to accomplish this.

 
public void draw(Camera c, Graphics g){}

A sample test class derived from Animator is supplied to you.

ParallelAnimator.java
 
import java.awt.*;
import javax.swing.*;
import static java.lang.Math.*;
 
public class ParallelAnimator extends Animator
{
  private static final String[] files={"./cube.dat","./pyramid.dat"};
  public ParallelAnimator()
  {
    super();
 
    scene=new Scene(files);
    setupCamera();
  }
 
  protected void setupCamera()
  {
    camera= new Camera(-5,5,-5,5);
  }
 
  protected void animate(Graphics g)
  {
    camera.setViewport(getWidth(),getHeight());
 
    if(g==null || scene==null || camera==null)
      return;
 
    Matrix mX=new Matrix(), mY=new Matrix(), mZ=new Matrix();
    mX.setRotationX(-PI/11);
    mY.setRotationY(PI/13);
    mZ.setRotationZ(PI/17); 
    scene.transform(mZ.multiply(mY.multiply(mX))); 
 
    scene.draw(camera,g);
  }
 
  public static void main(String[] args) 
  {
    new ParallelAnimator().loop();
  }
 
  private Scene scene;
  protected Camera camera;
}

Brief Note on 2D Viewing Transformation

Let [Xmin, Xmax, Ymin, Ymax] denote a 2D window and [Umin, Umax, Vmin, Vmax] the corresponding viewport.

Suppose (x,y) is a point in the window, and (u, v) is the corresponding point in the viewport. Then,

u = Umin + (dU/dX) *(x - Xmin)
v = Vmin + (dV/dY) *(y - Ymin)

where,

dX = Xmax - Xmin, dY = Ymax - Ymin, and similarly for dU and dV.

Note that these formulae can be expressed in the form:

u = aX + bX*x and v = aY + bY*y, for constants aX, bX, aY, bY:

bX = dU/dX; aX = Umin - bX*Xmin;
bY = dV/dY; aY = Vmin - bY*Ymin;

Note that when implementing this for X11 window, provided that the viewport is the same size as the X11 window, it is not necessary for us to do 2D clipping - since the server will always clip to the boundaries of the X11 window.