import java.awt.*;
import java.applet.Applet;
import java.lang.Math;

/*

Mein erster Versuch, eine schoene Oberflaeche fuer
die Levitron-Simulation zu erstellen.

Jetzt soll auch etwas gezeichnet werden.

Start mit

javac maglev.java
appletviewer index.htm

26.6.99 Koepken

23.7.99 Quader aus allen Richtungen geht!

1.8.99 Kreisel geht auch!

18.8.99 Erste Versuche mit Kreiseldynamik

7.12.03 Einbau der richtigen Dynamik aus dyn_of_lev

(C) 1999-2005 Hans-Georg Koepken

Feel free to improve this code, but please share the results with
me and everybody else - GNU like.

mail@koepken.de

*/

public class maglev extends Applet
{
    public camera camera1;
    public control control1;
    public Label stat;
    public String str="Teststring";

    public void init()
    {
        camera1 = new camera(this);
	control1 = new control();
	stat = new Label();

	GridBagLayout gridbag= new GridBagLayout();
	setLayout(gridbag);
	GridBagConstraints c= new GridBagConstraints();
	c.fill=GridBagConstraints.VERTICAL;

	gridbag.setConstraints(control1,c);
	add(camera1);
	add(control1);
	stat.setText("Waiting for thread...");
	add(stat);
	validate();

	new simulation(this).start();

    }

    public void statechanged()
    {
        camera1.repaint();
    }
}

class control extends Panel
{
    Scrollbar hslider;
    Scrollbar wslider;
    Scrollbar nslider;

    Scrollbar rslider;
    Scrollbar eslider;
    Scrollbar sslider;

    public control()
    {
        setLayout(new GridLayout(1,0));
	hslider=new Scrollbar(Scrollbar.VERTICAL,110,1, 80,135);
	wslider=new Scrollbar(Scrollbar.VERTICAL,90,1, 90,110);
	nslider=new Scrollbar(Scrollbar.VERTICAL,100,1,  0,200);
	rslider=new Scrollbar(Scrollbar.VERTICAL,-20,1,-90, 90);
	eslider=new Scrollbar(Scrollbar.VERTICAL, 15,1,-90, 90);
	sslider=new Scrollbar(Scrollbar.VERTICAL, 50,1,  0,100);
	add(hslider);
	add(wslider);
	add(nslider);
	add(rslider);
	add(eslider);
	add(sslider);
	validate();
    }

    public int height()
    {
        return 200-hslider.getValue();
    }

    public int weight()
    {
        return 200-wslider.getValue();
    }

    public int rpm()
    {
        return 200-nslider.getValue();
    }

    public int rot()
    {
        return -rslider.getValue();
    }

    public int elav()
    {
        return -eslider.getValue();
    }

    public int speed()
    {
        return 100-sslider.getValue();
    }


}	

class camera extends Canvas
{
    maglev mymain;
    Dimension minSize = new Dimension(300,200);
    int x[]={1,10,10,1}, y[]={1,1,20,20};
	Polygon ab = new Polygon(x,y,4);

    public camera(maglev caller)
    {
    	super();
        mymain=caller;
    }
    
    public Dimension preferredSize()
    {
        return minimumSize();
    }

    public synchronized Dimension minimumSize()
    {
        return minSize;
    }

    public void paint(Graphics g)
    {
    	update(g);
    }
    
    quader q = new quader();
    kreisel kr = new kreisel();
    quader pl = new quader();
    vec3 pos = new vec3(0.0,0.0,25.0);
    vec3 richt = new vec3(0.0,0.5,0.866);
    
    Dimension offDimension;
    Image offImage;
    Graphics offGraphics;

