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}