1patternScale = 40;
  2patternThickness = 5;
  3patternDepth = 5;
  4repeatX = 6;
  5repeatY = 6;
  6
  7
  8$fs = 0.1;
  9
 10module roundedcube(size = [1, 1, 1], center = false, radius = 0.5, apply_to = "all") {
 11	// If single value, convert to [x, y, z] vector
 12	size = (size[0] == undef) ? [size, size, size] : size;
 13
 14	translate_min = radius;
 15	translate_xmax = size[0] - radius;
 16	translate_ymax = size[1] - radius;
 17	translate_zmax = size[2] - radius;
 18
 19	diameter = radius * 2;
 20
 21	obj_translate = (center == false) ?
 22		[0, 0, 0] : [
 23			-(size[0] / 2),
 24			-(size[1] / 2),
 25			-(size[2] / 2)
 26		];
 27
 28	translate(v = obj_translate) {
 29		hull() {
 30			for (translate_x = [translate_min, translate_xmax]) {
 31				x_at = (translate_x == translate_min) ? "min" : "max";
 32				for (translate_y = [translate_min, translate_ymax]) {
 33					y_at = (translate_y == translate_min) ? "min" : "max";
 34					for (translate_z = [translate_min, translate_zmax]) {
 35						z_at = (translate_z == translate_min) ? "min" : "max";
 36
 37						translate(v = [translate_x, translate_y, translate_z])
 38						if (
 39							(apply_to == "all") ||
 40							(apply_to == "xmin" && x_at == "min") || (apply_to == "xmax" && x_at == "max") ||
 41							(apply_to == "ymin" && y_at == "min") || (apply_to == "ymax" && y_at == "max") ||
 42							(apply_to == "zmin" && z_at == "min") || (apply_to == "zmax" && z_at == "max")
 43						) {
 44							sphere(r = radius);
 45						} else {
 46							rotate = 
 47								(apply_to == "xmin" || apply_to == "xmax" || apply_to == "x") ? [0, 90, 0] : (
 48								(apply_to == "ymin" || apply_to == "ymax" || apply_to == "y") ? [90, 90, 0] :
 49								[0, 0, 0]
 50							);
 51							rotate(a = rotate)
 52							cylinder(h = diameter, r = radius, center = true);
 53						}
 54					}
 55				}
 56			}
 57		}
 58	}
 59}
 60
 61module drawLine(a=0,b=0,xStart=0,xEnd=0)
 62{ 
 63    lineLength = sqrt(pow(a*(xEnd-xStart),2)+pow(xEnd-xStart,2))+patternThickness;
 64    translate([xStart,a*xStart+b,0])
 65    rotate([0,0,atan(a)]) translate ([-patternThickness/2,-patternThickness/2,-patternDepth/2]) roundedcube([lineLength,patternThickness,patternDepth], false, patternThickness/2, "z");//cube([lineLength,patternThickness,patternDepth]);  
 66}
 67
 68module drawYLine(xOrig=0,yOrig=0,length=0)
 69{ 
 70    lineLength = length+patternThickness;
 71    translate([xOrig,yOrig,0])
 72    rotate([0,0,90]) translate ([-patternThickness/2,-patternThickness/2,-patternDepth/2]) roundedcube([lineLength,patternThickness,patternDepth], false, patternThickness/2, "z");//cube([lineLength,patternThickness,patternDepth]);  
 73}
 74
 75
 76module asanoha(){
 77
 78    interXT = patternScale/(1+tan(67.5));
 79
 80    drawLine(0,0,0,patternScale);
 81    drawLine(-1,0,0,interXT);
 82    drawLine(tan(67.5),-patternScale,0,interXT);
 83    drawLine(tan(22.5),-patternScale*tan(22.5),interXT,patternScale);
 84    
 85    
 86    interXB = patternScale/(1+tan(22.5));
 87    
 88    drawLine(0,-patternScale,0,patternScale);
 89    drawLine(-1,0,interXB,patternScale);
 90    drawLine(tan(22.5),-patternScale,0,interXB);
 91    drawLine(tan(67.5),-patternScale*tan(67.5),interXB,patternScale);
 92    
 93    
 94    drawLine(1,-patternScale,0,patternScale);
 95    drawYLine(0,-patternScale,patternScale);
 96    drawYLine(patternScale,-patternScale,patternScale);
 97}
 98
 99module movePattern(repeatXN=0,repeatYN=0){
100    translate([patternScale*2*repeatXN,patternScale*2*repeatYN,0]) children();
101}
102
103module fullAsanoha(){
104    asanoha();
105    rotate([0,0,90]) translate([-patternScale,-patternScale,0]) asanoha();
106    rotate([0,0,90]) asanoha();
107    translate([patternScale,patternScale,0]) asanoha();
108}
109
110// Actually start drawing things
111for(repeatXN = [0 : repeatX-1]){
112    for(repeatYN = [0 : repeatY-1]){
113        movePattern(repeatXN,repeatYN) fullAsanoha();
114    }
115}