/** Henon's Strange Attractor Generator by Robert J Morton 30 October 1997 */ import java.awt.*; import javax.swing.*; import java.awt.image.BufferedImage; public class hengraph extends JPanel implements Runnable { private int XE, // Horizontal extent of window and JFrame. YE, // Vertical extent of window and JFrame. XBIAS = 150, // pixel co-ordinates of real point 0,0 YBIAS = 150, XMAX = 300, // dimensions of the display area (pixels) YMAX = 300, i, // Pixel co-ordinates of chaotic body j; // within the visible xy plane. private long tf = 150, // inter-plot time frame (milliseconds) t; // current system time private double Scale = 100, // pixels per unit real eg 100 pixels = 1.00d x = 0, // real co-ordinates of 'chaotic body' y = 0, z; private Color A[][], // pixel colour array colour, // current plot colour bgc = Color.black, // background colour fgc = new Color(0,255,128), // bright green for trace axc = new Color(96,128,0); // special browny-green for axes 64,192,0 private BufferedImage I; // off-screen image on which to plot the graph private Graphics2D gi; // graphics reference for off-screen image private Thread T; // declare a thread reference variable public hengraph(int XE, int YE) { this.XE = XE; // horizontal [X] dimension of the JPanel this.YE = YE; // vertical [Y] dimension of the JPanel setBounds(0,0,XE,YE); // the JPanel fills the whole of the JFrame area setLayout(null); // JPanel has free-form layout [for graph] /* Create a Buffered Image "I" on which to plot Henon's Attractor off- screen and get its graphics context "gi" for realising the plots. */ I = new BufferedImage(XE,YE,BufferedImage.TYPE_INT_RGB); gi = I.createGraphics(); A = new Color[XMAX][YMAX]; // create colour array for the display area for(i = 0; i < XMAX; i++) // clear the colour array to background colour for(j = 0; j < YMAX; j++) A[i][j] = bgc; for(i = 0; i < XMAX; i++) // c reate the x-axis graticule A[i][YBIAS] = axc; for(j = 0; j < YMAX; j++) // create the y-axis graticule A[XBIAS][j] = axc; // Set the system time at which the next plot's time frame must end. t = System.currentTimeMillis() + tf; T = new Thread(this); // creating the thread object T.start(); // and starting it running by } public void paint(Graphics g) { // PAINT / RE-PAINT THE PICTURE SO FAR g.drawImage(I,20,20,this); // display the buffered image } private void initialPlot() { for(j = 0; j < YMAX; j++) { // for each of the YMAX lines in the picture int I = 0; // starting dot of next single-colour stretch of line i = 0; // to find next pixel in current line with different colour colour = A[I][j]; // make colour of first dot the reference colour // While not yet reached the end of the current line... while(++i < XMAX) { // if this dot is a different colour from the previous dot... if(colour != A[i][j]){ gi.setColor(colour); // set colour to colour of previous dot gi.drawLine(I,j,i-1,j); // draw line from start dot to previous dot colour = A[I = i][j]; // make reference colour that of this dot } } gi.setColor(colour); // set colour for final stretch of current line gi.drawLine(I,j,i-1,j); // draw the last stretch of the current line } } private void currentPlot(){ z = x; // z inherits last time's value of x x = 1.4*x*x+0.3*y-1; // advance x y = z; // advance y int i=XBIAS+(int)(x*Scale); // Compute the pixel co-ordinates int j=YBIAS-(int)(y*Scale); // corresponding to new values of x and y. A[i][j] = fgc; // put the plot on the 'canvas' gi.setColor(fgc); // set colour for plot gi.drawLine(i,j,i,j); // draw the plot in the applet window } public void run() { // run the Track Recorder painting thread initialPlot(); while(true) { // permanent loop currentPlot(); repaint(); // paint in the next plot /* Get the time left in this plot's time frame and if it is less than 5 milliseconds, set it to 5 milliseconds. */ long s = t - System.currentTimeMillis(); if(s < 5) s = 5; /* Sleep for the remainder of the time frame. If an external interrupt occurs during this time, catch it and process it. */ try{Thread.currentThread().sleep(s); } catch (InterruptedException e) { } // Set the system time at which the next plot's time frame will end. t = System.currentTimeMillis() + tf; } } }