import java.applet.Applet; import java.awt.*; import java.awt.event.*; import java.applet.*; import java.awt.geom.*; import java.math.*; import java.io.*; /*This class does basic real arithmetic in the ring Z[phi], where phi is the golden ratio. The class has the form a[0]+ phi a[1] */ public class GoldenComplex { GoldenReal x,y; /**constructors*/ public GoldenComplex() { x=new GoldenReal(); y=new GoldenReal(); } public GoldenComplex(GoldenComplex z) { x=new GoldenReal(z.x); y=new GoldenReal(z.y); } public GoldenComplex(GoldenReal x0,GoldenReal y0) { this.x=x0; this.y=y0; } public GoldenComplex(int[] X) { x=new GoldenReal(X[0],X[1]); y=new GoldenReal(X[2],X[3]); } public GoldenComplex(long[] X) { x=new GoldenReal(X[0],X[1]); y=new GoldenReal(X[2],X[3]); } public GoldenComplex(int x1,int x2,int x3,int x4) { x=new GoldenReal(x1,x2); y=new GoldenReal(x3,x4); } public GoldenComplex(Complex w,int depth) { this.x=new GoldenReal(w.x,depth); this.y=new GoldenReal(w.y,depth); } public GoldenComplex(Complex w,int depth,double tol) { this.x=new GoldenReal(w.x,depth,tol); this.y=new GoldenReal(w.y,depth,tol); } public void print() { x.printNoLine(); System.out.print(" "); y.printNoLine(); System.out.print(" "); double xx=x.toDouble(); double yy=y.toDouble(); System.out.println(xx+" "+yy); } public void print2() { double xx=x.toDouble(); double yy=y.toDouble(); System.out.println(xx+" "+yy); } public Complex toComplex() { Complex z=new Complex(x.toDouble(),y.toDouble()); return(z); } public static GoldenComplex random() { double d1=Math.random(); double d2=Math.random(); int[] t1=GoldenRatio.bestFit(d1,50); int[] t2=GoldenRatio.bestFit(d2,50); GoldenComplex z=new GoldenComplex(t1[0],t1[1],t2[0],t2[1]); return(z); } public static boolean equals(GoldenComplex z1,GoldenComplex z2) { if(GoldenReal.equals(z1.x,z2.x)==false) return(false); if(GoldenReal.equals(z1.y,z2.y)==false) return(false); return(true); } public static GoldenComplex plus(GoldenComplex z1,GoldenComplex z2) { GoldenComplex z3=new GoldenComplex(GoldenReal.plus(z1.x,z2.x),GoldenReal.plus(z1.y,z2.y)); return(z3); } public static GoldenComplex minus(GoldenComplex z1,GoldenComplex z2) { GoldenComplex z3=new GoldenComplex(GoldenReal.minus(z1.x,z2.x),GoldenReal.minus(z1.y,z2.y)); return(z3); } public static GoldenComplex times(GoldenComplex z1,GoldenComplex z2) { GoldenReal a11=GoldenReal.times(z1.x,z2.x); GoldenReal a22=GoldenReal.times(z1.y,z2.y); GoldenReal a12=GoldenReal.times(z1.x,z2.y); GoldenReal a21=GoldenReal.times(z1.y,z2.x); GoldenComplex w=new GoldenComplex(GoldenReal.minus(a11,a22),GoldenReal.plus(a12,a21)); return(w); } public GoldenComplex conjugate() { long[] U={x.a[0],x.a[1],-y.a[0],-y.a[1]}; GoldenComplex z=new GoldenComplex(U); return(z); } public GoldenComplex scale(GoldenReal t) { GoldenComplex V=new GoldenComplex(); V.x=GoldenReal.times(x,t); V.y=GoldenReal.times(y,t); return(V); } public static GoldenComplex triple(GoldenComplex z1,GoldenComplex z2,GoldenComplex z3) { GoldenComplex[] z=new GoldenComplex[5]; z[1]=GoldenComplex.minus(z2,z1); z[2]=GoldenComplex.minus(z3,z1); z[3]=z[2].conjugate(); z[4]=GoldenComplex.times(z[1],z[3]); return(z[4]); } /**This checks if the triangle z1,z2,z3 is positively oriented**/ public static boolean isPositivelyOriented(GoldenComplex z1,GoldenComplex z2,GoldenComplex z3) { GoldenComplex z=triple(z1,z2,z3); GoldenReal y=new GoldenReal(-z.y.a[0],-z.y.a[1]); if(y.isPositive()==true) return(true); return(false); } /**This checks if z1 is on the line segment joining z2 to z2*/ public static boolean isBetween(GoldenComplex z1,GoldenComplex z2,GoldenComplex z3) { GoldenComplex z=triple(z1,z2,z3); if((z.y.a[0]!=0)||(z.y.a[1]!=0)) return(false); GoldenReal x=new GoldenReal(-z.x.a[0],-z.x.a[1]); if(x.isPositive()==true) return(true); return(false); } public static boolean weakBetween(GoldenComplex z1,GoldenComplex z2,GoldenComplex z3) { if(equals(z1,z2)==true) return(true); if(equals(z1,z3)==true) return(true); GoldenComplex z=triple(z1,z2,z3); if((z.y.a[0]!=0)||(z.y.a[1]!=0)) return(false); GoldenReal x=new GoldenReal(-z.x.a[0],-z.x.a[1]); if(x.isPositive()==true) return(true); return(false); } /**This checks if the vectors z2-z1 and z3-z1 are positive multiples of each other.**/ public static boolean isFolded(GoldenComplex z1,GoldenComplex z2,GoldenComplex z3) { GoldenComplex z=triple(z1,z2,z3); if((z.y.a[0]!=0)||(z.y.a[1]!=0)) return(false); GoldenReal x=new GoldenReal(z.x.a[0],z.x.a[1]); if(x.isPositive()==true) return(true); return(false); } /**This checks if the 3 points are collinear**/ public static boolean collinear(GoldenComplex z1,GoldenComplex z2,GoldenComplex z3) { if(equals(z1,z2)==true) return(true); if(equals(z2,z3)==true) return(true); if(equals(z3,z1)==true) return(true); if(isBetween(z1,z2,z3)==true) return(true); if(isBetween(z2,z3,z1)==true) return(true); if(isBetween(z3,z1,z2)==true) return(true); return(false); } public static boolean collinear(GoldenComplex z1,GoldenComplex z2,GoldenComplex z3,GoldenComplex z4) { if(collinear(z1,z2,z3)==false) return(false); if(collinear(z2,z3,z4)==false) return(false); if(collinear(z3,z4,z1)==false) return(false); if(collinear(z4,z1,z2)==false) return(false); return(true); } /**This checks if the triangle z1,z2,z3 is positively oriented OR if the points are collinear*/ public static boolean weakPositivelyOriented(GoldenComplex z1,GoldenComplex z2,GoldenComplex z3) { if(isPositivelyOriented(z1,z2,z3)==true) return(true); if(collinear(z1,z2,z3)==true) return(true); return(false); } public static GoldenComplex random(int N) { return(new GoldenComplex(GoldenReal.random(N),GoldenReal.random(N))); } public static GoldenComplex interpolate(GoldenComplex z1,GoldenComplex z2) { GoldenReal x=GoldenReal.interpolate(z1.x,z2.x); GoldenReal y=GoldenReal.interpolate(z1.y,z2.y); GoldenComplex z=new GoldenComplex(x,y); return(z); } }