    public void update(Graphics g)
    {
    	Dimension d = size();

	// Create the offscreen
	if ( (offGraphics==null)
	  || (d.width!=offDimension.width) || (d.height!=offDimension.height) )
	{
		offDimension = d;
		offImage = createImage(d.width, d.height);
		offGraphics = offImage.getGraphics();
	}

	// altes Bild loeschen
	offGraphics.setColor(getBackground());
	offGraphics.fillRect(0,0,d.width,d.height);
	offGraphics.setColor(Color.black);
	
	q.p.set(0,0,-45);
	q.a.set(160,0,0);
	q.b.set(0,160,0);
	q.c.set(0,0,40);
	q.rotatez((double)mymain.control1.rot()/180.0*3.13159);
	q.rotatey((double)mymain.control1.elav()/180.0*3.13159);
	q.render();

	pl.p.set(0,0,1.72/100.0*(double)mymain.control1.height()*40.0-34.0-30.0);
	pl.a.set(60,0,0);
	pl.b.set(0,60,0);
	pl.c.set(0,0,10);
	pl.rotatez((double)mymain.control1.rot()/180.0*3.13159);
	pl.rotatey((double)mymain.control1.elav()/180.0*3.13159);
	pl.render();

//	kr.p.set(0,(double)mymain.control1.weight()-100.0,25+(double)mymain.control1.height());
//	kr.p.set(0,0,25);
	kr.p.set(pos);
	// activate rpm slider
//	double t1=0.3;
//	double t2=java.lang.Math.sqrt(1.0-t1*t1);
//	kr.v.set(0,t1,t2);
	kr.v.set(richt);
	kr.rotatez((double)mymain.control1.rot()/180.0*3.13159);
	kr.rotatey((double)mymain.control1.elav()/180.0*3.13159);
	kr.render();

	if(kr.p.x<q.p.x)
	{
		kr.draw(offGraphics);
		if(pl.p.x<q.p.x)
		{
		    pl.draw(offGraphics);
		    q.draw(offGraphics);
		}
		else
		{
		    q.draw(offGraphics);
		    pl.draw(offGraphics);
		}
	}
	else
	{
		if(pl.p.x<q.p.x)
		{
		    pl.draw(offGraphics);
		    q.draw(offGraphics);
		}
		else
		{
		    q.draw(offGraphics);
		    pl.draw(offGraphics);
		}
		kr.draw(offGraphics);
	}

	offGraphics.drawString(mymain.str,0,10);
	// Paint the image onto the screen
	g.drawImage(offImage,0,0,this);
    } 

    public boolean mouseDown(Event e, int x, int y)
    {
        repaint();
	return true;
    }
}

class simulation extends Thread
{
    maglev mymain;
	
    public simulation(maglev caller)
    {
    	super();
	mymain = caller;
    }

    double a=0.089;
    double c=0.139;
    double M0=8.2/1.0;
    double M=M0;
    double h=1.72;
    double KT=0.060;

