import java.util.*; public class Square { public static Scanner in = new Scanner(System.in); public static double xa, ya, xb, yb, xc, yc, xd, yd; public static double degree(double r) { return r*(180.0/Math.PI); } public static double dist(double x1, double y1, double x2, double y2) { double dx = x1-x2; double dy = y1-y2; return Math.sqrt(dx*dx+dy*dy); } public static ReturnVal intersect(double a, double b, double c, double d, double e, double f) { double den = a*e-b*d; double x, y; x = (c*e-b*f)/den; y = (a*f-c*d)/den; return new ReturnVal(x, y); } public static ReturnVal ratio(double alpha, double x1, double y1, double x2, double y2, double x3, double y3) { double s1 = Math.sin(alpha), c1 = Math.cos(alpha); ReturnVal ret = intersect(s1, -c1, 0, c1, s1, x1*c1+y1*s1); xa = ret.d1; ya = ret.d2; ret = intersect(s1, -c1, 0, c1, s1, x3*c1+y3*s1); xd = ret.d1; yd = ret.d2; ret = intersect(s1, -c1, s1*x2-c1*y2, c1, s1, x1*c1+y1*s1); xb = ret.d1; yb = ret.d2; ret = intersect(s1, -c1, s1*x2-c1*y2, c1, s1, x3*c1+y3*s1); xc = ret.d1; yc = ret.d2; //System.out.println("xa, ya = " + xa + "," + ya); double len = dist(xa, ya, xb, yb); //System.out.println("len = " + len); return new ReturnVal(len/dist(xb, yb, xc, yc) - 1, len); } public static double iterate(double a1, double a3, double x1, double y1, double x2, double y2, double x3, double y3) { ReturnVal ret = ratio(a1, x1, y1, x2, y2, x3, y3); double r1 = ret.d1; double length = ret.d2; ret = ratio(a3, x1, y1, x2, y2, x3, y3); double r3 = ret.d1; length = ret.d2; while (Math.abs(a1-a3) > 0.000000001) { double a = (a1+a3)/2.0; ret = ratio(a, x1, y1, x2, y2, x3, y3); double r = ret.d1; length = ret.d2; if (r*r1 > 0) { a1 = a; r1 = r; } else { a3 = a; r3 = r; } } return length; } public static boolean between(double a, double b, double c) { if (Math.abs(a-c) <= 0.0001 || Math.abs(b-c) <= 0.0001) return true; if (Math.abs(a-c) <= 0.0002 || Math.abs(b-c) <= 0.0002) System.out.println("BOUNDARY PROB: between: Math.abs(a-c) = " + Math.abs(a-c) + ", Math.abs(b-c) = " + Math.abs(b-c)); if (a < c && c < b) return true; return (b < c && c < a); } public static int onSegment(double x0, double y0, double x1, double y1, double x, double y) { if (Math.abs((x1-x0)*y - (y1-y0)*x - x1*y0 + x0*y1) > 0.0001) return 0; // not ont line if (Math.abs((x1-x0)*y - (y1-y0)*x - x1*y0 + x0*y1) > 0.00009) System.out.println("BOUNDARY PROB: onSegment check = " + Math.abs((x1-x0)*y - (y1-y0)*x - x1*y0 + x0*y1)); if (between(x0, x1, x) && between(y0, y1, y)) return 1; else return 0; // not ont segment } public static boolean ok(double x0, double y0, double x1, double y1, double x2, double y2, double x3, double y3) { // check for one point on each segment int count, count0, count1, count2, count3, val; val = onSegment(xa, ya, xb, yb, x0, y0); count = val; count0 = val; val = onSegment(xa, ya, xb, yb, x1, y1); count += val; count1 = val; val = onSegment(xa, ya, xb, yb, x2, y2); count += val; count2 = val; val = onSegment(xa, ya, xb, yb, x3, y3); count += val; count3 = val; if (count != 1) return false; val = onSegment(xb, yb, xc, yc, x0, y0); count = val; count0 += val; val = onSegment(xb, yb, xc, yc, x1, y1); count += val; count1 += val; val = onSegment(xb, yb, xc, yc, x2, y2); count += val; count2 += val; val = onSegment(xb, yb, xc, yc, x3, y3); count += val; count3 += val; if (count != 1) return false; val = onSegment(xc, yc, xd, yd, x0, y0); count = val; count0 += val; val = onSegment(xc, yc, xd, yd, x1, y1); count += val; count1 += val; val = onSegment(xc, yc, xd, yd, x2, y2); count += val; count2 += val; val = onSegment(xc, yc, xd, yd, x3, y3); count += val; count3 += val; if (count != 1) return false; count = 0; count += onSegment(xd, yd, xa, ya, x0, y0); count += onSegment(xd, yd, xa, ya, x1, y1); count += onSegment(xd, yd, xa, ya, x2, y2); count += onSegment(xd, yd, xa, ya, x3, y3); val = onSegment(xd, yd, xa, ya, x0, y0); count = val; count0 += val; val = onSegment(xd, yd, xa, ya, x1, y1); count += val; count1 += val; val = onSegment(xd, yd, xa, ya, x2, y2); count += val; count2 += val; val = onSegment(xd, yd, xa, ya, x3, y3); count += val; count3 += val; if (count != 1) return false; // check one segment for each point return (count0==1) && (count1==1) && (count2==1) && (count3==1); } public static void main(String [] args) { double x0, y0, x1, y1, x2, y2, x3, y3, r; int ncases; ncases = in.nextInt(); for(int icase=1; icase<=ncases; icase++) { System.out.print("Case " + icase + ": "); x0 = in.nextDouble(); y0 = in.nextDouble(); x1 = in.nextDouble(); y1 = in.nextDouble(); x2 = in.nextDouble(); y2 = in.nextDouble(); x3 = in.nextDouble(); y3 = in.nextDouble(); // set x0, y0 to lowest y0, then others in // clockwise order if (y1 0) { System.out.println("no solution"); continue; } // check for multiple solutions, when // diagonals are perpendicular and have // same length if ((x2-x0)*(x3-x1) == -(y2-y0)*(y3-y1) && Math.abs(dist(x0, y0, x2, y2)-dist(x1, y1, x3, y3)) <= 0.0001) { // System.out.println(dist(x0, y0, x2, y2)+10); System.out.printf("%.2f\n", dist(x0, y0, x2, y2)+10); continue; } if ((x2-x0)*(x3-x1) == -(y2-y0)*(y3-y1) && Math.abs(dist(x0, y0, x2, y2)-dist(x1, y1, x3, y3)) <= 0.0002) { System.out.println("BOUNDARY PROB: mult sol check value = " + Math.abs(dist(x0, y0, x2, y2)-dist(x1, y1, x3, y3))); } double length = 0.0, maxlength = 0.0; ReturnVal ret = ratio(0.0, x1, y1, x2, y2, x3, y3); double prevr = ret.d1; length = ret.d2; for(int angle = 1; angle <= 180; angle += 1) { ret = ratio(angle*Math.PI/180.0, x1, y1, x2, y2, x3, y3); r = ret.d1; length = ret.d2; //System.out.println("r = " + r + ", prevr = " + prevr); if (r*prevr <= 0) { length = iterate((angle-1)*Math.PI/180.0, angle*Math.PI/180.0, x1, y1, x2, y2, x3, y3); if (ok(0, 0, x1, y1, x2, y2, x3, y3) && length > maxlength) { maxlength = length; } } prevr = r; } if (maxlength == 0) { System.out.println("no solution"); } else System.out.printf("%.2f\n", maxlength+10); } } } class ReturnVal { public double d1, d2; ReturnVal(double v1, double v2) { d1 = v1; d2 = v2; } }