import java.applet.Applet; import java.awt.*; import java.awt.event.*; public class test1 extends Applet { PixCanvas P; ControlCanvas C; public void init() { setBackground(Color.white); P=new PixCanvas(); P.resize(500,500); P.setBackground(Color.black); C=new ControlCanvas(P); C.resize(305,500); C.setBackground(Color.blue); this.add(C); this.add(P); } } class DBCanvas extends Canvas { public void update(Graphics g) { Graphics g2; Image offscreen = null; offscreen = createImage(size().width, size().height); g2 = offscreen.getGraphics(); paint(g2); g.drawImage(offscreen, 0, 0, this); offscreen.flush(); } } class PixCanvas extends DBCanvas { Tiling T; PixCanvas() { T=new Tiling(5,2,0); T=T.reset(); } public void paint(Graphics g) { g.translate(250,250); g.setColor(Color.blue); g.drawOval(-1,-1,2,2); T.render(g); } } class ControlCanvas extends DBCanvas implements MouseListener { VSlider[] V=new VSlider[20]; ListenSquare L[]=new ListenSquare[10]; int tiles; ViewInteger v1,v2,v3; PixCanvas P; ControlCanvas(PixCanvas P) { this.P=P; addMouseListener(this); Color[] C=new Color[5]; C[1]=Color.black; C[2]=Color.green; C[3]=Color.yellow; C[4]=new Color(0,0,200); tiles=5; v1=new ViewInteger(0); v2=new ViewInteger(0); v3=new ViewInteger(0); for(int i=1;i<=10;++i) { V[i]=new VSlider(20*i-15,155,15,320,310,310,C,""); } L[1]=new ListenSquare(215,170,15,15,Color.green,"-",1); L[2]=new ListenSquare(275,170,15,15,Color.green,"+",2); L[3]=new ListenSquare(215,270,15,15,Color.green,"-",3); L[4]=new ListenSquare(275,270,15,15,Color.green,"+",4); L[5]=new ListenSquare(215,220,15,15,Color.green,"-",5); L[6]=new ListenSquare(275,220,15,15,Color.green,"+",6); L[7]=new ListenSquare(275,355,15,15,Color.green,"",7); L[8]=new ListenSquare(275,315,15,15,Color.green,"",8); L[9]=new ListenSquare(275,335,15,15,Color.green,"",9); } public void paint(Graphics g) { g.setColor(Color.white); g.setFont(new Font("TimesRoman",Font.PLAIN,15)); g.drawString("circles",230,327); g.drawString("lines",235,347); g.drawString("both",236,367); g.drawString("# of layers",223,265); g.drawString("# of tiles",226,165); g.drawString("# of twists",222,215); v1.x=P.T.n; v1.render(252,183,Color.yellow,g); v2.x=P.T.k; v2.render(252,233,Color.yellow,g); v3.x=P.T.layers; v3.render(252,283,Color.yellow,g); g.setColor(Color.yellow); g.setFont(new Font("TimesRoman",Font.PLAIN,20)); g.setColor(Color.black); g.fillRect(205,385,93,110); g.fillRect(5,5,294,145); g.setColor(Color.yellow); g.drawRect(205,385,93,110); g.drawRect(5,5,294,145); g.setColor(Color.white); g.drawString("Rich:",212,405); g.drawString("Applet 30",212,425); g.setFont(new Font("TimesRoman",Font.PLAIN,15)); g.drawString("Conformal",220,455); g.drawString("Rectangle",220,470); g.drawString("Tilings",220,485); for(int i=1;i<=tiles;++i) V[i].render(g); for(int i=1;i<=9;++i) L[i].render(g); g.setFont(new Font("TimesRoman",Font.PLAIN,12)); g.drawString("A conformal rectangle is a quadrilateral with 2 properties:",10,20); g.drawString("1. It is inscribed in a circle 2. One of the complex affine",10,35); g.drawString("maps which identifies opposite edges is linear. This linear",10,50); g.drawString("map is called the holonomy. Up to similarity a conformal",10,65); g.drawString("rectangle is determined by its holonomy and the cross ratio",10,80); g.drawString("of its vertices. This applets draws conformal rectangle",10,95); g.drawString("tilings of the punctured plane. The sliders let you select",10,110); g.drawString("the various cross ratios and the other buttons let you select",10,125); g.drawString("the topology. The holonomy is found by Newton's method.",10,140); } public void mouseReleased(MouseEvent e) {} public void mousePressed(MouseEvent e) {} public void mouseEntered(MouseEvent e) {} public void mouseExited(MouseEvent e) {} public void mouseClicked(MouseEvent e) { e.consume(); Point p=new Point(); p.x=e.getX(); p.y=e.getY(); int test1=0; for(int i=1;i<=tiles;++i) { if(V[i].inside(p)==1) test1=i; if(V[i].inside(p)==2) { P.T.sp[i]=1-P.T.sp[i];P.repaint(); V[i].mode=1-V[i].mode; V[i].redo(this); } } if(test1>0) { Tiling S=new Tiling(P.T.n,P.T.k,P.T.mode); S.k=P.T.k; S.n=P.T.n; S.layers=P.T.layers; S.l=P.T.l; for(int i=1;i<=P.T.n;++i) { S.sp[i]=P.T.sp[i]; S.m[i]=P.T.m[i]; } S.m[test1]=(p.y-V[test1].pos2)/50.0; S=S.improve(10); Complex z=new Complex(); z=S.error(); if(z.norm(z)<.0001) { P.T=S; V[test1].pos=p.y; V[test1].redo(this); P.repaint(); } } int test2=0; for(int i=1;i<=9;++i) { if(L[i].inside(p)==1) test2=i; } if(test2==1) { if(tiles>3) --tiles; P.T.n=tiles; for(int i=1;i<=10;++i) { V[i]=V[i].reset(); V[i].mode=0; } P.T=new Tiling(tiles,0,P.T.mode); P.T=P.T.reset(); P.repaint(); repaint(0,150,300,350); } if(test2==2) { if(tiles<10) ++tiles; P.T.n=tiles; for(int i=1;i<=10;++i) { V[i]=V[i].reset(); V[i].mode=0; } P.T=new Tiling(tiles,0,P.T.mode); P.T=P.T.reset(); P.repaint(); repaint(0,150,300,350); } if(test2==3) { if(P.T.layers>0) --P.T.layers; P.repaint(); repaint(150,150,150,350); } if(test2==4) { if(P.T.layers<35) ++P.T.layers; P.repaint(); repaint(150,150,150,350); } if(test2==5) { for(int i=1;i<=10;++i) { V[i]=V[i].reset(); V[i].mode=0; V[i].redo(this); } if(P.T.k>0) --P.T.k; P.T=P.T.reset(); P.T.layers=P.T.n; P.repaint(); repaint(150,150,150,350); } if(test2==6) { for(int i=1;i<=10;++i) { V[i]=V[i].reset(); V[i].mode=0; V[i].redo(this); } if(P.T.k50.0) z3=new Complex(0,0); S=perturb(z3); return(S); } Tiling improve(int w) { Tiling S=this; for(int i=1;i<=w;++i) S=S.improve(); return(S); } } class ConformalRectangle { Complex v,l; double m; ConformalRectangle(Complex v,Complex l,double m) { this.v=v; this.l=l; this.m=m; } ConformalRectangle() { this.v=new Complex(); this.l=new Complex(); this.m=0.0; } Complex keyVertex() { Complex w,b,X; Complex[] z=new Complex[10]; for(int i=1;i<=9;++i) z[i]=new Complex(); b=new Complex(); X=new Complex(); X.x=Math.exp(m); X.y=0.0; z[1].x=-2.0; z[1].y=0.0; z[2]=z[2].times(z[1],l); z[3]=X; z[4]=z[4].times(z[2],z[3]); z[5]=z[5].times(X,z[5].times(l,l)); z[6]=z[6].plus(z[2],z[3]); z[7]=z[6].plus(z[6],z[4]); z[8]=z[8].plus(z[7],z[5]); z[9]=z[9].quadraticRoot(l,z[8],l); return(z[9]); } void lineRender(Graphics g,Color C,int n,int special) { Complex[] z=new Complex[6]; for(int i=1;i<=5;++i) z[i]=new Complex(); z[1]=v; z[5]=z[1]; z[2]=z[2].times(l,v); z[4]=z[4].times(v,keyVertex()); z[3]=z[3].times(l,z[4]); for(int k=1;k<=n;++k) { for(int j=1;j<=5;++j) { z[j]=l.times(l,z[j]); } } int x1=0; int y1=0; int x2=0; int y2=0; int x3=0; int y3=0; x3=(int)(.5*z[1].x+.5*z[3].x); y3=(int)(.5*z[1].y+.5*z[3].y); if(z[1].norm(z[1])<750) { if(special==1) { g.setColor(new Color(0,0,100)); for(int j=1;j<=4;++j) { x1=(int)(z[j].x); y1=(int)(z[j].y); x2=(int)(z[j+1].x); y2=(int)(z[j+1].y); int[] xpoints={x1,x2,x3}; int[] ypoints={-y1,-y2,-y3}; g.fillPolygon(xpoints,ypoints,3); }} if(special==0) { g.setColor(C); for(int j=1;j<=4;++j) { x1=(int)(z[j].x); y1=(int)(z[j].y); x2=(int)(z[j+1].x); y2=(int)(z[j+1].y); g.drawLine(x1,-y1,x2,-y2); }} } } void circleRender(Graphics g,Color C,int n) { g.setColor(C); Complex[] z=new Complex[6]; for(int i=1;i<=5;++i) z[i]=new Complex(); z[1]=v; z[2]=z[2].times(l,v); z[4]=z[4].times(v,keyVertex()); z[3]=z[3].times(l,z[4]); z[5]=z[5].center(z[1],z[2],z[4]); for(int k=1;k<=n;++k) { for(int j=1;j<=5;++j) { z[j]=l.times(l,z[j]); } } double d=z[5].norm(z[5].minus(z[5],z[1])); int x1=(int)(z[5].x-d); int y1=(int)(z[5].y-d); int x2=(int)(2*d); int y2=(int)(2*d); g.drawOval(x1,-y1-(int)(2*d),x2,y2); } void lineRender2(Graphics g,Color C,int n,int special) { for(int i=0;i<=n;++i) lineRender(g,C,i,special); } void circleRender2(Graphics g,Color C,int n) { for(int i=0;i<=n;++i) circleRender(g,C,i); } } class Complex { double x,y; Complex() { this.x=0.0; this.y=0.0; } Complex(double x,double y) { this.x=x; this.y=y; } Complex random() { Complex z=new Complex(); z.x=2.0*Math.random()-1.0; z.y=2.0*Math.random()-1.0; return(z); } Complex randomUnit() { Complex z=new Complex(); z=z.random(); z=z.unit(z); return(z); } double norm(Complex z) { double d; d=z.x*z.x+z.y*z.y; d=Math.sqrt(d); return(d); } Complex unit(Complex z) { Complex w=new Complex(); double d; d=z.norm(z); w.x=z.x/d; w.y=z.y/d; return(w); } Complex plus(Complex z1,Complex z2) { Complex w= new Complex(); w.x=z1.x+z2.x; w.y=z1.y+z2.y; return(w); } Complex minus(Complex z1,Complex z2) { Complex w= new Complex(); w.x=z1.x-z2.x; w.y=z1.y-z2.y; return(w); } Complex times(Complex z1,Complex z2) { Complex w= new Complex(); w.x=z1.x*z2.x-z1.y*z2.y; w.y=z1.x*z2.y+z1.y*z2.x; return(w); } Complex inverse(Complex z) { Complex w=new Complex(); double d; d=z.x*z.x+z.y*z.y; w.x=z.x/d; w.y=-z.y/d; return(w); } Complex divide(Complex z1,Complex z2) { Complex w= new Complex(); w=w.times(z1,w.inverse(z2)); return(w); } Complex conjugate(Complex z) { Complex w=new Complex(); w.x=x; w.y=-y; return(w); } double disc(Complex z) { double d1,d2,d3,d4,d5; d1=norm(z);d3=d1*d1; d1=d1*d1*d1*d1; Complex zzz=z.times(z.times(z,z),z); d2=zzz.x; d3=d1-8.0*d2+18.0*d3-27.0; return(d3); } Complex log(Complex z) { Complex w=new Complex(); double d1=z.norm(z); double d2=Math.atan2(z.y,z.x); w.x=Math.log(d1); w.y=d2; return(w); } Complex squareRoot(Complex z) { Complex w=new Complex(); double d1,d2; d1=z.norm(z); d1=Math.sqrt(d1); d2=Math.atan2(z.y,z.x); d2=.5*d2; w.x=d1*Math.cos(d2); w.y=d1*Math.sin(d2); return(w); } Complex quadraticRoot(Complex a,Complex b,Complex c) { Complex z[]=new Complex[20]; for(int i=1;i<=11;++i) z[i]=new Complex(); z[3]=z[3].times(b,b); z[4]=a.times(a,c); z[4].x=4*z[4].x; z[4].y=4*z[4].y; z[5]=z[4].minus(z[3],z[4]); z[6]=z[5].squareRoot(z[5]); z[7]=z[6].minus(z[6],b); z[8]=z[7].divide(z[7],a.plus(a,a)); z[9]=z[6].plus(z[6],b); z[9].x=-z[9].x; z[9].y=-z[9].y; z[10]=z[9].divide(z[9],a.plus(a,a)); z[11]=z[8]; if(z[8].y<0) z[11]=z[10]; return(z[11]); } Complex center(Complex z1,Complex z2,Complex z3) { double x1,x2,y1,y2,x3,y3; double den; Complex z=new Complex(); x1=z1.x; y1=z1.y; x2=z2.x; y2=z2.y; x3=z3.x; y3=z3.y; den=2.0*(x2*y1-x3*y1-x1*y2+x3*y2+x1*y3-x2*y3); z.x=(x2*x2*y1-x3*x3*y1-x1*x1*y2+x3*x3*y2 - y1*y1*y2+y1*y2*y2+x1*x1*y3-x2*x2*y3 + y1*y1*y3-y2*y2*y3-y1*y3*y3+y2*y3*y3)/den; z.y=(x1*x1*x2-x1*x2*x2-x1*x1*x3+x2*x2*x3 + x1*x3*x3-x2*x3*x3+x2*y1*y1-x3*y1*y1- x1*y2*y2+x3*y2*y2+x1*y3*y3-x2*y3*y3)/den; return(z); } void print() { System.out.println(x+" + "+y+" I"); } } class ListenSquare { int x,y,w,h; Color C; String S; int v; ListenSquare(int x,int y,int w,int h,Color C,String S,int v) { this.x=x; this.y=y; this.h=h; this.w=w; this.C=C; this.S=S; this.v=v; } void render(Graphics g) { g.setColor(Color.black); g.fillRect(x,y,w,h); g.setColor(C); g.drawRect(x,y,w,h); g.setColor(Color.white); g.setFont(new Font("TimesRoman",Font.PLAIN,13)); g.drawString(S,x+5,y+13); } int inside(Point p) { int test=0; if((p.x>x)&&(p.xy)&&(p.yx)&&(p.xy)&&(p.yx)&&(p.xy+h+5)&&(p.y0) { int z=y-10*(y/10); g.setColor(C); char ch=(char)(z+48); Character CH1=new Character(ch); g.drawString(CH1.toString(),u-place,v); place=place+8; y=(y-z)/10; } if(x==0) g.drawString("0",u,v); } }