import java.awt.*; /** Program: Secant Purpose: animation: secant line approaching the tangent @author: Paul Garrett, garrett@math.umn.edu @version: Wed, 09 July 1997 */ public class Secant extends java.applet.Applet implements Runnable { Thread timerThread; Graphics offScreenGraphics; Image offScreenImage; final int height = 320; final int width = 550; final int drawHeight = 310; final int drawWidth = 450; final int inset = 5; final int inc = 4; final int range = 110; // want inc * range = 400 or so final int xaxInset = 50; // inset of x-axis from bottom of drawing area final int yaxInset = 50; // inset of y-axis from left of drawing area double x, y, x0, y0; int t, t0, t1; // t0 is basepoint, t1 is other point, t is variable public void init() { offScreenImage = createImage(width,height); offScreenGraphics = offScreenImage.getGraphics(); t0 = 20; x0 = tTox(t0); y0 = theFunction(tTox(t0)); t1 = 100; x = tTox(t1); y = theFunction(tTox(t1)); } public void start() { if (timerThread == null) { timerThread = new Thread(this); timerThread.start(); } repaint(); } public void stop() { if (timerThread != null) { timerThread.stop(); try { timerThread.join(); } catch (InterruptedException e) { } timerThread = null; } } void pause(int time) { try { Thread.sleep(time); } catch ( InterruptedException e) { } } public void run() { while (true) { if (t > t0 + 2) { pause(100); t--; x = tTox(t); y = theFunction(tTox(t)); repaint(); } else { pause(500); t = t1; x = tTox(t); y = theFunction(tTox(t)); repaint(); pause(500); } } } public void update(Graphics g) { paint(g); } /************************************************/ void drawAxes(Graphics g) { g.setColor(Color.black); g.fillRect(inset, drawHeight - xaxInset, drawWidth, 2); // x-axis int[] xs = {inset + drawWidth + 2, inset + drawWidth - 10, inset + drawWidth - 6, inset + drawWidth - 10}; int[] ys = {drawHeight - xaxInset, drawHeight - xaxInset-6, drawHeight - xaxInset, drawHeight - xaxInset+6}; g.fillPolygon(new Polygon(xs, ys, 4)); // arrowhead on x-axis g.fillRect(yaxInset-1, inset, 2, drawHeight); // y-axis int[] xs2 = {yaxInset, yaxInset - 6, yaxInset, yaxInset + 6}; int[] ys2 = {inset - 2, inset + 10, inset + 6, inset + 10}; g.fillPolygon(new Polygon(xs2, ys2, 4)); // arrowhead on y-axis } /********************************************************/ double theFunction(double x) { // should roughly map -1 < x < 2 to -1 < y < 2, for example return (x*x - 0.5 * x + 1.0)/2.0; //__EDIT__ } int xToPix (double x) { // rescales -1 < x < 2 to ... return (int) ( (x + 1.0) * ((double) drawWidth) / 3.0) + inset; } int yToPix (double y) { // rescales [-1,2] to ... return inset + drawHeight - ((int) ( (y + 1.0) * ((double) drawHeight) / 3.0)); } double tTox (int t) { // rescales [0,range] to [-1,2] return ((double) (t * inc)) * 3.0 / ((double) drawWidth) - 1.0; } void drawCurve(Graphics g) { //__EDIT__HERE__ g.setColor(Color.red); for (int i=0; i<= range; i++) { g.drawLine(xToPix(tTox(i)), yToPix(theFunction(tTox(i))), xToPix(tTox(i+1)), yToPix(theFunction(tTox(i+1)))); } g.setColor(Color.green); for (int i=0; i<= range; i++) { g.drawLine(xToPix(tTox(i)), yToPix(theFunction(tTox(i))) - 1, xToPix(tTox(i+1)), yToPix(theFunction(tTox(i+1))) - 1); } } void drawSecant(Graphics g) { g.setColor(Color.white); double left = -1.0; double right = 2.0; g.drawLine(inset, yToPix(y0 + (y-y0) * (left - x0)/(x-x0)), inset + drawWidth, yToPix(y0 + (y-y0) * (right - x0)/(x-x0))); g.setColor(Color.red); g.fillOval(xToPix(x)-2, yToPix(y), 6, 6); g.fillOval(xToPix(x0)-2, yToPix(y0), 6, 6); } /*****************************************************/ void drawOffScreen() { offScreenGraphics.setColor(Color.gray); offScreenGraphics.fillRect(0,0,width,height); offScreenGraphics.setColor(Color.black); drawAxes(offScreenGraphics); drawCurve(offScreenGraphics); drawSecant(offScreenGraphics); } public void paint(Graphics g) { drawOffScreen(); g.drawImage(offScreenImage,0,0,this); } } //__THE__END__