// // curve2.java // curve1 // // Created by Chris Thiel on Sat Sep 21 2002. // Updated 26 Jan 2003 to show (x+delta x) // Copyright (c) 2002 Chris Thiel // Free for Educational use with permission // A simple Java applet for students to graphically see how the // definition of the derivative comes from the secant line as // delta-x goes to zero. // My UNIX based Mac shows the delta symbol just fine, but the // Microsoft based machines shows it as a vertical line ?!? // Send me an email if you know the generic Java way to specify the delta symbol. // import java.awt.*; import java.applet.Applet; import java.io.*; import java.awt.Graphics; import java.awt.event.*; import java.lang.Math; public class curve2 extends Applet implements Runnable, AdjustmentListener { int XMAX=400; int YMAX=250; //the next line creates the scrollbar used in this applet //with a max value of XMAX, and a min value of 1 Scrollbar horiz=new Scrollbar(Scrollbar.HORIZONTAL,1,20,-170,180); Scrollbar vert=new Scrollbar(Scrollbar.VERTICAL,1,20,-100,120); Checkbox deriv=new Checkbox("Show instantaneous slope"); final int quantum = 10; Image offScreenImage=null; Graphics offScreenGraphics = null; Dimension offScreenSize = null; Thread t; int h = 0; int v = 0; int direction = 10; public void init() { Image img=null; h=0; direction = 10; //the next sets the layout as a BorderLayout setLayout(new BorderLayout()); //the next line adds horiz to South add("South",horiz); add("East",vert); add("North",deriv); //the next line adds an adjusment listener to horiz so it can //have events processed when the scroller is moved horiz.addAdjustmentListener(this); vert.addAdjustmentListener(this); } //adjustmentValueChanged() is the method that handles AdjustmentEvents //which is when the value of a Scrollbar is changed public void adjustmentValueChanged(AdjustmentEvent e){ //the next if statement checks to see if the AdjustmentEvent //came from horiz if(e.getAdjustable()==horiz){ //sets the text in num to the value of horiz h = horiz.getValue(); } if(e.getAdjustable()==vert){ //sets the text in num to the value of horiz v = vert.getValue(); } } public void run(){ while (true) { update(getGraphics()); try { Thread.sleep(quantum); }catch (InterruptedException e) { break; } }// of while } // of run public void start() { t = new Thread(this); t.start(); } public void stop() { t.stop(); t = null; } public final void update (Graphics theG) { //implements no flickers Dimension dim = getSize(); if ((offScreenImage==null)||(dim.width != offScreenSize.width)||(dim.height !=offScreenSize.height)) { offScreenImage = createImage(dim.width, dim.height); offScreenSize = dim; offScreenGraphics = offScreenImage.getGraphics(); } //first clear old offScreenGraphics.clearRect(0,0,offScreenSize.width, offScreenSize.height); //now draw new paint(offScreenGraphics); //now put the offScreen Image on Screen! theG.drawImage(offScreenImage, 0,0,null); }// update //convert graph coords to screen pixel location private int screenX (double x) { return (int)(.5*XMAX+x*(XMAX/32)); } private int screenY (double y) { return (int)(.5*YMAX-y*(YMAX/22)); } //Find f(x) in terms of a screen coord // change this for a different function private int f(double x){ return screenY(x*x ); } //Find f(x) in terms of 10 time the graph system coords // change this for a different function**********. private int f1(double x){ return (int)(100*(x*x)); } private int d(double x){ // Find f'(x) ****** change this for a different function *************** // to be the deritative of f return (int)(10*( 2.0*x)); } private int secantRise(){ return (int)(100*(f(h/10.0) - f((h-v)/10.0))); } private int secantRun(){ return (int)(100*(screenX(h/10.0) - screenX((h-v)/10.0 ))); } private int secantSlope(){ double rise =f(h/10.0) - f((h-v)/10.0); double run = screenX(h/10.0) - screenX((h-v)/10.0); if (run !=0) { return (int)(-10*rise/run); }else{return 0;} } public void paint( Graphics g ) { g.setColor(new Color(0x108000)); //green background from (0,20) to (450,295) g.fillRect ( 0, 0, XMAX, YMAX); g.setColor(new Color(0x08602F)); //lines for(int i = -16; i< 17; i++) g.drawLine( screenX(i),0,screenX(i) ,YMAX); // horizontals for(int i = -11; i< 11; i++) g.drawLine( 0, screenY(i), XMAX,screenY(i) ); //verticals g.setColor(Color.black); g.drawLine( 0, screenY(0), XMAX,screenY(0) ); // x-axis g.drawLine( screenX(0),0,screenX(0) ,YMAX); // y=axis //Draw the curve g.setColor(Color.white); for(double x = -17; x<17; x=x+.25) g.drawLine( screenX(x),f(x),screenX(x+.25),f(x+.25) ); //Dislay info g.setColor(Color.white); g.setFont (new Font("serif", Font.ITALIC+Font.BOLD, 14)); g.drawString( " x = "+h/10.0, 70, 50 ); g.drawString( " g(x) = "+f1(h/10.0)/100.0, 70, 65 ); if (v!=0) {g.setColor(Color.green);} g.drawString( " x = "+v/-10.0, 70, 80 ); g.drawString( " (x+x) = "+(h-v)/10.0, 60,95 ); g.drawString( "g(x+x) = "+f1((h-v)/10.0)/100.0, 60, 110 ); // Plot point (x+x, f(x+x) ) g.setColor(Color.blue); g.fillOval(screenX((h-v)/10.0)-2,f((h-v)/10.0)-2,5,5); //Plot point (x, f(x) ) g.setColor(Color.red); g.fillOval(screenX(h/10.0)-2,f(h/10.0)-2,5,5); if (deriv.getState()==true){ g.setColor(Color.cyan); g.drawString("instantaneous slope = "+d(h/10.0)/10.0,220,140); if (v!=0) { g.setColor(Color.green); g.drawString("secant slope = "+((f1(h-v)-f1(h))/v)/-1000.0,220,155); }else{ g.setColor(Color.cyan); g.drawLine(screenX(h/10.0)-100, f(h/10.0)+10*d(h/10.0), screenX(h/10.0)+100, f(h/10.0)-10*d(h/10.0)); } } //draw secant line g.setColor(Color.green); g.drawLine(screenX(h/10.0)-secantRun(),f(h/10.0)-secantRise(),screenX(h/10.0)+secantRun(),f(h/10.0)+secantRise()); //instructions g.setColor(Color.black); g.drawString("Change x with the horizontal bar",20,YMAX-40); g.drawString("Change x with the vertical bar",20,YMAX-25); } }