Bifurcation Map Generator
The following code is that of the java applet which generates the bifurcation map for the equation x = cx(1 - x).
/**
* Bifurcation Map Generator for x = cx(1 - x)
* @author Robert J Morton
* @version 5 December 1997
*/
import java.awt.*;
public class bifmap1 extends java.applet.Applet implements Runnable {
int H = 17, V = 15; //top and left margins (in pixels)
int X, Y; //dimensions of display window (in pixels)
int x, y; //co-ords of resultant plot (in pixels)
int scale = 160; //number of pixels per 1.0 real
int cMAX = scale * 3 + 1, rMAX = scale + 1; //dimensions of the plotting area
int W = V + scale; //origin on the vertical scale
double r; //the 'real' variable
double c; //the 'real' constant
double Scale = (int)(scale); //pixels per unit 'real' (100 pixels = 1.00)
int I; //number of iterations of x = x * x + c
int i; //current iteration number of the above
boolean finished = false; //indicates when the map has been completed
Image buffer = null; //reference for an off-screen image buffer
Graphics gc = null; //graphics context for the off-screen image
Color bg, tc, ac; //background colour, trace colour, attractor colour
Color A[][]; //pixel array to minimise calls to drawLine()
Thread Bif; //thread reference variable for this program
long TimeFrame = 150; //inter-plot time frame (milliseconds)
long T; //future system time at which a new plot is due to begin
public void init() { //NORMAL APPLET INITIALISER METHOD
int j, k; //utility loop variables
bg = Color.lightGray; //set background colour
ac = new Color( 0, 128, 64); //create the trace colour
tc = new Color( 0, 255, 128); //create the attractor colour
Dimension d = size(); //get size of window as given in HTML applet tag
X = d.width; Y = d.height; //establish window width and height
buffer = createImage(X, Y); //create the off-screen image buffer
gc = buffer.getGraphics(); //graphics context reference for the off-screen image
gc.setColor(Color.lightGray); //set background colour for the off-screen image
gc.fillRect(0, 0, X, Y); //paint the background colour for the off-screen image
A = new Color[cMAX][rMAX]; //create a pixel array for pixels
for(j = 0 ; j < cMAX ; j++) //and set them all to light grey
for(k = 0 ; k < rMAX ; k++) //Pixels are plotted in here so they can be checked
A[j][k] = bg; //to avoid having to call drawLine() unnecessarily.
gc.setColor(Color.gray); //set colour for scale lines
j = H - 5; //start of scale marks for vertical scale
gc.drawLine(H, V, H, W); //draw the vertical scale line
int di = scale / 5; //increment between scale marks on vertical scale
for(i = 0 ; i <= scale; i += di) //At each mark position on vertical scale
gc.drawLine(j, V + i, H, V + i); // draw the vertical scale's scale marks.
I = scale * 3; //length of the horizontal scale
j = W + 5; //bottom of scale marks for horizontal scale
gc.drawLine(H, W, H + I, W); //draw the horizontal scale line
di = scale / 2; //increment between scale marks
for(i = 0 ; i <= I; i += di) //At each scale mark position
gc.drawLine(H + i, W, H + i, j); // draw a scale mark.
Font font = new Font("Dialog", Font.PLAIN, 12); //choose the font for the text in this applet
gc.setFont(font);
int h = H - 15, //horizontal co-ordinate of vertical scale figures
v = V + 3; //start position of vertical co-ordinates
gc.drawString("1", h + 4, v); //number the vertical axis
gc.drawString(".8", h, v + (int)(scale * .2));
gc.drawString(".6", h, v + (int)(scale * .4));
gc.drawString(".4", h, v + (int)(scale * .6));
gc.drawString(".2", h, v + (int)(scale * .8));
gc.drawString("0", h + 3, v + scale);
h = H - 2; //start position of horizontal scale figures
v = V + scale + 16; //vertical co-ord of base of figures for horiz scale
gc.drawString("1", h, v); //number horizontal scale
gc.drawString("2", h + scale, v);
gc.drawString("3", h + (int)(Scale * 2), v);
gc.drawString("4", h + (int)(Scale * 3), v);
gc.setColor(Color.black); //set color for lettering
gc.drawString("x", H - 2, V - 4); //label the vertical axis
gc.drawString("c", H + 485, W + 2); //label the horizontal
x = 0; //set to start map from right-hand edge
T = System.currentTimeMillis() + TimeFrame; //end of first plot's time frame
}
public void paint(Graphics g) { //PAINT / RE-PAINT THE PICTURE SO FAR
g.drawImage(buffer, 0, 0, null); //(re)draw from the off-screen image buffer
}
public void update(Graphics g) { //called in response a request for a repaint()
Color C = tc; //set current colour to aura trace colour
if(x < cMAX) { //if not yet reached end of c axis
c = (double)(x) / Scale + 1; //real c value corresponding to current x-pixel
r = .01; //Reset r for a new iteration run
for(i = 0; i < 10000; i++) { //for I (further) iterations
if(i > 100) C = ac; //change colour when r has had time to settle
r = c * r * (1 - r); //advance the iteration process
if(r >= 1 || r <= 0) break; //bail out if r gone off screen
y = (int)(r * Scale); //y-plot for current value of r
Color K = A[x][y]; //current colour of corresponding pixel
if(K == bg || C == ac && K == tc) { //if pixel needs to be drawn
A[x][y] = C; //set pixel element to appropriate trace colour
int h = H + x, v = W - y; //applet window co-ords of new plot
gc.setColor(C); //set colour for final stretch of current line
gc.drawLine(h, v, h, v); //draw line from start dot to previous dot
g.setColor(C); //set colour for final stretch of current line
g.drawLine(h, v, h, v); //draw line from start dot to previous dot
}
} x++; //advance right one pixel
} else finished = true; //if we've completed the attractor, the map is finished
}
public void run() { //run the Track Recorder painting thread
while(true) { //permanent loop
if(!finished) repaint(); //paint in the next plot
long s = T - System.currentTimeMillis(); //get time left in this plot's time frame
if(s < 5) s = 5; //in case machine isn't fast enough
try { Thread.currentThread().sleep(s); //sleep for the time remaining
} catch (InterruptedException e) { } //catch interrupt from GUI or browser
T = System.currentTimeMillis() + TimeFrame; //get when next plot's time frame will end
}
}
public void start() { //Start the program thread by
Bif = new Thread(this); //creating the thread object
Bif.start(); //and starting it running by
} //requesting a call to run()
public void stop() { Bif.stop(); } //Stop this a program thread
/* Robert J Morton, the author of this program,
is a poor but Right Honourable Fellow of the
Ancient and Noble Order of the Long-term Unemployed.
Offers of work please to: robmorton@clara.net */
}
This page's parent within this Web Site.
About this Web Site.
Its home page.
Email its Author.