/** * Bounce Graph Class for Rob's * Difference Equation Iteration Demonstrator Applet * @author Robert J Morton UK-YE572246C * @version 27 November 1997 modified 07 August 2009, 18 April 2012 */ /* Plots values of a real variable x which is passed to it. It paints all plots onto the applet screen window and also onto an off-screen image. The image is kept updated and intact in real-time irrespective of whether or not the applet's window is wholly or partially obscured, moved or resized. In the event, the real-time internal image is transferred to the screen whenever the applet's paint(g) method is called. An up to date image is therefore always maintained on the visible part of the applet window. */ import java.awt.*; // for graphics operations (GUI) import javax.swing.*; // library for constructing Swing GUI class bouncegr extends JPanel{ private static final Color ax = Color.gray, // colour of the graph's axes at = new Color(0, 255, 128), // colour of parabola and diagonal fg = new Color(0, 128, 64); // colour of current bounce lines private Color bgClr; // colour of old bounce lines private Graphics gi; // graphics context for drawing on the image private Font font; // font for graph axis annotations private Image BG = null; // instance reference tof bounce-graph image private formula f; // instance reference of formula class private double k; // real-to-pixel conversion factor private static final int MAX = 161, // number of elements in each of the above HB = 10, VB = 15; // panel co-ordinates of top left corner of graph private int P[] = new int[MAX], // start of left-hand parabola line Q[] = new int[MAX], // end of left-hand parabola line R[] = new int[MAX], // start of right-hand parabola line S[] = new int[MAX], // end of right-hand parabola line Amax, Amin, // max/min excursions of axes Pmax, Pmin, // max/min vertical excursion of parabola pa, // x co-ordinate of the parabola axis x = 0, y = 0, // last time's pixel value of x * x + c X, Y; // local co-ordinates of graph's real origin private boolean ResetFlag, // true: repaint the graph axis and annotations FTTF = false, // first time through flag EqnFlag = false; /* false: equation X = CX(1 - X) is in effect true: equation X = X**2 + C is in effect */ bouncegr(Color bg, formula f, Graphics g, Image BG, Font font) { bgClr = bg; // save the background colour this.f = f; // instance reference of the formula class gi = g; // graphics reference of the bounce-graph image this.BG = BG; // copy instance reference of bounce-graph image this.font = font; // font for annotating the graph } void setEF(boolean b) {EqnFlag = b;} // set which equation is to be used void reset() { // PRIME/RESET THE BOUCE GRAPH IMAGE FTTF = false; // first time through flag gi.setColor(bgClr); // set to draw in background color gi.fillRect(0, 0, 185, 185); // and thus clear the image if(EqnFlag) { // IF USING X = X**2 + C X = 80; Y = 80; // co-ordinates of the graph's origin k = 40; // scaling factor (number of pixels = 1.0) Amax = +80; Amin = -80; // max and min excursions of x or y pa = 0; // x co-ordinate of parabola axis } else { // IF USING X = CX(1 - X) X = 0; Y = 160; // co-ordinate of graph's origin k = 160; // scaling factor (number of pixels = 1.0) Amax = 160; Amin = 0; // max and min excursion of y (and x) pa = 80; // x co-ordinate of parabola axis } // DRAW AND LABEL THE AXES // Set the origin and colour for the x and y axes, then draw them. int x = HB + X, y = VB + Y; gi.setColor(ax); gi.drawLine(x + Amin, y, x + Amax, y); // x-axis gi.drawLine(x, y - Amin, x, y - Amax); // y-axis // Set font and colour for x and y axis annotations then print them. gi.setFont(font); gi.setColor(Color.black); gi.drawString("x", x + Amax + 3, y + 2); // x label gi.drawString("y", x - 2, VB - 5); // y label // set colour for diagonal bounce line and then draw it gi.setColor(ax); gi.drawLine(x + Amin, y - Amin, x + Amax, y - Amax); /* Set END-POINTS to mark the thickness of the parabola's trace line for each horizontal line of pixels as far in the other direction as they can go. */ for(y=0; yPmax) Pmax=h; //capture max excursion of parabola if(hQ[h]) Q[h]=x; //capture the end of the line } //[can be on both arms at once at apex] if(x>=pa) { //if on right-hand arm of parabola if(xS[h]) S[h]=x; //capture the end of the line } /* Compute the x and y coordinates of the parabola plot and then draw it in the off-screen image. */ x = HB + X + x; y = VB + h; gi.drawLine(x, y, x, y); } void Plot() { // PLOT ONE ITERATION OF THE SELECTED FORMULA double rx = f.getX(); // get new value of x by iterating equation /* If not the first time through, wipe the old line-pair from the image; else zero y to avoid an arbitrary initial starting plot. */ if(FTTF) { Lines(gi, at); } else y = 0; x = y; // make last time's new plot this time's old plot y = (int)(k * rx); // compute this time's new plot // if not first time through draw new line-pair in image if(FTTF) { Lines(gi, fg); } FTTF = true; // set the 'first time through' flag repaint(); } // DRAW THE LINE-PAIR ON THE OFF-SCREEN IMAGE private void Lines(Graphics g, Color clr) { int H = HB + X, // x co-ordinate of graph origin in applet window V = VB + Y, // y co-ordinate of graph origin in applet window v = VB, // window y co-ordinate of top of graph's plotting area p = H + x, s = H + y, // end-points of the horzontal bounce line q = V - x, r = V - y; // end-points of the vertical bounce line g.setColor(clr); // set colour to draw or wipe as required g.drawLine(p, q, p, r); // draw or wipe the vertical line g.drawLine(p, r, s, r); // draw or wipe the horizontal line if(clr == at) { // if this is a wipe pass g.setColor(ax); // set colour for parabola // Repair the parabola +/- 3 lines from the plot for(int i = y - 3; i < y + 4; i++) { int h=Y-i; // element number of the two parabola points int b = v + h; // corresponding y co-ordinate /* Provided 'h' is within the parabola [i.e. not above or below it], repair the previously bombed left-hand and right-hand portions of parabola. */ if(h <= Pmax && h >= Pmin) { g.drawLine(H+P[h], b, H+Q[h], b); g.drawLine(H+R[h], b, H+S[h], b); } } // Set the colour and then re-draw the x and y axes. g.setColor(ax); g.drawLine(H + Amin, V, H + Amax, V); g.drawLine(H, V - Amin, H, V - Amax); /* Set colour for diagonal then put the 'take-off' and 'landing' 'fg' dots back on the diagonal. */ g.setColor(Color.white); g.drawLine(p,q,p,q); g.drawLine(s,r,s,r); } } }