import java.awt.*;
import java.lang.*;
import java.awt.event.*;
import java.io.*;
import java.util.*;
class myOtherCanvas extends Canvas {
String fname = "";
//filename
private double wlims[] = new double[4];
//world limits
private int slims[]= {0,500,0,500}; //screen limits
private int rot[] = {-70,30,0}; //rotate textfields defaults
private double trans[] = {0.0,0.0,0.0}; //translate textfields defaults
private PipeLine pipe;
Vector v; //vector containing lines of file (sort of)
int numLines = 0;
public void load (String s){ //get data for vector
fname = s;
FileInputStream strm=null;
if (!fname.equals("")){
//read in the file
try{
strm = new FileInputStream(fname);
}
catch (IOException e){
System.out.println("File "+fname+" not found.");
}
InputStreamReader strR=new InputStreamReader(strm);
BufferedReader buf = new BufferedReader(strR);
StreamTokenizer rt=new StreamTokenizer(buf);
try{
rt.nextToken();
numLines=(int)rt.nval;
v = new Vector(numLines); //Vector needs to be as long as the file
for(int i=0;i<4;i++){
rt.nextToken();
wlims[i]=rt.nval;
}
pipe=new PipeLine(wlims,slims);
for(int i=0;i<numLines;i++){
Vector temp = new Vector(6); //temporary vector that gets changed each time
rt.nextToken();
temp.insertElementAt(Double.valueOf(Double.toString(rt.nval)),0);
rt.nextToken();
temp.insertElementAt(Double.valueOf(Double.toString(rt.nval)),1);
rt.nextToken();
temp.insertElementAt(Double.valueOf(Double.toString(rt.nval)),2);
rt.nextToken();
temp.insertElementAt(Double.valueOf(Double.toString(rt.nval)),3);
rt.nextToken();
temp.insertElementAt(Double.valueOf(Double.toString(rt.nval)),4);
rt.nextToken();
temp.insertElementAt(Double.valueOf(Double.toString(rt.nval)),5);
v.insertElementAt(temp,i); //vector v is a vector of smaller vectors
}
}
catch (IOException e){
System.out.println("Error reading file "+fname);
}
//System.out.println("done");
}
}
public void paintme (Graphics g,Color c) { //converts points, draws lines
if (fname != "") {
for (int i =0; i<numLines; i++) {
Vector temp = (Vector)v.elementAt(i);
double point3d[] = new double [3];
double wc1[] = new double[2];
double wc2[] = new double[2];
int sc1[]=new int[2];
int sc2[]=new int[2];
point3d[0] = ((Double)(temp.elementAt(0))).doubleValue();
point3d[1] = ((Double)(temp.elementAt(1))).doubleValue();
point3d[2] = ((Double)(temp.elementAt(2))).doubleValue();
ThreeDto2D(point3d,wc1,rot,trans);
//convert to 2D
point3d[0] = ((Double)(temp.elementAt(3))).doubleValue();
point3d[1] = ((Double)(temp.elementAt(4))).doubleValue();
point3d[2] = ((Double)(temp.elementAt(5))).doubleValue();
ThreeDto2D(point3d,wc2,rot,trans); //convert to 2D again
pipe.WCtoSC(wc1,sc1);
//convert to screen coordinates
pipe.WCtoSC(wc2,sc2);
g.setColor(c);
g.drawLine(sc1[0],sc1[1],sc2[0],sc2[1]); //now draw the line
}
}
}
public void ThreeDto2D(double T[],double W[],int R[],double Tr[]){ //converts 3D points to 2D points
rotateX(T,R[0]); rotateY(T,R[1]); rotateZ(T,R[2]);
translate(T,Tr);
persp(T,8-Tr[2]);
W[0]=T[0];
W[1]=T[1];
}
public void rotateZ(double T[],int deg){
//rotate around Z
double t=3.14159/180.0*deg;
double hold;
hold=(T[0]*Math.cos(t)-T[1]*Math.sin(t));
T[1]=(T[0]*Math.sin(t)+T[1]*Math.cos(t));
T[0]=hold;
}
public void rotateX(double T[ ],int deg){
//rotate around X
double t=3.14159/180.0*deg;
double hold;
hold=(T[1]*Math.cos(t)-T[2]*Math.sin(t));
T[2]=(T[1]*Math.sin(t)+T[2]*Math.cos(t));
T[1]=hold;
}
public void rotateY(double T[ ],int deg){
//rotate around Y
double t=3.14159/180.0*deg;
double hold;
hold=(T[0]*Math.cos(t)-T[2]*Math.sin(t));
T[2]=(T[0]*Math.sin(t)+T[2]*Math.cos(t));
T[0]=hold;
}
public void translate(double T[],double Tr[]){
//translates points
T[0]+=Tr[0];
T[1]+=Tr[1];
T[2]+=Tr[2];
}
public void persp(double T[],double r){
//perspective (eye)
if (r<=0) r=1; //cannot see something too far away
T[0]=T[0]/(1.0+1.0/r);
T[1]=T[1]/(1.0+1.0/r);
T[2]=1.0;
}
public void draw(Color c){ //draws the objects--calls paintme
if(fname.equals("")) System.out.println("You must LOAD the file before drawing.");
Graphics g = getGraphics();
paintme(g,c);
}
public void setRot (int x, int y, int z) { //sets rotation array
rot[0]=x;
rot[1]=y;
rot[2]=z;
}
public void setTrans (double x, double y, double z) { //sets translation array
trans[0]=x;
trans[1]=y;
trans[2]=z;
}
public int animateUp (int x, int y, int z) { // increment x +
if(x>=360)
x-=360;
x+=10;
setRot(x,y,z);
return x;
}
public int animateDown (int x, int y, int z) { // increment x -
if(x<=0)
x+=360;
x-=10;
setRot(x,y,z);
return x;
}
public int animateRight (int x, int y, int z) { // increment y +
if(y>=360)
y-=360;
y+=10;
setRot(x,y,z);
return y;
}
public int animateLeft (int x, int y, int z) { //increment y -
if(y<=0)
y+=360;
y-=10;
setRot(x,y,z);
return y;
}
}
public class drawer extends Frame implements ActionListener, Runnable {
Panel top = new Panel();
Panel bottom = new Panel();
Panel eastside = new Panel();
Panel eastside1 = new Panel(); Panel eastside2 = new Panel();
Panel eastside3 = new Panel(); Panel eastside4 = new Panel();
Panel eastside5 = new Panel(); Panel eastside6 = new Panel();
Panel eastside7 = new Panel(); Panel eastside8 = new Panel();
Panel eastside9 = new Panel(); Panel eastside10 = new Panel();
Panel eastside11 = new Panel(); Panel eastside12 = new Panel();
Label filePrompt = new Label("Enter Filename");
Label rotX = new Label("Rotate x: ");
Label rotY = new Label("Rotate y: ");
Label rotZ = new Label("Rotate z: ");
Label transX = new Label("Translate x: ");
Label transY = new Label("Translate y: ");
Label transZ = new Label("Translate z: ");
Label dummy = new Label(" ");
TextField fileName= new TextField("",15);
TextField rotaX = new TextField("-70",5);
TextField rotaY = new TextField("30",5);
TextField rotaZ = new TextField("0",5);
TextField translX = new TextField("0",5);
TextField translY = new TextField("0",5);
TextField translZ = new TextField("0",5);
Button starter = new Button("Draw");
Button endit = new Button("Exit");
Button load = new Button("Load");
Button rotate = new Button("Rotate");
Button translate = new Button("Translate");
Button up = new Button("/\\");
Button down = new Button("\\/");
Button left = new Button("<-");
Button right = new Button("->");
Button stopspin = new Button("Stop");
Button clear = new Button("Clear");
myOtherCanvas c = new myOtherCanvas();
Thread tup = new Thread(this);
Thread tdown = new Thread(this);
Thread tright = new Thread(this);
Thread tleft = new Thread(this);
boolean suspend=false, firstup=true, firstdown=true, firstright=true, firstleft=true;
int xx=0, yy=0, zz=0;
//all this stuff is used to set up the screen (GUI)
public drawer(){
//this sets up the screen
top.add(filePrompt);
top.add(fileName);
top.add(load); top.add(starter);
starter.addActionListener(this);
load.addActionListener(this);
setLayout(new BorderLayout());
c.setBackground(Color.white);
endit.addActionListener(this);
clear.addActionListener(this);
add("North",top);
add("Center",c);
bottom.add(endit); bottom.add(clear);
add("South",bottom);
eastside.setLayout(new GridLayout(12,1));
eastside.add(eastside1); eastside.add(eastside2);
eastside.add(eastside3); eastside.add(eastside4);
eastside.add(eastside5); eastside.add(eastside6);
eastside.add(eastside7); eastside.add(eastside8);
eastside.add(eastside9); eastside.add(eastside10);
eastside.add(eastside11); eastside.add(eastside12);
eastside1.add(rotX); eastside1.add(rotaX);
eastside2.add(rotY); eastside2.add(rotaY);
eastside3.add(rotZ); eastside3.add(rotaZ);
eastside4.add(rotate); eastside5.add(transX);
eastside5.add(translX); eastside6.add(transY);
eastside6.add(translY); eastside7.add(transZ);
eastside7.add(translZ); eastside8.add(translate);
eastside9.add(up); eastside10.add(left);
eastside10.add(dummy); eastside10.add(right);
eastside11.add(down); eastside12.add(stopspin);
translate.addActionListener(this); rotate.addActionListener(this);
up.addActionListener(this); down.addActionListener(this);
left.addActionListener(this); right.addActionListener(this);
stopspin.addActionListener(this);
add("East",eastside);
}
public void actionPerformed(ActionEvent e){
// button clicks
Object source = e.getSource();
String s=fileName.getText();
if (source==endit){
//exit button
System.exit(0);
}
if (source==rotate) { //rotate button
c.draw(Color.white);
int x = Integer.parseInt(rotaX.getText());
int y = Integer.parseInt(rotaY.getText());
int z = Integer.parseInt(rotaZ.getText());
c.setRot(x,y,z);
c.draw(Color.blue);
}
if (source==translate) { //translate button
c.draw(Color.white);
double x2 = Double.valueOf(translX.getText()).doubleValue();
double y2 = Double.valueOf(translY.getText()).doubleValue();
double z2 = Double.valueOf(translZ.getText()).doubleValue();
c.setTrans(x2,y2,z2);
c.draw(Color.blue);
}
if (source==up) { //animate up button
c.draw(Color.white);
suspend=false;
if(firstup) { // if its the first time through start the thread
tup.start();
firstup=false;
}
else tup.resume(); // otherwise resume action
}
if (source==down) { //animate down button
c.draw(Color.white);
suspend=false;
if(firstdown) {
tdown.start();
firstdown=false;
}
else tdown.resume();
}
if (source==left) { //animate left button
c.draw(Color.white);
suspend=false;
if(firstleft) {
tleft.start();
firstleft=false;
}
else tleft.resume();
}
if (source==right) { //animate right button
c.draw(Color.white);
suspend=false;
if(firstright) {
tright.start();
firstright=false;
}
else tright.resume();
}
if (source==stopspin) { //stop animating
tup.suspend(); tdown.suspend();
tright.suspend(); tleft.suspend();
suspend=true;
c.draw(Color.red);
}
if (source == starter) { //draw button
xx = Integer.parseInt(rotaX.getText());
yy = Integer.parseInt(rotaY.getText());
zz = Integer.parseInt(rotaZ.getText());
c.setRot(xx,yy,zz);
double x3 = Double.valueOf(translX.getText()).doubleValue();
double y3 = Double.valueOf(translY.getText()).doubleValue();
double z3 = Double.valueOf(translZ.getText()).doubleValue();
c.setTrans(x3,y3,z3);
c.draw(Color.blue);
}
if (source == clear) { //clear button
c.draw(Color.white);
fileName.setText("");
c.load("");
rotaX.setText("-70");
rotaY.setText("30");
rotaZ.setText("0");
translX.setText("0");
translY.setText("0");
translZ.setText("0");
}
if (source == load) { //load button--must be pressed before draw
if (!s.equals("")){
c.draw(Color.white);
//System.out.println("drawing "+s);
c.draw(Color.blue);
}
c.load(s);
}
}
public void run() { // controls actions of threads
while (true) { //animate rotations
c.draw(Color.blue);
try { Thread.sleep(100); } // pause for 100 ms
catch(InterruptedException e) {}
xx = Integer.parseInt(rotaX.getText());
yy = Integer.parseInt(rotaY.getText());
zz = Integer.parseInt(rotaZ.getText());
Thread et = Thread.currentThread();
c.draw(Color.white);
if (et==tup)
xx=c.animateUp(xx,yy,zz);
else if (et==tdown)
xx=c.animateDown(xx,yy,zz);
else if (et==tleft)
yy=c.animateLeft(xx,yy,zz);
else if (et==tright)
yy=c.animateRight(xx,yy,zz);
c.draw(Color.blue);
rotaX.setText(String.valueOf(xx));
rotaY.setText(String.valueOf(yy));
rotaZ.setText(String.valueOf(zz));
if (suspend) // if stop is clicked
break;
}
}
public static void main(String args[]){
Frame f=new drawer();
f.setSize(700,700);
f.setTitle("3D Drawing Program!");
f.show();
}
}
[ October 05, 2003: Message edited by: Jean Paul Martin ]