/* essai de Mandelbrot en Java */ import java.awt.*; import java.awt.image.*; import java.applet.*; import java.util.Vector; import java.util.Enumeration; import java.util.Hashtable; public class Mandel3 extends Applet implements Runnable { Image mimg=null; Image jimg=null; public JuliaProducer jprod; public MandProducer mprod; int x1,y1; public void init() { setLayout(new BorderLayout()); resize(300,410); mprod=new MandProducer(this); mimg=createImage(mprod); jprod=new JuliaProducer(-0.777,0.136,this); jimg=createImage(jprod); mprod.start(); jprod.start(); } public boolean handleEvent(Event e) { int x2,y2; double fx,fy; switch(e.id) { case Event.MOUSE_DOWN: x1=-1; y1=-1; if ((e.modifiers & Event.SHIFT_MASK)==0) if ((e.modifiers & Event.CTRL_MASK)==0) { if (e.y<200) { mprod.drawcursor(); jprod.reinit(mprod.zx0+mprod.zinc*e.x,mprod.zy0-mprod.zinc*e.y); mprod.drawcursor(); mprod.produce(mprod.ic); getGraphics().drawImage(mimg,0,0,(ImageObserver)this); } } else { if (e.y>=210) jprod.rezoom(jprod.zx0+(e.x-150)*jprod.zinc, jprod.zy0-(e.y-310)*jprod.zinc,jprod.zinc); if (e.y<200) mprod.rezoom(mprod.zx0+(e.x-150)*mprod.zinc, mprod.zy0-(e.y-100)*mprod.zinc,mprod.zinc); } else if ((e.modifiers & Event.CTRL_MASK)==0) { x1=e.x; y1=e.y; } else { if (e.y>=210) jprod.rezoom(-1.5,1.0,0.01); if (e.y<200) mprod.rezoom(-2.0,1.0,0.01); } return true; case Event.MOUSE_UP: if ((y1>=210)&&(e.y>=210)) { x2=x1+e.x; y2=y1+e.y; fx=((double)(x1-e.x))/300.0; if (fx<0) fx=-fx; fy=((double)(y1-e.y))/200.0; if (fy<0) fy=-fy; if (fy>fx) fx=fy; if (fx>0.02) jprod.rezoom( jprod.zx0+x2*jprod.zinc/2.0-150.0*fx*jprod.zinc, jprod.zy0-(y2-420)*jprod.zinc/2.0+100.0*fx*jprod.zinc, jprod.zinc*fx); } if ((y1<200)&&(e.y<200)&&(y1>=0)) { x2=x1+e.x; y2=y1+e.y; fx=((double)(x1-e.x))/300.0; if (fx<0) fx=-fx; fy=((double)(y1-e.y))/200.0; if (fy<0) fy=-fy; if (fy>fx) fx=fy; if (fx>0.02) mprod.rezoom( mprod.zx0+x2*mprod.zinc/2.0-150.0*fx*mprod.zinc, mprod.zy0-y2*mprod.zinc/2.0+100.0*fx*mprod.zinc, mprod.zinc*fx); } return true; case Event.WINDOW_DESTROY: System.exit(0); return true; default: return false; } } public void run() { prepareImage(mimg,this); prepareImage(jimg,this); } public void paint(Graphics g) { g.drawImage(mimg,0,0,(ImageObserver)this); g.drawImage(jimg,0,210,(ImageObserver)this); } public boolean imageUpdate(Image img,int flags,int x,int y,int w,int h) { /* repaint(); */ return true; } } class MandProducer extends Thread implements ImageProducer { int mandbmp[]; boolean uptodate; public double zx0,zy0,zinc; Vector ic; ColorModel DCModel; Enumeration e; ImageConsumer cli; Hashtable props; Mandel3 boss; public void drawcursor() { int a,b,j; a=(int)((boss.jprod.cx-zx0)/zinc); b=(int)((zy0-boss.jprod.cy)/zinc); if ((a>=0)&&(a<=299)) for (j=b-5;j<=b+5;j++) if ((j>=0)&&(j<=199)) mandbmp[300*j+a]^=0xffff; if ((b>=0)&&(b<=199)) for (j=a-5;j<=a+5;j++) if ((j>=0)&&(j<=299)) mandbmp[300*b+j]^=0xffff; } public void drawmand() { double x,y,xx,yy,xt; int c,i,j; int index=0; if (!uptodate) { y=zy0; for (i=0;i<200;i++) { x=zx0; for (j=0;j<300;j++) { xx=x; yy=y; c=0; while ((c++<20)&&(xx*xx+yy*yy<4.0)) { xt=xx*xx-yy*yy+x; yy=2*xx*yy+y; xx=xt; } mandbmp[index++]=(255<<24)+c*0x0c0c0c; x+=zinc; } if (i==199) drawcursor(); if (i%20==19) { produce(ic); boss.getGraphics().drawImage(boss.mimg,0,0,(ImageObserver)boss); } y-=zinc; } uptodate=true; } else produce(ic); } public MandProducer(Mandel3 appl) { props=new Hashtable(); DCModel=ColorModel.getRGBdefault(); ic=new Vector(); uptodate=false; mandbmp=new int[200*300]; boss=appl; zx0=-2.0; zy0=1.0; zinc=0.01; } public synchronized void rezoom(double x0,double y0,double inc) { zx0=x0; zy0=y0; zinc=inc; uptodate=false; resume(); } void produce(Vector icbis) { for (e=icbis.elements();e.hasMoreElements();) { cli=(ImageConsumer)e.nextElement(); cli.setDimensions(300,200); cli.setProperties(props); cli.setColorModel(DCModel); cli.setHints(ImageConsumer.TOPDOWNLEFTRIGHT| ImageConsumer.COMPLETESCANLINES| ImageConsumer.SINGLEPASS); cli.setPixels(0,0,300,200,DCModel,(int[])mandbmp,0,300); cli.imageComplete(ImageConsumer.SINGLEFRAMEDONE); } } public void run() { while (true) { drawmand(); suspend(); } } public synchronized void addConsumer(ImageConsumer c) { ic.addElement(c); } public synchronized boolean isConsumer(ImageConsumer c) { return ic.contains(c); } public synchronized void removeConsumer(ImageConsumer c) { ic.removeElement(c); } public /* synchronized */ void startProduction(ImageConsumer c) { ic.addElement(c); produce(ic); } public void requestTopDownLeftRightResend(ImageConsumer c) { } } class JuliaProducer extends Thread implements ImageProducer { int juliabmp[]; public double cx,cy; public double zx0,zy0,zinc; boolean uptodate; Vector ic; ColorModel DCModel; Enumeration e; ImageConsumer cli; Hashtable props; Mandel3 boss; public void drawjulia() { double x,y,xx,yy,xt; int c,i,j; int index=0; if (!uptodate) { y=zy0; for (i=0;i<200;i++) { x=zx0; for (j=0;j<300;j++) { xx=x; yy=y; c=0; while ((c++<40)&&(xx*xx+yy*yy<4.0)) { xt=xx*xx-yy*yy+cx; yy=2*xx*yy+cy; xx=xt; } juliabmp[index++]=(255<<24)+c*0x060606; x+=zinc; } if (i%20==19) { produce(ic); boss.getGraphics().drawImage(boss.jimg,0,210,(ImageObserver)boss); } y-=zinc; } uptodate=true; } else produce(ic); } public JuliaProducer(double x,double y,Mandel3 appl) { cx=x; cy=y; zx0=-1.5; zy0=1.0; zinc=0.01; props=new Hashtable(); DCModel=ColorModel.getRGBdefault(); ic=new Vector(); uptodate=false; juliabmp=new int[200*300]; boss=appl; } public synchronized void reinit(double x,double y) { cx=x; cy=y; zx0=-1.5; zy0=1.0; zinc=0.01; uptodate=false; resume(); } public synchronized void rezoom(double x0,double y0,double inc) { zx0=x0; zy0=y0; zinc=inc; uptodate=false; resume(); } void produce(Vector icbis) { for (e=icbis.elements();e.hasMoreElements();) { cli=(ImageConsumer)e.nextElement(); cli.setDimensions(300,200); cli.setProperties(props); cli.setColorModel(DCModel); cli.setHints(ImageConsumer.TOPDOWNLEFTRIGHT| ImageConsumer.COMPLETESCANLINES| ImageConsumer.SINGLEPASS); cli.setPixels(0,0,300,200,DCModel,(int[])juliabmp,0,300); cli.imageComplete(ImageConsumer.SINGLEFRAMEDONE); } } public void run() { while (true) { drawjulia(); suspend(); } } public synchronized void addConsumer(ImageConsumer c) { ic.addElement(c); } public synchronized boolean isConsumer(ImageConsumer c) { return ic.contains(c); } public synchronized void removeConsumer(ImageConsumer c) { ic.removeElement(c); } public /* synchronized */ void startProduction(ImageConsumer c) { ic.addElement(c); produce(ic); } public void requestTopDownLeftRightResend(ImageConsumer c) { } }