// 2D site percolation on torus, Evgeny Demidov 31 Oct 2001 import java.awt.*; import java.awt.event.*; public class @file extends java.applet.Applet implements MouseListener, ItemListener, KeyListener{ int L = 25,L1, d, w, maxColor = 18, hd, hBut = 30, cl[][], np[], maxCl = 100000, periodic = 0; double p = .5; Image buffImage; Graphics buffGraphics; Color col[]; boolean painted = false; Choice chL,chB; Label lbL, lbP; TextField tfP; long generTime; public void init() { w = getSize().width; cl = new int[w+1][w]; np = new int [maxCl]; String s=getParameter("L"); if (s != null) L = Integer.parseInt(s); d = w/L; hd = w-d; L1 = L+1; s=getParameter("p"); if (s != null) p = Double.valueOf(s).doubleValue(); col = new Color[maxColor]; col[0] = Color.red; col[3] = new Color(0,200,0); col[6] = Color.blue; col[9] = new Color(220,220,0); col[12] = new Color(0,220,220); col[15] = new Color(255,0,255); col[1] = new Color(255,150,150); col[4] = new Color(120,255,120); col[7] = new Color(150,150,255); col[10] = new Color(255,255,120); col[13] = new Color(120,255,255); col[16] = new Color(255,150,255); for (int i = 0; i < 18; i += 3) col[i+2] = col[i].darker(); buffImage = createImage(w, w); buffGraphics = buffImage.getGraphics(); addMouseListener(this); chL = new Choice(); if (w == 400) for (int i = 0, l = 25; i < 5; i++){ chL.addItem(Integer.toString(l)); l *= 2;} else for (int i = 0, l = 20; i < 6; i++){ chL.addItem(Integer.toString(l)); l *= 2;}; chL.select(""+L); chL.addItemListener(this); lbL = new Label("L"); add(lbL); add(chL); lbP = new Label("p"); add(lbP); tfP = new TextField( "" + (float)p, 5); add(tfP); tfP.addKeyListener(this); chB = new Choice(); chB.addItem("square "); chB.addItem("cylinder"); chB.addItem("torus "); chB.select(periodic); chB.addItemListener(this); add(chB); } public void destroy() { removeMouseListener(this); } public void mouseClicked(MouseEvent e){} // event handling public void mousePressed(MouseEvent e) { painted = false; repaint(); e.consume(); } public void mouseReleased(MouseEvent e){} public void mouseEntered(MouseEvent e) {} public void mouseExited(MouseEvent e) {} public void keyTyped(KeyEvent e){} public void keyPressed(KeyEvent e){} public void keyReleased(KeyEvent e){ final int keyEnter = 10; if (e.getKeyCode() == keyEnter){ try{ p = Double.valueOf(tfP.getText()).doubleValue(); }catch(NumberFormatException ne){} painted = false; repaint(); } e.consume(); } public void itemStateChanged(ItemEvent e){ L = Integer.parseInt(chL.getSelectedItem()); d = w/L; hd = w-d; L1 = L+1; periodic = chB.getSelectedIndex(); painted = false; repaint(); } public void paint(Graphics g) { if ( !painted ){ generTime = System.currentTimeMillis(); showStatus( "labeling clusters"); buffGraphics.setColor(Color.white); buffGraphics.fillRect(0, 0, w, w); for (int i = 0; i < maxCl; i++) np[i] = 0; for (int i = 0; i < L1; i++) for (int j = 0; j < L; j++) cl[i][j] = -1; int newCl = 1, maxCl_1 = maxCl-1; for (int i = 1; i < L1; i++){ int leftCl = -1; for (int j = 0; j < L; j++){ if ( Math.random() > p){ leftCl = -1; continue;} int downCl = cl[i-1][j]; //System.out.println(""+i+" "+j+" l="+leftCl+" d="+downCl); if ( downCl == -1){ if (leftCl == -1){ leftCl = cl[i][j] = newCl; if (newCl < maxCl_1) newCl++;} else cl[i][j] = leftCl;} else{ downCl = proper(downCl); if (leftCl == -1){ leftCl = cl[i][j] = downCl; continue;} if (leftCl == downCl){ cl[i][j] = leftCl; continue;} if (leftCl < downCl) cl[i][j] = np[downCl] = leftCl; else{ cl[i][j] = np[leftCl] = downCl; leftCl = downCl;}} }} int clA, clB, L_1 = L-1; if (periodic > 0){ for (int i = 1; i < L1; i++) if (((clA = cl[i][0]) != -1)&&((clB = cl[i][L_1]) != -1)) if ((clA = proper(clA)) != (clB = proper(clB))) if (clA > clB) np[clA] = clB; else np[clB] = clA;} int percCl = -1, topCl; boolean isPercolating = false; perc: for (int i = 0; i < L; i++){ if ((percCl = cl[1][i]) == -1) continue; percCl = proper(percCl); for (int j = 0; j < L; j++){ if ((topCl = cl[L][j]) != -1) if (percCl == proper(topCl)){ isPercolating = true; break perc;}}} if (periodic > 1){ for (int i = 0; i < L; i++) if (((clA = cl[1][i]) != -1)&&((clB = cl[L][i]) != -1)) if ((clA = proper(clA)) != (clB = proper(clB))) if (clA > clB) np[clA] = clB; else np[clB] = clA; if ( isPercolating ) percCl = proper(percCl);} showStatus( "drawing"); for (int i = 0; i < L; i++){ for (int j = 0; j < L; j++){ int c = cl[i+1][j]; if ( c > 0){ c = proper(c); if ( isPercolating && (c == percCl)) buffGraphics.setColor(Color.black); else buffGraphics.setColor(col[c % maxColor]); buffGraphics.fillRect(j*d,hd-i*d, d,d);} }} generTime = System.currentTimeMillis() - generTime; painted = true;} g.drawImage(buffImage, 0, hBut, this); showStatus( "p=" + (float)p + " t=" + generTime + "ms"); } public int proper(int label ){ int l; while( (l = np[label]) != 0) label = l; return label; } public void update(Graphics g){ paint(g); } }