import java.applet.Applet; import java.awt.*; import java.awt.event.*; import java.applet.*; import java.awt.geom.*; import java.math.*; public class Penrose { Complex z; Complex w; int shape; public Penrose() { } public Penrose(Penrose P) { this.z=new Complex(P.z); this.w=new Complex(P.w); this.shape=P.shape; } public void print() { System.out.println("-----"); z.print(); w.print(); System.out.println(shape); System.out.println("-----"); } public Complex[] toKite() { double th=2*Math.PI/10.0; Complex[] p=new Complex[4]; p[0]=new Complex(0,0); p[1]=new Complex(1,0); p[2]=new Complex(Math.cos(th),Math.sin(th)); p[3]=new Complex(Math.cos(2*th),Math.sin(2*th)); return(p); } public Complex[] toDart() { double th=2*Math.PI/10.0; Complex[] p=new Complex[4]; p[0]=new Complex(0,0); p[1]=new Complex(1,0); p[2]=new Complex(Math.cos(th),Math.sin(th)); p[3]=new Complex(Math.cos(2*th),Math.sin(2*th)); double phi=(1+Math.sqrt(5.0))/2.0; p[2].x=p[2].x/phi; p[2].y=p[2].y/phi; return(p); } public GeneralPath toPath0() { Complex[] a=this.toKite(); for(int i=0;i<4;++i) { a[i]=Complex.times(a[i],w); a[i]=Complex.plus(a[i],z); } GeneralPath gp=new GeneralPath(); gp.moveTo((float)(a[0].x),(float)(a[0].y)); gp.lineTo((float)(a[1].x),(float)(a[1].y)); gp.lineTo((float)(a[2].x),(float)(a[2].y)); gp.lineTo((float)(a[3].x),(float)(a[3].y)); gp.closePath(); return(gp); } public GeneralPath toPath1() { Complex[] a=this.toDart(); for(int i=0;i<4;++i) { a[i]=Complex.times(a[i],w); a[i]=Complex.plus(a[i],z); } GeneralPath gp=new GeneralPath(); gp.moveTo((float)(a[0].x),(float)(a[0].y)); gp.lineTo((float)(a[1].x),(float)(a[1].y)); gp.lineTo((float)(a[2].x),(float)(a[2].y)); gp.lineTo((float)(a[3].x),(float)(a[3].y)); gp.closePath(); return(gp); } public GeneralPath toPath() { if(shape==0) return(toPath0()); return(toPath1()); } public Penrose[] absoluteSub0() { Penrose[] P=new Penrose[4]; double phi=(1+Math.sqrt(5.0))/2.0; P[0]=new Penrose(); P[1]=new Penrose(); P[2]=new Penrose(); P[3]=new Penrose(); Complex[] a=this.toKite(); P[0]=new Penrose(); P[0].z=new Complex(a[1]); P[0].w=Complex.minus(a[2],a[1]); P[0].shape=0; P[1].z=new Complex(a[3]); P[1].w=new Complex(a[3]); P[1].w.x=P[1].w.x/phi; P[1].w.y=P[1].w.y/phi; P[1].w=new Complex(-P[1].w.x,-P[1].w.y); P[1].shape=0; P[2].z=new Complex(a[0]); P[2].w=Complex.divide(a[1],a[2]); P[2].w.x=P[2].w.x/phi; P[2].w.y=P[2].w.y/phi; P[2].shape=1; P[3].z=new Complex(a[0]); P[3].w=new Complex(a[2]); P[3].w.x=P[3].w.x/phi; P[3].w.y=P[3].w.y/phi; P[3].shape=1; return(P); } public Penrose[] absoluteSub1() { Penrose[] P=new Penrose[3]; double phi=(1+Math.sqrt(5.0))/2.0; P[0]=new Penrose(); P[1]=new Penrose(); P[2]=new Penrose(); Complex[] a=this.toDart(); P[0]=new Penrose(); P[0].z=new Complex(a[0]); P[0].w=new Complex(a[1]); P[0].w.x=P[0].w.x/phi; P[0].w.y=P[0].w.y/phi; P[0].shape=0; P[1]=new Penrose(); P[1].z=new Complex(a[1]); P[1].w=Complex.minus(a[2],a[1]); P[1].shape=1; P[2].z=new Complex(a[3]); P[2].w=Complex.minus(a[2],a[3]); P[2].w=Complex.divide(P[2].w,a[3]); P[2].shape=1; return(P); } public Penrose[] sub0() { Penrose[] P=absoluteSub0(); for(int i=0;i<4;++i) { P[i].z=Complex.plus(z,Complex.times(w,P[i].z)); P[i].w=Complex.times(w,P[i].w); } return(P); } public Penrose[] sub1() { Penrose[] P=absoluteSub1(); for(int i=0;i<3;++i) { P[i].z=Complex.plus(z,Complex.times(w,P[i].z)); P[i].w=Complex.times(w,P[i].w); } return(P); } public Penrose[] sub() { if(this.shape==0) return(sub0()); return(sub1()); } public static int match0(Penrose P1,Penrose P2) { if(P1.shape!=P2.shape) return(0); if(Complex.dist(P1.z,P2.z)>.000001) return(0); if(Complex.dist(P1.w,P2.w)>.000001) return(0); return(1); } public static int match(Penrose P1,Penrose[] P2,int count) { for(int i=0;i