    public void deriv(double t, double[] q, double[] dq)
	{
	    double t2,t4,t5,t6,t8,t9,t10,t11,t12,t17,t18,t20,t21,t23,t25,t26,t28,t30,t31,t34,t35,t38,t41,t42,t44,t51,t55,t67,t70,t73,t78;
	    double t81,t90,t93,t96,t97,t98,t99,t123,t129,t131;

	    /* ab hier aus Maple kopiert */
	    dq[0] = q[6];
	    dq[1] = q[7];
	    dq[2] = q[8];
	    t2 = 0.10e1 / a;
	    dq[3] = q[9] * t2;
	    t4 = q[11];
	    t5 = q[3];
	    t6 = java.lang.Math.cos(t5);
	    t8 = q[10] - t4 * t6;
	    t9 = t8 * t2;
	    t10 = java.lang.Math.sin(t5);
	    t11 = t10 * t10;
	    t12 = 0.10e1 / t11;
	    dq[4] = t9 * t12;
	    dq[5] = -t9 * t12 * t6 + t4 / c;
	    t17 = q[4];
	    t18 = java.lang.Math.cos(t17);
	    t20 = q[2];
	    t21 = t20 * t20;
	    t23 = 0.2e1 * t21 - 0.3e1;
	    t25 = 0.1e1 + t21;
	    t26 = t25 * t25;
	    t28 = java.lang.Math.sqrt(t25);
	    t30 = 0.10e1 / t28 / t26 / t25;
	    t31 = t23 * t20 * t30;
	    t34 = t21 * t30;
	    t35 = q[0];
	    t38 = t23 * t30;
	    t41 = t23 * t21;
	    t42 = t26 * t26;
	    t44 = 0.10e1 / t28 / t42;
	    dq[6] = M * (-0.3e1 / 0.2e1 * t10 * t18 * t31 + t6 * (-0.6e1 * t34 * t35 - 0.3e1 / 0.2e1 * t38 * t35 + 0.21e2 / 0.2e1 * t41 * t44 * t35));
	    t51 = java.lang.Math.sin(t17);
	    t55 = q[1];
	    dq[7] = M * (-0.3e1 / 0.2e1 * t10 * t51 * t31 + t6 * (-0.6e1 * t34 * t55 - 0.3e1 / 0.2e1 * t38 * t55 + 0.21e2 / 0.2e1 * t41 * t44 * t55));
	    t67 = t30 * t35;
	    t70 = t18 * t23;
	    t73 = t21 * t44;
	    t78 = t30 * t55;
	    t81 = t51 * t23;
	    t90 = 0.10e1 / t28 / t26;
	    t93 = t21 * t20;
	    t96 = t20 * t30;
	    t97 = t35 * t35;
	    t98 = t55 * t55;
	    t99 = t97 + t98;
	    dq[8] = M * (t10 * (-0.6e1 * t18 * t21 * t67 - 0.3e1 / 0.2e1 * t70 * t67 + 0.21e2 / 0.2e1 * t70 * t73 * t35 - 0.6e1 * t51 * t21 * t78 - 0.3e1 / 0.2e1 * t81 * t78 + 0.21e2 / 0.2e1 * t81 * t73 * t55) + t6 * (-0.9e1 * t90 * t20 + 0.15e2 * t93 * t30 - 0.9e1 * t96 * t99 + 0.42e2 * t93 * t44 * t99 + 0.63e2 / 0.4e1 * t23 * t44 * t99 * t20 - 0.189e3 / 0.4e1 * t23 * t93 / t28 / t42 / t25 * t99)) - 0.1e1;
	    t123 = t8 * t8;
	    t129 = t96 * t35;
	    t131 = t96 * t55;
	    dq[9] = -t9 / t10 * t4 + t123 * t2 / t11 / t10 * t6 + M * (t6 * (-0.3e1 / 0.2e1 * t70 * t129 - 0.3e1 / 0.2e1 * t81 * t131) - t10 * (0.10e1 / t28 / t25 - 0.3e1 * t21 * t90 - 0.3e1 * t34 * t99 - 0.3e1 / 0.4e1 * t38 * t99 + 0.21e2 / 0.4e1 * t41 * t44 * t99));
	    dq[10] = M * t10 * (0.3e1 / 0.2e1 * t81 * t129 - 0.3e1 / 0.2e1 * t70 * t131);
	    dq[11] = 0.0e0;
/* bis hier aus Maple kopiert */  
	}

    int NQ=12;
	double[] q= new double[NQ];

    public double sim(double t1, double t2)//, double[] q)
	{
	    double t;
	    double  dt=0.002;
	    double[] qm= new double[NQ];
	    double[] dqm=new double[NQ];
	    double[] dq= new double[NQ];
	    int i;
	    for(t=t1;t<t2;t+=dt) {
		deriv(t,q,dqm);
		for(i=0;i<NQ;i++)
		    qm[i]=q[i]+dt/2*dqm[i];
		deriv(t,qm,dq);
		for(i=0;i<NQ;i++)
		    q[i]+=dt*dq[i];
	    }
	    return t;
	}

//    int N=5000;
    long DTplot=50; // msec
    double DTsim;
    double PSCALE=40.0;

    long firsttime=System.currentTimeMillis();
    long lasttime=0;
    long newtime=0;
    long dtime=0;

    public void run()
	{
	    double t=0.0, ts=0.0;
	    double h=1.72;
		double spin0=((double)mymain.control1.rpm()/100.0);
		q[2]=1.72;
		q[3]=0.005;
		q[10]=1.04249*spin0;
		q[11]=1.0425*spin0;

	
    	for (int i=0; true ; i++) {
			DTsim=DTplot/1000.0*mymain.control1.speed()/100.0;
			// speed==0 macht Reset der Simulation
			if(mymain.control1.speed()<10) {
				double spin=((double)mymain.control1.rpm()/100.0);
				for (int j=0; j<12; j++) {
					q[j]=0.0;
				}
				t=0.0;
				q[2]=1.72;
				q[3]=0.005;
				q[10]=1.04249*spin;
				q[11]=1.0425*spin;
			}
		
			////////////////////
			// SIM AUFRUFEN !!
			M=M0*100.0/(double)mymain.control1.weight();
			t=sim(t/KT,(t+DTsim)/KT)*KT;//,q);
			////////////////////
			h=1.72/100.0*(double)mymain.control1.height();
			if(q[2]<h) {
			q[2]=h;
			q[8]=0.0;
	    }
	    //mymain.camera1.richt.rotatez(18.0/180.0*3.14159);
	    mymain.camera1.pos.set(q[0]*PSCALE,q[1]*PSCALE,q[2]*PSCALE-34.0);
	    //mymain.camera1.pos.set(0.0,(double)mymain.control1.weight()-100.0,25+(double)mymain.control1.height());
	    mymain.camera1.richt.set(java.lang.Math.sin(q[3])*java.lang.Math.cos(q[4]),java.lang.Math.sin(q[3])*java.lang.Math.sin(q[4]),java.lang.Math.cos(q[3]));
	    
	    mymain.str = "tsim=" + java.lang.Math.round(t*1000)/1000.0;
	    mymain.stat.setText(mymain.str);
	    mymain.camera1.repaint();
	    newtime=System.currentTimeMillis();
	    dtime=DTplot-(newtime-lasttime);
	    if(dtime<0)
		dtime=0;
	    lasttime=newtime;
	    try
	    {
	        sleep(dtime);
	    }
	    catch (InterruptedException e) {}
	}
    }
}

