package Current.popups.Unfold; import Current.plot.Dyadic.*; import Current.gui.*; import Current.basic.*; import Current.manage.*; import java.applet.Applet; import java.awt.event.*; import java.awt.*; import java.awt.geom.*; public class UnfoldFunctionCanvas extends DBCanvas implements MouseListener, MouseMotionListener { public Color C0,C1,C2,C3; public double START,END; public double A; public Complex B; public Manager M; public int[][] n=new int[4][5000]; public int[][] d=new int[4][5000]; public int[][] f=new int[3][5000]; public Integer[][] N=new Integer[4][5000]; public Integer[][] D=new Integer[4][5000]; public Integer[][] F=new Integer[3][5000]; public ListenSquare[] L=new ListenSquare[11]; public double[][] diff=new double[8][8]; public int[] adiff=new int[3]; public int form; public int palindrome; public int dyadic; public int choice=1; public IntegerSelector[] I=new IntegerSelector[5]; public VertexPair CV; public UnfoldFunctionCanvas(Manager M) { // add the manager this.M=M; M.addListener(this); palindrome=0; START=0; END=0; A=0; B=new Complex(); C0=Color.white; C1=Color.blue; C2=Color.red; C3=Color.black; START=0; END=0; n[0][0]=0; d[0][0]=0; n[0][1]=0; form=1; addMouseListener(this); addMouseMotionListener(this); L[0]=new ListenSquare(433,52,12,12,Color.white); //info L[1]=new ListenSquare(340,49,12,12,new Color(80,150,255)); L[1].on=1; L[2]=new ListenSquare(340,34,12,12,new Color(80,150,255)); L[3]=new ListenSquare(340,19,12,12,new Color(80,150,255)); //palindrome recognizer L[3].on=1; L[4]=new ListenSquare(340,4,12,12,Color.white); //printout functions I[0]=new IntegerSelector(397,5,30,12,0,0,9,1); //function printout namer I[1]=new IntegerSelector(10,40,30,11,0,0,9,1); //partial derivative selector I[2]=new IntegerSelector(70,40,30,11,0,0,9,1); //partial derivative selector I[3]=new IntegerSelector(240,38,30,12,0,0,20,1); //box size CV=null; } public void mousePressed(MouseEvent e) { e.consume(); START=e.getX(); } public void mcbReceive(Parameter p){ repaint(); } public void mcbCleanup() { M.remove(this); } public void mouseReleased(MouseEvent e) { } public void mouseEntered(MouseEvent e) {} public void mouseExited(MouseEvent e) {} public void mouseClicked(MouseEvent e) { e.consume(); MouseData MD=MouseData.process(M,e); Point X=MD.X; if(L[0].inside(X)==1) document(); if(L[1].inside(X)==1) {L[2].on=0;L[1].on=1;form=1;} if(L[2].inside(X)==1) {L[1].on=0;L[2].on=1;form=2;} //toggles the special feature for palindromes if(L[3].inside(X)==1) { L[3].on=1-L[3].on; choice=L[3].on; } for(int i=0;i<4;++i) I[i].modify(X); dyadic=I[3].val; //names function for printout //prints out function if(L[4].inside(X)==1) { printNumerator(); printDenominator(); } repaint(); } public void mouseMoved(MouseEvent e) {} public void mouseDragged(MouseEvent e) { MouseData MD=MouseData.process(M,e); Point X=MD.X; int test=MD.X.y; if(test>15) { END=e.getX(); B.x=B.x+END-START; START=END; repaint(); } } public void paint(Graphics gfx) { Graphics2D g=(Graphics2D) gfx; g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); Dimension D=this.getSize(); loadFunctions(); g.setColor(new Color(130,0,0)); g.fillRect(0,0,this.getWidth(),this.getHeight()); g.translate(460,0); if(form==1) drawFunction1(g); if(form==2) drawFunction2(g); g.translate(-460,0); g.setColor(new Color(0,0,100)); g.fillRect(0,0,445,this.getHeight()); g.setColor(Color.white); g.drawRect(0,0,445,this.getHeight()-1); g.setColor(new Color(100,0,150)); g.fillRect(335,0,110,this.getHeight()); g.setColor(Color.white); g.drawRect(335,0,110,this.getHeight()); Color C1=Color.white; Color C2=Color.yellow; Color C3=new Color(70,130,255); Color C4=new Color(255,0,200); drawFunctionValue(5,11,0,0,g,C1); drawFunctionValue(5,23,1,0,g,C2); drawFunctionValue(5,35,0,1,g,C2); drawFunctionValue(5,61,g,C3); drawGradientPicture(200,32,g,new Color(0,0,150),new Color(0,0,255),C2); drawAbsoluteSecondBounds(240,11,g,C4); drawCertificate(200,32,g,new Color(255,0,0,80)); g.setColor(Color.white); g.drawRect(0,0,D.width-1,D.height-1); L[0].infoRender(g); L[1].render(g,Color.blue); L[2].render(g,Color.blue); L[3].on=choice; L[3].render(g,Color.blue); L[4].render(g,Color.white); I[0].render(g,new Color(255,0,255),C3,Color.white,10); for(int i=1;i<4;++i) I[i].render(g,Color.blue,C3,Color.white,10); g.setFont(new Font("Helvetica",Font.PLAIN,11)); g.setColor(Color.white); g.drawString("see palindromes", 360, 30); g.drawString("no foil", 360, 45); g.drawString("foil", 360, 60); g.drawString("print F",360,15); g.setFont(new Font("Helvetica",Font.PLAIN,10)); g.setColor(new Color(50,100,255)); g.drawString("-log(side)",240,60); } /*loading up the functions: When the function is a palindrome, and we have chosen to recognize palindromes, we compute the functions specially. For palindromes, we can only compute the function and its first derivatives. For general functions, we can compute as many derivatives as we like. However, we set the max at about 8 derivatives, just so that we don't produce huge numbers.*/ public void loadFunctions() { if(palindrome*choice==0) { for(int i=0;i<=1;++i) { for(int j=0;j<=1;++j) { diff[i][j]=Function.evaluate(n,d,i,j,M.getZ()); } } adiff[0]=Function.absoluteSecondDerivative(f,2,0); adiff[1]=Function.absoluteSecondDerivative(f,1,1); adiff[2]=Function.absoluteSecondDerivative(f,0,2); I[1].max=9; I[2].max=9; } if(palindrome*choice==1) { diff[0][0]=PalindromeFunction.evaluate(f,M.getZ()); diff[1][0]=PalindromeFunction.gradient(1,f,M.getZ()); diff[0][1]=PalindromeFunction.gradient(2,f,M.getZ()); adiff[0]=PalindromeFunction.absoluteSecondDerivative(f,2,0); adiff[1]=PalindromeFunction.absoluteSecondDerivative(f,1,1); adiff[2]=PalindromeFunction.absoluteSecondDerivative(f,0,2); I[1].max=1; I[2].max=1; I[1].val=0; I[2].val=0; } } /**This routine lets us display (in theory) arbitrarily high derivatives of our defining functions*/ public void drawFunctionValue(int x, int y, int a1,int a2,Graphics g,Color C) { if(CV!=null) { double dd=0; if(a1+a2<=1) dd=diff[a1][a2]; if(a1+a2>1) dd=Function.evaluate(n,d,a1,a2,M.getZ()); Double D=new Double(dd); g.setColor(C); g.setFont(new Font("Monospaced",Font.PLAIN,10)); Integer A1=new Integer(a1); Integer A2=new Integer(a2); String S="D"+A1.toString()+A2.toString()+"F="+D.toString(); g.drawString(S,x,y); } } public void drawFunctionValue(int x, int y, Graphics g,Color C) { drawFunctionValue(x,y,I[1].val,I[2].val,g,C); } public void mcbReceive(VertexPairDummy v) { CV=new VertexPair(v.o1,v.e1,v.o2,v.e2); } /**absolute second derivative bounds*/ public void drawAbsoluteSecondBounds(int x,int y,Graphics g,Color C) { g.setFont(new Font("Monospaced",Font.PLAIN,10)); g.setColor(C); Integer D20=new Integer(adiff[0]); String S20="A20="+D20.toString(); g.drawString(S20,x,y); Integer D11=new Integer(adiff[1]); String S11="A11="+D11.toString(); g.drawString(S11,x,y+12); Integer D02=new Integer(adiff[2]); String S02="A02="+D02.toString(); g.drawString(S02,x,y+24); } /**picture of gradient*/ public void drawGradientPicture(int x,int y,Graphics2D g,Color C1,Color C2,Color C3) { Complex zz=new Complex(diff[1][0],-diff[0][1]); zz=zz.unit(); zz=zz.times(new Complex(24.0,0)); GeneralPath path=new GeneralPath(); path.moveTo((float)(x),(float)(y)); path.lineTo((float)(x+zz.x),(float)(y+zz.y)); g.setStroke(new BasicStroke((float)(2.0))); g.setColor(C2); g.setStroke(new BasicStroke((float)(1.0))); for(int i=0;i<=7;++i) { GeneralPath radial=octagonWedge(x,y,i,i+1); g.setColor(C1); g.fill(radial); g.setColor(C2); g.draw(radial); } g.setStroke(new BasicStroke((float)(2.0))); g.setColor(C3); g.draw(path); g.setStroke(new BasicStroke((float)(1.0))); } public GeneralPath octagonWedge(int x,int y,int a, int b) { GeneralPath radial=new GeneralPath(); radial.moveTo((float)(x),(float)(y)); for(int i=a;i<=b;++i) { radial.lineTo((float)(x+30*Math.cos(i*Math.PI/4)),(float)(y+30*Math.sin(i*Math.PI/4))); } radial.closePath(); return(radial); } /*certificate*/ public void drawCertificate(int x,int y,Graphics2D g,Color C) { int cert=Certify.doMainStep(diff[1][0],diff[0][1],adiff,dyadic); g.setColor(C); GeneralPath radial=new GeneralPath(); radial=octagonWedge(x,y,-1-cert,1-cert); if(cert>0) g.fill(radial); } public void drawFunction1(Graphics g) { g.setFont(new Font("Monospaced",Font.PLAIN,10)); g.setColor(Color.white); g.translate((int)(B.x),0); g.drawString("F:",5,35); int space=30; for(int i=1;i<=f[0][0];++i) { specialRender(f[2][i],space,15,g); specialRender(f[0][i],space,43,g); specialRender(f[1][i],space,54,g); space=space+10*spaceEater1(i)+5; } g.translate((int)(-B.x),0); } public void drawFunction2(Graphics g) { g.setFont(new Font("Monospaced",Font.PLAIN,10)); g.setColor(Color.white); g.translate((int)(B.x),0); g.setColor(Color.white); if(n[3][1]==-1) g.setColor(Color.black); g.drawString("P:",5,18); g.setColor(Color.white); int space=30; for(int i=1;i<=n[0][0];++i) { specialRender(n[1][i],space,12,g); specialRender(n[2][i],space,24,g); space=space+10*spaceEater2(i)+5; } space=30; g.drawString("Q:",5,56); for(int i=1;i<=d[0][0];++i) { specialRender(d[1][i],space,49,g); specialRender(d[2][i],space,61,g); space=space+10*spaceEater2(i)+5; } g.translate((int)(-B.x),0); } public int spaceEater1(int k) { int max=0; if(max