// Jason E. Holt // Works out how many unit squares can fit into a circle with a certain // radius, and outputs SVG graphics of circles that contain more squares // // This code released into the public domain // Compile with gcc -lm // Make sure you have an svg/ directory if you want svg images #include #include #include #define PI 3.14159 double epsilon = 0.000000001; double rsquared; double rsquaredfudge; int inside(double x, double y) { // printf("%f,%f = %f < %f? %d\n", x,y, x*x+y*y, rsquared, // x*x+y*y <= (rsquared+epsilon) ); return x*x+y*y < rsquaredfudge; } // Pack unit squares into circle of radius r, starting at theta // radians to the left of the y axis. If makesvg, output an .svg // graphic of the packing; filename will include, r, theta and // maxsquares (which you presumably computed previously before deciding // to output a graphic of the winning combination) int pack(double r, double theta, int makesvg, int maxsquares) { int squares=0; double x = -sin(theta)*r; double y = sqrt(rsquared-x*x); FILE *f; if(makesvg) { char fn[255]; sprintf(fn, "svg/%.9f-%d-%.9f.svg", r, maxsquares, theta); f = fopen(fn, "w"); fprintf(f, "\n\n"); fprintf(f, "\n"); fprintf(f, "\n"); fprintf(f, "\n", r, r); } while(inside(x,y)) { //printf("theta=%f, (%f,%f) (r=%f)\n", theta, x, y, sqrt(x*x+y*y)); while( ((y > 0.5) && inside(x+1.0, y)) || ((y <= 0.5) && inside(x+1.0, y-1.0)) ) { squares++; if(makesvg) { fprintf(f, "\n"); } x+=1.0; } y-=1.0; x = -sqrt(rsquared - y*y); double bottomx = -sqrt(rsquared - (y-1.0)*(y-1.0)); if(bottomx > x) x = bottomx; } if(makesvg) { fprintf(f, "\n"); fprintf(f, "\n"); fclose(f); } // fprintf(stderr,"Theta=%f: %d squares, r=%f\n", // theta, squares, r); return squares; } main() { double minr=1.0; double r; double maxr=20.00; double theta=0; int lastmaxsquares = 0; for(r=minr; r maxsquares) { fprintf(stderr,"New record: %d squares, theta=%f, r=%f\n", squares, theta, r); maxsquares = squares; besttheta = theta; } } if(maxsquares > lastmaxsquares) { pack(r,besttheta,1, maxsquares); lastmaxsquares = maxsquares; } } }