/* Viewing Sources */


/*
Nhan Le
PolyApplet.java

-a simple applet that graphs polynomial functions
-a multitude of features will will be added in future revisions including but not limited to:
	integral calculations, 
	visual representations of areas under curve, 
	and new interface 
		recode "zoom in/zoom out"
		add traces to provide values/derivatives

<applet code="PolyApplet" width="500" height="500"></applet>
 */


import java.awt.*;
import java.awt.event.*;
import java.applet.*;
import java.util.*;
import java.math.*;


class Poly{
	private Vector terms;
	Poly(){	this("0");}
	Poly(String constants){
		StringTokenizer st = new StringTokenizer(constants, " ");
		terms = new Vector();
		while(st.hasMoreTokens())
			terms.add(new Double(st.nextToken()));
	}
	public String toString(){
		StringBuffer sb = new StringBuffer(
			"\ndegree: "+(terms.size()-1)+
			"\npoly expression: "
		);
		Enumeration e = terms.elements();
		int i = terms.size()-1;//i is the degree of the Polynomial
		while(e.hasMoreElements()&&i>=1)
			sb.append(((Double)e.nextElement()).toString() +"x^"+(i--)+" + ");
		sb.append(((Double)e.nextElement()).toString());
		return sb.toString();
	}
	public double eval(double x){
		double d =0.0;
		Enumeration e = terms.elements();
		int i = terms.size()-1;//i is the degree of the Polynomial
		while(e.hasMoreElements()&&i>=1)
			d += ((Double)e.nextElement()).doubleValue() * Math.pow(x,(i--));
		d += ((Double)e.nextElement()).doubleValue();
		return d;
	}
}

class PolyGraph extends Canvas{
	private Poly equation;
		//
	private final double width = 500;
	private final double height = 360;
		//window width and height
		
	private double mx;//min x
	private double Mx;//max x
	private double my;//min y
	private double My;//max y
		// the min/max x/y are window values like on TI calcs

	private double xUnit;
	private double yUnit;
		//
	PolyGraph(){
		this("0",-3,3,-2,2);
	}
	PolyGraph(String equation, double mx, double Mx, double my, double My){
		this.equation = new Poly(equation);
		setBackground(Color.black);

		this.mx=mx;
		this.Mx=Mx;
		this.my=my;
		this.My=Mx;
			//
		
		xUnit = width / (Math.abs(mx) + Math.abs(Mx));
			//xUnit: absolute length of one x unit on the graph

		yUnit = height / (Math.abs(my) + Math.abs(My));
			//yUnit: absolute length of one y unit on the graph
			
	}
	public void paint(Graphics g){
		g.translate((int)(width/2), (int)(height/2));

		//init t intervals - "where to graph"{
			double 	ti_x=mx, 
					// t initial x
				tf_x=Mx, 
					// t final x
				ti_y=my,
					// t initial y
				tf_y=Mx;
					// t final y				
		//}

		//draw vertical and horizontal axis "bars"{
			g.setColor(new Color(0.5f, 0.0f, 0.0f));
			for(double t=ti_x; t<=tf_x; t+=1.0){
				vertical(g,(int)(t*xUnit));
			}
			for(double t=ti_y; t<=tf_y; t+=1.0){
				horizontal(g,(int)(t*yUnit));				
			}
		//}

		//draw x and y axis{
			g.setColor(Color.red);
			vertical(g,0);
			horizontal(g,0);
		//}

		//draw the polynomial function{
			g.setColor(Color.yellow);
			double	t_x = ti_x,
				t_y = ti_y;
			for(; (t_x<=tf_x)&&(t_y<=tf_y); t_x+=0.01, t_y+=0.01){
				g.drawLine(	
					(int)(t_x*xUnit),
					(int)(-1*equation.eval(t_y)*yUnit),
					(int)(t_x*xUnit),
					(int)(-1*equation.eval(t_y+0.01)*yUnit)
				);
			}
		//}
	}
	private void vertical(Graphics g, int x){
		g.drawLine(x,(int)(height*(-.5)),x,(int)(height*(.5)));
	}
	private void horizontal(Graphics g, int y){
		g.drawLine((int)(width*-.5),y,(int)(width*.5),y);
	}
	public void setEquation(String polystring){
		equation = new Poly(polystring);
	}
	public void zoomIn(){
		mx+=1.0;
		Mx-=1.0;
		my+=1.0;
		My-=1.0;
		xUnit = width / (Math.abs(mx) + Math.abs(Mx));
		yUnit = height / (Math.abs(my) + Math.abs(My));
		repaint();
	}
	public void zoomOut(){
		mx-=1.0;
		Mx+=1.0;
		my-=1.0;
		My+=1.0;
		xUnit = width / (Math.abs(mx) + Math.abs(Mx));
		yUnit = height / (Math.abs(my) + Math.abs(My));
		repaint();
	}
}


