1include <BOSL2/std.scad>
  2
  3
  4ruler_dimensions = [73,51]; //mm
  5ruler_thickness = 2; //mm
  6ruler_edge_radii = [2,4,6,8]; //mm
  7
  8resolution = 200;
  9padding = 4; //mm
 10spacing = 1; //mm
 11
 12squares_sizes = [1,2,3,4,5,6,8,10,12]; //mm
 13
 14circles_offset = [0,6]; //mm
 15circles_diameters = [1,2,3,4,5,6,8,10,12]; //mm
 16
 17rectangles_sizes = [[0.5,1,3,4,6,8],[0.5,1,2,4,6,8],[0.5,1,2,3,6,8],[0.5,1,2,3,4,6,8],[0.5,1,2,3,4,8]]; //mm
 18rectangles_lengths = [2,3,4,5,6]; //mm
 19
 20polygon_offset = [Sum(rectangles_sizes[0])+len(rectangles_sizes[0])*spacing,0]; //mm
 21polygon_diameters = [[1,2,3,4,5,6,8],[1,2,3,4,6,8]]; //mm
 22polygon_spacings = [0,6]; //mm 6 is from sin(30deg)*(max diameter)/2+(max diameter)/2
 23polygon_sides = [3,6]; //mm
 24
 25half_circle_diameters = [4,6,8,10]; //mm
 26half_circle_thickness = 2; //mm
 27
 28graduations_thickness = 0.5; //mm
 29graduations_depth = 1; //mm
 30graduations_cm_length = 3;
 31graduations_mm_length = 2;
 32
 33
 34text_contents = "OnTake N°1";
 35text_font = "Iosevka Heavy";
 36text_size = 4; //mm
 37text_depth = 1; //mm 
 38text_offset = [36,25];
 39
 40
 41function SubSum(x=0,Index=0)=x[Index]+((Index<=0)?0:SubSum(x=x,Index=Index-1));
 42function Sum(x)=SubSum(x=x,Index=len(x)-1);
 43
 44function partial(list,start,end) = [for (i = [start:end]) list[i]];
 45
 46module rectangles(rectangle_lengths=[],rectangle_width=0){
 47    for (i=[0:len(rectangle_lengths)-1]){
 48    if (i > 0){
 49    j = Sum(partial(rectangle_lengths,0,i-1))+i*spacing;
 50    translate([j,0,0]) cube([rectangle_lengths[i],rectangle_width,ruler_thickness]);
 51    } else {
 52    cube([rectangle_lengths[i],rectangle_width,ruler_thickness]);
 53    }
 54    }
 55}
 56
 57module regular_polygons(polygon_diameters=[],polygon_sides=4){
 58    for (i=[0:len(polygon_diameters)-1]){
 59        translate([(polygon_sides % 2)*polygon_diameters[i]*cos((polygon_sides-2)*90/polygon_sides)/2,(polygon_sides % 2)*polygon_diameters[i]*sin((polygon_sides-2)*90/polygon_sides)/2,0])
 60        translate([(1-polygon_sides % 2)*polygon_diameters[i]/2,(1-polygon_sides % 2)*polygon_diameters[i]/2,0])
 61        if (i > 0){
 62    j = Sum(partial(polygon_diameters,0,i-1))+i*spacing;
 63    translate([j,0,0]) rotate([0,0,90]) cylinder(d=polygon_diameters[i],h=ruler_thickness,$fn=polygon_sides);
 64    } else {
 65     rotate([0,0,90]) cylinder(d=polygon_diameters[i],h=ruler_thickness,$fn=polygon_sides);
 66    }
 67    }
 68}
 69
 70difference(){
 71    prismoid(size1=[ruler_dimensions.x,ruler_dimensions.y],size2=[ruler_dimensions.x,ruler_dimensions.y],h=ruler_thickness,anchor=BOTTOM+LEFT+FRONT,rounding=ruler_edge_radii,$fn=resolution);
 72    translate([padding,padding,0])
 73    for (i=[0:len(squares_sizes)-1]){
 74    if (i > 0){
 75    j = Sum(partial(squares_sizes,0,i-1))+i*spacing;
 76    translate([j,0,0]) cube([squares_sizes[i],squares_sizes[i],ruler_thickness]);
 77    } else {
 78    cube([squares_sizes[i],squares_sizes[i],ruler_thickness]);
 79    }
 80    }
 81    translate([padding+Sum(circles_diameters)+(len(circles_diameters)-1)*spacing+circles_offset.x,padding+max(circles_diameters)+circles_offset.y,0])
 82    scale([-1,-1,1])
 83    regular_polygons(polygon_diameters=circles_diameters,polygon_sides=resolution);
 84    for (i=[0:len(rectangles_lengths)-1]){
 85    translate([padding,ruler_dimensions.y-padding-(Sum(partial(rectangles_lengths,0,i))+i*spacing),0])
 86    rectangles(rectangle_lengths=rectangles_sizes[i],rectangle_width=rectangles_lengths[i]);
 87    }
 88    for (i=[0:len(rectangles_lengths)-1]){
 89    translate([padding,ruler_dimensions.y-padding-(Sum(partial(rectangles_lengths,0,i))+i*spacing),0])
 90    rectangles(rectangle_lengths=rectangles_sizes[i],rectangle_width=rectangles_lengths[i]);
 91    }
 92    for (i=[0:len(rectangles_lengths)-1]){
 93    translate([padding,ruler_dimensions.y-padding-(Sum(partial(rectangles_lengths,0,i))+i*spacing),0])
 94    rectangles(rectangle_lengths=rectangles_sizes[i],rectangle_width=rectangles_lengths[i]);
 95    }
 96    translate([polygon_offset.x,polygon_offset.y,0])
 97    for (i=[0:len(polygon_sides)-1]){
 98    translate([padding,ruler_dimensions.y-padding-(Sum(partial(polygon_spacings,0,i))+i*spacing),0])
 99    scale([1,-1,1])
100    regular_polygons(polygon_diameters=polygon_diameters[i],polygon_sides=polygon_sides[i]);
101    }
102    for (i=[0:len(half_circle_diameters)-1]){
103        if (i>0){
104    translate([ruler_dimensions.x-padding,padding+(Sum(partial(half_circle_diameters,0,i-1))+i*spacing),0])
105    half_circle(diameter=half_circle_diameters[i],thickness=half_circle_thickness);
106        } else {
107        translate([ruler_dimensions.x-padding,padding+i*spacing,0])
108    half_circle(diameter=half_circle_diameters[i],thickness=half_circle_thickness);
109            }
110        }
111    translate([text_offset.x,text_offset.y,ruler_thickness-text_depth]) linear_extrude(text_depth) text(text_contents,size=text_size,font=text_font);
112    for (i=[0:round(ruler_dimensions.x*10)]){
113    translate([i-graduations_thickness/2,0,ruler_thickness-graduations_depth])
114        if (i%10 == 0){
115            cube([graduations_thickness,graduations_cm_length,graduations_depth]);
116        } else {
117            cube([graduations_thickness,graduations_mm_length,graduations_depth]);
118        }
119    }
120}
121
122
123module half_circle(diameter=0,thickness=0){
124    translate([0,diameter/2,0])
125    difference(){
126    cylinder(d=diameter,h=ruler_thickness,$fn=resolution);
127    cylinder(d=diameter-thickness,h=ruler_thickness,$fn=resolution);
128    translate([0,-diameter/2,0]) cube([diameter/2,diameter,ruler_thickness]);
129    }
130}