import java.applet.Applet; import java.awt.*; import java.awt.event.*; public class test1 extends Applet { PolyCanvas P; TextCanvas T; Manager M; public void init() { setBackground(Color.blue); M=new Manager(); P=new PolyCanvas(M); P.resize(520,540); P.setBackground(Color.black); T=new TextCanvas(M); T.resize(300,540); T.setBackground(Color.blue); add(P); add(T); M.P=P; M.T=T; } } class Manager { TextCanvas T; PolyCanvas P; Manager() {} } 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); g2.dispose(); offscreen.flush(); } } class PolyCanvas extends DBCanvas implements MouseListener, MouseMotionListener { Manager M; int state,choice; PolyVector[] P=new PolyVector[10]; ListenSquare[] S=new ListenSquare[6]; PolyCanvas(Manager M) { this.M=M; addMouseListener(this); addMouseMotionListener(this); /*initialize states*/ state=0; choice=-1; /*controls*/ S[0]=new ListenSquare(20,20,500,500); S[1]=new ListenSquare(20,520,500,20); S[2]=new ListenSquare(-1,20,21,500); S[3]=new ListenSquare(20,-1,500,21); S[1].state=0; S[2].state=0; S[3].state=-200; S[1].type=1; S[2].type=2; S[3].type=1; S[4]=new ListenSquare(-1,520,21,20); S[5]=new ListenSquare(-1,-1,21,21); /*grid lines*/ for(int i=1;i<=8;++i) P[i]=new PolyVector(); P[4]=P[4].regular(4,3,3,250,250,100); P[5]=P[4].regular(4,1,3,250,250,200); P[6]=P[4].regular(4,3,3,250,250,400.0); P[7]=P[4].regular(4,1,3,250,250,800.0); } public void paint(Graphics g) { /*render controls*/ g.setColor(new Color(0,0,50)); S[1].render(g,new Color(0,0,100),Color.blue,Color.red); S[2].render(g,new Color(0,0,100),Color.blue,Color.red); S[3].render(g,new Color(0,0,100),Color.blue,Color.white); S[4].render(g,Color.red,Color.blue); S[5].render(g,Color.black,Color.blue); g.clipRect(21,21,499,499); g.translate(-S[1].state+20,-S[2].state+20); Color C=Color.red; if(state==1) { double x2=250+200*Math.cos(2*Math.PI*5/12); double y2=250+200*Math.sin(2*Math.PI*5/12); g.setColor(new Color(0,0,60)); int x1=(int)(300+x2/2.0); int y1=(int)(125+y2/2.0); g.fillOval(x1-100,y1-100,200,200); P[1].render(g,C,C); /*grid lines*/ Color c=new Color(100,100,100); P[4].render(g,c); P[5].render(g,c); P[6].render(g,c); P[7].render(g,c); g.setColor(c); int xx=0; int yy=0; for(int i=1;i<=3;++i) { xx=(int)(P[7].v[i].x); yy=(int)(P[7].v[i].y); g.drawLine(xx,yy,250,250); } for(int i=1;i<=3;++i) { xx=(int)(P[6].v[i].x); yy=(int)(P[6].v[i].y); g.drawLine(xx,yy,250,250); } g.setColor(new Color(100,100,100)); P[8]=P[8].regular(4,1,9,250,250,100); int x3=0; int y3=0; for(int k=0;k<=2;++k) { x3=(int)(P[8].v[1+3*k].x); y3=(int)(P[8].v[1+3*k].y); g.drawOval(x3,y3,1,1); } P[1].render3(g,Color.white); P[2]=P[1]; for(int i=1;i<=S[3].state+250;++i) { P[2]=P[2].diag21(); P[2]=P[2].dilate(); P[2].render2(g,Color.white); } } /*demo*/ if(state>1) { int xx=0; int yy=0; g.setColor(new Color(100,100,100)); for(int i=1;i<=3;++i) { xx=(int)(P[7].v[i].x); yy=(int)(P[7].v[i].y); g.drawLine(xx,yy,250,250); } for(int i=1;i<=3;++i) { xx=(int)(P[6].v[i].x); yy=(int)(P[6].v[i].y); g.drawLine(xx,yy,250,250); } P[5].render(g,Color.black,new Color(100,100,100)); } if(state==2) { P[1].render(g,Color.red,Color.black); P[1].render3(g,Color.white); } if(state==3) { P[1].render(g,Color.red,Color.black); P[2].render(g,new Color(150,0,0),new Color(150,0,0)); P[1].render4(g,Color.red,Color.white); } if(state==4) { P[1].render(g,new Color(150,0,0),Color.black); } if(state==5) { P[1].render(g,new Color(150,0,0),Color.black); } if(state==6) { P[1].render(g,Color.red,Color.black); P[1].render3(g,Color.white); } if(state>1) { g.setColor(new Color(150,150,150)); g.drawOval(250,250,1,1); } } public void mouseExited(MouseEvent e) {} public void mouseMoved(MouseEvent e) {} public void mouseReleased(MouseEvent e) {} public void mouseEntered(MouseEvent e) {} public void mousePressed(MouseEvent e) { e.consume(); Point pp=new Point(); pp.x=e.getX(); pp.y=e.getY(); int test=0; for(int i=0;i<=4;++i) { if(S[i].inside(pp)==1) test=i; } choice=test; } public void mouseDragged(MouseEvent e) { e.consume(); Point X=new Point(); Point Y=new Point(); X.x=e.getX(); X.y=e.getY(); if(X.x<0) X.x=0; if(X.x>540) X.x=540; if(X.y<0) X.y=0; if(X.y>540) X.y=540; if(choice==0) { state=1; if(M.T.demo==1) {M.T.demo=0;M.T.repaint();} Y.x=X.x+S[1].state-20; Y.y=X.y+S[2].state-20; P[1]=P[4].convert(Y); repaint(); } if(choice==1) S[1].state=X.x-250-20; if(choice==2) S[2].state=X.y-250-20; if(choice==3) S[3].state=X.x-250-20; if(choice==4) { S[1].state=0; S[2].state=0; } repaint(); } public void mouseClicked(MouseEvent e) { e.consume(); Point X=new Point(); Point Y=new Point(); X.x=e.getX(); X.y=e.getY(); if(S[0].inside(X)==1) { state=1; if(M.T.demo==1) {M.T.demo=0;M.T.repaint();} Y.x=X.x+S[1].state-20; Y.y=X.y+S[2].state-20; P[1]=P[4].convert(Y); repaint(); } if(S[1].inside(X)==1) S[1].state=X.x-250-20; if(S[3].inside(X)==1) S[3].state=X.x-250-20; if(S[2].inside(X)==1) S[2].state=X.y-250-20; if(S[4].inside(X)==1) { S[1].state=0; S[2].state=0; } repaint(); } } class ListenTriangle { double x1,x2,x3; double y1,y2,y3; int state; Color C; ListenTriangle() { this.x1=x1; this.x2=x2; this.x3=x3; this.y1=y1; this.y2=y2; this.y3=y3; this.C=C; this.state=0; } int inside(Point p) { double v1x,v1y,v2x,v2y; double A1,A2,A3; int val; v1x=p.x-this.x1; v1y=p.y-this.y1; v2x=p.x-this.x2; v2y=p.y-this.y2; A3=v1x*v2y-v1y*v2x; v1x=p.x-this.x2; v1y=p.y-this.y2; v2x=p.x-this.x3; v2y=p.y-this.y3; A1=v1x*v2y-v1y*v2x; v1x=p.x-this.x3; v1y=p.y-this.y3; v2x=p.x-this.x1; v2y=p.y-this.y1; A2=v1x*v2y-v1y*v2x; val=0; if((A1<0)&&(A2<0)&&(A3<0)) val=1; if((A1>0)&&(A2>0)&&(A3>0)) val=1; return(val); } void render(Graphics g) { g.setColor(this.C); Polygon P=new Polygon(); int x[]={(int)(this.x1),(int)(this.x2),(int)(this.x3)}; int y[]={(int)(this.y1),(int)(this.y2),(int)(this.y3)}; P.xpoints=x; P.ypoints=y; P.npoints=3; if(state==1) g.fillPolygon(P); if(state==0) g.drawPolygon(P); } } class Vector { double x,y,z; Vector() { this.x=0; this.y=0; this.z=0; } Vector(double x,double y,double z) { this.x=x; this.y=y; this.z=z; } Vector cross(Vector V,Vector W) { Vector X=new Vector(); X.x=V.y*W.z-V.z*W.y; X.y=V.z*W.x-V.x*W.z; X.z=V.x*W.y-V.y*W.x; return(X); } Vector normalize() { Vector X=this; X.x=x/z; X.y=y/z; X.z=1.0; return(X); } double norm() { double d=0; d=x*x+y*y+z*z; d=Math.sqrt(d); return(d); } Vector unit() { Vector V=new Vector(); double d=this.norm(); V.x=x/d; V.y=y/d; V.z=z/d; return(V); } Vector rotate(double d) { Vector W=new Vector(); W.x=x*Math.cos(d)+y*Math.sin(d); W.y=-x*Math.sin(d)+y*Math.cos(d); W.z=1.0; return(W); } double dot(Vector V,Vector W) { double d=0; d=V.x*W.x+V.y*W.y+V.z*W.z; return(d); } Vector scale(double d) { Vector W=new Vector(); W.x=d*x; W.y=d*y; W.z=d*z; return(W); } Vector scale2(double d) { Vector W=new Vector(); W.x=d*x; W.y=d*y; W.z=1.0; return(W); } Vector add(Vector V,Vector W) { Vector X=new Vector(); X.x=V.x+W.x; X.y=V.y+W.y; X.z=V.z+W.z; return(X); } Vector sub(Vector V,Vector W) { Vector X=new Vector(); X.x=V.x-W.x; X.y=V.y-W.y; X.z=V.z-W.z; return(X); } Vector reflect(Vector W) { Vector X=new Vector(); double d=X.dot(this,W); X=X.sub(this.scale(2*d),W); return(X); } Vector reflect(Vector A,Vector B) { Vector[] V=new Vector[10]; V[1]=A; V[2]=B; V[1].z=1; V[2].z=1; V[3]=sub(V[1],V[2]); V[3]=V[3].unit(); V[4]=sub(this,V[2]); V[5]=V[3].reflect(V[4]); V[6]=add(V[5],V[2]); V[6].z=1; return(V[6]); } Vector reflect(ListenTriangle T,int j) { Vector[] V=new Vector[10]; Vector W=new Vector(x,y,z); W.z=0; if(j==1) { V[1]=new Vector(T.x1,T.y1,1.0); V[2]=new Vector(T.x2/2+T.x3/2,T.y2/2+T.y3/2.0,1.0); } if(j==2) { V[1]=new Vector(T.x2,T.y2,1.0); V[2]=new Vector(T.x1/2+T.x3/2,T.y1/2+T.y3/2.0,1.0); } if(j==3) { V[1]=new Vector(T.x3,T.y3,1); V[2]=new Vector(T.x2/2+T.x1/2,T.y2/2+T.y1/2.0,1.0); } V[3]=this.sub(V[1],V[2]); V[3]=V[3].unit(); V[4]=this.sub(W,V[2]); V[5]=V[3].reflect(V[4]); V[6]=V[5].add(V[5],V[2]); V[6].z=1; return(V[6]); } void print() { System.out.println(x+" "+y+ " " +z); } } class PolyVector { Vector[] v=new Vector[11]; int n; PolyVector() { for(int i=1;i<=10;++i) v[i]=new Vector(); } void render(Graphics g,Color C1,Color C2) { int[] X=new int[11]; int[] Y=new int[11]; for(int i=0;i<=8;++i) { X[i]=(int)(this.v[i+1].x/this.v[i+1].z); Y[i]=(int)(this.v[i+1].y/this.v[i+1].z); } g.setColor(C1); g.fillPolygon(X,Y,n); g.setColor(C2); g.drawPolygon(X,Y,n); } void render(Graphics g,Color C1) { int[] X=new int[22]; int[] Y=new int[22]; for(int i=0;i<=n;++i) { X[i]=(int)(this.v[i+1].x/this.v[i+1].z); Y[i]=(int)(this.v[i+1].y/this.v[i+1].z); } g.setColor(C1); g.drawPolygon(X,Y,n); } void render2(Graphics g,Color C1) { g.setColor(C1); int x=(int)(v[1].x); int y=(int)(v[1].y); g.fillOval(x-1,y-1,2,2); g.drawOval(x-1,y-1,2,2); } void render3(Graphics g,Color C1) { g.setColor(C1); int x=(int)(v[1].x); int y=(int)(v[1].y); g.fillOval(x-1,y-1,2,2); g.drawOval(x-1,y-1,2,2); } void render4(Graphics g,Color C1,Color C2) { int[] X=new int[11]; int[] Y=new int[11]; int j=0; for(int i=0;i<=8;++i) { j=mod(2*i); X[i]=(int)(this.v[j].x/this.v[j].z); Y[i]=(int)(this.v[j].y/this.v[j].z); } g.setColor(C2); g.drawPolygon(X,Y,n); } Vector opposite(int j) { Vector V=new Vector(); V=V.add(v[mod(j+(n-1)/2)],v[mod(j+(n+1)/2)]); V=V.scale(.5); return(V); } PolyVector convert(Point P) { PolyVector W=new PolyVector(); Vector A=new Vector(); Vector B=new Vector(); int k=0; W.v[1].x=P.x; W.v[1].y=P.y; W.v[1].z=1.0; for(int i=1;i<=n;++i) { k=mod(i+2); A=v[k]; B=opposite(k); W.v[3*i-1]=v[k]; W.v[3*i-0]=W.v[3*i-2].reflect(A,B); k=mod(i+2+(n+1)/2); A=v[k]; B=opposite(k); W.v[3*i+1]=W.v[3*i-0].reflect(A,B); } W.n=3*n; return(W); } PolyVector regular(int d,int k,int n,double x,double y,double r) { PolyVector P=new PolyVector(); P.n=n; for(int i=1;i<=P.n;++i) { P.v[i].x=x+r*Math.cos(2*Math.PI*(d*i+k)/(d*n)); P.v[i].y=y+r*Math.sin(2*Math.PI*(d*i+k)/(d*n)); P.v[i].z=1; } return(P); } int mod(int j) { int k; k=j; if(k>n) k=k-n; if(k<1) k=k+n; return(k); } PolyVector diag(int h) { PolyVector P=new PolyVector(); for(int i=1;i<=n;++i) { P.v[i]=P.v[i].cross(v[mod(i)],v[mod(i+h)]); P.v[i]=P.v[i].normalize(); } P.n=n; return(P); } PolyVector diag21() { PolyVector P=new PolyVector(); P=this.diag(2); P=P.diag(1); PolyVector Q=new PolyVector(); for(int i=1;i<=n;++i) { Q.v[i]=P.v[mod(i+3)]; } Q.n=n; return(Q); } PolyVector rotate(double d) { Vector V=new Vector(250.0,250.0,0.0); PolyVector P=new PolyVector(); Vector W=new Vector(); W=W.sub(v[2],V); for(int i=1;i<=n;++i) { P.v[i]=V.sub(v[i],V); P.v[i]=P.v[i].rotate(d); P.v[i]=P.v[i].add(P.v[i],V); } P.n=n; return(P); } PolyVector dilate() { Vector V=new Vector(250.0,250.0,0.0); PolyVector P=new PolyVector(); Vector W=new Vector(); W=W.sub(v[2],V); double d=100.0/W.y; for(int i=1;i<=n;++i) { P.v[i]=V.sub(v[i],V); P.v[i]=P.v[i].scale2(d); P.v[i]=P.v[i].add(P.v[i],V); } P.n=n; return(P); } } class ListenSquare { double x1,x2; double y1,y2; int state; int type; Color C; ListenSquare(double x1,double y1,double x2,double y2) { this.x1=x1; this.x2=x2; this.y1=y1; this.y2=y2; this.state=0; this.type=0; } int inside(Point p) { int val; val=1; if(p.x<=this.x1) val=0; if(p.x>this.x1+this.x2) val=0; if(p.y<=this.y1) val=0; if(p.y>this.y1+this.y2) val=0; return(val); } void render(Graphics g,Color C1,Color C2,Color C3) { int xx1,yy1,xx2,yy2; xx1=(int)(this.x1); yy1=(int)(this.y1); xx2=(int)(int)(this.x2); yy2=(int)(int)(this.y2); g.setColor(C1); g.fillRect(xx1,yy1,xx2,yy2); g.setColor(C3); if(type==1) g.fillRect(xx1+xx2/2+state-5,yy1,10,yy2); if(type==2) g.fillRect(xx1,yy1+yy2/2+state-5,xx2,10); if(type==3) g.fillRect(xx1,yy1,xx2/2+state,yy2); g.setColor(C2); g.drawRect(xx1,yy1,xx2,yy2); } void render(Graphics g,Color C1,Color C2) { int xx1,yy1,xx2,yy2; xx1=(int)(this.x1); yy1=(int)(this.y1); xx2=(int)(int)(this.x2); yy2=(int)(int)(this.y2); g.setColor(C1); g.fillRect(xx1,yy1,xx2,yy2); g.setColor(C2); g.drawRect(xx1,yy1,xx2,yy2); } } class TextCanvas extends DBCanvas implements MouseListener,MouseMotionListener { int scroll,choice,demo; Manager M; ListenSquare[] L=new ListenSquare[3]; TextCanvas(Manager M) { scroll=0; addMouseListener(this); addMouseMotionListener(this); this.M=M; L[0]=new ListenSquare(-1,-1,20,541); L[0].state=-265; L[0].type=2; L[1]=new ListenSquare(133,535,20,20); L[2]=new ListenSquare(163,535,20,20); choice=0; demo=0; } public void paint(Graphics g) { g.setColor(new Color(0,0,60)); g.fillRect(1,0,300,540); L[0].render(g,new Color(0,0,100),Color.blue,Color.green); g.setColor(Color.white); g.translate(0,-scroll+105); g.setFont(new Font("Helvetica",Font.PLAIN,30)); g.drawString("Rich: Applet 41",55,-40); g.setColor(Color.green); g.setFont(new Font("Helvetica",Font.PLAIN,15)); g.drawString("Applet operation",95,0); g.setColor(Color.white); g.setColor(Color.black); g.fillOval(25,9,10,10); g.fillOval(25,49,10,10); g.fillOval(25,89,10,10); g.fillOval(25,129,10,10); g.setColor(Color.green); g.drawOval(25,9,10,10); g.drawOval(25,49,10,10); g.drawOval(25,89,10,10); g.drawOval(25,129,10,10); g.setColor(Color.white); g.drawString("Scroll this window by clicking or",42,20); g.drawString("dragging on the slider to the left.",42,40); g.drawString("See the demo by clicking or dragging",42,60); g.drawString("the mouse on the big black screen.",42,80); g.drawString("Recenter the big screen by clicking",42,100); g.drawString("or dragging the red sliders and box.",42,120); g.drawString("Change the number of white dots",42,140); g.drawString("by clicking or dragging the white slider.",42,160); g.setColor(Color.green); g.translate(0,20); g.drawString("The red polygon",95,180); g.setColor(Color.white); g.drawString("The red 9-gon you create has 6-fold",25,200); g.drawString("symmetry. Also, 3 of its vertices are fixed,",25,220); g.drawString("independent of the other points. This",25,240); g.drawString("means that the 9-gon is determined by",25,260); g.drawString("the single point you select with the",25,280); g.drawString("mouse. The white dots represent other",25,300); g.drawString("9-gons. If you want to see one of the",25,320); g.drawString("other 9-gons, just click on its dot.",25,340); g.setColor(Color.green); g.translate(0,20); g.drawString("The dynamical system",85,360); g.setColor(Color.white); g.drawString("The white dots represent 9-gons which",25,380); g.drawString("result from applying a certain construction,",25,400); g.drawString("repeatedly, starting with the initial 9-gon.",25,420); g.drawString("The construction is done in 4 steps:",25,440); g.translate(0,10); g.drawString("Draw the second diagonals.",40,460); g.drawString("Successively intersect the diagonals.",40,480); g.drawString("Rotate 180 degrees about center.",40,500); g.drawString("Rescale to fit the grey triangle.",40,520); if(demo==0) g.drawString("start",100,550); if(demo==1) g.drawString("reset",96,550); L[1].render(g,Color.black,Color.green); L[2].render(g,Color.green,Color.green); g.setColor(Color.white); if(M.P.state>1) g.drawString("do demo",190,550); g.setColor(Color.white); g.setColor(Color.black); g.fillOval(25,449,10,10); g.fillOval(25,469,10,10); g.fillOval(25,489,10,10); g.fillOval(25,509,10,10); g.setColor(Color.green); g.drawOval(25,449,10,10); g.drawOval(25,469,10,10); g.drawOval(25,489,10,10); g.drawOval(25,509,10,10); g.setColor(Color.green); if(M.P.state==3) g.fillOval(25,449,10,10); if(M.P.state==4) g.fillOval(25,469,10,10); if(M.P.state==5) g.fillOval(25,489,10,10); if((M.P.state==2)&&(demo==1)) g.fillOval(25,509,10,10); g.setColor(Color.green); if(M.P.state==3) g.drawOval(25,449,10,10); if(M.P.state==4) g.drawOval(25,469,10,10); if(M.P.state==5) g.drawOval(25,489,10,10); if((M.P.state==2)&&(demo==1)) g.drawOval(25,509,10,10); g.translate(0,10); g.setColor(Color.white); g.drawString("To see a demo, click once on the black",25,580); g.drawString("box and then 4 times on the green box.",25,600); g.drawString("The demo shows the construction for",25,620); g.drawString("convex 9-gons. The general case is",25,640); g.drawString("formally the same, but harder to draw.",25,660); g.drawString("The demo stops when you click or drag",25,680); g.drawString("the mouse on the big screen.",25,700); g.translate(0,20); g.setColor(Color.green); g.drawString("Some basic structure",95,720); g.setColor(Color.white); g.setColor(Color.black); g.fillOval(25,729,10,10); g.fillOval(25,769,10,10); g.fillOval(25,829,10,10); g.fillOval(25,869,10,10); g.setColor(Color.green); g.drawOval(25,729,10,10); g.drawOval(25,769,10,10); g.drawOval(25,829,10,10); g.drawOval(25,869,10,10); g.setColor(Color.white); g.drawString("Each (generic) orbit lies on an elliptic",42,740); g.drawString("curve and is conjugate to a rotation.",42,760); g.drawString("The 3 tiny grey dots correspond to the",42,780); g.drawString("9-gons which have complete symmetry. ",42,800); g.drawString("These dots lie on singular orbits. ",42,820); g.drawString("The boundary of the navy disk is the",42,840); g.drawString("limit of nearly circular infinite orbits.",42,860); g.drawString("Each orbit on the disk boundary is the",42,880); g.drawString("vertex set of an equilateral triangle.",42,900); g.translate(0,10); g.drawString("The elliptic curves are the level sets",25,920); g.drawString("of a certain quantity that is preserved",25,940); g.drawString("by the dynamical system. This invariant",25,960); g.drawString("quantity is defined to be the product",25,980); g.drawString("x1 x2 x3 x4 x5 x6 x7 x8 x9",75,1010); g.setColor(Color.white); g.drawString("where",140,1040); g.drawString("(aN+bN) (cN+bN)",120,1070); g.drawLine(120,1080,230,1080); g.drawString("aN cN",155,1100); g.drawString("xN=",90,1085); g.drawString("aN, bN and cN are the lengths computed",25,1130); g.drawString("at the vertex vN according to the figure. ",25,1150); g.translate(40,1170); g.drawLine(0,0,30,70); g.drawLine(120,90,30,70); g.drawLine(120,90,210,70); g.drawLine(240,0,210,70); g.drawLine(1,0,31,70); g.drawLine(120,91,30,71); g.drawLine(120,91,210,71); g.drawLine(239,0,209,70); g.setColor(Color.green); g.drawLine(0,0,120,90); g.drawLine(120,90,240,0); g.drawLine(30,70,210,70); g.setColor(Color.white); g.drawString("vN",114,110); g.setColor(Color.blue); g.fillOval(115,85,10,10); g.fillOval(-5,-5,10,10); g.fillOval(25,65,10,10); g.fillOval(205,65,10,10); g.fillOval(235,-5,10,10); g.setColor(Color.green); g.fillOval(90,67,6,6); g.drawOval(90,67,6,6); g.fillOval(143,67,6,6); g.drawOval(143,67,6,6); g.setColor(Color.white); g.drawOval(115,85,10,10); g.drawOval(-5,-5,10,10); g.drawOval(25,65,10,10); g.drawOval(205,65,10,10); g.drawOval(235,-5,10,10); g.drawString("aN",45,68); g.drawString("cN",173,68); g.drawString("bN",111,68); g.translate(-40,-1165); g.drawString("When the polygon is not convex, care",25,1300); g.drawString("needs to be taken in interpreting the",25,1320); g.drawString("notion of length, to get the signs right.",25,1340); g.drawString("At any rate, the formula above is a ",25,1360); g.drawString("rational function of the vertices of a",25,1380); g.drawString("convex polygon, and as such extends in",25,1400); g.drawString("a natural way to all polygons.",25,1420); g.translate(0,580); g.setColor(Color.green); g.drawString("Round-off errors",100,880); g.setColor(Color.white); g.drawString("Some of the plots are inaccurate, due to",25,900); g.drawString("round-off errors. These errors are most",25,920); g.drawString("pronounced for orbits which are nearly",25,940); g.drawString("singular or unbounded. The inaccurate",25,960); g.drawString("plots are easy to spot; they tend to look",25,980); g.drawString("messy. The chances of error increase ",25,1000); g.drawString("with the number of white dots computed.",25,1020); g.drawString("I hope there are enough accurate plots",25,1040); g.drawString("to evoke the basic structure of the system.",25,1060); g.translate(0,0); g.setColor(Color.green); g.drawString("References",120,1100); g.setColor(Color.white); g.drawString("The dynamical system in this applet is a",25, 1120); g.drawString("special case of something called the",25,1140); g.drawString("pentagram map. I've written a few papers",25,1160); g.drawString("on it. My paper `The Pentagram Map' has",25,1180); g.drawString("a proof that the invariant quantity above",25,1200); g.drawString("really is an invariant quantity. My list of",25,1220); g.drawString("publications has the complete reference.",25,1240); g.drawString("Even though I've thought a lot about the",25,1260); g.drawString("pentagram map, it still baffles me.",25,1280); g.translate(0,scroll-105); } public void mouseMoved(MouseEvent e) {} public void mouseExited(MouseEvent e) {} public void mouseReleased(MouseEvent e) {} public void mouseEntered(MouseEvent e) {} public void mousePressed(MouseEvent e) { e.consume(); choice=0; Point p=new Point(); p.x=e.getX(); p.y=e.getY(); if(L[0].inside(p)==1) choice=1; } public void mouseDragged(MouseEvent e) { e.consume(); Point p=new Point(); p.x=e.getX(); p.y=e.getY(); if(p.y<0) p.y=0; if(p.y>540) p.y=540; if(choice==1) { scroll=3*p.y-5; L[0].state=p.y-270; repaint(); } } public void mouseClicked(MouseEvent e) { e.consume(); Point pp=new Point(); pp.x=e.getX(); pp.y=e.getY(); if(choice==1) { scroll=3*pp.y-5; L[0].state=pp.y-270; repaint(); } pp.y=pp.y+scroll-155; if(L[1].inside(pp)==1) { Point p=new Point(); demo=0; repaint(); p.x=350; p.y=330; M.P.P[1]=M.P.P[4].convert(p); M.P.state=2; M.P.repaint(); } if(L[2].inside(pp)==1) { demo=1; if(M.P.state>1) { ++M.P.state; repaint(); if(M.P.state==3) M.P.P[2]=M.P.P[1].diag21(); if(M.P.state==4) M.P.P[1]=M.P.P[1].diag21(); if(M.P.state==5) M.P.P[1]=M.P.P[1].rotate(Math.PI); if(M.P.state==6) M.P.P[1]=M.P.P[1].dilate(); M.P.repaint(); if(M.P.state==6) M.P.state=2; } } } }