class vec3
{
    double x=0, y=0, z=0;

    public vec3()
    {
    	x=0.0;
	y=0.0;
	z=0.0;
    }

    public vec3(double xx, double yy, double zz)
    {
    	x=xx;
	y=yy;
	z=zz;
    }

    public void set(double xx, double yy, double zz)
    {
    	x=xx;
	y=yy;
	z=zz;
    }

    public void set(vec3 v)
    {
    	x=v.x;
	y=v.y;
	z=v.z;
    }

    public void add(vec3 v, vec3 w, double fak)
    {
    	x=v.x+w.x*fak;
	y=v.y+w.y*fak;
	z=v.z+w.z*fak;
    }

    public void add(vec3 v)
    {
    	x+=v.x;
	y+=v.y;
	z+=v.z;
    }

    public void mul(double k)
    {
    	x*=k;
	y*=k;
	z*=k;
    }
    
    public void div(double k)
    {
    	x/=k;
	y/=k;
	z/=k;
    }
    
    public double abs()
    {
    	return(java.lang.Math.sqrt(x*x+y*y+z*z));
    }

    public void cross(vec3 v, vec3 w)
    {
	x=v.y*w.z-v.z*w.y;
	y=v.z*w.x-v.x*w.z;
	z=v.x*w.y-v.y*w.x;
    }
    
    public void rotatez(double alpha)
    {
    	double xx,yy,zz;
	
	xx=java.lang.Math.cos(alpha)*x+java.lang.Math.sin(alpha)*y;
	yy=-java.lang.Math.sin(alpha)*x+java.lang.Math.cos(alpha)*y;
	zz=z;
	x=xx;
	y=yy;
	z=zz;
    }

    public void rotatey(double beta)
    {
	double xx,yy,zz;

	xx=java.lang.Math.cos(beta)*x-java.lang.Math.sin(beta)*z;
	yy=y;
	zz=java.lang.Math.sin(beta)*x+java.lang.Math.cos(beta)*z;
	x=xx;
	y=yy;
	z=zz;
    }
}

class quader
{
    vec3 p=new vec3();
    vec3 a=new vec3();
    vec3 b=new vec3();
    vec3 c=new vec3();

    raute ab=new raute();
    raute bc=new raute();
    raute ac=new raute();

   public void rotatez(double alpha)
    {
    	p.rotatez(alpha);
    	a.rotatez(alpha);
    	b.rotatez(alpha);
    	c.rotatez(alpha);
    }

    public void rotatey(double beta)
    {
    	p.rotatey(beta);
    	a.rotatey(beta);
    	b.rotatey(beta);
    	c.rotatey(beta);
    }

    public void render()
    {
    	ab.set(p,c,a,b);
	bc.set(p,a,c,b);
	ac.set(p,b,a,c);
    }

    public void draw(Graphics g)
    {
    	g.setColor(java.awt.Color.blue);
	ab.fill(g);
	bc.fill(g);
	ac.fill(g);
	g.setColor(java.awt.Color.black);
	ab.draw(g);
	bc.draw(g);
	ac.draw(g);
    }
}

class raute
{
    int x[]={1,10,10,1,1}, y[]={1,1,20,20,1};
    Polygon vw=new Polygon(x,y,5);
    
