/*
This code is released into the public domain at zero cost and with no warrenty to its quaility or usability.
use and abuse as you see fit.

	Rotation 03

	rednuht jumpstation.co.uk 2006

	Interactive, click in the 8 segments and note the result (in blue)
	From http://www.jumpstation.co.uk/rotation/
*/
import java.applet.*;
import java.awt.*;
import java.awt.image.*;
import java.awt.Color.*;
import java.awt.event.*;


public class rotation03 extends Applet implements Runnable, MouseListener
{

	Thread sequence = null;
	int speed = 250;
	static int width = 162;
	static int height = 162;
	static int mode=0;
	static double angle = 0;
	static double cx = 80;
	static double cy = 80;
	static double r = 70;
	static double sx = 20;
	static double sy = 20;
	static boolean quit,painter;
	
	public void init()
	{
		addMouseListener(this);
		mode=0;		
	}	

	public void drawPixel(Graphics g, int x, int y) {
		g.drawLine(x, y, x, y);
	}

	public void update (Graphics g)
	{ 		paint(g);	}

	//========================================== drawCircle
	//    // Convenience method to draw from center with radius
	public void drawCircle(Graphics cg, int xCenter, int yCenter, int r) {
	        cg.drawOval(xCenter-r, yCenter-r, 2*r, 2*r);
	}//end drawCircle
	    


	public void paint(Graphics g) {
		double rangle,xa,ya;
		if (painter==false) { mode=0; }
		if (mode==0) {
			g.setColor(new Color(255,255,255));
			g.fillRect(0,0,width,height);
			g.setColor(new Color(200,200,200));
			g.drawLine(0,(int)cy,width,(int)cy);
			g.drawLine((int)cx,0,(int)cx,height);
			g.drawLine(0,0,width,height);
			g.drawLine(width,0,0,height);
			g.setColor(new Color(0,0,0));
			g.drawRect(5,5,width-10,height-10);
			g.setColor(new Color(255,0,0));
			drawPixel(g,(int)cx, (int)cy);
			drawCircle(g,(int)cx,(int)cy,(int)r);
			mode++;
		} else if(mode==1) {
			// find radius
			r=Math.sqrt(Math.pow(length((int)sx,(int)cx),2)+Math.pow(length((int)sy,(int)cy),2));	
			g.setColor(new Color(0,255,0));
			drawPixel(g,(int)sx, (int)sy);
			g.drawLine((int)cx,(int)cy,(int)sx, (int)sy);
			drawCircle(g,(int)cx,(int)cy,(int)r);
			mode++;
		} else if(mode==2) {
			// find angle
			double precalc;
			precalc = length((int)sx,(int)cx) / r;
			angle = (180D/Math.PI) * Math.asin(precalc); 
			mode++;
		} else if(mode==3) {
			mode++;
		} else if(mode==4) {
			g.setColor(new Color(0,0,255));
			rangle = angle * Math.PI /180D;
			xa = Math.cos(rangle) * r + cx;
			ya = Math.sin(rangle) * r + cy;
			drawPixel(g,(int)xa, (int)ya);
			g.drawLine((int)cx,(int)cy,(int)xa, (int)ya);
			if (angle>360) { angle=angle-360; }
			mode++;
		}
		painter=false;
	}

	// this function used to always return a positive value but was screwing up things later on.
	// turns out it is better to allow negative lengths
	public int length(int a, int b) {
		return(a-b);
	}


   	public void run() {
      	while (true) { // infinite cycle
 			try {Thread.sleep(speed);} catch (InterruptedException e){}
			painter=true;
			repaint();
		}
   	}

   	public void start() {
     		if(sequence==null) {
        		sequence=new Thread(this);
        		sequence.start();
     		}	
   	}

   	public void stop() { 
   		sequence = null;
   	}


    public void mousePressed(MouseEvent event) { }

    public void mouseReleased(MouseEvent event) { }

    public void mouseEntered(MouseEvent event) { }

    public void mouseExited(MouseEvent event) { }

    public void mouseClicked(MouseEvent event) { 
		sx=event.getX();
		sy=event.getY();
		mode=0;
    }

}
