import java.io.*; import java.util.*; import java.text.*; public class Lebesgue { /* calculates area for simplest cover with slant and checks angles for BBG paper */ private static double Q[]; private static double M[]; static DecimalFormat af = new DecimalFormat("#.############"); static DecimalFormat af1 = new DecimalFormat("#.###"); public static void main(String[] args) { for(double a=0.0; a<2.001; a+=0.1) { double p[][] = cover( a ); double area = polygonArea( p ); area += segmentArea(p[7],p[8]); area += segmentArea(p[9],p[10]); double ang1 = angle(Q,p[8],p[9]); double ang2 = angle(M,p[9],p[8]); System.out.println(af1.format(a)+"\t"+area+"\t"+ang1+"\t"+ang2); } // table of Hansen values areas(); } public static void areas() { double xi = 1.0 - Math.sqrt(3.0)*0.5; for(int i=0; i<7; i++) { double xip = 2*xi*xi/(1 - xi*Math.sqrt(3.0) + Math.sqrt(1.0 - 2.0*Math.sqrt(3.0)*xi - xi*xi)); double b = xi + Math.sqrt(3.0)*0.5*xip; double d = Math.sqrt(xip*xip*0.25 + b*b); double theta = 2.0*Math.asin(d*0.5); double Ai = xi*xip*0.25 - (xminussinx(theta))*0.5; System.out.println(i+" "+xi+" "+Ai); xi = xip; } } public static double xminussinx(double x) { double t = -x; double y = 0.0; double n = 3; while( y+t != y ) { t = -t*x*x/(n*(n-1)); y += t; n += 2; } return y; } public static double[][] cover(double slant) { double hex[][] = hexagon(); double dod[][] = dodecagon(slant); double cov[][] = new double[11][2]; cov[0] = hex[0]; // point F1 cov[1] = dod[1]; // point E2 cov[2] = dod[2]; // point E3 cov[3] = hex[2]; // point D1 cov[4] = dod[5]; // point C2 cov[5] = dod[6]; // point C3 cov[6] = hex[4]; // point B1 // area removed near A1 cov[7] = nearestPoint(hex[4],hex[5],dod[2]); // point on edge B1A1 nearest E3 Q = nearestPoint(hex[2],hex[3],dod[10]); // point Q on edge D1C1 nearest A3 cov[8] = triangulate(dod[2],Q); // point X at distance one from E3 and Q M = midPoint(hex[1],hex[2]); // midpoint of E1D1 cov[9] = triangulate(M,dod[5]); // point Y at distance one from M and C2 cov[10] = nearestPoint(hex[5],hex[0],dod[5]); // point on A1F1 nearest G return cov; } public static double[][] hexagon() { // returns a regular hexagon double hex[][] = new double[6][2]; // six (x,y) points hex[0] = edgePoint(30.0); // first point F1 is on left edge of hexagon // the remaining five points are constructed by rotations of 60 degrees for(int i=1; i<6; i++) { hex[i] = rotate(hex[i-1], 60.0); } return hex; } public static double[][] square() { // returns a square double squ[][] = new double[4][2]; // four (x,y) points squ[0][0] = 0.0; squ[0][1] = 1.0; // the remaining three points are constructed by rotations of 90 degrees for(int i=1; i<4; i++) { squ[i] = rotate(squ[i-1], 90.0); } return squ; } public static double[][] dodecagon(double slant) { // returns a twelve sided polygon formed by cutting off corners from a regular // hexagon with cuts tangent to an incribed curcle of unit diameter at a slanted angle double dod[][] = new double[12][2]; // twelve (x,y) points dod[0] = edgePoint(15.0-slant*0.5); // first point F3 is on left edge of hexagon dod[1] = edgePoint(-15.0-slant*0.5); // second point E2 is also on left edge of hexagon // the remaining ten points are constructed by rotations of 60 degrees for(int i=2; i<12; i++) { dod[i] = rotate(dod[i-2], 60.0); } return dod; } public static double[] edgePoint(double angle) { // a point on the left edge of a hexagon at an angle from the centre // angle in radians double angler = angle*Math.PI/180.0; double e[] = {-0.5, 0.5*Math.tan(angler)}; return e; } public static double[] triangulate( double a[], double b[] ) { // finds a point of distance 1 from a and b double d = dist(a, b); if(d >= 1.0) { System.err.println("points too far apart to trianglulate"); return a; } double dx = (b[0] - a[0])/d; double dy = (b[1] - a[1])/d; double mx = (a[0] + b[0])*0.5; double my = (a[1] + b[1])*0.5; double l = Math.sqrt(1.0-d*d*0.25); double t[] = {mx - dy*l, my + dx*l}; return t; } public static double[] nearestPoint( double a[], double b[], double c[] ) { // find the point on line through a and b, which is nearest to c // a point on the segment is given by a(1-s) + bs for parameter s // diastance from c is (a-b)^2 s^2 - 2(a-b).(a-c) s + (a-c)^2 double ab[] = {a[0]-b[0],a[1]-b[1]}; double ac[] = {a[0]-c[0],a[1]-c[1]}; double A = dot(ab,ab); double B = dot(ab,ac); double C = dot(ac,ac)-1.0; // find minimum of As^2 - 2Bs + C = 0 double s = B/A; double d[] = {a[0]*(1.0-s) + b[0]*s, a[1]*(1.0-s) + b[1]*s}; return d; } public static double[] radialPoint( double a[], double b[], double c[] ) { // find the point on line through a and b, near b which is at distance one from c // a point on the segment is given by a(1-s) + bs for parameter s // diastance squared from c is (a-b)^2 s^2 - 2(a-b).(a-c) s + (a-c)^2 = 1 double ab[] = {a[0]-b[0],a[1]-b[1]}; double ac[] = {a[0]-c[0],a[1]-c[1]}; double A = dot(ab,ab); double B = dot(ab,ac); double C = dot(ac,ac)-1.0; // solve As^2 - 2Bs + C = 0 double s = (B + Math.sqrt(B*B - A*C))/A; double d[] = {a[0]*(1.0-s) + b[0]*s, a[1]*(1.0-s) + b[1]*s}; return d; } public static double[] midPoint( double a[], double b[] ) { double m[] = {0.5*(a[0]+b[0]), 0.5*(a[1]+b[1])}; return m; } public static double[] rotate( double a[], double angle ) { // rotate a point an angle about the origin double angler = angle*Math.PI/180.0; // angle in radians double cos = Math.cos(angler); double sin = Math.sin(angler); double b[] = {cos*a[0] - sin*a[1], sin*a[0] + cos*a[1]}; return b; } public static double polygonArea( double p[][] ) { // compute the area of a polygon int n = p.length; // number of points double area = 0.0; for(int i=0; i