    public void set(vec3 p, vec3 d, vec3 v, vec3 w)
    {
    	double yy=p.y-d.y/2,zz=p.z-d.z/2;
	
    	if(d.x>0)
	{
	    yy+=d.y;
	    zz+=d.z;
	}
	vw.xpoints[0]=100+(int)(yy		-v.y/2-w.y/2);
	vw.xpoints[1]=100+(int)(yy+v.y		-v.y/2-w.y/2);
	vw.xpoints[2]=100+(int)(yy+v.y+w.y	-v.y/2-w.y/2);
	vw.xpoints[3]=100+(int)(yy+w.y		-v.y/2-w.y/2);
	vw.xpoints[4]=100+(int)(yy		-v.y/2-w.y/2);
	vw.ypoints[0]=100-(int)(zz		-v.z/2-w.z/2);
	vw.ypoints[1]=100-(int)(zz+v.z		-v.z/2-w.z/2);
	vw.ypoints[2]=100-(int)(zz+v.z+w.z	-v.z/2-w.z/2);
	vw.ypoints[3]=100-(int)(zz+w.z		-v.z/2-w.z/2);
	vw.ypoints[4]=100-(int)(zz		-v.z/2-w.z/2);
 
    }

    public void draw(Graphics g)
    {
    	g.drawPolygon(vw);
    }

    public void fill(Graphics g)
    {
    	g.fillPolygon(vw);
    }
}

class kreisel
{
    vec3 p=new vec3();
    vec3 v=new vec3();

    kegel griff=new kegel();
    kegel scheibe=new kegel();
    kegel spitze=new kegel();

    public void rotatez(double alpha)
    {
    	p.rotatez(alpha);
    	v.rotatez(alpha);
    }

    public void rotatey(double beta)
    {
    	p.rotatey(beta);
    	v.rotatey(beta);
    }

    public void render()
    {
    	griff.d1=20;
	griff.d2=8;
	griff.p.add(p,v,5);
	griff.v.add(v,v,50);
    	griff.render();
	scheibe.d1=100;
	scheibe.d2=100;
	scheibe.p.add(p,v,-5);
	scheibe.v.add(v,v,9);
	scheibe.render();
	spitze.d1=20;
	spitze.d2=3;
	spitze.p.add(p,v,-5);
	spitze.v.add(v,v,-21);
	spitze.render();
    }

    public void draw(Graphics g)
    {
    	if(v.x<0)
	{
		griff.draw(g);
		scheibe.draw(g);
		spitze.draw(g);
	}
	else
	{
		spitze.draw(g);
		scheibe.draw(g);
		griff.draw(g);
	}
    }
}


class kegel
{
	vec3 p = new vec3(),v = new vec3();
	double d1,d2;

	double ax,ay,bx,by;	// die beiden Ellipsenmittelpunkte
	double vabs2, vabs3;	// Betrag von v (Projektion und 3d)
	double d1x,d1y,h1x,h1y;	// Achsen von Ellipse 1
	double d2x,d2y,h2x,h2y;	// Achsen von Ellipse 2
	double h1,l,d1d2,c,w,gamma; // zur Tangentenpunktbestimmung

	// x und y liegen jetzt in der 2D-Ebene
	// das entspricht y und z in der 3D-Ebene
	int x[]=new int[100];
	int y[]=new int[100];
	int ind=0;
	Polygon rand=new Polygon(x,y,100);

	int xi[]=new int[100];
	int yi[]=new int[100];
	int indi=0;
	Polygon innen=new Polygon(x,y,100);

	public void rotatez(double alpha)
	{
		p.rotatez(alpha);
		v.rotatez(alpha);
	}

	public void rotatey(double beta)
	{
		p.rotatey(beta);
		v.rotatey(beta);
	}
	
