import java.applet.*;
import java.awt.*;
import java.awt.geom.*;
import java.awt.event.*;
public class CakeMan extends Applet implements Runnable, KeyListener
{
class myMouse extends MouseAdapter implements MouseMotionListener
{
boolean pressed = false;
int x=0, y=0;
public void mousePressed(MouseEvent e)
{
x = e.getX();
y = e.getY();
pressed = true;
runner = null;
}
public void mouseReleased(MouseEvent e)
{
pressed = false;
start();
}
public void mouseDragged(MouseEvent e)
{
if(pressed)
{
xAngel += x - e.getX();
yAngel += y - e.getY();
x = e.getX();
y = e.getY();
repaint();
}
}
public void mouseMoved(MouseEvent e) {}
}
public void init()
{
new SinCosTabel();
setSize(width, height);
i = createImage(width, height);
addMouseListener(mm);
addMouseMotionListener(mm);
halfWidth = width/2;
halfHeight = height/2;
for(int i = 0; i < vertexes.length; i++)
{
for(int j = 0; j < vertexes[i].length; j++)
vertexes[i][j] *= scale;
}
addKeyListener(this);
}
public void start()
{
runner = new Thread(this);
runner.start();
}
public void stop()
{
if(runner != null)
{
runner.interrupt();
runner = null;
}
}
public void keyTyped(java.awt.event.KeyEvent evt) {}
int saveN = 0;
public void keyPressed(java.awt.event.KeyEvent evt)
{ System.out.println(evt.getKeyCode());
switch(evt.getKeyCode())
{
case 82: rotate = !rotate; break;
case 70: fly = !fly; break;
case 90: if(!zoom) n = saveN; else saveN = n; zoom = !zoom; break;
case 67: clear = !clear; break;
case 83: scroll = !scroll; break;
}
}
public void keyReleased(java.awt.event.KeyEvent evt) {}
static int width = 400;
static int height = 400;
int halfWidth = 100;
int halfHeight = 100;
int dist = 10;
int scale = 10;
int n = 0;
myMouse mm = new myMouse();
Image i = null;
static int FACTOR =200;
Thread runner = null;
Color backgroundColor = Color.white;
boolean fly = false;
boolean rotate = true;
boolean zoom = false;
boolean clear = true;
boolean scroll = false;
float vertexes[][] = { {-4, 4, dist}, {4, 4, dist}, {4, -4, dist}, { -4, -4, dist}, //Body
{-3, -4, dist}, {-3, -9, dist}, {-1, -9, dist}, {-1, -4, dist},//Leg
{3, -4, dist}, {3, -9, dist}, {1, -9, dist}, {1, -4, dist}, //Leg
{-2, 4, dist}, {-2, 7, dist}, {2, 7, dist}, {2, 4, dist}, //Head.
{-4, 4, dist}, {-8, 0, dist}, {-6, -2, dist}, {-4, 2, dist}, //arm
{4,4, dist}, {8, 0, dist}, {6, -2, dist}, {4, 2, dist}, //arm
{-1,6,dist}, {-1.5F, 6, dist}, {-1.5F, 6.5F,dist}, {-1, 6.5F,dist},//ųje
{1,6,dist}, {1.5F, 6, dist}, {1.5F, 6.5F,dist}, {1, 6.5F,dist},
{1.5F, 5,dist},{0,5,dist},{-1.5F,5,dist}, {0,4.5F, dist}, //mund
{-0.3F,5.5F,dist}, {-0.3F,6,dist},{0.3F,6,dist}, {0.3F,5.5F,dist},
};
float convertedVertexes[][] = new float[vertexes.length][3];
int shapes[][] = { {0, 1, 2, 3}, { 4, 5, 6, 7}, {8,9,10,11}, { 12, 13,14,15}, {16,17,18,19}, {20,21,22,23},
{24,25,26,27}, {28,29,30,31}, { 32, 33,34,35},{36,37,38,39} };
Color shapesColors[] = { Color.blue, Color.green, Color.green, Color.yellow, Color.red, Color.red, Color.blue,Color.blue,Color.red,Color.green};
int zAngel=0, yAngel=0, xAngel=0;
public void run()
{
mm.pressed = false;
while(!runner.interrupted() && !mm.pressed)
{
if(zoom)
{
if((n/50)%2 == 0)
dist++;
else
dist--;
changeDistance(dist);
}
n++;
if(rotate)
{
if((n/100)%2 == 0)
{ xAngel++;
zAngel++;
}
else
{ yAngel++;
zAngel++;
}
}
repaint();
try{ runner.sleep(10); }catch(InterruptedException e) {}
}
}
void changeDistance(int distance)
{
if(!fly)
distance *= scale;
for(int i = 0; i < vertexes.length; i++)
vertexes[i][2] = distance;
}
void rotate(int nr)
{
float x = vertexes[nr][0];
float y = vertexes[nr][1];
float z = vertexes[nr][2]-(dist*scale);
float newX = (float)(vertexes[nr][0] * SinCosTabel.cos[zAngel] - y * SinCosTabel.sin[zAngel]);
float newY = (float)(x * SinCosTabel.sin[zAngel] + y * SinCosTabel.cos[zAngel]);
convertedVertexes[nr][0] = (float)(newX * SinCosTabel.cos[yAngel] - z * SinCosTabel.sin[yAngel]);
float newZ = (float)(newX * SinCosTabel.sin[yAngel] + z * SinCosTabel.cos[yAngel]);
convertedVertexes[nr][1] = (float)(newY * SinCosTabel.cos[xAngel] - newZ * SinCosTabel.sin[xAngel]);
convertedVertexes[nr][2] = (float)(newY * SinCosTabel.sin[xAngel] + newZ * SinCosTabel.cos[xAngel]);
convertedVertexes[nr][2] += scale*dist;
}
public void update(Graphics g)
{
Graphics2D g2D = (Graphics2D)i.getGraphics();
if(clear)
{
g2D.setColor(backgroundColor);
g2D.clearRect(0, 0, width, height);
}
if(scroll)
{
g2D.copyArea(0, 1, width, height-1, 0,-1);
}
if(yAngel>=360) yAngel=0;
if(zAngel>=360) zAngel=0;
if(xAngel>=360) xAngel=0;
if(yAngel< 0) yAngel = 359;
if(zAngel < 0) zAngel = 359;
if(xAngel <0) xAngel = 359;
for(int i = 0; i < vertexes.length; i++)
{
rotate(i);
//Next convert the 3D point to a 2D point.
if(convertedVertexes[i][2] != 0)
{
convertedVertexes[i][0] = FACTOR * convertedVertexes[i][0]/ convertedVertexes[i][2];
convertedVertexes[i][1] = FACTOR * convertedVertexes[i][1]/ convertedVertexes[i][2];
}
else
{
convertedVertexes[i][0] =FACTOR * convertedVertexes[i][0];
convertedVertexes[i][1] = FACTOR * convertedVertexes[i][1];
}
//Next translate the coord so 0.0 is at the right corner.
convertedVertexes[i][0] += halfWidth;
convertedVertexes[i][1] += halfHeight;
}
//Draw the shapes on the image.
for(int i = 0; i < shapes.length; i++)
{
GeneralPath gp = new GeneralPath();
int nr = shapes[i][0];
gp.moveTo(convertedVertexes[nr][0], convertedVertexes[nr][1]);
for(int j = 1; j < shapes[i].length; j++)
{
nr = shapes[i][j];
gp.lineTo(convertedVertexes[nr][0], convertedVertexes[nr][1]);
}
gp.closePath();
g2D.setColor(shapesColors[i]);
g2D.fill(gp);
}
((Graphics2D)g).drawImage(i,0,0,this);
}
}
class SinCosTabel
{
public static double sin[] = new double[361];
public static double cos[] = new double[361];
SinCosTabel()
{
for(int i = 0; i < 361; i++)
{
sin[i] = Math.sin(Math.toRadians(i));
cos[i] = Math.cos(Math.toRadians(i));
}
}
}