patternScale = 40; patternThickness = 5; patternDepth = 5; repeatX = 6; repeatY = 6; $fs = 0.1; module roundedcube(size = [1, 1, 1], center = false, radius = 0.5, apply_to = "all") { // If single value, convert to [x, y, z] vector size = (size[0] == undef) ? [size, size, size] : size; translate_min = radius; translate_xmax = size[0] - radius; translate_ymax = size[1] - radius; translate_zmax = size[2] - radius; diameter = radius * 2; obj_translate = (center == false) ? [0, 0, 0] : [ -(size[0] / 2), -(size[1] / 2), -(size[2] / 2) ]; translate(v = obj_translate) { hull() { for (translate_x = [translate_min, translate_xmax]) { x_at = (translate_x == translate_min) ? "min" : "max"; for (translate_y = [translate_min, translate_ymax]) { y_at = (translate_y == translate_min) ? "min" : "max"; for (translate_z = [translate_min, translate_zmax]) { z_at = (translate_z == translate_min) ? "min" : "max"; translate(v = [translate_x, translate_y, translate_z]) if ( (apply_to == "all") || (apply_to == "xmin" && x_at == "min") || (apply_to == "xmax" && x_at == "max") || (apply_to == "ymin" && y_at == "min") || (apply_to == "ymax" && y_at == "max") || (apply_to == "zmin" && z_at == "min") || (apply_to == "zmax" && z_at == "max") ) { sphere(r = radius); } else { rotate = (apply_to == "xmin" || apply_to == "xmax" || apply_to == "x") ? [0, 90, 0] : ( (apply_to == "ymin" || apply_to == "ymax" || apply_to == "y") ? [90, 90, 0] : [0, 0, 0] ); rotate(a = rotate) cylinder(h = diameter, r = radius, center = true); } } } } } } } module drawLine(a=0,b=0,xStart=0,xEnd=0) { lineLength = sqrt(pow(a*(xEnd-xStart),2)+pow(xEnd-xStart,2))+patternThickness; translate([xStart,a*xStart+b,0]) rotate([0,0,atan(a)]) translate ([-patternThickness/2,-patternThickness/2,-patternDepth/2]) roundedcube([lineLength,patternThickness,patternDepth], false, patternThickness/2, "z");//cube([lineLength,patternThickness,patternDepth]); } module drawYLine(xOrig=0,yOrig=0,length=0) { lineLength = length+patternThickness; translate([xOrig,yOrig,0]) rotate([0,0,90]) translate ([-patternThickness/2,-patternThickness/2,-patternDepth/2]) roundedcube([lineLength,patternThickness,patternDepth], false, patternThickness/2, "z");//cube([lineLength,patternThickness,patternDepth]); } module asanoha(){ interXT = patternScale/(1+tan(67.5)); drawLine(0,0,0,patternScale); drawLine(-1,0,0,interXT); drawLine(tan(67.5),-patternScale,0,interXT); drawLine(tan(22.5),-patternScale*tan(22.5),interXT,patternScale); interXB = patternScale/(1+tan(22.5)); drawLine(0,-patternScale,0,patternScale); drawLine(-1,0,interXB,patternScale); drawLine(tan(22.5),-patternScale,0,interXB); drawLine(tan(67.5),-patternScale*tan(67.5),interXB,patternScale); drawLine(1,-patternScale,0,patternScale); drawYLine(0,-patternScale,patternScale); drawYLine(patternScale,-patternScale,patternScale); } module movePattern(repeatXN=0,repeatYN=0){ translate([patternScale*2*repeatXN,patternScale*2*repeatYN,0]) children(); } module fullAsanoha(){ asanoha(); rotate([0,0,90]) translate([-patternScale,-patternScale,0]) asanoha(); rotate([0,0,90]) asanoha(); translate([patternScale,patternScale,0]) asanoha(); } // Actually start drawing things for(repeatXN = [0 : repeatX-1]){ for(repeatYN = [0 : repeatY-1]){ movePattern(repeatXN,repeatYN) fullAsanoha(); } }