	public void render()
	{
		ax=p.y;
		ay=p.z;
		bx=ax+v.y;
		by=ay+v.z;
		vabs2=java.lang.Math.sqrt(v.y*v.y+v.z*v.z);
		vabs3=java.lang.Math.sqrt(v.x*v.x+v.y*v.y+v.z*v.z);
		d1x=d1*(-v.z)/vabs2;
		d1y=d1*  v.y /vabs2;
		h1x=d1*  v.y /vabs2 * java.lang.Math.abs(v.x)/vabs3;
		h1y=d1*  v.z /vabs2 * java.lang.Math.abs(v.x)/vabs3;
		d2x=d2*(-v.z)/vabs2;
		d2y=d2*  v.y /vabs2;
		h2x=d2*  v.y /vabs2 * java.lang.Math.abs(v.x)/vabs3;
		h2y=d2*  v.z /vabs2 * java.lang.Math.abs(v.x)/vabs3;

		// Winkel des Tangentenpunktes bestimmen
		h1=java.lang.Math.sqrt(h1x*h1x+h1y*h1y);
		if (h1<0.0001)
			h1=0.0001;
		l=vabs2*d1/h1;
		if (d1>1.0001*d2)
			d1d2=d1/d2;
		else
			d1d2=1.0001;
		c=l/(d1d2-1);
		if (l+c>d1/2)
			w=java.lang.Math.sqrt((l+c)*(l+c)-d1*d1/4);
		else
			w=0;
		gamma=java.lang.Math.atan(2*w/d1);

		// Ellipsen
		int i;
		for (i=0;i<100;i++)
		{
			rand.xpoints[i]=100;
			rand.ypoints[i]=100;
			innen.xpoints[i]=100;
			innen.ypoints[i]=100;
		}
		ind=0;
		ind=ellipse(rand,ind,ax,ay,h1x,h1y,d1x,d1y,gamma,2*3.14159-gamma);
		ind=ellipse(rand,ind,bx,by,h2x,h2y,d2x,d2y,-gamma,gamma);
		rand.xpoints[ind]=rand.xpoints[0];
		rand.ypoints[ind]=rand.ypoints[0];
		ind++;
		indi=0;
		if(v.x<=0)
			indi=ellipse(innen,indi,ax,ay,h1x,h1y,d1x,d1y,0,2*3.14159);
		else
			indi=ellipse(innen,indi,bx,by,h2x,h2y,d2x,d2y,0,2*3.14159);
		rand.npoints=ind;
		innen.npoints=indi;
	}
	
	public void draw(Graphics g)
	{
		// zum Testen die Hauptachsen der Ellipsen zeichnen:
/*		g.drawLine(	100+(int)(ax-d1x/2),100-(int)(ay-d1y/2),
				100+(int)(ax+d1x/2),100-(int)(ay+d1y/2));
		g.drawLine(	100+(int)(ax-h1x/2),100-(int)(ay-h1y/2),
				100+(int)(ax+h1x/2),100-(int)(ay+h1y/2));
		g.drawLine(	100+(int)(bx-d2x/2),100-(int)(by-d2y/2),
				100+(int)(bx+d2x/2),100-(int)(by+d2y/2));
		g.drawLine(	100+(int)(bx-h2x/2),100-(int)(by-h2y/2),
				100+(int)(bx+h2x/2),100-(int)(by+h2y/2));
		g.drawLine(	
		100+(int)(ax+h1x/2*java.lang.Math.cos(gamma)+d1x/2*java.lang.Math.sin(gamma)),
		100-(int)(ay+h1y/2*java.lang.Math.cos(gamma)+d1y/2*java.lang.Math.sin(gamma)),
		100+(int)(bx+h2x/2*java.lang.Math.cos(gamma)+d2x/2*java.lang.Math.sin(gamma)),
		100-(int)(by+h2y/2*java.lang.Math.cos(gamma)+d2y/2*java.lang.Math.sin(gamma)));
*/		//g.drawPolygon(innen);
		g.setColor(java.awt.Color.red);
		g.fillPolygon(rand);
		g.setColor(java.awt.Color.black);
		g.drawPolygon(rand);
		g.drawPolygon(innen);
// 	      	g.drawRect(10,10,55,55);
	}
	
	// lokale Funktion (halbe Ellipse ab index i in x[],y[]
	// Lage wird durch 2D-Vektoren p, b und h festgelegt
	int ellipse(Polygon p, int ind,
		double px, double py, 
		double hx, double hy, 
		double dx, double dy,
		double gamma0, double gamma1)
	{
		double ga=0;
		int i=ind;

		for (ga=gamma0; ga<gamma1; ga+=5.0/180.0*3.14159)
		{
			p.xpoints[i]=100+(int)(px	+hx/2*java.lang.Math.cos(ga)
							+dx/2*java.lang.Math.sin(ga));
			p.ypoints[i]=100-(int)(py	+hy/2*java.lang.Math.cos(ga)
							+dy/2*java.lang.Math.sin(ga));
			i++;
		}
		return(i);
	}
}


