// Julia set dynamics, Evgeny Demidov, 12 January 2006 import java.awt.*; import java.awt.image.*; import java.awt.event.*; import java.util.StringTokenizer; public class @file extends java.applet.Applet implements KeyListener, MouseMotionListener{ double maxIZI2=10., Ymid=.0, Xmid=-.5, DelX=3., Cr,Ci, Xm=1, Ym=0, Rm=.1, Step; int maxIt = 256, maxColor = 96, w, h, w2,h2, ix,iy, ixo,iyo, ir,ir2, lbSize, px[],py[], pxo[],pyo[], pixArr[]; Image img; IndexColorModel RainbowColor; boolean bXOR=false; Label lbZ, lbCr, lbCi, lbR, lbD; TextField tfZ, tfCr, tfCi, tfR, tfD; public void init() { String s=getParameter("XYmidDelCD"); if (s != null) { StringTokenizer st = new StringTokenizer(s); Xmid = Double.valueOf(st.nextToken()).doubleValue(); Ymid = Double.valueOf(st.nextToken()).doubleValue(); DelX = Double.valueOf(st.nextToken()).doubleValue(); Cr = Double.valueOf(st.nextToken()).doubleValue(); Ci = Double.valueOf(st.nextToken()).doubleValue();} s=getParameter("MaxIt"); if (s != null) maxIt=Integer.parseInt(s); s=getParameter("MaxIZI2"); if (s != null) maxIZI2 = Double.valueOf(s).doubleValue(); s=getParameter("MaxColor"); if (s != null) maxColor=Integer.parseInt(s); int M=maxColor/3, M2=2*M; maxColor = 3*M; // maxColor is 3*int long M4 = (long)M*M*M*M; byte rColor[] = new byte[maxColor+2], bColor[] = new byte[maxColor+2], gColor[] = new byte[maxColor+2]; for (int i = 1; i < M2; i++){ // set Color Map long dum = M - i; dum *=dum; dum *=dum; gColor[i] = bColor[(i+M) % maxColor] = rColor[(i+M2) % maxColor] = (byte)(255 - (255*dum)/M4);} rColor[maxColor+1] = gColor[maxColor+1] = bColor[maxColor+1] = (byte)200; RainbowColor = new IndexColorModel( 8, maxColor+2, rColor,gColor,bColor); s=getParameter("XYR"); if (s != null) { StringTokenizer st = new StringTokenizer(s); Xm = Double.valueOf(st.nextToken()).doubleValue(); Ym = Double.valueOf(st.nextToken()).doubleValue(); Rm = Double.valueOf(st.nextToken()).doubleValue();} this.setLayout( new FlowLayout(FlowLayout.LEFT, 0, 0) ); lbZ = new Label("Z", Label.RIGHT); add(lbZ); if (Ym < 0.) s = ""+Xm+" "+Ym+" i"; else s = ""+Xm+" +"+Ym+" i"; tfZ = new TextField(s, 20); add(tfZ); lbCr = new Label("Cr", Label.RIGHT); add(lbCr); tfCr = new TextField(""+Cr, 8); add(tfCr); lbCi = new Label("Ci", Label.RIGHT); add(lbCi); tfCi = new TextField(""+Ci, 8); add(tfCi); lbR = new Label("R", Label.RIGHT); add(lbR); tfR = new TextField(""+Rm, 3); add(tfR); lbD = new Label("dz", Label.RIGHT); add(lbD); tfD = new TextField(""+DelX, 3); add(tfD); tfCr.addKeyListener(this); tfCi.addKeyListener(this); tfD.addKeyListener(this); tfR.addKeyListener(this); w = getSize().width; h = getSize().height; lbSize = tfZ.getPreferredSize().height; h -= lbSize; w2 = w/2; h2 = h/2; Step=DelX/w; pixArr = new int[w*(h+2)]; px = new int[9]; pxo = new int[9]; py = new int[9]; pyo = new int[9]; addMouseMotionListener(this); Draw(); } public void Draw(){ Step=DelX/w; ix = ixo = w2 + (int)((Xm - Xmid)*w/DelX); iy = iyo = h2 - (int)((Ym - Ymid)*w/DelX); ir = (int)(Rm*w/DelX); ir2 = 2*ir; Polygon(); System.arraycopy(px,0,pxo,0,9); System.arraycopy(py,0,pyo,0,9); double X,Y; int pix=w, ix,iy; for (iy=0, Y=Ymid+Step*h2; iy < h; iy++, Y-=Step) { for (ix=0, X=Xmid-Step*(w2-1); ix < w; ix++, X+=Step, pix++) { pixArr[pix] =iterateDE(X,Y); } } img = createImage(new MemoryImageSource(w, h, RainbowColor, pixArr, w, w)); } public void Polygon(){ double R=Xm-Rm, I=Ym-Rm; st(R, I, 0); R=Xm; st(R,I,1); R=Xm+Rm; st(R,I,2); I=Ym; st(R,I,3); I=Ym+Rm; st(R,I,4); R=Xm; st(R,I,5); R=Xm-Rm; st(R,I,6); I=Ym; st(R,I,7); px[8]=px[0]; py[8]=py[0]; } public void st(double R, double I, int k){ px[k] = w2 + (int)((R*R-I*I+Cr - Xmid)*w/DelX); py[k] = h2 - (int)((2*R*I+Ci - Ymid)*w/DelX) + lbSize; } public void destroy(){ removeMouseMotionListener(this); } public void mouseMoved(MouseEvent e){} //1.1 event handling public void mouseDragged(MouseEvent e) { ix = e.getX(); iy = e.getY() - lbSize; Xm = Xmid+(ix-w2)*Step; Ym = Ymid-(iy-h2)*Step; if (Ym < 0.) tfZ.setText( ""+(float)Xm+" "+(float)Ym+" i"); else tfZ.setText( ""+(float)Xm+" +"+(float)Ym+" i"); Polygon(); bXOR = true; repaint(); } public void keyTyped(KeyEvent e){} public void keyPressed(KeyEvent e){} public void keyReleased(KeyEvent e){ final int keyEnter = 10; if (e.getKeyCode() == keyEnter){ try{ Cr = Double.valueOf(tfCr.getText()).doubleValue(); Ci = Double.valueOf(tfCi.getText()).doubleValue(); Rm = Double.valueOf(tfR.getText()).doubleValue(); DelX = Double.valueOf(tfD.getText()).doubleValue(); }catch(NumberFormatException ne){} Draw(); repaint(); } } public void update(Graphics g){ paint(g); } public void paint(Graphics g) { if(!bXOR){ g.drawImage(img, 0, lbSize, this); drawLabel(g); int r = (int)(w/DelX); g.setColor(Color.white); g.drawOval(w2-r,h2-r+lbSize,r+r,r+r); g.drawLine(w2-5,h2+lbSize, w2+5,h2+lbSize); g.drawLine(w2,h2-5+lbSize, w2,h2+5+lbSize); g.setXORMode(Color.black); g.fillPolygon(px,py,9); g.drawRect(ix-ir,iy-ir+lbSize,ir2,ir2); g.setPaintMode();} else{ g.setXORMode(Color.black); g.setColor(Color.white); g.fillPolygon(pxo,pyo,9); g.drawRect(ixo-ir,iyo-ir+lbSize,ir2,ir2); System.arraycopy(px,0,pxo,0,9); System.arraycopy(py,0,pyo,0,9); ixo = ix; iyo = iy; g.fillPolygon(px,py,9); g.drawRect(ix-ir,iy-ir+lbSize,ir2,ir2); g.setPaintMode(); bXOR=false;} // showStatus( "Cr="+Cr+" Ci="+Ci); } public void drawLabel(Graphics gra) { double R=0.,I=0.; gra.setColor(Color.white); int x,y; gra.setFont( new Font( gra.getFont().getName(), Font.BOLD, 15 ) ); int maxLabel=0; while (true) { String s=getParameter("lb"+maxLabel); if (s == null) break; StringTokenizer st = new StringTokenizer(s); x=w2+(int)((Double.valueOf(st.nextToken()).doubleValue()-Xmid)/Step); y=h2+(int)((Ymid-Double.valueOf(st.nextToken()).doubleValue())/Step); gra.drawString(st.nextToken(), x,y); maxLabel++; } } int iterateDE(double X, double Y){ double I=Y, R=X, I2=I*I, R2=R*R, Dr=.7,Di=.7,D, K=5; int n=0; do { D = (R*Dr - I*Di); Di = (R*Di + I*Dr); Dr = D; I=(R+R)*I+Ci; R=R2-I2+Cr; R2=R*R; I2=I*I; n++; } while ((R2+I2 < 100.) && (n < maxIt) ); if (n == maxIt) return maxColor; else{ R = -K*(Math.log(Math.log(R2+I2)*Math.sqrt((R2+I2)/(Dr*Dr+Di*Di)))-n*.693); if (R < 0) R=0; return (int)R % maxColor; }; } }