home *** CD-ROM | disk | FTP | other *** search
/ Java 1.2 How-To / JavaHowTo.iso / javafile / ch07 / Mandelbrot.java < prev    next >
Encoding:
Java Source  |  1998-12-14  |  5.6 KB  |  272 lines

  1. import java.applet.Applet;
  2. import java.awt.*;
  3. import java.awt.event.*;
  4. import java.awt.image.*;
  5.  
  6. /*
  7.  * a class for generating and displaying the
  8.  * Mandelbrot set
  9.  */
  10. public class Mandelbrot extends Applet implements MouseListener,
  11.                         MouseMotionListener, ActionListener
  12. {
  13.  
  14. /*
  15.  * the maximum number of colors for
  16.  * each pixel
  17.  */
  18. final int MaxColors = 256;
  19.  
  20. /*
  21.  * the width and height of the image
  22.  */
  23. int mWidth, mHeight;
  24.  
  25. /*
  26.  * the array of pixel values
  27.  */
  28. int pixels[];
  29.  
  30. /*
  31.  * the set values
  32.  */
  33. int mandelSet[];
  34.  
  35. /*
  36.  * the image produce by the set
  37.  */
  38. Image theImage = null;
  39.  
  40. /*
  41.  * the mapping function from set values to pixel values
  42.  */
  43. int pixMap[] = new int[MaxColors];
  44.  
  45. /*
  46.  * a flag used for recalculating
  47.  */
  48. boolean startCalculate = false;
  49.  
  50. /*
  51.  * instance of MandelRect class
  52.  */
  53. MandelRect mandelRect;
  54.  
  55. /*
  56.  * the control buttons
  57.  */
  58. Button startButton;
  59. Button zoomButton;
  60.  
  61. /*
  62.  * called when the applet is loaded
  63.  * initialize the pixmap array and add user interface
  64.  */
  65. public void init () {
  66.  
  67.     mWidth = 100;
  68.     mHeight = 100;
  69.     pixels = new int [mWidth * mHeight];
  70.     mandelSet = new int [mWidth * mHeight];
  71.  
  72.     mandelRect = new MandelRect (mWidth, mHeight);
  73.  
  74.     int red, green, blue;
  75.     int i;
  76.  
  77.     pixMap[0] = 0xffffffff;
  78.     for (i=1; i<MaxColors-1; i+=1) {
  79.         red = i;
  80.         green = (i<128) ? i << 1 : 255-(i<<1);
  81.         blue = MaxColors-i;
  82.         pixMap[i] = (255 << 24) | (red << 16) | (green << 8) | blue;
  83.     }
  84.     pixMap[MaxColors-1] = 0xff000000;
  85.  
  86.     setLayout(new BorderLayout());
  87.  
  88.     startButton = new Button ("Start over");
  89.     zoomButton = new Button ("Zoom in");
  90.     startButton.addActionListener(this);
  91.     zoomButton.addActionListener(this);
  92.     addMouseListener(this);
  93.     addMouseMotionListener(this);
  94.  
  95.     Panel p = new Panel ();
  96.     p.setLayout (new FlowLayout ());
  97.     p.add (startButton);
  98.     p.add (zoomButton);
  99.     add ("South", p);
  100. }
  101.  
  102. /*
  103.  * called when the applet is started
  104.  * forces a recalculation of the set
  105.  */
  106. public void start () {
  107.  
  108.     startCalculate = true;
  109.     repaint ();
  110. }
  111.  
  112. /*
  113.  * call update for efficiency
  114.  * @param g - destination graphics object
  115.  */
  116. public void paint (Graphics g) {
  117.  
  118.     update (g);
  119. }
  120.  
  121. /**
  122.  * override default update() method to avoid erase flicker
  123.  * @param g - destination graphics object
  124.  */
  125. public void update (Graphics g) {
  126.  
  127.     if (startCalculate) {
  128.         calculate ();
  129.         startCalculate = false;
  130.     }
  131.     if (theImage != null) g.drawImage (theImage, 0, 0, this);
  132.     else repaint (1000);
  133.     mandelRect.paint (g);
  134. }
  135.  
  136. /*
  137.  * perform the actual set calculation
  138.  */
  139. void calculate () {
  140.  
  141.     int i, index;
  142.     double width, height;
  143.     double row, col;
  144.     double zr, zi, cr, ci, tzr, tzi;
  145.     double hFactor, vFactor;
  146.     double x, y;
  147.  
  148.     theImage = null;
  149.  
  150.     x = mandelRect.mandelX;
  151.     y = mandelRect.mandelY;
  152.     width = (double) mandelRect.imgWidth;
  153.     height = (double) mandelRect.imgHeight;
  154.     hFactor = mandelRect.mandelWidth/width;
  155.     vFactor = mandelRect.mandelHeight/height;
  156.  
  157.     index = 0;
  158.     for (row=0; row<height; row+=1) {
  159.         for (col=0; col<width; col+=1) {
  160.             zr = 0;
  161.             zi = 0;
  162.             cr = x + col * hFactor;
  163.             ci = y + row * vFactor;
  164.             for (i=1; i<64; i+=1) {
  165.                 tzr = zr*zr - zi*zi + cr;
  166.                 tzi = 2*zr*zi + ci;
  167.                 zr = tzr;
  168.                 zi = tzi;
  169.                 if (zr*zr + zi*zi > 4.0) break;
  170.             }
  171.             mandelSet[index++] = (i << 2)-1;
  172.         }
  173.     }
  174.  
  175.     for (i=0; i<mWidth*mHeight; i+=1) {
  176.         pixels[i] = pixMap[mandelSet[i]];
  177.     }
  178.  
  179.     theImage = createImage (
  180.         new MemoryImageSource(mWidth, mHeight, pixels, 0, mWidth));
  181. }
  182.  
  183. public void mouseClicked(MouseEvent e){}
  184. public void mouseEntered(MouseEvent e){}
  185. public void mouseExited(MouseEvent e){}
  186.  
  187. public void mouseReleased(MouseEvent e)
  188. {
  189.     int x =e.getX();
  190.     int y =e.getY();
  191.  
  192.     mandelRect.setWidthHeight (x, y);
  193.     mandelRect.setPaintRect (true);
  194.     repaint ();
  195. }
  196.  
  197. public void mouseMoved(MouseEvent e){}
  198.  
  199. public void mousePressed(MouseEvent e)
  200. {
  201.     int x =e.getX();
  202.     int y =e.getY();
  203.  
  204.     mandelRect.setXY (x, y);
  205. }
  206.  
  207. public void mouseDragged(MouseEvent e)
  208. {
  209.     int x =e.getX();
  210.     int y =e.getY();
  211.  
  212.     mandelRect.setWidthHeight (x, y);
  213.     mandelRect.setPaintRect (true);
  214.     repaint ();
  215.  
  216. }
  217. /**
  218.  * reorder the images, depending on which button is pressed
  219.  * @param evt - event object
  220.  * @param arg - target object
  221.  */
  222. public void actionPerformed(ActionEvent evt)
  223. {
  224.     Object object1 = evt.getSource();
  225.  
  226.     if (object1 == startButton) {
  227.         mandelRect = new MandelRect (mWidth, mHeight);
  228.         startCalculate = true;
  229.         repaint ();
  230.     }
  231.     if (object1 == zoomButton)
  232.     {
  233.         startCalculate = true;
  234.         mandelRect.setPaintRect (false);
  235.         mandelRect.scaleSet ();
  236.         repaint ();
  237.     }
  238. }
  239.  
  240. /**
  241.  * application entry point
  242.  * create window and new set
  243.  * @param args - command-line arguments
  244.  */
  245. public static void main (String args[]) {
  246.  
  247.     Frame f = new Frame ("Mandelbrot set");
  248.     Mandelbrot mandel = new Mandelbrot ();
  249.  
  250.     mandel.init ();
  251.     f.setSize (210, 275);
  252.     f.add ("Center", mandel);
  253.     f.show ();
  254.     f.addWindowListener(new WindowCloser());
  255.  
  256.     mandel.start ();
  257. }
  258. }
  259.  
  260. class WindowCloser extends WindowAdapter
  261. {
  262.     public void windowClosing(WindowEvent e)
  263.     {
  264.         Window win = e.getWindow();
  265.         win.setVisible(false);
  266.         win.dispose();
  267.         System.exit(0);
  268.     }
  269. }
  270.  
  271.  
  272.