/*
cube.java by Gengbin Zheng
using Z-Buffer to perform hidden surface elimination
*/
import java.awt.*;
import java.applet.*;
public class cube extends Applet implements Runnable {
Button moveButton, scaleButton, RotateButton, resetButton;
Checkbox slowCheck;
myCanvas canvas;
TextField statusBar;
Thread thread;
public void init()
{
GridBagLayout layout = new GridBagLayout();
setLayout(layout);
moveButton = new Button("Move");
scaleButton = new Button("Scale");
RotateButton = new Button("Rotate");
resetButton = new Button("Reset");
slowCheck = new Checkbox("Too slow?", null, false);
GridBagConstraints constraints = new GridBagConstraints();
canvas = new myCanvas(slowCheck);
constraints.fill = GridBagConstraints.BOTH;
constraints.weightx = 1;
constraints.gridheight = 5;
constraints.gridwidth = GridBagConstraints.RELATIVE;
constraints.weighty = 1;
layout.setConstraints(canvas, constraints);
add(canvas);
constraints.fill = GridBagConstraints.BOTH;
constraints.weightx = 0;
constraints.gridheight = 1;
constraints.gridwidth = GridBagConstraints.REMAINDER;
layout.setConstraints(moveButton, constraints);
add(moveButton);
layout.setConstraints(scaleButton, constraints);
add(scaleButton);
layout.setConstraints(RotateButton, constraints);
add(RotateButton);
layout.setConstraints(resetButton, constraints);
add(resetButton);
layout.setConstraints(slowCheck, constraints);
add(slowCheck);
statusBar = new TextField("Move");
statusBar.setEditable(false);
constraints.fill = GridBagConstraints.HORIZONTAL;
constraints.weightx = 1;
constraints.gridheight = 1;
constraints.gridwidth = GridBagConstraints.REMAINDER;
constraints.weighty = 0;
layout.setConstraints(statusBar, constraints);
add(statusBar);
resize(450,350);
}
public void start()
{
thread = new Thread(this);
thread.start();
}
public void run()
{
}
public void stop()
{
thread.stop();
}
void HandleButtons(Object label)
{
String helpMsg;
if (label == "Move")
helpMsg = "Move";
else if (label == "Scale")
helpMsg = "Scale";
else if (label == "Rotate")
helpMsg = "Rotate";
else
helpMsg = "";
if (helpMsg != "") statusBar.setText(helpMsg);
canvas.HandleButtons(label);
}
public boolean action(Event evt, Object arg)
{
if (evt.target instanceof Button)
{
HandleButtons(arg);
}
else if (evt.target instanceof Checkbox)
{
canvas.HandleCheckbox(evt);
}
return true;
}
}
class myCanvas extends Canvas {
Mycube mycube;
Point oldPt, newPt;
boolean working;
// double buffering
Image img = null;
Graphics backg;
final int MOVE=1, SCALE=2, ROTATE=3;
int action;
Checkbox slowCheck;
public myCanvas(Checkbox box)
{
mycube = new Mycube();
working = false;
action = MOVE;
slowCheck = box;
}
void setcursor(boolean working)
{
Cursor curs;
if (working)
curs = new Cursor(Cursor.HAND_CURSOR);
else
curs = new Cursor(Cursor.DEFAULT_CURSOR);
setCursor(curs);
}
public boolean mouseDown(Event evt, int x, int y)
{
if (action == MOVE)
{
if (working == false)
{
working = true;
oldPt = new Point(x,y);
mycube.setShow(!slowCheck.getState());
setcursor(true);
}
}
if (action == SCALE)
{
if (working == false)
{
working = true;
oldPt = new Point(x,y);
mycube.setShow(!slowCheck.getState());
setcursor(true);
}
}
if (action == ROTATE)
{
if (working == false)
{
working = true;
oldPt = new Point(x,y);
mycube.setShow(!slowCheck.getState());
setcursor(true);
}
}
return true;
}
public boolean mouseUp(Event evt, int x, int y)
{
if (working)
{
working = false;
mycube.setShow(true);
if (slowCheck.getState() == true) repaint();
setcursor(false);
}
return true;
}
public boolean mouseDrag(Event evt, int x, int y)
{
if (action == MOVE)
{
if (working)
{
newPt = new Point(x,y);
mycube.move(oldPt, newPt);
oldPt = newPt;
repaint();
}
}
if (action == SCALE)
{
if (working)
{
newPt = new Point(x,y);
mycube.scale(oldPt, newPt);
oldPt = newPt;
repaint();
}
}
if (action == ROTATE)
{
if (working)
{
newPt = new Point(x,y);
mycube.rotate(oldPt, newPt);
oldPt = newPt;
repaint();
}
}
return true;
}
public void HandleButtons(Object label)
{
if (label == "Move")
{
action = MOVE;
}
else if (label == "Scale")
{
action = SCALE;
}
else if (label == "Rotate")
{
action = ROTATE;
}
else if (label == "Reset")
{
mycube.reset();
repaint();
}
}
public void HandleCheckbox(Event evt)
{
String label = slowCheck.getLabel();
if (label == "Too slow?")
{
// mycube.setShow(!slowCheck.getState());
}
}
public void paint(Graphics g)
{
update(g);
}
public void update(Graphics g)
{
Dimension d=size();
if (img == null)
{
img = createImage(d.width, d.height);
backg = img.getGraphics();
}
backg.setColor(new Color(255,255,255)); //Set color for background
backg.fillRect(0,0, d.width, d.height); //Draw Backround
mycube.draw(g, backg, d);
g.drawImage(img, 0, 0, this);
}
}
class Mycube {
CVector points[][];
CVector v[];
int nPlanes;
int nVertex;
final int size = 60;
final int SHIFT = 130;
final int zshift = 300;
final int BUFWID = 400;
final int BUFHIG = 350;
double a,b,c,d;
double aa,bb,cc,dd;
// int maxx,maxy;
// int pcb,pct,pcl,pcr;
int xpc1,ypc1,xpc2,ypc2;
P_Y_TONG py_tong[];
Y_TONG y_tong[];
P_Y_TONG p_aet;
EDGE_ELE edge_aet;
double buf[];
Color planeColor[];
CVector center;
boolean show;
// tmp
double cosv, sinv;
class P_Y_TONG
{
double a,b,c,d;
int deltay;
int id;
Color color;
P_Y_TONG next;
}
class Y_TONG
{
double xup;
double deltax;
int deltay;
int id;
Y_TONG next;
}
class EDGE_ELE
{
double xl, deltaxl;
int deltayl;
double xr, deltaxr;
int deltayr;
double zl, deltazx, deltazy;
int id;
EDGE_ELE next;
}
Mycube()
{
int i;
nPlanes = 6;
nVertex = 4;
v = new CVector[8];
for (i=0; i<8; i++) v[i] = new CVector();
init_pos(v);
points = new CVector[6][4];
int plane[] = new int[4];
plane[0]=0 ; plane[1]=1; plane[2]=2; plane[3]=3;
for (i=0; i<4 ; i++)
points[0][i] = v[plane[i]];
plane[0]=4 ; plane[1]=5; plane[2]=6; plane[3]=7;
for (i=0; i<4 ; i++)
points[1][i] = v[plane[i]];
plane[0]=1 ; plane[1]=2; plane[2]=6; plane[3]=5;
for (i=0; i<4 ; i++)
points[2][i] = v[plane[i]];
plane[0]=0 ; plane[1]=3; plane[2]=7; plane[3]=4;
for (i=0; i<4 ; i++)
points[3][i] = v[plane[i]];
plane[0]=2 ; plane[1]=3; plane[2]=7; plane[3]=6;
for (i=0; i<4 ; i++)
points[4][i] = v[plane[i]];
plane[0]=1 ; plane[1]=0; plane[2]=4; plane[3]=5;
for (i=0; i<4 ; i++)
points[5][i] = v[plane[i]];
planeColor = new Color[nPlanes];
for (i=0; i<nPlanes; i++)
{
switch (i)
{
case 0:
case 1:
planeColor[i] = new Color(255,0,0); break;
case 2:
case 3:
planeColor[i] = new Color(0, 255, 0); break;
case 4:
case 5:
planeColor[i] = new Color(0, 0, 255); break;
}
// randomely
// planeColor[i] = new Color((int)(Math.random()*255), (int)(Math.random()*255), (int)(Math.random()*255));
}
py_tong = new P_Y_TONG[BUFHIG+10];
y_tong = new Y_TONG[BUFHIG+10];
p_aet= new P_Y_TONG();
edge_aet = new EDGE_ELE();
buf = new double[BUFWID];
center = new CVector();
show = true;
init3d();
}
void init_pos(CVector v[])
{
int i;
v[0].set(0,0,0);
v[1].set(0,size,0);
v[2].set(size,size,0);
v[3].set(size,0,0);
v[4].set(0,0,size);
v[5].set(0,size,size);
v[6].set(size,size,size);
v[7].set(size,0,size);
CVector vshift = new CVector(SHIFT,SHIFT,SHIFT);
for (i=0; i<8; i++) v[i].add(vshift);
CVector vcenter = new CVector();
vcenter.x = (v[0].x + v[6].x)/2;
vcenter.y = (v[0].y + v[6].y)/2;
vcenter.z = (v[0].z + v[6].z)/2;
for (i=0; i<8; i++)
{
v[i].sub(vcenter);
v[i].rotatex(45.0);
v[i].rotatey(45.0);
v[i].rotatez(45.0);
v[i].add(vcenter);
}
}
void init3d()
{
final double VXL=-200.0,VXR=200.0,WXR=200.0,WXL=-200.0;
final double VYT=200.0,VYB=-200.0,WYT=200.0,WYB=-200.0;
a=(VXR-VXL)/(WXR-WXL);
b=VXL-a*WXL;
c=(VYT-VYB)/(WYT-WYB);
d=VYB-c*WYB;
}
/*
void set_abcd(int mx, int my)
{
maxx=mx;
maxy=my;
pcb=maxy-1; pct=0;
pcr=maxx-1; pcl=0;
a=(pcr-pcl)/(1+1);
b=pcl-a*(-1);
c=(pct-pcb)/(1+1);
d=pcb-c*(-1);
}
*/
void get_abcd(CVector v1, CVector v2, CVector v3)
{
CVector t1,t2;
t1 = new CVector(v1);
t1.sub(v3);
t2 = new CVector(v1);
t2.sub(v2);
aa = t1.y*t2.z - t1.z*t2.y;
bb=-t1.x*t2.z + t1.z*t2.x;
cc=t1.x*t2.y - t2.x*t1.y;
dd=-(aa*v1.x+bb*v1.y+cc*v1.z);
}
Color GetColor(int id)
{
P_Y_TONG ptr;
for (ptr=p_aet ; ptr != null; ptr=ptr.next)
if (ptr.id == id ) return ptr.color;
return new Color(0,0,0);
}
P_Y_TONG GetP_Y_Tong(int id)
{
P_Y_TONG ptr;
for (ptr=p_aet ; ptr!=null; ptr=ptr.next)
if (ptr.id == id ) return ptr;
return null;
}
EDGE_ELE GetEdgePair(int col,P_Y_TONG py_ptr1)
{
Y_TONG y_ptr,yl_ptr,yr_ptr;
int flag;
EDGE_ELE e_ptr;
flag=0;
yl_ptr=yr_ptr=null;
for (y_ptr=y_tong[col] ; y_ptr != null ; y_ptr=y_ptr.next)
{
if (y_ptr.id != py_ptr1.id) continue;
// parallel line
if (y_ptr.deltay == 0) continue;
if (flag == 0) {
yl_ptr=y_ptr;
flag++;
}
else
yr_ptr=y_ptr;
}
// no proper edge !
if (yl_ptr==null) return null;
if (yl_ptr.xup > yr_ptr.xup || (yl_ptr.xup==yr_ptr.xup && yl_ptr.deltax > yr_ptr.deltax))
{
y_ptr=yl_ptr;
yl_ptr=yr_ptr;
yr_ptr=y_ptr;
}
e_ptr= new EDGE_ELE();
e_ptr.id =py_ptr1.id;
e_ptr.xl=yl_ptr.xup;
e_ptr.deltaxl=yl_ptr.deltax;
e_ptr.deltayl=yl_ptr.deltay;
e_ptr.xr=yr_ptr.xup;
e_ptr.deltaxr=yr_ptr.deltax;
e_ptr.deltayr=yr_ptr.deltay;
e_ptr.zl= py_ptr1.c !=0 ?-(py_ptr1.d+ py_ptr1.a*yl_ptr.xup + py_ptr1.b*col)/py_ptr1.c:0;
e_ptr.deltazx = py_ptr1.c !=0? -py_ptr1.a/py_ptr1.c:0;
e_ptr.deltazy = py_ptr1.c !=0 ? py_ptr1.b/py_ptr1.c:0;
return e_ptr;
}
void z_buffer(Graphics g, int width, int height)
{
int i,j;
int ymax, ymin, yy, maxy, miny, maxx, minx;
P_Y_TONG py_ptr, py_head, py_ptr1;
Y_TONG y_ptr,y_head,yl_ptr;
EDGE_ELE e_ptr,e_tmp;
CVector v1, v2, v3;
for (i=0; i<BUFHIG; i++)
{
py_tong[i] = null;
y_tong[i] = null;
}
p_aet = null;
edge_aet = null;
// create Polygon Y Tong & Y Tong
maxy=-65530; miny=65530;
maxx=-65530; minx=65530;
for (i=0; i<nPlanes; i++)
{
py_ptr = new P_Y_TONG();
py_ptr.id = i;
py_ptr.color = planeColor[i];
v1 = points[i][0];
v2 = points[i][1];
v3 = points[i][2];
get_abcd(v1,v2,v3);
py_ptr.a = aa;
py_ptr.b = bb;
py_ptr.c = cc;
py_ptr.d = dd;
ymax=-65530; ymin=65530;
for (j=1; j<= nVertex; j++)
{
y_ptr = new Y_TONG();
y_ptr.id=i;
v1 = points[i][j-1];
v2 = points[i][j%nVertex];
xpc1=(int)v1.x; ypc1=(int)v1.y;
xpc2=(int)v2.x; ypc2=(int)v2.y;
double del = 1.0*(xpc2-xpc1)/(ypc2-ypc1);
if (ypc1 > BUFHIG) {
ypc1 = BUFHIG-1;
xpc1 = (int)(xpc2 - del*(ypc2-ypc1));
}
if (ypc2 > BUFHIG) {
ypc2 = BUFHIG-1;
xpc2 = (int)(v1.x + del*(ypc2-v1.y));
}
y_ptr.deltay=Math.abs(ypc2 - ypc1);
y_ptr.deltax=ypc2==ypc1?0:-del;
y_ptr.xup=ypc2 > ypc1 ? xpc2 : xpc1;
if (ypc1>ymax) ymax=ypc1;
if (ypc1<ymin) ymin=ypc1;
if (ypc2>ymax) ymax=ypc2;
if (ypc2<ymin) ymin=ypc2;
// insert to Y Tong
yy=Math.max(ypc1,ypc2);
if (yy>=0 && yy<BUFHIG)
{
y_head=y_tong[yy];
y_ptr.next=y_head;
y_tong[yy]=y_ptr;
}
}
py_ptr.deltay=ymax-ymin;
if (ymax >= 0 && ymax<BUFHIG)
{
py_head=py_tong[ymax];
py_ptr.next=py_head;
py_tong[ymax]=py_ptr;
}
if (ymax > maxy) maxy = ymax;
if (ymin < miny) miny = ymin;
/*
if (xpc1 > maxx) maxx = xpc1;
if (xpc1 < minx) minx = xpc1;
if (xpc2 > maxx) maxx = xpc2;
if (xpc2 < minx) minx = xpc2;
*/
}
for (i=BUFHIG-1; i>=0 ; i--)
// for (i=maxy; i>=miny ; i--)
{
for (j=0; j<BUFWID;j++) buf[j]=-65530.0;
// new P_Y tong insert
if (py_tong[i] != null)
{
for (py_ptr=py_tong[i] ; py_ptr.next != null ; py_ptr=py_ptr.next);
py_ptr.next=p_aet;
p_aet=py_tong[i];
// new line pairs
for (py_ptr1=p_aet; py_ptr1 != py_ptr.next ; py_ptr1=py_ptr1.next)
{
e_ptr=GetEdgePair(i,py_ptr1);
if (e_ptr == null) continue;
e_ptr.next=edge_aet;
edge_aet=e_ptr;
}
}
for (e_ptr=edge_aet; e_ptr != null; e_ptr=e_ptr.next)
{
if (e_ptr.deltayl != 0 && e_ptr.deltayr != 0) continue;
if (e_ptr.deltayl == 0 && e_ptr.deltayr == 0)
{
py_ptr=GetP_Y_Tong(e_ptr.id);
if (py_ptr != null)
{
e_tmp=GetEdgePair(i,py_ptr);
if (e_tmp != null)
{
e_tmp.next=edge_aet;
edge_aet=e_tmp;
}
}
continue;
}
// search new line
yl_ptr=null;
for (y_ptr=y_tong[i] ; y_ptr != null;y_ptr=y_ptr.next)
{
if (y_ptr.id != e_ptr.id ) continue;
if (y_ptr.deltay == 0) continue;
break;
}
if (y_ptr != null)
{
double tmpx,tmpdx;
int tmpdy;
tmpx=e_ptr.deltayl != 0? e_ptr.xl: e_ptr.xr;
tmpdx=e_ptr.deltayl != 0? e_ptr.deltaxl: e_ptr.deltaxr;
tmpdy=e_ptr.deltayl != 0? e_ptr.deltayl: e_ptr.deltayr;
if (tmpx < y_ptr.xup || (tmpx==y_ptr.xup && tmpdx<y_ptr.deltax))
{
e_ptr.xl=tmpx;
e_ptr.deltaxl=tmpdx;
e_ptr.deltayl=tmpdy;
e_ptr.xr = y_ptr.xup;
e_ptr.deltaxr=y_ptr.deltax;
e_ptr.deltayr=y_ptr.deltay;
}
else {
e_ptr.xr=tmpx;
e_ptr.deltaxr=tmpdx;
e_ptr.deltayr=tmpdy;
e_ptr.xl = y_ptr.xup;
e_ptr.deltaxl=y_ptr.deltax;
e_ptr.deltayl=y_ptr.deltay;
}
}
}
//
for (e_ptr=edge_aet ; e_ptr != null; e_ptr=e_ptr.next)
{
int k;
double zx;
Color acolor;
if (e_ptr.deltayl ==0 && e_ptr.deltayr==0 ) continue;
if (e_ptr.xl > e_ptr.xr) continue;
zx=e_ptr.zl;
// tranform
xpc1=(int)(a*e_ptr.xl+b+0.5);
ypc1=(int)(c*i+d+0.5);
xpc2=(int)(a*e_ptr.xr+b+0.5);
int s0, s1;
s0 = s1= -1;
acolor=GetColor(e_ptr.id);
g.setColor(acolor);
for (k=xpc1 ; k<=xpc2 ; k++)
{
zx+=e_ptr.deltazx;
if (k>=0 && k< BUFWID && zx > buf[k]) {
buf[k]=zx;
if (s0 == -1) s0 = s1 = k;
else {
if (k == s1+1) s1++;
else {
g.drawLine(s0, ypc1, s1, ypc1);
s0 = s1 = -1;
}
}
}
}
if (s0 != -1)
g.drawLine(s0, ypc1, s1, ypc1);
}
// modified Y_AET table
for (e_ptr=edge_aet ; e_ptr != null; e_ptr=e_ptr.next)
{
if (e_ptr.deltayl ==0 && e_ptr.deltayr==0 ) continue;
e_ptr.deltayl--;
e_ptr.deltayr--;
e_ptr.xl+=e_ptr.deltaxl;
e_ptr.xr+=e_ptr.deltaxr;
e_ptr.zl+=e_ptr.deltazx*e_ptr.deltaxl + e_ptr.deltazy;
}
// modified P_Y_tong
for (py_ptr=p_aet ; py_ptr != null; py_ptr=py_ptr.next)
if (py_ptr.deltay != 0) py_ptr.deltay--;
}
}
double dot(CVector v1,CVector v2)
{
return v1.x*v2.x+v1.y*v2.y+v1.z*v2.z;
}
void move(Point pt1, Point pt2)
{
center.x = (points[0][0].x + points[1][2].x)/2;
center.y = (points[0][0].y + points[1][2].y)/2;
center.z = (points[0][0].z + points[1][2].z)/2;
CVector v1=new CVector(pt1.x,pt1.y,zshift);
CVector v2=new CVector(pt2.x,pt2.y,zshift);
v1.sub(center); v2.sub(center);
CVector dist = new CVector();
dist.x = v2.x - v1.x;
dist.y = v2.y - v1.y;
dist.z = v2.z - v1.z;
for (int i=0; i<4; i++)
{
v1=points[0][i];
v1.sub(center);
v1.add(dist);
v1.add(center);
v2=points[1][i];
v2.sub(center);
v2.add(dist);
v2.add(center);
}
}
void scale(Point pt1, Point pt2)
{
double scale;
center.x = (points[0][0].x + points[1][2].x)/2;
center.y = (points[0][0].y + points[1][2].y)/2;
center.z = (points[0][0].z + points[1][2].z)/2;
CVector v1=new CVector(pt1.x,pt1.y,zshift);
CVector v2=new CVector(pt2.x,pt2.y,zshift);
v1.sub(center); v2.sub(center);
scale = v2.mag()/v1.mag();
for (int i=0; i<4; i++)
{
v1=points[0][i];
v1.sub(center);
v1.mul(scale);
v1.add(center);
v2=points[1][i];
v2.sub(center);
v2.mul(scale);
v2.add(center);
}
}
void cal_cossin(int dim,CVector v1,CVector v2)
{
double t1,t2,t;
cosv=dot(v1.unit(),v2.unit());
t=1.0-cosv*cosv;
if (t<1e-5) sinv=0.0;
else sinv=Math.sqrt(t);
switch (dim)
{
case 1:
t1=Math.atan2(v1.z,v1.y); t2=Math.atan2(v2.z,v2.y);
break;
case 2:
t1=Math.atan2(v1.x,v1.z); t2=Math.atan2(v2.x,v2.z);
break;
case 3:
t1=Math.atan2(v1.y,v1.x); t2=Math.atan2(v2.y,v2.x);
break;
default:
t1 = t2 = 0;
}
if (t1 * t2 < 0 && Math.max(t1,t2) > 3.14159265/2.0 )
{
if (t1<0) t1+=2.0*3.1415;
else t2+=2.0*3.1415;
}
if ( t1 > t2) sinv=-sinv;
}
void rotate(Point pt1, Point pt2)
{
double cosx,sinx,cosy,siny,cosz,sinz;
center.x = (points[0][0].x + points[1][2].x)/2;
center.y = (points[0][0].y + points[1][2].y)/2;
center.z = (points[0][0].z + points[1][2].z)/2;
CVector v1=new CVector(0,pt1.y,zshift);
CVector v2=new CVector(0,pt2.y,zshift);
v1.sub(center); v2.sub(center);
cal_cossin(1,v1,v2);
cosx = cosv; sinx = sinv;
v1.x = pt1.x; v1.y = 0; v1.z = zshift;
v2.x = pt2.x; v2.y = 0; v2.z = zshift;
v1.sub(center); v2.sub(center);
cal_cossin(2,v1,v2);
cosy = cosv; siny = sinv;
v1.x = pt1.x; v1.y = pt1.y; v1.z = 0;
v2.x = pt2.x; v2.y = pt2.y; v2.z = 0;
v1.sub(center); v2.sub(center);
cal_cossin(3,v1,v2);
cosz = cosv; sinz = sinv;
for (int i=0; i<4; i++)
{
v1 = points[0][i];
v1.sub(center);
v1.rotatex(cosx,sinx);
v1.rotatey(cosy,siny);
v1.rotatez(cosz,sinz);
v1.add(center);
v2 = points[1][i];
v2.sub(center);
v2.rotatex(cosx,sinx);
v2.rotatey(cosy,siny);
v2.rotatez(cosz,sinz);
v2.add(center);
}
}
void reset()
{
init_pos(v);
}
void draw(Graphics g, Graphics backg, Dimension d)
{
if (!show)
{
CVector v1,v2;
backg.setColor(new Color(0,0,0)); //Set color for background
for (int i=0; i< nPlanes; i++)
{
for (int j=1; j <= nVertex; j++)
{
v1 = points[i][j-1];
v2 = points[i][j%nVertex];
backg.drawLine((int)v1.x, (int)v1.y, (int)v2.x, (int)v2.y);
}
}
}
else
z_buffer(backg, d.width, d.height);
}
void setShow(boolean val)
{
show = val;
}
}
class CVector {
double x,y,z;
CVector()
{
x = 0.0; y = 0.0; z = 0.0;
}
CVector(double xx, double yy, double zz)
{
x = xx; y = yy; z = zz;
}
CVector(CVector a)
{
x = a.x; y = a.y; z = a.z;
}
void copy(CVector c)
{
x = c.x; y = c.y; z = c.z;
}
void set(double xx, double yy, double zz)
{
x = xx; y = yy; z = zz;
}
double mag()
{
double m;
m=Math.sqrt(x*x+y*y+z*z);
return m;
}
void add (CVector v2)
{
x = x + v2.x;
y = y + v2.y;
z = z + v2.z;
}
void sub (CVector v2)
{
x = x - v2.x;
y = y - v2.y;
z = z - v2.z;
}
void mul(double d)
{
x *= d;
y *= d;
z *= d;
}
void div(double d)
{
x /= d;
y /= d;
z /= d;
}
CVector unit()
{
double m = mag();
CVector n = new CVector();
n.x = x / m;
n.y = y / m;
n.z = z / m;
return n;
}
void rotatex (double a)
{
double ty,tz;
double b;
b=a*3.14159265/180.0;
ty=Math.cos(b)*y-Math.sin(b)*z;
tz=Math.sin(b)*y+Math.cos(b)*z;
y=ty;
z=tz;
}
void rotatex(double cosb,double sinb)
{
double ty,tz;
ty=cosb*y-sinb*z;
tz=sinb*y+cosb*z;
y=ty;
z=tz;
}
void rotatey(double a)
{
double tx,tz;
double b;
b=a*3.14159265/180.0;
tx=Math.cos(b)*x+Math.sin(b)*z;
tz=-Math.sin(b)*x+Math.cos(b)*z;
x=tx;
z=tz;
}
void rotatey(double cosb,double sinb)
{
double tx,tz;
tx=cosb*x+sinb*z;
tz=-sinb*x+cosb*z;
x=tx;
z=tz;
}
void rotatez (double a)
{
double tx,ty;
double b;
b=a*3.14159265/180.0;
tx=Math.cos(b)*x-Math.sin(b)*y;
ty=Math.sin(b)*x+Math.cos(b)*y;
x=tx;
y=ty;
}
void rotatez (double cosb,double sinb)
{
double tx,ty;
tx=cosb*x-sinb*y;
ty=sinb*x+cosb*y;
x=tx;
y=ty;
}
}
class Point
{
int x,y;
Point(Point p)
{
x = p.x;
y = p.y;
}
Point(int _x, int _y)
{
x = _x;
y = _y;
}
Point()
{
x = 0;
y = 0;
}
void copy(Point p)
{
x = p.x;
y = p.y;
}
}