public class PolyApplet extends Applet 
implements ActionListener{
	private TextField tfpolyexpression;
	private Label lpolyexpression;
	private Button bgraph;
	private Button zin;
	private Button zout;
	private PolyGraph pg;

	public void init(){
		pg = new PolyGraph("1 0 1 -3",-10,10,-10,10);
		setLayout(new BorderLayout());
		add(createTitlePanel(),BorderLayout.NORTH);
		add(pg,BorderLayout.CENTER);
		add(createControlPanel(),BorderLayout.SOUTH);
	}
	public void paint(Graphics g){
		pg.repaint();
		setSize(500,500);
			//asserts that the applet size does not change
	}
	public void actionPerformed(ActionEvent ae){
		if(ae.getSource() == bgraph){
			pg.setEquation(getPolyExpression());
		}
		else if(ae.getSource()==zin){
			pg.setEquation(getPolyExpression());
			pg.zoomIn();
		}
		else if(ae.getSource()==zout){
			pg.setEquation(getPolyExpression());
			pg.zoomOut();
		}	
		repaint();
	}
	public String getPolyExpression(){
		return tfpolyexpression.getText();
	}
	private Panel createTitlePanel(){
		Panel p = new Panel(new GridLayout(1,1));
		Label ltitle = new Label(
			"PolyApp.java v0.59",
			Label.CENTER
		);
		p.add(ltitle);
		return p;
	}
	private Panel createInputPanel(){
		Panel p = new Panel(new GridLayout(1,2));
		tfpolyexpression = new TextField();
		tfpolyexpression.setText("1 0 1 -2");
		lpolyexpression = new Label(
			"<- enter polynomial",
			Label.LEFT
		);
		p.add(tfpolyexpression);
		p.add(lpolyexpression);
		return p;
	}
	private Panel createZoomPanel(){
		Panel p = new Panel(new GridLayout(1,4));
		zin = new Button("zoom in");
		zout = new Button("zoom out");
		p.add(zin);
		p.add(zout);
		zin.addActionListener(this);
		zout.addActionListener(this);
		return p;
	}
	private Panel createControlPanel(){
		Panel p = new Panel(new BorderLayout());
		Panel n = new Panel(new GridLayout(3,1));
		Label linstructions = new Label(
			"Enter coefficients separated "+
			"by spaces.",
			Label.CENTER
		);
		Label lexample = new Label(
			"example: \"1 0 1 -2\" "+
			"is \"x^3 + x - 2\"",
			Label.CENTER
		);
		n.add(linstructions);
		n.add(lexample);
		n.add(createZoomPanel());
		p.add(n,BorderLayout.NORTH);
		p.add(createInputPanel(),BorderLayout.CENTER);

		bgraph = new Button("graph");
		p.add(bgraph,BorderLayout.SOUTH);
		bgraph.addActionListener(this);
		return p;
   }
}

/* sources by Nhan Le */
/* [email protected] */
/* [email protected] */
/* [email protected] */
/* if you find the sources useful or if you want to make any modifications, just email me */
/* html generated using GNU source-highlight 1.8 =-) */