// P0803.java:$B2sE>BN(B(Z$B%P%C%U%!K!(B)

package applet;

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import Glib.*;

public class P0803 extends xApplet
	implements ActionListener
{	JTextField tf;
	JButton[]bt=new JButton[3];
	String[]str={"Start","Clear","Exit"};
	xGraphics3 G3;
	int k=300;
	double b=0.5,step=Math.PI/1200,rtx=22.5,rty=0.0;
	xPoint3D Lt=new xPoint3D(1.0,1.0,1.0);

	public void init()
	{	app_init(6);
		Container cp=getContentPane();
		cp.setBackground(getBackground());
		cp.setLayout(new FlowLayout(FlowLayout.LEFT));
		JLabel lb=new JLabel("$BY(J?N(!'(Bb=");
		lb.setForeground(Color.black);
		cp.add(lb);
		tf=new JTextField(4);
		tf.setBackground(Color.white);
		tf.addActionListener(this);
		cp.add(tf);
		for(int i=0;i<str.length;i++)
		{	bt[i]=new JButton(str[i]);
			bt[i].addActionListener(this);
			cp.add(bt[i]);
		}
		G3=new xGraphics3(getGraphics());
		G3.set0(CA,1);
		int i=(int)(Math.floor((rtx+90.0)/180.0));
		rtx=rtx-i*180.0;
		i=(int)(Math.floor((rty+90.0)/180.0));
		rty=rty-i*180.0;
		G3.setproj(rtx,rty);
		G3.setshdspectra(5,3);
	}

	public void actionPerformed(ActionEvent evt)
	{	if(evt.getSource()==tf)
			b=Double.valueOf(tf.getText()).doubleValue();
		if(evt.getSource()==bt[0])
			paint2();
		if(evt.getSource()==bt[1])
			repaint();
		if(evt.getSource()==bt[2])
			System.exit(0);
	}

	private void paint2()
	{	xTimer t=new xTimer();
		t.settimer();
		int[]zbuf=new int[AppSize.width*AppSize.height];
		int pixel=getno(AppSize.width-1,AppSize.height-1)+1;
		for(int no=0;no<pixel;no++)
			zbuf[no]=-10000;
		xPoint3D lt=xMath.ev(Lt);
		for(double fi=0;fi<=2*Math.PI;fi=fi+step)
		{	for(double th=0;th<=Math.PI;th=th+step)
			{	xPoint3D p=func(th,fi);
				xPoint3D nv=xMath.ev(getnv(th,fi));
				if(G3.getproj(nv).z>-0.1)
				{	xPoint3D sp=G3.getproj(xMath.mlt(k,p));
					int x=xMath.fint(sp.x);
					int y=xMath.fint(sp.y);
					int z=xMath.fint(sp.z);
					int sx=CA.x+x;
					int sy=CA.y+y;
					if(sx>=0 && sx<AppSize.width
						&& sy>=0 && sy<AppSize.height)
					{	int no=getno(sx,sy);
						if(z>zbuf[no])
						{	int its=(int)(240*xMath.ip(lt,nv));
							G3.putpixel(x,y,G3.getspectrum(its));
							zbuf[no]=z;
						}
					}
				}
			}
		}
		t.gettimer();
		G3.textout(10,60,"Time="+t.Time,240,16);
	}

	private int getno(int x,int y)
	{	return x+y*AppSize.width;
	}

	private xPoint3D func(double th,double fi)
	{	double x=Math.sin(th)*Math.sin(fi);
		double y=b*Math.sin(2*th);
		double z=Math.sin(th)*Math.cos(fi);
		return new xPoint3D(x,y,z);
	}

	private xPoint3D getnv(double th,double fi)
	{	double x=-2*b*Math.cos(2*th)*Math.sin(fi);
		double y=Math.cos(th);
		double z=-2*b*Math.cos(2*th)*Math.cos(fi);
		return new xPoint3D(x,y,z);
	}
}
