import java.applet.*;import java.awt.*;import java.awt.event.*;import java.awt.image.*;import java.io.*;public class MSetApplet extends Applet implements ActionListener, MouseListener, Runnable {  Thread theThread;  Image im;  int width = 400, height = 400;  double xmin=-2, xmax=2, ymin=-2, ymax=2;  int lastMinI=0;  MemoryImageSource imSource;  boolean julia=false;  double cr, ci;  boolean saveImage;    public static void main(String[] args) {    Frame f = new Frame();    int curarg=0;    MSetApplet applet = new MSetApplet();    applet.saveImage=true;    if (args[0].equalsIgnoreCase("-j")) {      applet.julia = true;      curarg++;      applet.cr = new Double(args[curarg++]).doubleValue();      applet.ci = new Double(args[curarg++]).doubleValue();    }    if (args[0].equalsIgnoreCase("-m")) {      applet.julia = true;      curarg++;      // use defined ones above...      //applet.cr = new Double(args[curarg++]).doubleValue();      //applet.ci = new Double(args[curarg++]).doubleValue();    }    f.setSize(Integer.parseInt(args[curarg++]), Integer.parseInt(args[curarg++]));    if (args.length > curarg) {      try {        applet.lastMinI = Integer.parseInt(args[curarg++]);      } catch (NumberFormatException e) { curarg--; }    }    f.add(applet);    f.show();    applet.init();    applet.start();  }    public void init() {    setLayout(new BorderLayout());    Button b = new Button("Zoom out");    b.addActionListener(this);    addMouseListener(this);    add(b, "South");    width = getSize().width;    height = getSize().height;  }  public void start() {    updateData();  }  public void stop() {    if (theThread != null) theThread.stop();  }  public void destroy() {    if (theThread != null) theThread.stop();  }  public void actionPerformed(ActionEvent e) {    zoom(4);    updateData();  }  public void mouseClicked(MouseEvent e) {    zoom(xmin+(xmax-xmin)*e.getX()/width, ymin+(ymax-ymin)*e.getY()/height, .25);    updateData();  }  public void mousePressed(MouseEvent e) { }  public void mouseReleased(MouseEvent e) { }  public void mouseEntered(MouseEvent e) { }  public void mouseExited(MouseEvent e) { }    public void updateData() {    if (theThread != null) theThread.stop();    try {      theThread = new Thread(this);      theThread.setDaemon(true);      theThread.setPriority(Thread.currentThread().getPriority()-1);      theThread.run();    } catch (Exception ex) { ex.printStackTrace(); }  }    public void update(Graphics g) {    paint(g);  }  public void paint(Graphics g) {    g.drawImage(im, 0, 0, this);    System.out.println("painted "+im);  }    public void zoom(double zfact) {    zoom((xmax+xmin)/2, (ymax+ymin)/2, zfact);  }  public void zoom(double x, double y, double zfact) {    double dx = xmax-xmin, dy = ymax-ymin;    dx *= zfact; dy *= zfact;    xmin = x - dx/2; xmax = x + dx/2;    ymin = y - dy/2; ymax = y + dy/2;  }    public int[] toRedOrange(int data[]) {    for(int i=0; i<data.length; i++) {      if (data[i] == -1) data[i] = (255 << 24);      else data[i] = (data[i] << 8) | (255 << 16) | (255 << 24);  // red & orange    }    return data;  }    public void run() {    System.out.println("Busy...");    width = getSize().width;    height = getSize().height;    System.out.println("making "+getSize());    int[] data = getImageData(width, height);    if (saveImage) {      try {        File f;        if (julia) f = new File("Julia.bmp");        else f = new File("Mset.bmp");        System.out.println("Writing "+f);        SimpleBMPWriter.write(f, data, width, height);        String[] mainArgs = { "-a", f.toString(), "1500" };        //SimpleBMPWriter.main(mainArgs);  // append to end of file 1500 null bytes ... but calls System.exit()        System.out.println("Wrote "+f);      }      catch (IOException e) {        System.out.println(e);      }      catch (Exception e) {        e.printStackTrace(System.out);      }    }    imSource = new MemoryImageSource(width, height, data, 0, width);    im = createImage(imSource);    System.out.println("made image "+im);    repaint();  }      public int[] getImageData(int w, int h) {    long time = System.currentTimeMillis();    int iter = lastMinI+250;    System.out.println(""+iter+" iterations.");    int[] data;    if (julia) data = getJSet(cr, ci, xmin,ymin,xmax,ymax,(xmax-xmin)/w,(ymax-ymin)/h,iter);    else data = getMSet(xmin,ymin,xmax,ymax,(xmax-xmin)/w,(ymax-ymin)/h,iter);    int minData=data[0];    lastMinI = minData;    for(int i=0; i<data.length; i++) if (minData > data[i]) minData = data[i];    for(int i=0; i<data.length; i++) {      if (data[i] == iter) data[i] = -1;      else data[i] = Math.min(5*(data[i]-minData),255);    }    data = toRedOrange(data);    System.out.println("Done in "+(System.currentTimeMillis()-time)+".");    return data;  }    public final static int[] getMSet(double xmin,                                    double ymin,                                    double xmax,                                    double ymax,                                    double xres,                                    double yres,                                    int interations) {    int x, y, i, w=(int)((xmax-xmin)/xres), h=(int)((ymax-ymin)/yres);    int[] data = new int[w*h];    double cr, ci, zr, zi, tr, ti, zrsqr, zisqr;    long time = System.currentTimeMillis();    for(y=0; y<h; y++) {      for(x=0; x<w; x++) {        cr = xmin+(xmax-xmin)*x/w;        ci = ymin+(ymax-ymin)*y/h;        zr = cr; zi = ci;        for(i=0; i<interations; i++) {          zrsqr = zr*zr;          zisqr = zi*zi;          if (zrsqr+zisqr > 4) break;          tr = cr + zrsqr-zisqr;          zi = ci + 2*zr*zi;          zr = tr;        }        data[w*y+x] = i;      }      if (System.currentTimeMillis()-time > 1000) {        System.out.println(""+100*y/h+" %");        time = System.currentTimeMillis();      }     }    return data;  }    public final static int[] getJSet(double cr,                                    double ci,                                    double xmin,                                    double ymin,                                    double xmax,                                    double ymax,                                    double xres,                                    double yres,                                    int interations) {    int x, y, i, w=(int)((xmax-xmin)/xres), h=(int)((ymax-ymin)/yres);    int[] data = new int[w*h];    double zr, zi, tr, ti, zrsqr, zisqr;    long time = System.currentTimeMillis();    for(y=0; y<h; y++) {      for(x=0; x<w; x++) {        zr = xmin+(xmax-xmin)*x/w;        zi = ymin+(ymax-ymin)*y/h;        for(i=0; i<interations; i++) {          zrsqr = zr*zr;          zisqr = zi*zi;          if (zrsqr+zisqr > 4) break;          tr = cr + zrsqr-zisqr;          zi = ci + 2*zr*zi;          zr = tr;        }        data[w*y+x] = i;      }      if (System.currentTimeMillis()-time > 1000) {        System.out.println(""+100*y/h+" %");        time = System.currentTimeMillis();      }     }    return data;  }  }