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.k
50.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);
}
}