require_once("/home/users/web/b1565/pow.daviddude/htdocs/functions.php"); do_header("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; ido_footer(); ?>max) 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 (y ymax) return true; return false; } private boolean XoutOfBounds (double x) { if (Double.isInfinite(x)) return true; if (Double.isNaN(x)) return true; if (x xmax) return true; return false; } private boolean YonScreen (double y) { return (y>=0 && y =0 && x 0) 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 (listSize 100) 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) {} }