import java.applet.Applet; import java.awt.*; import java.awt.event.*; import java.applet.*; import java.awt.geom.*; import java.math.*; /**This class defines our dyadic planar sets, as well as the routines used in the proof.**/ public class Box { Complex z; //the center GaussianInteger g; //2^{25} times the center int k; // - log of the sidelength int DYADIC; //says whether we have a dyadic box int type; // type 0 is a square; type 1 is an interval on the real axis; type 2 is the point at infinity public Box() {} /**specifies a box of type t by its center and -log of the sidelength**/ public Box(Complex zz,int kk,int t,int d) { this.z=zz; this.k=kk; this.type=t; this.DYADIC=1; this.g=GaussianInteger.convert(zz,25); } /**copies a box**/ public Box(Box B) { this.z=new Complex(B.z); this.k=B.k; this.g=new GaussianInteger(B.g); this.DYADIC=B.DYADIC; this.type=B.type; } /**Prints out the box**/ public void print() { System.out.print("type "+type+" size "+k+" DYADIC "+DYADIC+" center "); z.print(); if(DYADIC==1) g.print(); } /**These routines get various pieces of information about the box **/ /**The inverse stereographic image of the center**/ public Vector getCenter() { if(type==2) return(new Vector(0,0,1)); return(Stereo.inverseStereo(z)); } /**side length**/ public double sidelength() { double d=Math.pow(0.5,this.k); return(d); } /**Gets the vertices of a box**/ public Complex[] toVertices() { double d=Math.pow(.5,k+1); if(type==0) { Complex[] Z=new Complex[4]; Z[0]=new Complex(z.x-d,z.y-d); Z[1]=new Complex(z.x-d,z.y+d); Z[2]=new Complex(z.x+d,z.y+d); Z[3]=new Complex(z.x+d,z.y-d); return(Z); } if(type==1) { Complex[] Z=new Complex[2]; Z[0]=new Complex(z.x-d,z.y); Z[1]=new Complex(z.x+d,z.y); return(Z); } Complex[] Z={new Complex(0,0)}; return(Z); } /**Gets numbers which are the vertices of the box scaled up by 2^25**/ public GaussianInteger[] toGaussianVertices() { int d=(int)(Math.pow(2,25-k-1)); if(type==0) { GaussianInteger[] Z=new GaussianInteger[4]; Z[0]=new GaussianInteger(g.x-d,g.y-d); Z[1]=new GaussianInteger(g.x-d,g.y+d); Z[2]=new GaussianInteger(g.x+d,g.y+d); Z[3]=new GaussianInteger(g.x+d,g.y-d); return(Z); } if(type==1) { GaussianInteger[] Z=new GaussianInteger[2]; Z[0]=new GaussianInteger(g.x-d,g.y); Z[1]=new GaussianInteger(g.x+d,g.y); return(Z); } GaussianInteger[] Z={new GaussianInteger(0,0)}; return(Z); } /**Gets the vertices of a box and then does inverse stereographic projection. The boxes of type 2 corresponds to the infinit point in the plane, which in turn corresponds to the point (0,0,1) on the unit sphere. **/ public Vector[] toVectors() { if(type==0) { Complex[] Z=toVertices(); Vector[] V=new Vector[4]; for(int i=0;i<4;++i) V[i]=Stereo.inverseStereo(Z[i]); return(V); } if(type==1) { Complex[] Z=toVertices(); Vector[] V=new Vector[2]; for(int i=0;i<2;++i) V[i]=Stereo.inverseStereo(Z[i]); return(V); } Vector[] V={new Vector(0,0,1)}; return(V); } /**These routines get various of the vertices of a box. The first works for generic boxes, and the second works for intervals contained on the real axis.**/ public Complex getVertex0(int i,int j) { Complex[] Z=toVertices(); int q=2*i+j; return(Z[q]); } public Complex getVertex1(int i) { Complex[] Z=toVertices(); return(Z[i]); } /**This is the main routine for subdividing a box. **/ public Box subdivide0(int choice) { Complex[] Z=toVertices(); GaussianInteger[] G=toGaussianVertices(); Complex w=Complex.average(Z[choice],z); Box B=new Box(w,k+1,0,1); B.g=GaussianInteger.average(G[choice],g); B.DYADIC=1; return(B); } /**This routine is used for the box B0, contained on the real axis. This is really just an interval, so it is subdivided in half*/ public Box subdivide1(int i) { Complex[] Z=toVertices(); GaussianInteger[] G=toGaussianVertices(); Complex w=Complex.average(Z[i],z); Box B=new Box(w,k+1,1,1); B.g=GaussianInteger.average(G[i],g); B.DYADIC=1; return(B); } /**Basic quantities associated to a box**/ /**the quantities underline x, .etc, from the paper. These are only used for boxes which do not cross the coordinate axes**/ public double xAbsMin() { double r=sidelength()/2; double t=Math.abs(z.x)-r; return(t); } public double yAbsMin() { double r=sidelength()/2; double t=Math.abs(z.y)-r; return(t); } public double xAbsMax() { double r=sidelength()/2; double t=Math.abs(z.x)+r; return(t); } public double yAbsMax() { double r=sidelength()/2; double t=Math.abs(z.y)+r; return(t); } /**The min and max coords for a box, magnified by 2^25 **/ public int xMin() { int r=(int)(Math.pow(2,25-k-1)); return(g.x-r); } public int xMax() { int r=(int)(Math.pow(2,25-k-1)); return(g.x+r); } public int yMin() { int r=(int)(Math.pow(2,25-k-1)); return(g.y-r); } public int yMax() { int r=(int)(Math.pow(2,25-k-1)); return(g.y+r); } public double xMaxDouble() { double r=sidelength()/2; double t=z.x+r; return(t); } /**The quantity delta **/ public double delta() { if(type==2) return(0); //the infinite box double s=sidelength(); double x=xAbsMin(); double y=yAbsMin(); double d=2*s/(1+x*x+y*y); return(d); } /**the quantity tau**/ public double tau() { if(type==2) return(0); if(type==1) return(1); return(Math.sqrt(2)); } /**This routine checks whether a given box is contained inside a square of sidelength 2^{-k} centered at the point w **/ public int confine(Complex w,int k) { double r=Math.pow(.5,k+1); Complex[] Z=this.toVertices(); for(int i=0;i=r) return(0); } return(1); } }