//------------------------------------------------------------------------ // Diffusion Limited Aggregation // (May 1997, Sep 2000, Jan 2002, Apr 2007) // // Copyright(C) 1997-2007 Chi-Hang Lam // Permission to distribute, use or modify this software is hereby granted // provided that the above copyright notice appear in all copies // // Please send comments, corrections or modifications to // Chi-Hang Lam e-mail: apachlam@polyu.edu.hk //------------------------------------------------------------------------ import java.awt.*; import java.awt.event.*; import java.util.Vector; import java.util.Enumeration; //public class dla extends java.applet.Applet { public class dla extends java.applet.Applet{ //public class dla extends JApplet implements ActionListener { private final static long serialVersionUID = 42; Thread grow_thread; Cluster cluster; Scrollbar zoombar; Label Ltitle1,Ltitle2,Ltitle3; int zoomold; public void init(){ cluster=new Cluster(); Panel p = new Panel(); p.setLayout(new GridLayout(0,1)); p.add(new Label("")); Ltitle1=new Label("Diffusion"); Ltitle1.setFont(new Font("TimesRoman",Font.BOLD,16)); p.add(Ltitle1); Ltitle2=new Label("Limited"); Ltitle2.setFont(new Font("TimesRoman",Font.BOLD,16)); p.add(Ltitle2); Ltitle3=new Label("Aggregation"); Ltitle3.setFont(new Font("TimesRoman",Font.BOLD,16)); p.add(Ltitle3); p.add(new Label("______________________")); setFont(new Font("TimesRoman",Font.PLAIN,12)); Button button; //p.add(growbut=new Button(Sgrow)); //growbut.addActionListener(new GrowEvent()); p.add(button=new Button("Grow")); button.addActionListener(new GrowEvent()); p.add(button=new Button("GrowSlowly")); button.addActionListener(new GrowSlowlyEvent()); p.add(button=new Button("Pause")); button.addActionListener(new PauseEvent()); p.add(button=new Button("Resume")); button.addActionListener(new ResumeEvent()); p.add(button=new Button("Reset")); button.addActionListener(new ResetEvent()); p.add(new Label("zoom:")); p.add(zoombar=new Scrollbar(Scrollbar.HORIZONTAL,zoomold=100,30,1,100+30)); zoombar.addAdjustmentListener(new ZoomEvent()); p.add(new Label("")); p.add(cluster.LN); p.add(cluster.LRg); p.add(cluster.LRmax); p.add(cluster.LRbirth); p.add(cluster.LRkill); //p.add(cluster.debug); setLayout(new BorderLayout(2,2)); add("East",p); add("Center",cluster); cluster.newcluster(); } class GrowEvent implements ActionListener{ public void actionPerformed(ActionEvent e){ cluster.demoflg=false; cluster.pauseflg=false; startgrowth(); } } class GrowSlowlyEvent implements ActionListener{ public void actionPerformed(ActionEvent e){ cluster.demoflg=true; cluster.pauseflg=false; startgrowth(); } } class PauseEvent implements ActionListener{ public void actionPerformed(ActionEvent e){ cluster.pauseflg=true; } } class ResumeEvent implements ActionListener{ public void actionPerformed(ActionEvent e){ cluster.pauseflg=false; cluster.wake(); } } class ResetEvent implements ActionListener{ public void actionPerformed(ActionEvent e){ reset(); } } class ZoomEvent implements AdjustmentListener{ public void adjustmentValueChanged ( AdjustmentEvent e ) { int zoom=zoombar.getValue(); if (Math.abs(zoom-zoomold)>0){ cluster.zoomvalue=zoom; cluster.repaint(); zoomold=zoom; } } } void reset(){ if (grow_thread!=null){ cluster.contflg=false; } try {Thread.sleep(500);} catch (InterruptedException Ie) {} cluster.newcluster(); zoombar.setValue(zoomold=100); } void startgrowth(){ reset(); cluster.contflg=true; grow_thread = new Thread(cluster); grow_thread.setPriority(Thread.MIN_PRIORITY); grow_thread.start(); } } class Cluster extends Canvas implements Runnable { private final static long serialVersionUID = 42; Graphics gr; Vector Balls; Ball walker,oldwalker; DrawCluster drawcluster; double stepsize=0.1; // stepsize double demostepsize=0.1; // stepsize during slow growth double hitdist=1.; double Birthrad,killRad,killRad2,Rmax,Rg,Rg2,Rmaxold,viewwidth; double cx,cy,centx,centy,redraw_threshold; double dpixel,N=1; int dpixeldraw; boolean walkerdrawn=false,demoflg; boolean jumpflg=true,showwflg=true,autozoomflg,pauseflg=false,birthflg=true,contflg; double marginfactor=1.2,zoomfactor,zoomvalue; Color contcolor[]; int Nlastcolor,ballcnt; Label LN,LRg,LRmax,LRbirth,LRkill,debug; Cluster(){ setcontcolor(); LN=new Label(""); LRmax=new Label(""); LRg=new Label(""); LRbirth=new Label(""); LRkill=new Label(""); debug=new Label(""); } int n1=0; double r1=1,g1=0,b1=0; int ncolor=256; void setcont(int dn, double r2,double g2, double b2){ double r, g, b; for (int n = n1; (n < n1 + dn) && (n < ncolor); ++n) { r = r1 + (r2 - r1) * (n - n1) / dn; g = g1 + (g2 - g1) * (n - n1) / dn; b = b1 + (b2 - b1) * (n - n1) / dn; contcolor[n]=new Color((float)r,(float)g,(float)b); } n1 += dn; r1 = r2; g1 = g2; b1 = b2; } void setcontcolor(){ int dn; contcolor=new Color[ncolor]; dn = (int) (ncolor / 5.)+1; setcont(dn, 1., 1., 0.); setcont(dn, 0.3, 1., 0.3); setcont(dn, 0., 1., 1.); setcont(dn, 0.3, 0.3, 1.); setcont(dn, 1., 0.3, 1.); } void newcluster(){ gr=getGraphics(); setBackground(Color.black); if (Balls==null) Balls=new Vector(2000,500); else Balls.removeAllElements(); N=0; Birthrad=0; Rg2=0; Rmax=-1; zoomvalue=100; autozoomflg=true; viewwidth=10.; ballcnt=0; Nlastcolor=80; jumpflg=!demoflg; repaint(); launch(); attach(); } public void run(){ do{ walk(); } while (contflg); } void walk(){ double theta,dx,dy,R2,jumpsize,dr; boolean hitflg; Thread t=Thread.currentThread(); launch(); jumpsize=dist(); do { t.yield(); if (pauseflg) pause(); theta=Math.random()*6.283185; if (jumpflg)dr=jumpsize-hitdist+stepsize; else dr=demostepsize; walker.x+=dr*Math.cos(theta); walker.y+=dr*Math.sin(theta); movewalker(); R2=walker.x*walker.x+walker.y*walker.y; if (R2>killRad2){ if (demoflg){ gr.setColor(Color.blue); flashcircle(killRad); } launch(); } jumpsize=dist(); hitflg=(jumpsizeviewwidth)){ viewwidth=2*Rmax*marginfactor; repaint(); } } walker=null; walkerdrawn=false; } String d2str(double x,int d){ double f=Math.pow(10.,d); return( new Double(Math.round(x*f)/f).toString() ); } double dist(){ double dx,dy,d2,d2min; d2min=9999; for(Enumeration e = Balls.elements(); e.hasMoreElements();) { Ball b=(Ball)e.nextElement(); dx=walker.x-b.x; dy=walker.y-b.y; d2=dx*dx+dy*dy; if (d2