/* * RationalLine.java * * Created on December 9, 2005, 5:38 PM */ package Current.basic; import java.awt.geom.*; /** * A rational line is a linear condition on the angles of a triangle such * that all the coefficients are integers (and not all are zero). * For instance, if a,b,c are integers then they determine a rational line * consisting of the set of all triangles with angles x,y,z for which * ax+by+cz=0. * @author pat */ public class RationalLine { public static final RationalLine[] boundary={ new RationalLine(1,0,0), new RationalLine(0,1,0), new RationalLine(-1,1,1), new RationalLine(1,-1,1) }; // array of coefficients of lines as described above. public int[] x=new int[3]; /** Creates a new instance of RationalLine */ public RationalLine(int a, int b, int c) { x[0]=a; x[1]=b; x[2]=c; } public RationalLine(RationalLine L) { x[0]=L.x[0]; x[1]=L.x[1]; x[2]=L.x[2]; } public RationalLine(RationalTriangle a, RationalTriangle b) { x=BasicMath.cross(a.x,b.x); reduce(); } public double dot(Complex z) { return x[0]*z.x+x[1]*z.y+x[2]*(2-z.x-z.y); } public boolean equals(RationalLine L) { if (L==null) return false; return (x[0]==L.x[0])&&(x[1]==L.x[1])&&(x[2]==L.x[2]); } public void reduce() { int gcd=BasicMath.gcd(x); if (gcd!=0) { x[0]/=gcd; x[1]/=gcd; x[2]/=gcd; } // normalize so that the last nonzero coordinate is positive. boolean change=false; for (int i=2; i>=0; i--) { if (x[i]<0) { change=true; break; } if (x[i]>0) { change=false; break; } } if (change) for (int i=2; i>=0; i--) x[i]*=-1; } public boolean isZero() { return (x[0]==0)&&(x[1]==0)&&(x[2]==0); } /** returns true if the line intersects the closure of the square */ public boolean isBoundaryValid() { for (int i=0; i<4; i++) { RationalTriangle p=new RationalTriangle(this, boundary[i]); if (p.isBoundaryValid()) return true; } return false; } /** Returns a line that can be drawn in McBilliards coordinates on the * parameter space. Returns null, if the intersection with the McBilliards square is * empty. */ public Line2D.Double toLineSegment(){ RationalTriangle[] ret=new RationalTriangle[2]; int i=0; for (int j=0; j<4; j++) { ret[i]=new RationalTriangle(this, boundary[j]); //System.out.println("pt: "+i+" : "+ret[i]); if (ret[i].isBoundaryValid()){ i++; } else { //System.out.println("invalid"); } if (i==2) if (!((new RationalLine(ret[0], ret[1])).isZero())) { return new Line2D.Double(ret[0].toPoint(),ret[1].toPoint()); } else { //System.out.println("failed test"); i--; } } return null; } public String toString() { return "("+x[0]+", "+x[1]+", "+x[2]+")"; } public String toSaveString(){ return ""+x[0]+" "+x[1]+" "+x[2]; } public String toStringEquation() { return ""+x[0]+"x+"+x[1]+"y+"+x[2]+"z=0"; } public String toStringFunction() { return ""+x[0]+"x+"+x[1]+"y+"+x[2]+"z"; } public void neg() { x[0]*=-1; x[1]*=-1; x[2]*=-1; } }