|
|
GCalc Source Code
/* GCalc Graphing Calculator Applet
Version 1.5
Copyright 2001 Jiho Kim
*/
//package GCalc;
import java.applet.Applet;
import java.awt.event.*;
import java.awt.*;
import java.util.*;
public class GCalc extends Applet implements ActionListener, ItemListener
{
String notice = "GCalc\nVersion 1.501\nCopyright 1999-2001 Jiho Kim\n";
TextField textfield1;
Graph graph1;
Button axisButton, scoresButton, gridButton, dotsButton;
Button standardZoomButton, trigZoomButton, squareZoomButton, graphFitZoomButton;
Button zoomInButton, zoomOutButton;
TextField xZoom, yZoom;
TextField xminTF, xmaxTF, xsclTF,
yminTF, ymaxTF, ysclTF;
Button resetButton, previousButton, nextButton;
Button regraphButton;
Choice colorChoice;
String[] colorString;
Color[] colorArray;
StringList sl;
public static void main(String[] args)
{
Frame f = new Frame("GCalc");
GCalc gc = new GCalc();
gc.init();
gc.start();
f.addWindowListener(f);
f.add("Center",gc);
f.setSize(700,430);
f.setResizable(false);
f.show();
}
public void init()
{
initApplet();
initGUI();
}
void initApplet()
{
setVisible(true);
setBackground(new Color(240,240,200));
setLayout(new BorderLayout(5,5));
graph1 = new Graph(this,460,330);
colorString = new String[5];
colorArray = new Color[5];
colorString[0]="Blue"; colorArray[0]=Color.blue;
colorString[1]="Green"; colorArray[1]=Color.green.darker();
colorString[2]="Purple"; colorArray[2]=Color.magenta.darker();
colorString[3]="Brown"; colorArray[3]=Color.orange.darker();
colorString[4]="Black"; colorArray[4]=Color.black;
sl = new StringList();
}
void initGUI()
{
Font normalFont = new Font("Courier", Font.PLAIN, 12);
Panel graphProperties = new Panel();
graphProperties.setLayout(new GridLayout(1,4,1,0));
axisButton = new Button("Axis ON");
scoresButton = new Button ("Scale ON");
gridButton = new Button("Grid OFF");
dotsButton = new Button("Continuous");
axisButton.addActionListener(this);
scoresButton.addActionListener(this);
gridButton.addActionListener(this);
dotsButton.addActionListener(this);
graphProperties.add(axisButton);
graphProperties.add(scoresButton);
graphProperties.add(gridButton);
graphProperties.add(dotsButton);
//Center--Graph, input textfield, graph properties
Panel west=new Panel();
textfield1 = new TextField("",42);
textfield1.setFont(new Font("Courier", Font.PLAIN, 12));
textfield1.setBackground(Color.white);
textfield1.addActionListener(this);
Panel westCenter = new Panel();
westCenter.setLayout(new BorderLayout(5,5));
westCenter.add("North",textfield1);
westCenter.add("Center",graph1);
westCenter.add("South",graphProperties);
west.add(westCenter);
add("West",west);
//East--zoom Buttons7
standardZoomButton = new Button("Standard Zoom");
trigZoomButton = new Button ("Trig Zoom");
squareZoomButton = new Button("Square Zoom");
graphFitZoomButton = new Button("Graph-Fit Zoom");
standardZoomButton.addActionListener(this);
trigZoomButton.addActionListener(this);
squareZoomButton.addActionListener(this);
graphFitZoomButton.addActionListener(this);
Panel zoomButtons = new Panel();
zoomButtons.setLayout(new GridLayout(4,1));
zoomButtons.add(standardZoomButton);
zoomButtons.add(trigZoomButton);
zoomButtons.add(squareZoomButton);
zoomButtons.add(graphFitZoomButton);
zoomInButton = new Button("Zoom In");
zoomOutButton = new Button("Zoom Out");
xZoom = new TextField("2.0");
yZoom = new TextField("2.0");
xZoom.setFont(normalFont);
yZoom.setFont(normalFont);
xZoom.setBackground(Color.white);
yZoom.setBackground(Color.white);
zoomInButton.addActionListener(this);
zoomOutButton.addActionListener(this);
xZoom.addActionListener(this);
yZoom.addActionListener(this);
Panel manualZooms = new Panel();
manualZooms.setLayout(new GridLayout(4,1));
manualZooms.add(zoomInButton);
manualZooms.add(zoomOutButton);
manualZooms.add(xZoom);
manualZooms.add(yZoom);
//East--range fields
xminTF = new TextField("",20);
xmaxTF = new TextField("",20);
xsclTF = new TextField("",20);
yminTF = new TextField("",20);
ymaxTF = new TextField("",20);
ysclTF = new TextField("",20);
xminTF.addActionListener(this);
xmaxTF.addActionListener(this);
xsclTF.addActionListener(this);
yminTF.addActionListener(this);
ymaxTF.addActionListener(this);
ysclTF.addActionListener(this);
xminTF.setFont(normalFont);
xmaxTF.setFont(normalFont);
xsclTF.setFont(normalFont);
yminTF.setFont(normalFont);
ymaxTF.setFont(normalFont);
ysclTF.setFont(normalFont);
xminTF.setBackground(Color.white);
xmaxTF.setBackground(Color.white);
xsclTF.setBackground(Color.white);
yminTF.setBackground(Color.white);
ymaxTF.setBackground(Color.white);
ysclTF.setBackground(Color.white);
Panel xminPanel = new Panel();
Panel xmaxPanel = new Panel();
Panel xsclPanel = new Panel();
Panel yminPanel = new Panel();
Panel ymaxPanel = new Panel();
Panel ysclPanel = new Panel();
xminPanel.setLayout(new BorderLayout());
xmaxPanel.setLayout(new BorderLayout());
xsclPanel.setLayout(new BorderLayout());
yminPanel.setLayout(new BorderLayout());
ymaxPanel.setLayout(new BorderLayout());
ysclPanel.setLayout(new BorderLayout());
xminPanel.add("Center",new Label ("XMin", Label.LEFT));
xminPanel.add("East",xminTF);
xmaxPanel.add("Center",new Label ("XMax", Label.LEFT));
xmaxPanel.add("East",xmaxTF);
xsclPanel.add("Center",new Label ("XScale", Label.LEFT));
xsclPanel.add("East",xsclTF);
yminPanel.add("Center",new Label ("YMin", Label.LEFT));
yminPanel.add("East",yminTF);
ymaxPanel.add("Center",new Label ("YMax", Label.LEFT));
ymaxPanel.add("East",ymaxTF);
ysclPanel.add("Center",new Label ("YScale", Label.LEFT));
ysclPanel.add("East",ysclTF);
Panel xyRange = new Panel();
xyRange.setLayout(new GridLayout(6,1));
xyRange.add(xminPanel);
xyRange.add(xmaxPanel);
xyRange.add(xsclPanel);
xyRange.add(yminPanel);
xyRange.add(ymaxPanel);
xyRange.add(ysclPanel);
//East--misc buttons
resetButton = new Button ("RESET");
previousButton = new Button ("Prev");
nextButton = new Button("Next");
previousButton.addActionListener(this);
nextButton.addActionListener(this);
resetButton.addActionListener(this);
colorChoice = new Choice();
colorChoice.addItemListener(this);
for (int i=0; imax) max=yy;
}
}
}
if (max!=Double.MIN_VALUE && min!=Double.MAX_VALUE && max!=min &&
min!=Double.NEGATIVE_INFINITY && max!=Double.POSITIVE_INFINITY)
{
graph1.changeRange(graph1.xmin,graph1.xmax,graph1.xscl,
min,max,graph1.yscl);
graph1.clearGraph();
graph1.drawPostfix();
}
}
else
{
graphFitZoomButton.setLabel("In progress");
graph1.fitToZoomBox();
graph1.drawPostfix();
}
updateRangeTF();
graphFitZoomButton.setLabel("Graph-Fit Zoom");
}
else
if (target == standardZoomButton)
{
standardZoomButton.setLabel("In progress");
graph1.changeRange(-10,10,1,-10,10,1);
graph1.clearGraph();
graph1.drawPostfix();
updateRangeTF();
standardZoomButton.setLabel("Standard Zoom");
}
else
if (target == trigZoomButton)
{
trigZoomButton.setLabel("In progress");
graph1.changeRange(-2.5*Math.PI,2.5*Math.PI,Math.PI/2,-4,4,1);
graph1.clearGraph();
graph1.drawPostfix();
updateRangeTF();
trigZoomButton.setLabel("Trig Zoom");
}
else
if (target == squareZoomButton)
{
squareZoomButton.setLabel("In progress");
double d = graph1.ypixels*(graph1.xmax-graph1.xmin)/2/graph1.xpixels;
graph1.changeRange(graph1.xmin,graph1.xmax,graph1.xscl,
graph1.yavg-d,graph1.yavg+d,graph1.yscl);
graph1.clearGraph();
graph1.drawPostfix();
updateRangeTF();
squareZoomButton.setLabel("Square Zoom");
}
else
if (target == zoomInButton)
{
zoomInButton.setLabel("In progress");
setZoomValues();
double d = (graph1.xmax-graph1.xmin)/graph1.xzoom/2;
double e = (graph1.ymax-graph1.ymin)/graph1.yzoom/2;
graph1.changeRange(graph1.xavg-d,graph1.xavg+d,graph1.xscl,
graph1.yavg-e,graph1.yavg+e,graph1.yscl);
graph1.clearGraph();
graph1.drawPostfix();
updateRangeTF();
updateZoomTF();
zoomInButton.setLabel("Zoom In");
}
else
if (target == zoomOutButton)
{
zoomOutButton.setLabel("In progress");
setZoomValues();
double d = (graph1.xmax-graph1.xmin)*graph1.xzoom/2;
double e = (graph1.ymax-graph1.ymin)*graph1.yzoom/2;
graph1.changeRange(graph1.xavg-d,graph1.xavg+d,graph1.xscl,
graph1.yavg-e,graph1.yavg+e,graph1.yscl);
graph1.clearGraph();
graph1.drawPostfix();
updateRangeTF();
updateZoomTF();
zoomOutButton.setLabel("Zoom Out");
}
else
if (target == xmaxTF || target == xminTF || target == ymaxTF ||
target == yminTF || target == xsclTF || target == ysclTF )
{
setRangeValues();
graph1.clearGraph();
graph1.drawPostfix();
}
else
if (target==resetButton)
{
setRangeValues();
graph1.clearList();
graph1.clearGraph();
textfield1.setText("");
colorChoice.select(0);
sl.clear();
}
else
if (target == previousButton)
{
textfield1.setText(sl.getPrev());
}
else
if (target == nextButton)
{
textfield1.setText(sl.getNext());
}
}
void processUserInput(String strInput)
{
String mystr = strInput.trim().toLowerCase();
String postfixText="";
int commandType = 0;
if (mystr.equals("clear"))
{
commandType = 3;
graph1.clearList();
graph1.clearGraph();
textfield1.setText("");
colorChoice.select(0);
sl.clear();
System.gc();
}
/* else if (mystr.equals("hide"))
{
commandType = 1;
graph1.setVisible(! graph1.isVisible());
graph1.clearGraph();
graph1.drawPostfix();
textfield1.setText("");
}
*/ else if (mystr.equals("axis"))
{
commandType = 1;
graph1.axis = ! graph1.axis;
graph1.clearGraph();
textfield1.setText("");
}
else if (mystr.equals("tick"))
{
commandType = 1;
graph1.scores = ! graph1.scores;
graph1.clearGraph();
textfield1.setText("");
}
else if (mystr.equals("dots"))
{
commandType = 1;
graph1.dots = ! graph1.dots;
graph1.clearGraph();
graph1.drawPostfix();
textfield1.setText("");
}
else if (mystr.equals("grid"))
{
commandType = 1;
graph1.grid = ! graph1.grid;
graph1.clearGraph();
textfield1.setText("");
}
else if (mystr.equals("prev"))
{
commandType = 1;
textfield1.setText(sl.getPrev());
}
else if (mystr.equals("next"))
{
commandType = 1;
textfield1.setText(sl.getNext());
}
else if (mystr.startsWith("~"))
{
commandType = 1;
int val=0;
try
{
Integer d = Integer.valueOf(mystr.substring(1));
val = d.intValue();
}
catch (NumberFormatException exception) {}
graph1.remove(val);
graph1.clearGraph();
graph1.drawPostfix();
textfield1.setText("");
}
else if (mystr.startsWith("list"))
{
commandType = 1;
graph1.getList().showInfix();
textfield1.setText("");
}
else if (mystr.startsWith("#"))
{
commandType = 1;
int val=0;
try
{
Integer d = Integer.valueOf(mystr.substring(1));
val = d.intValue();
}
catch (NumberFormatException exception) {}
textfield1.setText(graph1.getList().get(val).infixStr);
}
Postfix postfix=null;
if (commandType==0)
{
long timer = System.currentTimeMillis();
commandType = 2;
sl.add(mystr);
sl.resetCursor();
setRangeValues();
postfix = new Postfix(mystr);
postfixText = postfix.getStack().showAll();
graph1.drawPostfix(postfix, colorArray[colorChoice.getSelectedIndex()]);
// graph1.drawPostfix(postfix.derivative(), new Color(200,200,200));
graph1.drawPostfix();
textfield1.setText("");
colorChoice.select((colorChoice.getSelectedIndex()+1)%colorArray.length);
}
if (commandType==2 && !postfixText.equals(""))
{
System.out.println("INFIX: "+mystr);
System.out.println("POSTFIX: "+postfixText);
// System.out.println("FULLY PARENTHESIZED INFIX: "+postfix.infix());
// System.out.println("DERIVATIVE:"+postfix.derivative().infix());
System.out.println();
}
}
public void setZoomValues()
{
double xz, yz;
try
{
Double d = Double.valueOf(xZoom.getText());
xz = d.doubleValue();
}
catch (NumberFormatException exception)
{
xz = graph1.xzoom;
}
try
{
Double d = Double.valueOf(yZoom.getText());
yz = d.doubleValue();
}
catch (NumberFormatException exception)
{
yz = graph1.yzoom;
}
if (xz*yz!=0)
{
graph1.yzoom = Math.abs(yz);
graph1.xzoom = Math.abs(xz);
updateZoomTF();
}
}
public void setRangeValues()
{
double xmax1, xmin1, xscl1;
double ymax1, ymin1, yscl1;
Postfix pf;
pf = new Postfix(xminTF.getText());
xmin1=pf.isConstant()?pf.evaluate(0):graph1.xmin;
pf = new Postfix(xmaxTF.getText());
xmax1=pf.isConstant()?pf.evaluate(0):graph1.xmax;
pf = new Postfix(xsclTF.getText());
xscl1=pf.isConstant()?pf.evaluate(0):graph1.xscl;
pf = new Postfix(yminTF.getText());
ymin1=pf.isConstant()?pf.evaluate(0):graph1.ymin;
pf = new Postfix(ymaxTF.getText());
ymax1=pf.isConstant()?pf.evaluate(0):graph1.ymax;
pf = new Postfix(ysclTF.getText());
yscl1=pf.isConstant()?pf.evaluate(0):graph1.yscl;
if (xmax1>xmin1 && ymax1>ymin1 /*&& yscl1!=0 && xscl1!=0*/)
{
graph1.changeRange(xmin1, xmax1, xscl1, ymin1, ymax1, yscl1);
updateRangeTF();
}
}
void updateRangeTF()
{
xmaxTF.setText(""+graph1.xmax);
xminTF.setText(""+graph1.xmin);
xsclTF.setText(""+graph1.xscl);
ymaxTF.setText(""+graph1.ymax);
yminTF.setText(""+graph1.ymin);
ysclTF.setText(""+graph1.yscl);
}
void updateZoomTF()
{
xZoom.setText(""+graph1.xzoom);
yZoom.setText(""+graph1.yzoom);
}
}
class Graph extends Canvas implements MouseListener, MouseMotionListener
{
private GCalc host;
private Image image;
private Graphics page;
public boolean axis, dots, scores, grid;
public double xmax, xmin, xscl, xscl2, xavg, xfact;
public double ymax, ymin, yscl, yscl2, yavg, yfact;
public double xzoom, yzoom;
public int xpixels, ypixels;
private PostfixList pfl;
private float mx, my;
public int dragstartX, dragstartY;
public int dragdX, dragdY;
int preferredWidth;
int preferredHeight;
Graph (GCalc gc, int xSize, int ySize)
{
this(gc, xSize, ySize, -10, 10, 1, -10, 10, 1);
}
Graph (GCalc gc, int xSize, int ySize, double xmin1, double xmax1, double xscl1,
double ymin1, double ymax1, double yscl1)
{
host = gc;
xpixels=xSize;
ypixels=ySize;
setSize(xpixels+1,ypixels+1);
changeRange(xmin1, xmax1, xscl1, ymin1, ymax1, yscl1);
initDefault();
clearList();
addMouseListener(this);
addMouseMotionListener(this);
}
private void initDefault()
{
axis = true;
dots = false;
scores = true;
grid = false;
xzoom=2;
yzoom=2;
my=0;
mx=0;
dragstartX=-1;
dragstartY=-1;
dragdX=0;
dragdY=0;
}
public void mouseClicked (MouseEvent event)
{
switch (event.getClickCount())
{
case 1:
break;
default:
double x=event.getX()/xfact+xmin;
double y=event.getY()/yfact+ymax;
changeRange(x-(xmax-xmin)/2, x+(xmax-xmin)/2, xscl,
y-(ymax-ymin)/2, y+(ymax-ymin)/2, yscl);
host.updateRangeTF();
clearGraph();
drawPostfix();
break;
}
mouseMoved(event);
}
public void mouseMoved (MouseEvent event)
{
if (page!=null)
{
page.setPaintMode();
referencePt((float) (event.getX()/xfact+xmin),(float) (event.getY()/yfact+ymax));
drawCoordinate();
}
repaint();
}
public void referencePt(float xx, float yy)
{
mx=xx;
my=yy;
}
public void mouseDragged (MouseEvent event)
{
if (dragstartX==-1 && dragstartY==-1)
{
dragstartX=event.getX();
dragstartY=event.getY();
dragdX=0;
dragdY=0;
}
else
{
page.setXORMode(Color.white);
page.setColor(Color.orange);
page.drawRect(dragstartX-dragdX, dragstartY-dragdY, 2*dragdX, 2*dragdY);
dragdX=Math.abs(event.getX()-dragstartX);
dragdY=Math.abs(event.getY()-dragstartY);
page.drawRect(dragstartX-dragdX, dragstartY-dragdY, 2*dragdX, 2*dragdY);
mouseMoved(event);
}
}
public void mouseReleased (MouseEvent event)
{
page.setPaintMode();
if (dragstartX!=-1 && dragstartY!=-1)
host.graphFitZoomButton.setLabel("Box Zoom");
else
host.graphFitZoomButton.setLabel("Graph-Fit Zoom");
}
public void mousePressed (MouseEvent event)
{
if (dragstartX!=-1 && dragstartY!=-1)
{
page.setXORMode(Color.white);
page.setColor(Color.orange);
page.drawRect(dragstartX-dragdX, dragstartY-dragdY, 2*dragdX, 2*dragdY);
// dragstartX=-1;
// dragstartY=-1;
dragstartX=event.getX();
dragstartY=event.getY();
dragdX=0;
dragdY=0;
}
}
public void mouseEntered (MouseEvent event)
{
mouseMoved(event);
}
public void mouseExited (MouseEvent event)
{
mx=Float.NaN;
my=Float.NaN;
drawCoordinate();
}
private void drawCoordinate()
{
page.setColor(Color.gray);
page.fillRect(3,2,120,23);
page.setColor(Color.lightGray);
page.fillRect(0,0,120,23);
page.setColor(Color.black);
page.drawString("x = "+nonNaNString(mx), 5, 10);
page.drawString("y = "+nonNaNString(my), 5, 20);
repaint();
}
private static String nonNaNString(float a)
{
if (Float.isNaN(a)) return "";
return ""+a;
}
public void changeRange (double xmin1, double xmax1, double xscl1,
double ymin1, double ymax1, double yscl1)
{
if (xmax1>xmin1 && ymax1>ymin1 &&
!isNotReal(xmin1) && !isNotReal(xmax1) && !isNotReal(xscl1) &&
!isNotReal(ymin1) && !isNotReal(ymax1) && !isNotReal(yscl1) )
{
xscl = Math.abs(xscl1);
yscl = Math.abs(yscl1);
xmax = xmax1;
xmin = xmin1;
ymax = ymax1;
ymin = ymin1;
}
xavg = (xmax+xmin)/2; xfact=xpixels/(xmax-xmin);
yavg = (ymax+ymin)/2; yfact=ypixels/(ymin-ymax);
if (image!=null) clearGraph();
}
public void fitToZoomBox()
{
double xmin2=(dragstartX-dragdX)/xfact+xmin;
double xmax2=(dragstartX+dragdX)/xfact+xmin;
double ymax2=(dragstartY-dragdY)/yfact+ymax;
double ymin2=(dragstartY+dragdY)/yfact+ymax;
changeRange(xmin2,xmax2,xscl,
ymin2,ymax2,yscl);
}
public void paint(Graphics g)
{
update(g);
}
public void update(Graphics g)
{
if (image==null)
{
image = createImage(xpixels+1,ypixels+1);
page = image.getGraphics();
clearGraph();
}
g.drawImage(image, 0,0, this);
}
public void clearList()
{
pfl=new PostfixList();
}
public void clearGraph()
{
if (image==null) return;
page.setColor(Color.white);
page.fillRect(0,0,xpixels+1,ypixels+1);
if (grid) drawGrid();
if (axis) drawAxis();
if (scores) drawScores();
pfl.deflagAll();
referencePt(Float.NaN,Float.NaN);
drawCoordinate();
dragstartX=-1;
dragstartY=-1;
dragdX=0;
dragdY=0;
host.graphFitZoomButton.setLabel("Graph-Fit Zoom");
}
private void drawAxis()
{
int sx = (int) (-xmin*xfact+.5); //(sx,sy) is where the origin is
int sy = (int) (-ymax*yfact+.5);
page.setColor(Color.red);
if (YonScreen(sy))
page.drawLine(0,sy,xpixels-1,sy);
if (XonScreen(sx))
page.drawLine(sx,0,sx,ypixels-1);
}
private void saveScl()
{
xscl2 = xscl;
yscl2 = yscl;
if (xscl!=0 && 1/xscl>Math.abs(3*xfact))
xscl = Math.abs(1/xfact);
if (yscl!=0 && 1/yscl>Math.abs(3*yfact))
yscl = Math.abs(1/yfact);
}
private void restoreScl()
{
xscl = xscl2;
yscl = yscl2;
}
private void drawGrid()
{
int sx = (int) (-xmin*xfact+.5); //(sx,sy) is where the origin is
int sy = (int) (-ymax*yfact+.5);
saveScl();
page.setColor(Color.lightGray);
if (xscl!=0)
{
for (double i = xscl*((int) (xmin/xscl+.5)); i<=xmax; i+=xscl)
{
int sx1 = (int) ((i-xmin)*xfact+.5);
int sx2 = (int) ((-i-xmin)*xfact+.5);
page.drawLine(sx1,0,sx1,ypixels-1);
page.drawLine(sx2,0,sx2,ypixels-1);
}
}
if (yscl!=0)
{
for (double i = yscl*((int) (ymin/yscl+.5)); i<=ymax; i+=yscl)
{
int sy1 = (int) ((i-ymax)*yfact+.5);
int sy2 = (int) ((-i-ymax)*yfact+.5);
page.drawLine(0,sy1,xpixels-1,sy1);
page.drawLine(0,sy2,xpixels-1,sy2);
}
}
restoreScl();
}
private void drawScores()
{
int sx = (int) (-xmin*xfact+.5); //(sx,sy) is where the origin is
int sy = (int) (-ymax*yfact+.5);
saveScl();
page.setColor(Color.blue);
if (YonScreen(sy) && xscl!=0) //Draw X axis
{
for (double i = xscl*((int) (xmin/xscl+.5)); i<=xmax; i+=xscl)
{
int sx1 = (int) ((i-xmin)*xfact+.5);
int sx2 = (int) ((-i-xmin)*xfact+.5);
page.drawLine(sx1,sy-1,sx1,sy+1);
page.drawLine(sx2,sy-1,sx2,sy+1);
}
}
if (XonScreen(sx) && yscl!=0) //Draw Y axis
{
for (double i = yscl*((int) (ymin/yscl+.5)); i<=ymax; i+=yscl)
{
int sy1 = (int) ((i-ymax)*yfact+.5);
int sy2 = (int) ((-i-ymax)*yfact+.5);
page.drawLine(sx-1,sy1,sx+1,sy1);
page.drawLine(sx-1,sy2,sx+1,sy2);
}
}
restoreScl();
}
private boolean YoutOfBounds (double y)
{
if (Double.isInfinite(y)) return true;
if (Double.isNaN(y)) return true;
if (yymax) return true;
return false;
}
private boolean XoutOfBounds (double x)
{
if (Double.isInfinite(x)) return true;
if (Double.isNaN(x)) return true;
if (xxmax) return true;
return false;
}
private boolean YonScreen (double y)
{
return (y>=0 && y=0 && x0)
ws.push(1);
else
if (oper1<0)
ws.push(-1);
else
ws.push(0);
}
}
}
}
catch (NullPointerException exception)
{
//Primative malformed input detection.
ws = new StackDoub();
ws.push(Double.MIN_VALUE);
}
if (! ws.isEmpty())
a=ws.pop();
else
a=Double.NaN;
return a;
}
public Stack getStack()
{
return pf.copy();
}
public boolean isConstant()
{
return isConstant;
}
public String infix()
{
if (pf!=null)
return infix(pf.copy());
return "?:?";
}
private static String infix(Stack s)
{
String str = "";
Token tk = s.pop();
if (tk.isBinary())
{
Stack b = sub(s);
Stack a = sub(s);
str = "("+infix(a)+tk.getContent()+infix(b)+")";
}
else
if (tk.isNumber())
{
str = tk.getContent();
}
else
{
Stack a = sub(s);
str = "("+tk.getContent()+" "+infix(a)+")";
}
return str;
}
}
class Token
{
//The order of these tokens matter and are often hard coded into the code.
//take care not to disturb it.
public static String[] validString =
{
"0","1","2","3","4","5","6","7","8","9",".",
"(", ")", "^", "*", "/", "+", "-",
"sinh", "cosh", "tanh", "csch", "sech", "coth",
"asinh", "acosh", "atanh", "acsch", "asech", "acoth",
"sin", "cos", "tan", "csc", "sec", "cot",
"asin", "acos", "atan", "acsc", "asec", "acot",
"sqrt", "neg",
"log", "abs", "ln", "exp", "sign",
"ddx",
"rnd","x","PI", "E"
};
public int index=-1;
public String content="";
boolean numerical;
int length;
Token(String str)
{
String t = str.trim().toLowerCase();
numerical = false;
for (int i = 0; i=0 && index<11) index=0; //Makes sure all numerical values have index 0
}
public boolean is(String a)
{
return getContent().equalsIgnoreCase(a);
}
public boolean isValid()
{
return index!=-1;
}
public boolean isNumber()
{
return (numerical);
}
public boolean isOperation()
{
return (precedence()>0);
}
public boolean isBinary()
{
return (precedence()==4 || precedence()==3 || precedence()==2);
}
public String getContent()
{
return content;
}
public float precedence()
{
float order=-1;
Token tk = this;
String tk_str = tk.getContent().toLowerCase();
if (tk_str.equals("("))
{
order = 5;
}
else if (tk_str.equals(")"))
{
order = 6;
}
else if (tk_str.equals("+"))
{
order = 4;
}
else if (tk_str.equals("-"))
{
order = 4;
}
else if (tk_str.equals("*"))
{
order = 3;
}
else if (tk_str.equals("/"))
{
order = 3;
}
else if (tk_str.equals("^"))
{
order = 2;
}
else if (
tk_str.equals("sin") || //Trig functions
tk_str.equals("cos") ||
tk_str.equals("tan") ||
tk_str.equals("csc") ||
tk_str.equals("sec") ||
tk_str.equals("cot") ||
tk_str.equals("asin") || //Inverse trig functions
tk_str.equals("acos") ||
tk_str.equals("atan") ||
tk_str.equals("acsc") ||
tk_str.equals("asec") ||
tk_str.equals("acot") ||
tk_str.equals("sinh") || //Hyperbolic trig functions
tk_str.equals("cosh") ||
tk_str.equals("tanh") ||
tk_str.equals("csch") ||
tk_str.equals("sech") ||
tk_str.equals("coth") ||
tk_str.equals("asinh") || //Inverse hyperbolic trig functions
tk_str.equals("acosh") ||
tk_str.equals("atanh") ||
tk_str.equals("acsch") ||
tk_str.equals("asech") ||
tk_str.equals("acoth") ||
tk_str.equals("ddx") || //Derivative
tk_str.equals("neg") || //Negation
tk_str.equals("sqrt") || //Square root
tk_str.equals("exp") || //Exponential base e
tk_str.equals("ln") || //Natural log
tk_str.equals("log") || //Common log
tk_str.equals("abs") || //Absolute value
tk_str.equals("sign") //sign
)
{
order=1;
}
else if (tk.isNumber())
{
order = 0;
}
else
{
order =-1;
}
return order;
}
public String getValue(String s)
{
String ret = "";
char[] input = s.toLowerCase().toCharArray();
int state = 1;
int i = 0;
StackDoub st = new StackDoub();
while (state<30)
{
st.push(state);
// System.out.println(state+" "+input[i]);
switch (state)
{
case 1:
if (Character.isDigit(input[i]))
state = 2;
else
if (input[i]=='.')
state = 6;
else
state = 99;
break;
case 2:
if (Character.isDigit(input[i]))
state = 2;
else
if (input[i]=='e')
state = 3;
else
if (input[i]=='.')
state = 7;
else
{
i = i - 1;
state = 99;
}
break;
case 3:
if (Character.isDigit(input[i]))
state = 5;
else
if (input[i]=='e')
{
i = i - 2;
st.pop();
state = 99;
}
else
if (input[i]=='.')
state = 8;
else
if (input[i]=='+' || input[i]=='-')
state = 4;
else
state = 99;
break;
case 4:
if (Character.isDigit(input[i]))
state = 5;
else
if (input[i]=='e')
{
i = i - 3;
st.pop();
st.pop();
state = 99;
}
else
if (input[i]=='.')
{
i = i - 3;
st.pop();
st.pop();
state = 99;
}
else
if (input[i]=='+' || input[i]=='-')
{
i = i - 3;
st.pop();
st.pop();
state = 99;
}
else
state = 99;
break;
case 5:
if (Character.isDigit(input[i]))
state = 5;
else
if (input[i]=='.')
state = 8;
else
{
i = i - 1;
state = 99;
}
break;
case 6:
if (Character.isDigit(input[i]))
state = 7;
else
if (input[i]=='e')
state = 8;
else
if (input[i]=='.')
state = 8;
else
if (input[i]=='+' || input[i]=='-')
state = 8;
else
state = 99;
break;
case 7:
if (Character.isDigit(input[i]))
state = 7;
else
if (input[i]=='e')
state = 3;
else
if (input[i]=='.')
state = 8;
else
{
i = i - 1;
state = 99;
}
break;
case 8:
break;
}
if (i==(input.length-1) || state==99)
{
if (state == 99)
state = (int) st.pop();
if (state!=2 && state!=7 && state != 5)
state=8;
else
state = 99;
}
if (state == 8)
{
s = "?";
i=0;
state = 99;
}
i++;
}
length = i;
ret = s.substring(0,length);
return ret;
}
public int length()
{
return length;
}
}
class Stack
{
StackCell top;
Stack()
{
top = null;
}
public void clear()
{
top = null;
}
public boolean isEmpty()
{
return top == null;
}
public void push(Token s)
{
StackCell newCell = new StackCell(s, top);
top = newCell;
}
public void push(String s)
{
push(new Token(s));
}
public void push(Stack s)
{
Stack t = new Stack();
if (s==null) return;
while (! s.isEmpty())
t.push(s.pop());
while (! t.isEmpty())
{
push(t.peek());
s.push(t.pop());
}
}
public Token pop()
{
if (top!=null)
{
Token result = top.now;
top = top.next;
return result;
}
return new Token("?");
}
public Token peek()
{
return top.now;
}
/*
public static void showAll(Stack s0)
{
Stack s1 = new Stack();
while (! s0.isEmpty())
{
Token tk = s0.pop();
s1.push(tk);
}
while (! s1.isEmpty())
{
s0.push(s1.pop());
}
}
*/
public String showAll()
{
Stack s1 = new Stack();
String ret="";
while (! this.isEmpty())
{
Token tk = this.pop();
ret = tk.getContent()+" "+ret;
s1.push(tk);
}
while (! s1.isEmpty())
{
this.push(s1.pop());
}
return ret;
}
public Stack copy ()
{
Stack s1 = new Stack();
Stack s2 = new Stack();
while (! this.isEmpty())
{
s1.push(this.pop());
}
while (! s1.isEmpty())
{
s2.push(new Token(s1.peek().getContent()));
this.push(s1.pop());
}
return s2;
}
public Stack flip ()
{
Stack s1 = new Stack();
Stack s2 = new Stack();
while (! this.isEmpty())
{
s1.push(this.peek());
s2.push(this.pop());
}
while (! s1.isEmpty())
{
this.push(s1.pop());
}
return s2;
}
public boolean isConstant()
{
Stack s1 = new Stack();
boolean isconstant = true;
while (! isEmpty())
{
Token tk = pop();
s1.push(tk);
if (tk.is("x")) isconstant = false;
}
while (! s1.isEmpty())
push(s1.pop());
return isconstant;
}
public boolean isZero()
{
Postfix p = new Postfix(this);
return (this.isConstant() && Math.abs(p.evaluate(10))<1e-20);
}
public boolean isOne()
{
Postfix p = new Postfix(this);
return (this.isConstant() && Math.abs(p.evaluate(10)-1)<1e-20);
}
public boolean isNegativeOne()
{
Postfix p = new Postfix(this);
return (this.isConstant() && Math.abs(p.evaluate(10)+1)<1e-20);
}
}
class StackCell
{
Token now;
StackCell next;
StackCell(Token a, StackCell b)
{
now = a;
next = b;
}
}
class StackDoub
{
java.util.Stack stack;
StackDoub()
{
stack = new java.util.Stack();
}
public boolean isEmpty()
{
return stack.empty();
}
public void push(double s)
{
stack.push(new Double(s));
}
public double pop()
{
return ((Double) stack.pop()).doubleValue();
}
public double peek()
{
return ((Double) stack.peek()).doubleValue();
}
}
class PostfixList
{
Vector List;
int listSize;
PostfixList()
{
List = new Vector();
listSize=0;
}
void showInfix()
{
System.out.println("\n-----------------");
System.out.println("Current Functions");
System.out.println("-----------------");
if (listSize==0)
{
System.out.println("None");
}
else
{
int i=0;
for (int k=listSize; k>0; i++)
{
String s = get(i).infixStr.trim();
if (s.length()>0)
{
System.out.println("F"+i+"(x)="+s);
k--;
}
}
}
}
void add(Postfix pf, Color c)
{
boolean placed=false;
if (listSize100)
v.removeElementAt(100);
}
String getPrev()
{
cursor = (cursor+1)%v.size();
return (String) v.elementAt(cursor);
}
String getNext()
{
cursor = (cursor-1+v.size())%v.size();
return (String) v.elementAt(cursor);
}
}
class Frame extends java.awt.Frame implements WindowListener
{
Frame()
{
super();
}
Frame(String title)
{
super(title);
}
public void windowActivated(WindowEvent e) {}
public void windowClosed(WindowEvent e) {}
public void windowClosing(WindowEvent e)
{
dispose();
System.exit(0);
}
public void windowDeactivated(WindowEvent e) {}
public void windowDeiconified(WindowEvent e) {}
public void windowIconified(WindowEvent e) {}
public void windowOpened(WindowEvent e) {}
}
|
|