import java.applet.Applet; import java.awt.*; import java.awt.event.*; import java.applet.*; import java.awt.geom.*; import java.math.*; public class PictureCanvas extends ScaleCanvas implements KeyListener, MouseListener, MouseMotionListener { Manager M; Complex[][] Z=new Complex[2][4]; //the displayed configuration BoxConfiguration BC2; Point JX; ListenSquare INFO; Documentation DOC; public PictureCanvas() { addMouseListener(this); addMouseMotionListener(this); addKeyListener(this); setScales(320,100); Z[0]=Configuration.configuration1(); Z[1]=Configuration.configuration1(); double a=Math.sqrt(-1); INFO=new ListenSquare(0,0,12,12,Color.red); } public PictureCanvas addManager(Manager M) { PictureCanvas PP=this; PP.M=M; return(PP); } public void paint(Graphics g2) { Graphics2D g=(Graphics2D) g2; g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON); drawFrame(g); if(M.C.SHOW.L[2].on==1) drawGrid(g); if(M.C.CC1.SELECT.mode==1) drawConfiner(g,2); drawProof(g); if(M.C.SHOW.L[3].on==1) drawCircle(g); if(M.C.SHOW.L[4].on==1) drawInverted(g); if(M.C.SHOW.L[0].on==1) drawNearMin1(g); if(M.C.SHOW.L[1].on==1) drawNearMin2(g); if(M.C.CC1.SELECT.mode==0) drawPoints(g); INFO.infoRenderLive(g); } /**This is the inverted configuration, the result of switching P4=infinity and P0. The point of showing this alternate configuration is that anything confined inside the region NEARMIN2 is inverted to something not confined in NEARMIN2. Thus by symmetry our proof can ignore configurations confined in NEARMIN2.*/ public void drawInverted(Graphics2D g) { Color[] C = Configuration.colors(); Complex[] W=Configuration.stereoInverted(Z[0]); Color C1=new Color(255,0,0,100); for(int i=0;i<4;++i) drawSquare(g,C1,C[i],W[i],5); } /**This is the frame**/ public void drawFrame(Graphics2D g) { g.setColor(new Color(0,0,255)); Color C=Color.black; if(M.C.CC1.SELECT.mode==1) C=new Color(0,0,255); g.fillRect(0,0,getWidth(),getHeight()); drawRectangle(g,C,new Color(0,200,200),-3,-3,3,3); drawRectangle(g,C,new Color(0,0,200),1,0,3,0); } /**Here are the points. The BondControl controls the sizes of the squares **/ public BoxConfiguration getBC(int choice) { BoxConfiguration BOX=convert2(Z[choice],M.C.CC1.size[choice]); return(BOX); } /**converts a a list of complex numbers to boxes**/ public static BoxConfiguration convert2(Complex[] Z,int[] k) { BoxConfiguration BOX=new BoxConfiguration(); for(int i=0;i<4;++i) { BOX.B[i]=new Box(); BOX.B[i].DYADIC=5; BOX.B[i].z=new Complex(Z[i]); BOX.B[i].k=k[i]; BOX.B[i].type=0; BOX.B[i].g=new GaussianInteger(0,0); } BOX.B[0].type=1; BOX.B[4]=new Box(new Complex(0,0),0,2,1); return(BOX); } public void drawPoints(Graphics2D g) { int fill=M.C.SHOW.L[6].on; Color[] C = Configuration.colors(); BoxConfiguration BC=getBC(0); drawBC(g,BC,C,fill); } public void drawConfiner(Graphics2D g,int k) { Color[] C = Configuration.colors(); BoxConfiguration BC=getBC(1); drawBC(g,BC,C,k); } public void drawBC(Graphics2D g,BoxConfiguration X,Color[] C,int fill) { for(int i=0;i<4;++i) { GeneralPath gp=XtraBox.toGeneralPath(X.B[i]); if((i==0)&&(fill==2)) { Box TEMP=new Box(X.B[0]); TEMP.type=0; gp=XtraBox.toGeneralPath(TEMP); } gp=transform(gp); g.setColor(C[i]); if((fill<2)&&(i==0)) g.setStroke(new BasicStroke(4)); if(fill==2) { g.fill(gp); } if(fill==3) { g.setColor(Color.black); g.fill(gp); g.setColor(C[i]); } if(fill==1) g.fill(gp); g.draw(gp); g.setStroke(new BasicStroke(1)); } } public void drawProof(Graphics2D g) { int mode1=M.C.PC.SI[0].val; int mode2=M.C.PC.ACTION.mode; if((mode1==1)&&(mode2==1)) drawConfiner(g,3); } /**Here are the basins around the minimal configurations.*/ public void drawNearMin1(Graphics2D g) { Color C1=new Color(100,0,255,100); Color C2=Color.white; Complex[] W=Configuration.configuration1(); int k=M.C.CONFINE.val; //log2(diam) for(int i=0;i<4;++i) drawSquare(g,C1,C2,W[i],k); } public void drawNearMin2(Graphics2D g) { Color C1=new Color(0,0,100,100); Color C2=Color.blue; Complex[] W=Configuration.configuration2(); drawSquare(g,C1,C2,W[1],6); drawSquare(g,C1,C2,W[2],6); drawSquare(g,C1,C2,W[3],6); } public void drawGrid(Graphics2D g) { double[] thick={.7,1,1.3,1.8,2.5,4,7}; int t=M.C.GRID.val; int s=t-5; Color[] C={new Color(0,0,150),new Color(0,0,190),new Color(0,0,220),new Color(0,0,250),new Color(20,40,250),new Color(40,100,255),new Color(50,120,255)}; Color CC=Color.orange; for(int i=5;i>-2;--i) { if(i<=t) CC=C[5-i+s]; if(M.C.CC1.SELECT.mode==1) CC=new Color(50,100,255); if(i<=t) drawGrid(g,i,thick[5-i+s],CC); } } public void drawGrid(Graphics2D g,int k, double thick,Color C) { GeneralPath gp=new GeneralPath(); double d0=Math.pow(2,k); double d1=d0; for(int i=(int)(-2*d1);i<=2*d1;++i) { float x=(float)(1.0*i/d0); float y1=(float)(-2); float y2=-y1; gp.moveTo(x,y1); gp.lineTo(x,y2); } for(int i=(int)(-2*d1);i<=2*d1;++i) { float y=(float)(1.0*i/d0); gp.moveTo(-2,y); gp.lineTo(2,y); } g.setStroke(new BasicStroke((float)(thick))); gp=transform(gp); g.setColor(C); g.draw(gp); g.setStroke(new BasicStroke(1)); } /**Here is the unit circle**/ public void drawCircle(Graphics2D g) { double Pi=Math.PI; GeneralPath gp=new GeneralPath(); gp.reset(); gp.moveTo(1,0); for(int i=1;i<100;++i) { double t=1.0*i; double c=Math.cos(2*Pi*t/100); double s=Math.sin(2*Pi*t/100); gp.lineTo((float)(c),(float)(s)); } gp.closePath(); g.setColor(new Color(0,0,180)); gp=transform(gp); g.draw(gp); } /** This routine selects a new point **/ public void movePoint() { int choice=M.C.CC1.SELECT.mode; int index=-1; double test=0; double min=2; for(int i=0;i<4;++i) { test=XtraComplex.dist(SOURCE,Z[choice][i]); if(test0) { Z[choice][index]=new Complex(SOURCE); } if(index==0) { double t=SOURCE.x; if(t<1) t=1; if(t>3) t=3; Z[choice][index]=new Complex(t,0); } if(M.C.CC1.DYADIC.on==1) Z[choice]=Configuration.dyadic(Z[choice],M.C.CC1.size[0]); } public void mousePressed(MouseEvent e) { } public void mouseClicked(MouseEvent e) { MouseData J=MouseData.process(e); DOC=new Documentation(); DOC.M=M; if(INFO.inside(J.X)==1) DOC.pictureInfo(); else { if(J.mode==2) { SOURCE=unTransform(J.X); movePoint(); } if(J.mode==3) scaleUp(J.X,1); if(J.mode==1) scaleUp(J.X,-1); if(INFO.inside(J.X)==1) DOC.pictureInfo(); } repaint(); } public void doMouseClick(Point X,int mode) { DOC=new Documentation(); DOC.M=M; if(INFO.inside(X)==1) DOC.pictureInfo(); else { if(mode==2) { SOURCE=unTransform(X); movePoint(); } if(mode==3) scaleUp(X,1); if(mode==1) scaleUp(X,-1); } repaint(); } public void mouseReleased(MouseEvent e) { } public void mouseEntered(MouseEvent e) { requestFocus(); } public void mouseExited(MouseEvent e) { } public void mouseMoved(MouseEvent e) { try{ MouseData J=MouseData.process(e); JX=J.X; } catch(Exception ee) {} } public void mouseDragged(MouseEvent e) { MouseData J=MouseData.process(e); if(J.mode==2) { SOURCE=unTransform(J.X); movePoint(); } repaint(); M.C.repaint(); } public void keyTyped(KeyEvent e) { int test=0; char ch=e.getKeyChar(); if(ch=='z') test=1; if(ch=='x') test=2; if(ch=='c') test=3; if(test>0) doMouseClick(JX,test); repaint(); } public void keyPressed(KeyEvent e) {} public void keyReleased(KeyEvent e) {} }