Math function and bar
/************************************************************************* * * * This source code file, and compiled classes derived from it, can * * be used and distributed without restriction, including for commercial * * use. (Attribution is not required but is appreciated.) * * * * David J. Eck * * Department of Mathematics and Computer Science * * Hobart and William Smith Colleges * * Geneva, New York 14456, USA * * Email: eck@hws.edu WWW: http://math.hws.edu/eck/ * * * *************************************************************************/ // The SimpleGraph applet is a configurable applet that displays the graph of // a single function of one variable and computes a Riemann sum for that // function. import java.awt.*; import java.awt.event.*; import java.applet.Applet; import java.util.StringTokenizer; import edu.hws.jcm.draw.*; import edu.hws.jcm.data.*; import edu.hws.jcm.functions.*; import edu.hws.jcm.awt.*; public class RiemannSums extends GenericGraphApplet { // Declare some private variables that are created in one method in // this class and used in a second method. private Variable intervals; // Gives the number of intervals. private VariableInput intCtInput; // For letting the user enter the number of intervals. private Choice methodChoice; // Gives the method to be used: Left Endpoint, ..., Trapezoid. private Function func; // The function that is graphed. private Graph1D graph; // The graph of the function. private RiemannSumRects sums; public void itemStateChanged(ItemEvent evt) { // React when user changes the summation method. if (evt.getSource() == methodChoice) { sums.setMethod(methodChoice.getSelectedIndex()); mainController.compute(); } else super.itemStateChanged(evt); } protected void setUpParameterDefaults() { // Override to give a different default function parameterDefaults = new java.util.Hashtable(); String func = " 3 / (1 + " + getParameter("Variable","x") + "^2)"; parameterDefaults.put("Function",func); parameterDefaults.put("ComputeButtonName","Compute!"); } protected void setUpCanvas() { // Override this to add more stuff to the canvas. // When setUpCanvas is called, the functionInput already exists, if one is // to be used, since it is created in setUpBopttomPanel(), which is called // before setUpCanvas. If functionInput exists, add a graph of the function // from functionInput to the canvas. If not, create a graph of the function // specified by the parameter named "Function". if (functionInput != null) func = functionInput.getFunction(xVar); else { String def = getParameter("Function", " abs(" + xVar.getName() + ") ^ " + xVar.getName()); Function f = new SimpleFunction( parser.parse(def), xVar ); func = new WrapperFunction(f); } graph = new Graph1D(func); Color color = getColorParam("GraphColor"); if (color != null) graph.setColor(color); // Get the data for the RiemannSumRects object. Create it (along with other // associated objects) and add it to the canvas. double[] intCtD = getNumericParam("IntervalCount"); if (intCtD == null || intCtD.length < 1) intCtD = new double[] { 5 }; else if (Double.isNaN(intCtD[0]) || intCtD[0] < 1 || intCtD[0] > 5000) intCtD[0] = 5; int intCt = (int)(intCtD[0]+0.5); if ("yes".equalsIgnoreCase( getParameter("UseIntervalInput", "yes") )){ intCtInput = new VariableInput(null, "" + intCt); intCtInput.setInputStyle(VariableInput.INTEGER); intCtInput.setMin(1); intCtInput.setMax(5000); intervals = intCtInput.getVariable(); } else intervals = new Variable(null,intCt); int method = RiemannSumRects.LEFTENDPOINT; String methodStr = getParameter("Method"); if (methodStr != null && methodStr.trim().length() > 0) { switch (methodStr.trim().charAt(0)) { case 'L': case 'l': method = RiemannSumRects.LEFTENDPOINT; break; case 'R': case 'r': method = RiemannSumRects.RIGHTENDPOINT; break; case 'M': case 'm': method = RiemannSumRects.MIDPOINT; break; case 'C': case 'c': method = RiemannSumRects.CIRCUMSCRIBED; break; case 'I': case 'i': method = RiemannSumRects.INSCRIBED; break; case 'T': case 't': method = RiemannSumRects.TRAPEZOID; break; } } if ("yes".equalsIgnoreCase( getParameter("UseMethodInput", "yes") )) { methodChoice = new Choice(); methodChoice.add("Left Endpoint"); methodChoice.add("Right Endpoint"); methodChoice.add("Midpoint"); methodChoice.add("~Circumscribed"); methodChoice.add("~Inscribed"); methodChoice.add("Trapezoid"); methodChoice.select(method); methodChoice.addItemListener(this); } sums = new RiemannSumRects(func,intervals); sums.setMethod(method); canvas.add(sums); Color c = getColorParam("RectColor"); if (c != null) sums.setColor(c); c = getColorParam("OutlineColor"); if (c != null) sums.setOutlineColor(c); super.setUpCanvas(); // Do the common setup: Add the axes, for example. canvas.getCoordinateRect().setGap(10); // Extra space around edges. canvas.add(graph); // Add the graph to the canvas. // Add a DrawString to the canvas to show the value of the sum. DrawString ds = new DrawString("sum = #", DrawString.TOP_LEFT, new Value[] { sums.getValueObject(RiemannSumRects.CURRENT_METHOD) } ); ds.setBackgroundColor(getColorParam("TextBackground",Color.white)); ds.setColor(getColorParam("TextColor",Color.black)); ds.setFrameWidth(1); canvas.add(ds); mainController.add(ds); mainController.add(sums); if (intCtInput != null) intCtInput.setOnUserAction(mainController); canvas.getCoordinateRect().setOnChange(mainController); } // end setUpCanvas() protected void setUpMainPanel() { // Override this method to add the methodChoice menu and interval count inputs, if any, // to the panel. (They were created in the setUpCanvas method.) super.setUpMainPanel(); // Do the common setup if (methodChoice == null && intCtInput == null) return; JCMPanel panel = new JCMPanel(); panel.setLayout(new FlowLayout()); panel.setBackground(getColorParam("PanelBackground",Color.lightGray)); if (intCtInput != null) { panel.add(new Label("Intervals:")); panel.add(intCtInput); } if (methodChoice != null) { panel.add(new Label("Method:")); panel.add(methodChoice); } if (inputPanel == null) mainPanel.add(panel, BorderLayout.SOUTH); else { inputPanel.setBackground(getColorParam("PanelBackground",Color.lightGray)); inputPanel.add(panel, BorderLayout.SOUTH); } } // end setUpMainPanel() protected void doLoadExample(String example) { // This method is called when the user loads an example from the // example menu (if there is one). It overrides an empty method // in GenericGraphApplet. // For this applet, the example string should contain // an expression that defines the function to be graphed. // This can optionally be followed by a semicoloon and a list of four or five // numbers. The first four numbers give the x- and y- limes to be used for the // example. The fifth number, if present, gives the interval count. // After the numbers, there can be another semicolon // and the name of the summation method to be used. int pos = example.indexOf(";"); double[] limits = { -5,5,-5,5 }; // x- and y-limits to use if (pos > 0) { // get limits, method from example text String limitsText = example.substring(pos+1); example = example.substring(0,pos); pos = limitsText.indexOf(";"); if (pos > 0) { // data includes a method name. String methodStr = limitsText.substring(pos+1).trim(); limitsText = limitsText.substring(0,pos); if (methodStr.length() > 0) { int method; switch (methodStr.charAt(0)) { case 'L': case 'l': method = RiemannSumRects.LEFTENDPOINT; break; case 'R': case 'r': method = RiemannSumRects.RIGHTENDPOINT; break; case 'M': case 'm': method = RiemannSumRects.MIDPOINT; break; case 'C': case 'c': method = RiemannSumRects.CIRCUMSCRIBED; break; case 'I': case 'i': method = RiemannSumRects.INSCRIBED; break; case 'T': case 't': method = RiemannSumRects.TRAPEZOID; break; default: method = -1; } if (method >= 0) { sums.setMethod(method); if (methodChoice != null) methodChoice.select(method); } } } StringTokenizer toks = new StringTokenizer(limitsText, " ,"); if (toks.countTokens() >= 4) { for (int i = 0; i < 4; i++) { try { Double d = new Double(toks.nextToken()); limits[i] = d.doubleValue(); } catch (NumberFormatException e) { } } if (toks.countTokens() > 0) { // get number of intervals try { Double d = new Double(toks.nextToken()); double intCtD = d.doubleValue(); if (intCtD < 1) intCtD = 1; else if (intCtD > 5000) intCtD = 5000; intervals.setVal((int)(intCtD + 0.5)); } catch (NumberFormatException e) { } } } } // Set up the example data and recompute everything. if (functionInput != null) { // If there is a function input box, put the example text in it. functionInput.setText(example); } else { // If there is no user input, set the function in the graph directly. // Also, in this case, func is a "WrapperFunction". Set the // definition of that WrapperFunction to be the same as f try { Function f = new SimpleFunction( parser.parse(example), xVar ); ((WrapperFunction)func).setFunction(f); } catch (ParseError e) { // There should't be parse error's in the Web-page // author's examples! If there are, the function // just won't change. } } CoordinateRect coords = canvas.getCoordinateRect(0); coords.setLimits(limits); coords.setRestoreBuffer(); mainController.compute(); } // end doLoadExample() public static void main(String[] a){ javax.swing.JFrame f = new javax.swing.JFrame(); Applet app = new RiemannSums(); app.init(); f.getContentPane().add (app); f.pack(); f.setSize (new Dimension (500, 500)); f.setVisible(true); } } // end class RiemannSums