Subversion Repositories wimsdev

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
3653 schaersvoo 1
/*************************************************************************
2
*                                                                        *
3
*  This source code file, and compiled classes derived from it, can      *
4
*  be used and distributed without restriction, including for commercial *
5
*  use.  (Attribution is not required but is appreciated.)               *
6
*                                                                        *
7
*   David J. Eck                                                         *
8
*   Department of Mathematics and Computer Science                       *
9
*   Hobart and William Smith Colleges                                    *
10
*   Geneva, New York 14456,   USA                                        *
11
*   Email: eck@hws.edu          WWW: http://math.hws.edu/eck/            *
12
*                                                                        *
13
*************************************************************************/
14
 
15
 
16
// The SimpleGraph applet is a configurable applet that displays the graph of
17
// a single function of one variable and computes a Riemann sum for that
18
// function.
19
 
20
import java.awt.*;
21
import java.awt.event.*;
22
import java.applet.Applet;
23
import java.util.StringTokenizer;
24
import edu.hws.jcm.draw.*;
25
import edu.hws.jcm.data.*;
26
import edu.hws.jcm.functions.*;
27
import edu.hws.jcm.awt.*;
28
 
29
 
30
public class RiemannSums extends GenericGraphApplet {
31
 
32
   // Declare some private variables that are created in one method in
33
   // this class and used in a second method.
34
 
35
   private Variable intervals;       // Gives the number of intervals.
36
   private VariableInput intCtInput; // For letting the user enter the number of intervals.
37
   private Choice methodChoice;      // Gives the method to be used:  Left Endpoint, ..., Trapezoid.
38
 
39
   private Function func;   // The function that is graphed.
40
   private Graph1D graph;   // The graph of the function.
41
 
42
   private RiemannSumRects sums;
43
 
44
   public void itemStateChanged(ItemEvent evt) {
45
         // React when user changes the summation method.
46
       if (evt.getSource() == methodChoice) {
47
          sums.setMethod(methodChoice.getSelectedIndex());
48
          mainController.compute();
49
       }
50
       else
51
          super.itemStateChanged(evt);
52
   }
53
 
54
   protected void setUpParameterDefaults() { // Override to give a different default function
55
      parameterDefaults = new java.util.Hashtable();
56
      String func = " 3 / (1 + " + getParameter("Variable","x") + "^2)";
57
      parameterDefaults.put("Function",func);
58
      parameterDefaults.put("ComputeButtonName","Compute!");
59
   }
60
 
61
   protected void setUpCanvas() {  // Override this to add more stuff to the canvas.
62
 
63
      // When setUpCanvas is called, the functionInput already exists, if one is
64
      // to be used, since it is created in setUpBopttomPanel(), which is called
65
      // before setUpCanvas.  If functionInput exists, add a graph of the function
66
      // from functionInput to the canvas.  If not, create a graph of the function
67
      // specified by the parameter named "Function".
68
 
69
      if (functionInput != null)
70
         func = functionInput.getFunction(xVar);
71
      else {
72
         String def = getParameter("Function", " abs(" + xVar.getName() + ") ^ " + xVar.getName());
73
         Function f = new SimpleFunction( parser.parse(def), xVar );
74
         func = new WrapperFunction(f);
75
      }
76
      graph = new Graph1D(func);
77
      Color color = getColorParam("GraphColor");
78
      if (color != null)
79
         graph.setColor(color);
80
 
81
      // Get the data for the RiemannSumRects object.  Create it (along with other
82
      // associated objects) and add it to the canvas.
83
 
84
      double[] intCtD = getNumericParam("IntervalCount");
85
      if (intCtD == null || intCtD.length < 1)
86
         intCtD = new double[] { 5 };
87
      else if (Double.isNaN(intCtD[0]) || intCtD[0] < 1 || intCtD[0] > 5000)
88
         intCtD[0] = 5;
89
      int intCt = (int)(intCtD[0]+0.5);
90
 
91
      if ("yes".equalsIgnoreCase( getParameter("UseIntervalInput", "yes") )){
92
         intCtInput = new VariableInput(null, "" + intCt);
93
         intCtInput.setInputStyle(VariableInput.INTEGER);
94
         intCtInput.setMin(1);
95
         intCtInput.setMax(5000);
96
         intervals = intCtInput.getVariable();
97
      }
98
      else
99
         intervals = new Variable(null,intCt);
100
 
101
      int method = RiemannSumRects.LEFTENDPOINT;
102
 
103
      String methodStr = getParameter("Method");
104
      if (methodStr != null && methodStr.trim().length() > 0) {
105
         switch (methodStr.trim().charAt(0)) {
106
            case 'L': case 'l': method = RiemannSumRects.LEFTENDPOINT; break;
107
            case 'R': case 'r': method = RiemannSumRects.RIGHTENDPOINT; break;
108
            case 'M': case 'm': method = RiemannSumRects.MIDPOINT; break;
109
            case 'C': case 'c': method = RiemannSumRects.CIRCUMSCRIBED; break;
110
            case 'I': case 'i': method = RiemannSumRects.INSCRIBED; break;
111
            case 'T': case 't': method = RiemannSumRects.TRAPEZOID; break;
112
         }
113
      }
114
 
115
      if ("yes".equalsIgnoreCase( getParameter("UseMethodInput", "yes") )) {
116
         methodChoice = new Choice();
117
         methodChoice.add("Left Endpoint");
118
         methodChoice.add("Right Endpoint");
119
         methodChoice.add("Midpoint");
120
         methodChoice.add("~Circumscribed");
121
         methodChoice.add("~Inscribed");
122
         methodChoice.add("Trapezoid");
123
         methodChoice.select(method);
124
         methodChoice.addItemListener(this);
125
      }
126
 
127
      sums = new RiemannSumRects(func,intervals);
128
      sums.setMethod(method);
129
      canvas.add(sums);
130
 
131
      Color c = getColorParam("RectColor");
132
      if (c != null)
133
         sums.setColor(c);
134
      c = getColorParam("OutlineColor");
135
      if (c != null)
136
         sums.setOutlineColor(c);
137
 
138
      super.setUpCanvas();  // Do the common setup: Add the axes, for example.
139
      canvas.getCoordinateRect().setGap(10);  // Extra space around edges.
140
      canvas.add(graph);  // Add the graph to the canvas.
141
 
142
      // Add a DrawString to the canvas to show the value of the sum.
143
 
144
      DrawString ds = new DrawString("sum = #", DrawString.TOP_LEFT,
145
                           new Value[] { sums.getValueObject(RiemannSumRects.CURRENT_METHOD) } );
146
      ds.setBackgroundColor(getColorParam("TextBackground",Color.white));
147
      ds.setColor(getColorParam("TextColor",Color.black));
148
      ds.setFrameWidth(1);
149
      canvas.add(ds);
150
 
151
      mainController.add(ds);
152
      mainController.add(sums);
153
      if (intCtInput != null)
154
         intCtInput.setOnUserAction(mainController);
155
      canvas.getCoordinateRect().setOnChange(mainController);
156
 
157
   } // end setUpCanvas()
158
 
159
 
160
 
161
   protected void setUpMainPanel() {
162
         // Override this method to add the methodChoice menu and interval count inputs, if any,
163
         // to the panel.  (They were created in the setUpCanvas method.)
164
 
165
      super.setUpMainPanel(); // Do the common setup
166
 
167
      if (methodChoice == null && intCtInput == null)
168
         return;
169
 
170
         JCMPanel panel = new JCMPanel();
171
         panel.setLayout(new FlowLayout());
172
         panel.setBackground(getColorParam("PanelBackground",Color.lightGray));
173
         if (intCtInput != null) {
174
            panel.add(new Label("Intervals:"));
175
            panel.add(intCtInput);
176
         }
177
         if (methodChoice != null) {
178
            panel.add(new Label("Method:"));
179
            panel.add(methodChoice);
180
         }      
181
         if (inputPanel == null)
182
            mainPanel.add(panel, BorderLayout.SOUTH);
183
         else {
184
            inputPanel.setBackground(getColorParam("PanelBackground",Color.lightGray));
185
            inputPanel.add(panel, BorderLayout.SOUTH);
186
         }
187
 
188
   } // end setUpMainPanel()
189
 
190
 
191
 
192
   protected void doLoadExample(String example) {
193
         // This method is called when the user loads an example from the 
194
         // example menu (if there is one).  It overrides an empty method
195
         // in GenericGraphApplet.
196
         //   For this applet, the example string should contain
197
         // an expression that defines the function to be graphed.
198
         // This can optionally  be followed by a semicoloon and a list of four or five
199
         // numbers.  The first four numbers give the x- and y- limes to be used for the
200
         // example.  The fifth number, if present, gives the interval count.
201
         // After the numbers, there can be another semicolon
202
         // and the name of the summation method to be used.
203
 
204
      int pos = example.indexOf(";");
205
 
206
      double[] limits = { -5,5,-5,5 };  // x- and y-limits to use
207
 
208
      if (pos > 0) { // get limits, method from example text
209
         String limitsText = example.substring(pos+1);
210
         example = example.substring(0,pos);
211
         pos = limitsText.indexOf(";");
212
         if (pos > 0) {  // data includes a method name.
213
            String methodStr = limitsText.substring(pos+1).trim();
214
            limitsText = limitsText.substring(0,pos);
215
            if (methodStr.length() > 0) {
216
                int method;
217
                switch (methodStr.charAt(0)) {
218
                   case 'L': case 'l': method = RiemannSumRects.LEFTENDPOINT; break;
219
                   case 'R': case 'r': method = RiemannSumRects.RIGHTENDPOINT; break;
220
                   case 'M': case 'm': method = RiemannSumRects.MIDPOINT; break;
221
                   case 'C': case 'c': method = RiemannSumRects.CIRCUMSCRIBED; break;
222
                   case 'I': case 'i': method = RiemannSumRects.INSCRIBED; break;
223
                   case 'T': case 't': method = RiemannSumRects.TRAPEZOID; break;
224
                   default: method = -1;
225
               }
226
               if (method >= 0) {
227
                  sums.setMethod(method);
228
                  if (methodChoice != null)  
229
                     methodChoice.select(method);
230
               }
231
            }
232
         }
233
         StringTokenizer toks = new StringTokenizer(limitsText, " ,");
234
         if (toks.countTokens() >= 4) {
235
            for (int i = 0; i < 4; i++) {
236
               try {
237
                   Double d = new Double(toks.nextToken());
238
                   limits[i] = d.doubleValue();
239
               }
240
               catch (NumberFormatException e) {
241
               }
242
            }
243
            if (toks.countTokens() > 0) {
244
                  // get number of intervals
245
               try {
246
                   Double d = new Double(toks.nextToken());
247
                   double intCtD = d.doubleValue();
248
                   if (intCtD < 1)
249
                      intCtD = 1;
250
                   else if (intCtD > 5000)
251
                      intCtD = 5000;
252
                   intervals.setVal((int)(intCtD + 0.5));
253
               }
254
               catch (NumberFormatException e) {
255
               }
256
            }
257
         }
258
      }
259
 
260
      // Set up the example data and recompute everything.
261
 
262
      if (functionInput != null) {
263
            // If there is a function input box, put the example text in it.
264
         functionInput.setText(example);
265
      }
266
      else {
267
           // If there is no user input, set the function in the graph directly.
268
           // Also, in this case, func is a "WrapperFunction".  Set the
269
           // definition of that WrapperFunction to be the same as f
270
         try {
271
            Function f = new SimpleFunction( parser.parse(example), xVar );
272
            ((WrapperFunction)func).setFunction(f);
273
         }
274
         catch (ParseError e) {  
275
             // There should't be parse error's in the Web-page
276
             // author's examples!  If there are, the function
277
             // just won't change.
278
         }
279
      }
280
      CoordinateRect coords = canvas.getCoordinateRect(0);
281
      coords.setLimits(limits);
282
      coords.setRestoreBuffer();
283
      mainController.compute();
284
 
285
   } // end doLoadExample()
286
 
287
 
288
 
289
} // end class RiemannSums