Perspective
<< Astronomy | FinalProjectsTrailIndex | CanyonAnimation >>
Fr Chris explanation of Rotation and Perspective
Point3D.javapublic class Point3D {
public static final double screenDistance=150.0;
private double x;
private double y;
private double z;
public Point3D(double x0, double y0, double z0){
x=x0;
y=y0;
z=z0;
}
public Point3D(int x0, int y0, int z0){
x=x0;
y=y0;
z=z0;
}
// see http://www.mathorama.com/geom/lessons/stereo2.html
// or http://en.wikipedia.org/wiki/3D_projection#Perspective_projection
public int viewX(Point3D viewpoint){
double depth= this.z-viewpoint.getZ();//D+E
double width=this.x-viewpoint.getX();//w analogous to h
int ox= (int)Math.round(width*screenDistance/depth); //coord where eye is at (0,0)
return (int)viewpoint.getX()+ox;
}
public int viewY(Point3D viewpoint){
double depth= this.z-viewpoint.getZ();//D+E
double height=this.y-viewpoint.getY();//h
int oy= (int)Math.round(height*screenDistance/depth);
return (int)viewpoint.getY()+oy;
}
public double getX(){return x;}
public double getY(){return y;}
public double getZ(){return z;}
public void setX(double value){ this.x=value;}
public void setY(double value){ this.y=value;}
public void setZ(double value){ this.z=value;}
}
Cube.javaimport java.awt.Color;
import java.awt.Graphics;
public class Cube {
private Point3D v[];//vertices
private Color color;
public Cube(Point3D topFrontLeftCorner, double size, Color c){
this.color=c;
v=new Point3D[8];
v[0]=topFrontLeftCorner;
v[1]=new Point3D(topFrontLeftCorner.getX()+size,topFrontLeftCorner.getY(),topFrontLeftCorner.getZ());
v[2]=new Point3D(topFrontLeftCorner.getX()+size,topFrontLeftCorner.getY()+size,topFrontLeftCorner.getZ());
v[3]=new Point3D(topFrontLeftCorner.getX(),topFrontLeftCorner.getY()+size,topFrontLeftCorner.getZ());
v[4]=new Point3D(topFrontLeftCorner.getX(),topFrontLeftCorner.getY(),topFrontLeftCorner.getZ()+size);
v[5]=new Point3D(topFrontLeftCorner.getX()+size,topFrontLeftCorner.getY(),topFrontLeftCorner.getZ()+size);
v[6]=new Point3D(topFrontLeftCorner.getX()+size,topFrontLeftCorner.getY()+size,topFrontLeftCorner.getZ()+size);
v[7]=new Point3D(topFrontLeftCorner.getX(),topFrontLeftCorner.getY()+size,topFrontLeftCorner.getZ()+size);
}
/**
*
* @param g the Graphics object to draw on
* @param v the viewpoint
*/
public void draw(Graphics g, Point3D vp){
Color oldColor=g.getColor();
g.setColor(color);
connect(g,vp,0,1);
connect(g,vp,1,2);
connect(g,vp,2,3);
connect(g,vp,3,0);
connect(g,vp,4,5);
connect(g,vp,5,6);
connect(g,vp,6,7);
connect(g,vp,7,4);
connect(g,vp,0,4);
connect(g,vp,0,4);
connect(g,vp,1,5);
connect(g,vp,2,6);
connect(g,vp,3,7);
g.setColor(oldColor);
}
public void connect(Graphics g, Point3D vp, int a, int b){
g.drawLine((v[a]).viewX(vp) , v[a].viewY(vp),v[b].viewX(vp) , v[b].viewY(vp) );
}
}
CubeViewer.javaimport java.applet.Applet;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
/**
* Demonstrates an 3D Object like a cube
* and makes a "First-person" point-of view
* using the arrow keys to move up and down, left and right
* @author Chris Thiel, OFMCap
* size of applet should be 800 x 600
*/
@SuppressWarnings("serial")
public class CubeViewer extends Applet implements KeyListener
{
public static double amount=10.0; //amount of change each arrow will change
Point3D view;
Cube cube;
public void init(){
view=new Point3D(400,300,0);
cube=new Cube(new Point3D(300,200,100), 200.0, Color.BLUE);
this.addKeyListener(this);
}
public void paint(Graphics g){
String vx="x = "+view.getX();
String vy="y = "+view.getY();
String vz="z = "+view.getZ();
g.drawString(vx, 20, 20);
g.drawString(vy, 20, 35);
g.drawString(vz, 20, 50);
g.drawString("Click Screen for focus. Use Arrows to view left and right, a to go forward, z to go back", 20, 580);
cube.draw(g, view);
}
@Override
public void keyPressed(KeyEvent e) {
int keyCode=e.getKeyCode();
if(keyCode==38){ //up
view.setY(view.getY()+amount);
} else if (keyCode==40){ //down
view.setY(view.getY()-amount);
} else if (keyCode==37){ //left
view.setX(view.getX()-amount);
} else if (keyCode==39){ //right
view.setX(view.getX()+amount);
}else if (keyCode==65){ //forward
view.setZ(view.getZ()+amount);
}else if (keyCode==90){ //back
view.setZ(view.getZ()-amount);
}
repaint();
}
@Override
public void keyReleased(KeyEvent e) {}
@Override
public void keyTyped(KeyEvent e) {}
}
Explorations
- What happens when you go past the cube? Can you change this so you don't draw the cub if it is behind your point of view?
- Change the screenDistance--what effect does this have?
- Change the box's size and/or location.
- Add a red box in a different location
- Make an Object that is different from a cube like a Letter or a Table
- Draw the Cube differently. Rather than drawing the "wireframe" use g.fillPolygon (draw the furthest face first
- Add a rotation transform so you aren't always looking ahead