import java.applet.Applet; import java.awt.*; import java.awt.event.*; import java.applet.*; import java.awt.geom.*; import java.math.*; public class ScaleCanvas extends Canvas { Complex SOURCE=new Complex(0,0); AffineTransform[] A=new AffineTransform[2]; public ScaleCanvas() { setScales(200,90); } public void setScales(double m1,double m2,double n1,double n2) { A[0]=AffineTransform.getTranslateInstance(m1,m2); A[1]=AffineTransform.getScaleInstance(n1,-n2); } public void setScales(double m,double n) { setScales(m,m,n,n); } public void setScales(double m1,double m2,double n) { setScales(m1,m2,n,n); } public void paint(Graphics g2) {} public GeneralPath transform(GeneralPath H) { GeneralPath HH=new GeneralPath(H); HH.transform(A[1]); //scale HH.transform(A[0]); //translate return(HH); } /**ZOOM: This routine is the companion to the scaling routine. After I have zoomed into the picture in some way, my further mouse clicks have different meanings than they did before the zoom. In other words, suppose that I dilate the picture by 100000. When I click on the point with pixel value (50,50) I really mean to select the number (.00005,.00005). This routine changes the pixel value of the point to the intended value.*/ public Complex unTransform(Point X) { double ux=A[0].getTranslateX(); double uy=A[0].getTranslateY(); double tx=X.x; double ty=X.y; double sx=A[1].getScaleX(); double sy=A[1].getScaleY(); ux=(ux-tx)+tx; uy=(uy-ty)+ty; tx=tx-ux; ty=ty-uy; tx=tx/sx; ty=ty/sy; return(new Complex(tx,ty)); } /**ZOOM: this routine scales up or down with the mouse click. The first argument is the point about which you scale, and the second argument just tells you whether to go up or down. The basic idea is that I have globally defined some AffineTransform objects. These will rescale a GeneralPath whenever I draw it. So, I just modify the components of these AffineTransforms whenever I do this routine.*/ public void scaleUp(Point X,int k) { double scale=(1+Math.sqrt(5))/2; scale=Math.sqrt(scale); double ss=scale; if(k==1) ss=1/scale; double sx=A[1].getScaleX(); double sy=A[1].getScaleY(); double tx=X.x; double ty=X.y; double ux0=A[0].getTranslateX(); double uy=A[0].getTranslateY(); double ux1=ss*(ux0-tx)+tx; uy=ss*(uy-ty)+ty; sx=sx*ss; sy=sy*ss; A[1]=AffineTransform.getScaleInstance(sx,sy); A[0]=AffineTransform.getTranslateInstance(ux1,uy); repaint(); } public void drawSource(Graphics2D g,Color C,Complex z,double d) { GeneralPath gp=new GeneralPath(); float x=(float)(z.x); float y=(float)(z.y); gp.moveTo((float)(x-d),(float)(y-d)); gp.lineTo((float)(x-d),(float)(y+d)); gp.lineTo((float)(x+d),(float)(y+d)); gp.lineTo((float)(x+d),(float)(y-d)); gp.closePath(); gp=transform(gp); g.setColor(C); g.draw(gp); } public void doScale(MouseEvent e) { MouseData J=MouseData.process(e); int mode=J.mode; if(mode==1) scaleUp(J.X,-1); if(mode==3) scaleUp(J.X,+1); if(mode==2) { Complex temp=unTransform(J.X); SOURCE=temp; } } public void doScale2(MouseEvent e) { MouseData J=MouseData.process(e); int mode=J.mode; if(mode==2) { Complex temp=unTransform(J.X); SOURCE=temp; } } }