chiark / gitweb /
4e99fe51e9d8b2d65d21cfbc30f57beef77f80d1
[dl-things.git] / th-1068443 / th-1149469 / Sundial_Digital_V1.1_cleansed.scad
1 \r
2 //*************************************************************//\r
3 //   [EN]  ---   DIGITAL SUNDIAL\r
4 //   [FR]  ---   CADRAN SOLAIRE NUMERIQUE\r
5 //*************************************************************//\r
6 //\r
7 //      Author: Mojoptix\r
8 //      website: www.mojoptix.com\r
9 //      Email: julldozer@mojoptix.com\r
10 //      Date: 13 october 2015\r
11 //      License: Creative Commons CC-BY (Attribution)\r
12 //\r
13 //*************************************************************//\r
14 // Optimized by Margu on 24 november 2015\r
15 //*************************************************************//\r
16 //\r
17 //   [EN]   The episode #001 of the video podcast Mojoptix describes this sundial in details:\r
18 //              http://www.mojoptix.com/fr/2015/10/12/ep-001-cadran-solaire-numerique\r
19 //\r
20 \r
21 //\r
22 //   [FR]   L'episode #001 du podcast video mojoptix decrit ce cadran solaire en detail:\r
23 //              http://www.mojoptix.com/fr/2015/10/12/ep-001-cadran-solaire-numerique\r
24 //\r
25 \r
26 //*************************************************************//\r
27 \r
28 \r
29 // Choose what you want to print/display:\r
30 // 1: the gnomon\r
31 // 2: the central connector piece\r
32 // 3: the top part of the lid \r
33 // 4: the bottom part of the lid\r
34 // 10: display everything\r
35 FLAG_PRINT = 1;\r
36 \r
37 FLAG_northern_hemisphere = 1;   // set to 1 for Northen Hemisphere, set to 0 for Southern Hemisphere\r
38 \r
39 FLAG_gnomon_brim = 0;   // Add a brim to the gnomon\r
40 FLAG_bottom_lid_support = 1;    // Add some support structure for the lid teeth\r
41 \r
42 \r
43 \r
44 /* ************************************************************************/\r
45 /* PARAMETERS *************************************************************/\r
46 /*************************************************************************/\r
47 epsilon_thickness = 0.02; // used to ensure openscad is not confused by almost identical surfaces\r
48 \r
49 gnomon_brim_thickness = 0.3;\r
50 gnomon_brim_width = 10;\r
51 gnomon_brim_gap = 0.1;\r
52 \r
53 FLAG_mirror_x_characters = 1;     // set to 0 if viewing directly the characters on the blocks, set to 1 if viewing their reflection of a surface\r
54 \r
55 gnomon_radius = 30; // (change at your own risks !)\r
56 \r
57 pixel_size_x = gnomon_radius*8.0/40.0;\r
58 pixel_size_y = gnomon_radius*1.0/40.0;\r
59 pixel_pitch_x = gnomon_radius*10.0/40.0;\r
60 pixel_pitch_y = gnomon_radius*10.0/40.0;\r
61 \r
62 grid_pixel_depth = 0.1;\r
63 \r
64 nn = 40.0/gnomon_radius;\r
65 \r
66 /* ************************************************************************/\r
67 /* FONT *******************************************************************/\r
68 /* ************************************************************************/\r
69 /* index in the array   0 1 2 3 4 5 6 7 8 9 10 11           12\r
70    Characters:          0 1 2 3 4 5 6 7 8 9 :  {full white} {full dark}\r
71 Note: \r
72         1st coordinate in the array: the index in the array (see above)\r
73         2nd coordinate in the array: the Y (!!) coordinate\r
74         3nd coordinate in the array: the X coordinate   \r
75 */\r
76 font_nb_pixel_x = 4;    // 4 pixels wide\r
77 font_nb_pixel_y = 6;    // 6 pixels high\r
78 \r
79 font_char = [[\r
80                             [0,1,1,0],  //index 0: character "0"\r
81                             [1,0,0,1],\r
82                             [1,0,1,1],\r
83                             [1,1,0,1],\r
84                             [1,0,0,1],\r
85                             [0,1,1,0],\r
86                        ],[\r
87                             [0,1,0,0],  //index 1: character "1"\r
88                             [1,1,0,0],\r
89                             [0,1,0,0],\r
90                             [0,1,0,0],\r
91                             [0,1,0,0],\r
92                             [1,1,1,0],\r
93                        ],[\r
94                             [0,1,1,0],  //index 2: character "2"\r
95                             [1,0,0,1],\r
96                             [0,0,0,1],\r
97                             [0,1,1,0],\r
98                             [1,0,0,0],\r
99                             [1,1,1,1],\r
100                        ],[\r
101                             [0,1,1,0],  //index 3: character "3"\r
102                             [1,0,0,1],\r
103                             [0,0,1,1],\r
104                             [0,0,0,1],\r
105                             [1,0,0,1],\r
106                             [0,1,1,0],\r
107                        ],[\r
108                             [1,0,0,1],  //index 4: character "4"\r
109                             [1,0,0,1],\r
110                             [1,0,0,1],\r
111                             [1,1,1,1],\r
112                             [0,0,0,1],\r
113                             [0,0,0,1],\r
114                        ],[\r
115                             [1,1,1,1],  //index 5: character "5"\r
116                             [1,0,0,0],\r
117                             [1,1,1,0],\r
118                             [0,0,0,1],\r
119                             [0,0,0,1],\r
120                             [1,1,1,0],\r
121                        ],[\r
122                             [0,1,1,1],  //index 6: character "6"\r
123                             [1,0,0,0],\r
124                             [1,1,1,0],\r
125                             [1,0,0,1],\r
126                             [1,0,0,1],\r
127                             [0,1,1,0],\r
128                        ],[\r
129                             [1,1,1,1],  //index 7: character "7"\r
130                             [0,0,0,1],\r
131                             [0,0,0,1],\r
132                             [0,0,1,0],\r
133                             [0,1,0,0],\r
134                             [1,0,0,0],\r
135                        ],[\r
136                             [0,1,1,0],  //index 8: character "8"\r
137                             [1,0,0,1],\r
138                             [0,1,1,0],\r
139                             [1,0,0,1],\r
140                             [1,0,0,1],\r
141                             [0,1,1,0],\r
142                        ],[\r
143                             [0,1,1,0],  //index 9: character "9"\r
144                             [1,0,0,1],\r
145                             [1,0,0,1],\r
146                             [0,1,1,1],\r
147                             [0,0,0,1],\r
148                             [1,1,1,0],\r
149                        ],[\r
150                             [0,0,0,0],  //index 10: character ":"\r
151                             [0,0,0,0],\r
152                             [0,1,0,0],\r
153                             [0,0,0,0],\r
154                             [0,1,0,0],\r
155                             [0,0,0,0],\r
156                        ],[\r
157                             [1,1,1,1],  //index 11: character {full white}\r
158                             [1,1,1,1],\r
159                             [1,1,1,1],\r
160                             [1,1,1,1],\r
161                             [1,1,1,1],\r
162                             [1,1,1,1],\r
163                        ],[\r
164                             [0,0,0,0],  //index 12: character {full dark}\r
165                             [0,0,0,0],\r
166                             [0,0,0,0],\r
167                             [0,0,0,0],\r
168                             [0,0,0,0],\r
169                             [0,0,0,0],\r
170                        ],\r
171 // Added by Margu : we add some "characters" to display the transitions\r
172 // "0"-"1" transition character has pixels lit only if both corresponding digits are lit (boolean And operation)\r
173 // and so on ...\r
174                          [\r
175                             [0,1,0,0],  //index 13: character {"0" to "1" transition}\r
176                             [1,0,0,0],\r
177                             [0,0,0,0],\r
178                             [0,1,0,0],\r
179                             [0,0,0,0],\r
180                             [0,1,1,0],\r
181                        ],[\r
182                             [0,1,0,0],  //index 14: character {"1" to "2" transition}\r
183                             [1,0,0,0],\r
184                             [0,0,0,0],\r
185                             [0,1,0,0],\r
186                             [0,0,0,0],\r
187                             [0,1,1,0],\r
188                        ],[\r
189                             [0,1,1,0],  //index 15: character {"2" to "3" transition}\r
190                             [1,0,0,1],\r
191                             [0,0,0,1],\r
192                             [0,0,0,0],\r
193                             [1,0,0,0],\r
194                             [0,1,1,0],\r
195                        ],[\r
196                             [0,0,0,0],  //index 16: character {"3" to "4" transition}\r
197                             [1,0,0,1],\r
198                             [0,0,0,1],\r
199                             [0,0,0,1],\r
200                             [0,0,0,1],\r
201                             [0,0,0,0],\r
202                        ],[\r
203                             [1,0,0,1],  //index 17: character {"4" to "5" transition}\r
204                             [1,0,0,0],\r
205                             [1,0,0,0],\r
206                             [0,0,0,1],\r
207                             [0,0,0,1],\r
208                             [0,0,0,0],\r
209                        ],[\r
210                             [0,1,1,1],  //index 18: character {"5" to "6" transition}\r
211                             [1,0,0,0],\r
212                             [1,1,1,0],\r
213                             [0,0,0,1],\r
214                             [0,0,0,1],\r
215                             [0,1,1,0],\r
216                        ],[\r
217                             [0,1,1,1],  //index 19: character {"6" to "7" transition}\r
218                             [0,0,0,0],\r
219                             [0,0,0,0],\r
220                             [0,0,0,0],\r
221                             [0,0,0,0],\r
222                             [0,0,0,0],\r
223                        ],[\r
224                             [1,1,1,1],  //index 20: character {"7" to "8" transition}\r
225                             [0,0,0,1],  // not used, so wrong values !!!\r
226                             [0,0,0,1],\r
227                             [0,0,1,0],\r
228                             [0,1,0,0],\r
229                             [1,0,0,0],\r
230                        ],[\r
231                             [0,1,1,0],  //index 20: character {"8" to "9" transition}\r
232                             [1,0,0,1],  // not used, so wrong values !!!\r
233                             [0,1,1,0],\r
234                             [1,0,0,1],\r
235                             [1,0,0,1],\r
236                             [0,1,1,0],\r
237                        ],[\r
238                             [0,1,1,0],  //index 22: character {"9" to "0" transition}\r
239                             [1,0,0,1],\r
240                             [1,0,0,1],\r
241                             [0,1,0,1],\r
242                             [0,0,0,1],\r
243                             [0,1,1,0],\r
244                        ],[  \r
245                             [0,1,1,0],  //index 23: character {"0" to "2" transition}\r
246                             [1,0,0,1],\r
247                             [0,0,0,1],\r
248                             [0,1,0,0],\r
249                             [1,0,0,0],\r
250                             [0,1,1,0],\r
251                        ],[\r
252                             [0,0,0,0],  //index 24: character {"2" to "4" transition}\r
253                             [1,0,0,1],\r
254                             [0,0,0,1],\r
255                             [0,1,1,0],\r
256                             [0,0,0,0],\r
257                             [0,0,0,1],\r
258                        ],[\r
259                             [0,0,0,0],  //index 25: character {"4" to "0" transition}\r
260                             [1,0,0,1],\r
261                             [1,0,0,1],\r
262                             [1,1,0,1],\r
263                             [0,0,0,1],\r
264                             [0,0,0,0],\r
265                        ]\r
266                       ];\r
267 \r
268 \r
269 /* ************************************************************************/\r
270 /* MODULES ****************************************************************/\r
271 /* ************************************************************************/\r
272 \r
273 /* ************************************************************************/\r
274 module extrude_pixel(direction_angle_x,direction_angle_y, pixel_wall_angle_x, pixel_wall_angle_y) {\r
275 /* Extrude a pixel in a given direction.\r
276    input: \r
277         direction_angle_x: extrusion angle (from the normal to the pixel) in the x direction\r
278         direction_angle_y: extrusion angle (from the normal to the pixel) in the y direction\r
279    Return a (positive) solid that can then be substracted from another solid \r
280    (Origin at the center of the base pixel)\r
281 */\r
282     // compute geometry\r
283     top_pixel_location_z = 2*gnomon_radius;     // ie: somewhere outside the gnomon\r
284 //    top_pixel_location_x = top_pixel_location_z * tan(direction_angle_x);\r
285 //    top_pixel_location_y = top_pixel_location_z * tan(direction_angle_y); \r
286     top_pixel_size_x = pixel_size_x +2*top_pixel_location_z*tan(pixel_wall_angle_x);    // account for the non_vertical pixel walls\r
287     top_pixel_size_y = pixel_size_y +2*top_pixel_location_z*tan(pixel_wall_angle_y);\r
288     // build (positive) geometry: extrude vertically then rotate\r
289   union() {  rotate([direction_angle_y,direction_angle_x,0])     // rotate the whole extrusion in the chosen direction\r
290         hull(){\r
291             rotate([-direction_angle_y,-direction_angle_x,0])  // derotate the base pixel (to keep it flat at the bottom)\r
292                 cube([pixel_size_x,pixel_size_y,epsilon_thickness], center=true);\r
293             translate([0,0,top_pixel_location_z])\r
294                 cube([top_pixel_size_x, top_pixel_size_y,epsilon_thickness], center=true);\r
295         }\r
296     }\r
297 }\r
298 \r
299 \r
300 /* ************************************************************************/\r
301 module extrude_character(font_index, direction_angle_x, direction_angle_y, pixel_wall_angle_x, pixel_wall_angle_y) {\r
302 /* Extrude a (pixelated) character in a given direction:\r
303    input: \r
304         font_index: the index of the character in the font array\r
305         direction_angle_x: extrusion angle (from the normal to the pixel) in the x direction\r
306         direction_angle_y: extrusion angle (from the normal to the pixel) in the y direction\r
307    Return a (positive) solid that can then be substracted from another solid \r
308    (Origin at the center of the base character)\r
309 */\r
310     for (tx=[0:(font_nb_pixel_x-1)]){\r
311             for (ty=[0:(font_nb_pixel_y-1)]){ \r
312                 if(FLAG_mirror_x_characters==0) { // Note: y is the 2nd coordinate, x is the 3rd (see definition of the Font)\r
313                     if(font_char[font_index][ty][tx]==1) { \r
314                             translate([(tx-(font_nb_pixel_x-1)/2)*pixel_pitch_x, (ty-(font_nb_pixel_y-1)/2)*pixel_pitch_y,0]){\r
315                                     extrude_pixel(direction_angle_x,direction_angle_y, pixel_wall_angle_x, pixel_wall_angle_y);\r
316                             }\r
317                     }\r
318                 }\r
319                 else {  // mirror the characters across x\r
320                     if(font_char[font_index][ty][font_nb_pixel_x-1-tx]==1) {  \r
321                             translate([(tx-(font_nb_pixel_x-1)/2)*pixel_pitch_x, (ty-(font_nb_pixel_y-1)/2)*pixel_pitch_y,0]){\r
322                                     extrude_pixel(direction_angle_x,direction_angle_y, pixel_wall_angle_x, pixel_wall_angle_y);\r
323                             }\r
324                     }\r
325                 }\r
326                     \r
327     }}\r
328 }\r
329 \r
330 \r
331 /* ************************************************************************/\r
332 module build_create_pixel_grid(pixel_depth, ID_column_OFF=[]) {\r
333 /* Create a grid where each intersection row/column is a potential pixel\r
334    Input: \r
335         pixel_depth: the depth of the pixel grid\r
336         ID_column_OFF: list all the columns that should be left OFF (eg not built), exemple: [0,1]\r
337    Return a (positive) solid that can then be substracted from another solid \r
338    (Origin at the center of the base character)\r
339 */\r
340     if (len(ID_column_OFF)<font_nb_pixel_x) {\r
341         intersection(){\r
342             cube([(font_nb_pixel_x+1)*pixel_pitch_x,(font_nb_pixel_y)*pixel_pitch_y,pixel_depth*3], center=true);  // the column imprint only goes from the bottom to the top row\r
343             // Draw the columns\r
344             union(){\r
345                 for (tx=[0:(font_nb_pixel_x-1)]){\r
346                     FLAG_draw_this_column = len( search(tx, ID_column_OFF) ) ==  0;\r
347                     if (FLAG_draw_this_column ){\r
348                         translate([(tx-(font_nb_pixel_x-1)/2)*pixel_pitch_x, 0,pixel_depth/2])\r
349     //                        cube([pixel_size_x,gnomon_radius*3,pixel_depth+epsilon_thickness], center=true);\r
350                             cube([0.1,gnomon_radius*3,pixel_depth], center=true);                    \r
351                     }\r
352                 }\r
353             }\r
354         }\r
355     }\r
356         //Draw the rows\r
357         union(){\r
358             for (ty=[0:(font_nb_pixel_y-1)]){ \r
359                 translate([0, (ty-(font_nb_pixel_y-1)/2)*pixel_pitch_y,pixel_depth/2])\r
360 //                    cube([gnomon_radius*30,1.5*pixel_size_y,pixel_depth+epsilon_thickness], center=true);\r
361                     cube([gnomon_radius*30,0.1,pixel_depth], center=true);\r
362             }\r
363         }\r
364 }    \r
365 \r
366 /* ************************************************************************/\r
367 module build_block(gnomon_thickness, char_list, char_angle_x, char_angle_y, pixel_wall_angle_x, pixel_wall_angle_y) {\r
368 /* Build a block with a set of characters */\r
369     difference(){\r
370         // Build The gnomon shape\r
371             intersection(){\r
372                 translate([0,0,gnomon_radius/2])\r
373                         cube([gnomon_thickness,2*gnomon_radius,gnomon_radius], center=true);\r
374                 translate([0,0,0])\r
375                         rotate([90,0,90]) cylinder(r=gnomon_radius, h=gnomon_thickness, center=true, $fn=100);\r
376             }\r
377     \r
378         // Carve the light guides for each number\r
379         for (ti = [0:(len(char_list)-1)]){\r
380             extrude_character(char_list[ti],char_angle_x[ti],char_angle_y[ti], pixel_wall_angle_x, pixel_wall_angle_y);\r
381         }\r
382     }\r
383     // Add a brim\r
384     if (FLAG_gnomon_brim == 1) {\r
385 #        color("green"){\r
386             difference(){\r
387                 cube([gnomon_thickness, gnomon_radius*2+gnomon_brim_width*2, gnomon_brim_thickness],center=true);\r
388                 cube([10*gnomon_thickness, gnomon_radius*2+gnomon_brim_gap*2, 10*gnomon_brim_thickness],center=true);\r
389             }\r
390         }}\r
391 }\r
392 \r
393 /* ************************************************************************/\r
394 module build_spacer_block(gnomon_thickness) {\r
395 /* Build a spacer block*/\r
396     color("red"){\r
397      difference(){   \r
398         // The gnomon shape\r
399             intersection(){\r
400                 translate([0,0,gnomon_radius/2])\r
401                         cube([gnomon_thickness+epsilon_thickness,2*gnomon_radius,gnomon_radius], center=true);\r
402                 translate([0,0,0])\r
403                         rotate([90,0,90]) cylinder(r=gnomon_radius, h=gnomon_thickness+epsilon_thickness, center=true, $fn=100);\r
404             }\r
405         // The pixel grid\r
406         build_create_pixel_grid(grid_pixel_depth, ID_column_OFF=[0,1,2,3,4]);\r
407     }\r
408     }\r
409     // Add a brim\r
410     if (FLAG_gnomon_brim == 1) {\r
411 #        color("green"){\r
412             difference(){\r
413                 cube([gnomon_thickness, gnomon_radius*2+gnomon_brim_width*2, gnomon_brim_thickness],center=true);\r
414                 cube([10*gnomon_thickness, gnomon_radius*2+gnomon_brim_gap*2, 10*gnomon_brim_thickness],center=true);\r
415             }\r
416         }}    \r
417 \r
418 \r
419 }\r
420 \r
421 /* ************************************************************************/\r
422 module build_round_top_block() {\r
423     gnomon_thickness = gnomon_radius;\r
424 /* Build a round top block*/\r
425     color("green"){\r
426         intersection(){\r
427             translate([0,0,gnomon_radius/2])\r
428                     cube([gnomon_thickness,2*gnomon_radius,gnomon_radius], center=true);\r
429             translate([gnomon_radius/2,0,0])\r
430                     scale([0.3,1,1]) sphere(r=gnomon_radius, center=true, $fn=100);\r
431         }\r
432     }\r
433 \r
434     // Add a brim\r
435     if (FLAG_gnomon_brim == 1) {\r
436 #        color("green"){\r
437             difference(){\r
438                 translate([0.35*gnomon_thickness-gnomon_brim_width/2,0,0]) cube([0.3*gnomon_thickness+gnomon_brim_width, gnomon_radius*2+gnomon_brim_width*2, gnomon_brim_thickness],center=true);\r
439                 translate([gnomon_radius/2,0,0])\r
440                     minkowski(){\r
441                         scale([0.3,1,1]) sphere(r=gnomon_radius, center=true, $fn=100);\r
442                         sphere(r=gnomon_brim_gap, center=true, $fn=10);\r
443                     }\r
444             }\r
445         }}    \r
446     \r
447 }\r
448 /* ************************************************************************/\r
449 module Block_hours_tens() {\r
450     color("blue"){\r
451     gnomon_thickness = gnomon_radius*45.0/40.0; //45;\r
452     pixel_wall_angle_x = 0;         // [degrees] angle of the walls along the x direction\r
453     pixel_wall_angle_y = 6.0;         // [degrees] angle of the walls along the y direction    \r
454 \r
455 /*    char_angle_x = [0,0,0,0,0,0,0];\r
456     char_angle_y = [-45,-30,-15,0,15,30,45];\r
457     char_list = [1,1,1,1,1,1,1]; \r
458 */\r
459 // Modified by Margu\r
460 // We add intermediate angles (-37, -22, -15, -8, 8, 15, 22, 37) to display transition characters thus removing not needed material.\r
461 //  Because there is no need to make a dark transition for pixels which remain lit\r
462     char_angle_x = [0,0,0,0,0,0,0,0,0,0,0,0,0];\r
463     char_angle_y = [ -45,-37,  -30,  -22,  -15,  -8,  0,  8,  15,  22,  30,  38,  45];\r
464     char_list = [1,1,1,1,1,1,1,1,1,1,1,1,1];     \r
465       difference(){\r
466         build_block(gnomon_thickness, char_list, char_angle_x, char_angle_y, pixel_wall_angle_x, pixel_wall_angle_y);\r
467         build_create_pixel_grid(grid_pixel_depth, ID_column_OFF=[]);\r
468     }\r
469 }}\r
470 \r
471 /* ************************************************************************/\r
472 module Block_hours_units() {\r
473     color("blue"){\r
474     gnomon_thickness = gnomon_radius*45.0/40.0; //45;\r
475     pixel_wall_angle_x = 0;         // [degrees] angle of the walls along the x direction\r
476     pixel_wall_angle_y = 6.0;         // [degrees] angle of the walls along the y direction    \r
477 \r
478 // Modified by Margu\r
479 // We add intermediate angles (-37, -22, -15, -8, 8, 15, 22, 37) to display transition characters thus removing not needed material.\r
480 //  Because there is no need to make a dark transition for pixels which remain lit\r
481     char_angle_x = [0,0,0,0,0,0,0,0,0,0,0,0,0];\r
482     char_angle_y = [-45,-38,-30, -22, -15,-8,0,8,15,22,30,38,45];\r
483     char_list = [0,13,1,14,2,15,3,16,4,17,5,18,6];\r
484 \r
485     difference(){\r
486         build_block(gnomon_thickness, char_list, char_angle_x, char_angle_y, pixel_wall_angle_x, pixel_wall_angle_y);\r
487         build_create_pixel_grid(grid_pixel_depth, ID_column_OFF=[]);\r
488     }    \r
489 }}\r
490 \r
491 /* ************************************************************************/\r
492 module Block_minutes_tens() {\r
493     color("blue"){\r
494     gnomon_thickness = gnomon_radius*45.0/40.0; //45;\r
495     pixel_wall_angle_x = 0;         // [degrees] angle of the walls along the x direction\r
496     pixel_wall_angle_y = 1.0;         // [degrees] angle of the walls along the y direction \r
497         \r
498 // Modified by Margu\r
499 // We add intermediate angles (-48, -43, -38, -22, -15, -8, 8, 15, 22, 38, 43, 48) to display transition characters thus removing not needed material.\r
500 //  Because there is no need to make a dark transition for pixels which remain lit    \r
501     char_angle_x = [0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0,  0];\r
502     char_angle_y = [-50,-48,-45,-43,-40,-38, -35,-33,-30,-28,-25,-23, -20,-18,-15,-13,-10,-8, -5,-3,0,3,5,8, 10,13,15,18,20,23, 25,28,30,33,35,38, 40];\r
503     char_list = [0,23,2,24,4,25,0,23,2,24,4,25,0,23,2,24,4,25,0,23,2,24,4,25,0,23,2,24,4,25,0,23,2,24,4,25, 0];\r
504 \r
505     difference(){\r
506         build_block(gnomon_thickness, char_list, char_angle_x, char_angle_y, pixel_wall_angle_x, pixel_wall_angle_y);\r
507         build_create_pixel_grid(grid_pixel_depth, ID_column_OFF=[]);\r
508     }    \r
509 }}\r
510 \r
511 /* ************************************************************************/\r
512 module Block_minutes_units() {\r
513     color("blue"){\r
514     gnomon_thickness = gnomon_radius*45.0/40.0; //45;\r
515     pixel_wall_angle_x = 0;         // [degrees] angle of the walls along the x direction\r
516     pixel_wall_angle_y = 8.0;         // [degrees] angle of the walls along the y direction    \r
517 \r
518 \r
519     char_angle_x = [0,0,0,0,0,0,0];\r
520     char_angle_y = [-45,-30,-15,0,15,30,45];\r
521     char_list = [0,0,0,0,0,0,0];\r
522     \r
523         difference(){\r
524         build_block(gnomon_thickness, char_list, char_angle_x, char_angle_y, pixel_wall_angle_x, pixel_wall_angle_y);\r
525         build_create_pixel_grid(grid_pixel_depth, ID_column_OFF=[]);\r
526     }    \r
527 }}\r
528 \r
529 /* ************************************************************************/\r
530 module Block_semicolon() {\r
531     color("blue"){\r
532     gnomon_thickness = gnomon_radius*25.0/40.0; //25;\r
533     pixel_wall_angle_x = 0;         // [degrees] angle of the walls along the x direction\r
534     pixel_wall_angle_y = 8.0;         // [degrees] angle of the walls along the y direction    \r
535 \r
536 \r
537     char_angle_x = [0,0,0,0,0,0,0];\r
538     char_angle_y = [-45,-30,-15,0,15,30,45];\r
539     char_list = [10,10,10,10,10,10,10];\r
540 \r
541     difference(){\r
542         build_block(gnomon_thickness, char_list, char_angle_x, char_angle_y, pixel_wall_angle_x, pixel_wall_angle_y);\r
543         build_create_pixel_grid(grid_pixel_depth, ID_column_OFF=[3]);\r
544     }    \r
545 }}\r
546 \r
547 /* ************************************************************************/\r
548 module Block_rotating_base_upper() {\r
549 /* Build the upper part of the rotating base */\r
550     gnomon_thickness = gnomon_radius;\r
551     Screw_hole_diameter = 6.5;\r
552     Nut_width_blocking = 8.8+1.3;\r
553     Nut_width_non_blocking = 11.2;\r
554     Washer_Diameter = 11.9;\r
555     Washer_thickness = 1.3;\r
556     color("green"){\r
557     difference(){\r
558         // Build The gnomon shape\r
559         union(){\r
560             intersection(){\r
561                 translate([0,0,gnomon_radius/2])\r
562                         cube([2/3*gnomon_thickness,2*gnomon_radius,gnomon_radius], center=true);\r
563                 translate([0,0,0])\r
564                         rotate([90,0,90]) cylinder(r=gnomon_radius, h=gnomon_thickness, center=true, $fn=100);\r
565             }\r
566         }\r
567         // The negative space for the screw, nut and washer\r
568         translate([0,0,Washer_Diameter/2+3])\r
569             rotate([90,0,90]) cylinder(r=Screw_hole_diameter/2, h=2*gnomon_thickness, center=true, $fn=100);\r
570         translate([gnomon_thickness*(0.45-1/3),0,Washer_Diameter/2+3])\r
571             rotate([90,0,90]) cylinder(r=Washer_Diameter/2+4, h=Washer_thickness+2, center=true, $fn=100);\r
572         translate([gnomon_thickness*(0.45-1/3),0,0])\r
573              cube([Washer_thickness+2,Washer_Diameter+8, 2*(Washer_Diameter/2+3)], center=true);\r
574         translate([gnomon_thickness*(0.4-2/3),0,0])\r
575              cube([gnomon_thickness*0.8+1,Nut_width_blocking, 2*(Washer_Diameter/2+3)], center=true);\r
576         intersection(){        \r
577             translate([gnomon_thickness*(0.45-2/3),0,Washer_Diameter/2+3])\r
578                 cube([gnomon_thickness, 2*(Nut_width_non_blocking/2+1), 2*(Nut_width_non_blocking/2+1)],center=true); \r
579             translate([gnomon_thickness*(0.45-2/3),0,Washer_Diameter/2+3-epsilon_thickness])\r
580                 cube([gnomon_thickness*2/3+1,Nut_width_blocking, gnomon_radius], center=true);            \r
581         }\r
582             translate([gnomon_thickness*(0.45-2/3),0,0])\r
583                 cube([gnomon_thickness*2/3+1,Nut_width_blocking+1, 1], center=true);\r
584     }\r
585     }\r
586     \r
587     // Add a brim\r
588     if (FLAG_gnomon_brim == 1) {\r
589 #        color("green"){\r
590             difference(){\r
591                 translate([gnomon_brim_width/2,0,0,]) cube([2/3*gnomon_thickness+gnomon_brim_width, gnomon_radius*2+gnomon_brim_width*2, gnomon_brim_thickness],center=true);\r
592                translate([-2/3*gnomon_thickness/2,0,0,]) cube([2*2/3*gnomon_thickness+gnomon_brim_gap*2, gnomon_radius*2+gnomon_brim_gap*2, 10*gnomon_brim_thickness],center=true);\r
593             }\r
594         }}\r
595 }\r
596 \r
597 /* ************************************************************************/\r
598 module Block_rotating_base_mid() {\r
599 /* Build the mid part of the rotating base */\r
600     gnomon_thickness = 1.3*gnomon_radius;\r
601     Screw_hole_diameter = 6.5;\r
602     Nut_width_blocking = 8.8;\r
603     Nut_width_non_blocking = 11.2;\r
604     Washer_Diameter = 11.9;\r
605     Washer_thickness = 1.3;\r
606     color("red"){\r
607 \r
608     // The connection to the gnomon\r
609     difference(){\r
610         union(){\r
611             // The gnomon shape\r
612             intersection(){\r
613                 translate([0,0,gnomon_radius/2])\r
614                         cube([gnomon_thickness,2*gnomon_radius,gnomon_radius], center=true);\r
615                 translate([0,0,0])\r
616                         rotate([90,0,90]) cylinder(r=gnomon_radius, h=gnomon_thickness, center=true, $fn=100);\r
617             }\r
618             // The connection to the base\r
619             intersection(){\r
620                 translate([gnomon_thickness*(1-(1-0.7)/2.0),0,gnomon_radius/2])\r
621                     cube([gnomon_thickness*0.7, 0.8*gnomon_radius, gnomon_radius], center=true);\r
622                 translate([gnomon_thickness/2.0+gnomon_radius,0,0])\r
623                     rotate([90,0,90]) cylinder(r=gnomon_radius, h=2*gnomon_thickness, center=true, $fn=100);\r
624                 \r
625             }            \r
626         }\r
627         // The negative space for the screw and washer\r
628         translate([0,0,Washer_Diameter/2+3])\r
629             rotate([90,0,90]) cylinder(r=Screw_hole_diameter/2, h=20*gnomon_thickness, center=true, $fn=100);\r
630         translate([gnomon_thickness*(0.5-4/8),0,Washer_Diameter/2+2.5])\r
631             cube([gnomon_thickness*(6/8), 2*(Washer_Diameter/2+2), 2*(Washer_Diameter/2+3)],center=true);\r
632         translate([gnomon_thickness*(0.5-4/8),0,Washer_Diameter+4])        \r
633             rotate([90,0,0]) scale([0.37,0.2,1]) cylinder(r=gnomon_thickness, h=2*(Washer_Diameter/2+2), center=true, $fn=100);          \r
634         translate([gnomon_thickness,0,gnomon_radius/2.0])\r
635             rotate([90,0,0]) cylinder(r=Screw_hole_diameter/2, h=2*gnomon_thickness, center=true, $fn=100);            \r
636 /*        // Small cut to reduce warping issues\r
637         translate([gnomon_thickness,0,gnomon_radius])\r
638             cube([1,2*gnomon_thickness,gnomon_radius], center=true);\r
639 */\r
640         }        \r
641     }\r
642     \r
643     \r
644 \r
645 }\r
646 \r
647 \r
648 /* ************************************************************************/\r
649 module Block_jar_lid_top() {\r
650     gnomon_thickness = 2*gnomon_radius;\r
651     Screw_hole_diameter = 6.5;\r
652     Nut_width_blocking = 8.8;\r
653     Nut_width_non_blocking = 11.2;\r
654     Washer_Diameter = 11.9;\r
655     Washer_thickness = 1.3;\r
656     Base_Wall_thickness = 3.0;\r
657     box_width = gnomon_radius*4;\r
658     box_length = gnomon_radius*4;\r
659     box_height = gnomon_radius*2;\r
660     Base_diameter = 70;\r
661     Connector_x_offset = 10+5;\r
662 \r
663     // The Connector\r
664     difference(){\r
665         //General shape\r
666         hull(){\r
667             translate([0,0,gnomon_radius/2.0])\r
668                 rotate([90,0,0]) cylinder(r=gnomon_radius/2.0*1.2, h=gnomon_thickness*0.65, center=true, $fn=100);\r
669             translate([Connector_x_offset,0,-0.75*gnomon_radius/2.0-Base_Wall_thickness/2]) rotate([0,0,0]) cylinder(r=Base_diameter/2 ,h=Base_Wall_thickness, center=true, $fn=100);\r
670         }\r
671         // Space to rotate the gnomon\r
672         translate([0,0,gnomon_radius/2.0]) \r
673             rotate([90,0,0]) cylinder(r=gnomon_radius*0.7, h=0.8*gnomon_radius+2*epsilon_thickness, center=true, $fn=100);\r
674         translate([-gnomon_thickness*10,0,9.94*gnomon_radius])\r
675             cube([gnomon_thickness*20, 0.8*gnomon_radius+2*epsilon_thickness, 20*gnomon_radius], center=true);\r
676         translate([-gnomon_thickness*10,0,-0.06*gnomon_radius])\r
677             rotate([0,90,0]) scale([0.3,1,1]) cylinder(r=0.4*gnomon_radius, h=gnomon_thickness*20, center=true, $fn=100);\r
678         translate([gnomon_thickness*10,0,0.65*gnomon_radius])\r
679             rotate([0,90,0]) scale([1.5,1,1]) cylinder(r=0.4*gnomon_radius, h=gnomon_thickness*20, center=true, $fn=100);        \r
680         // Hole for the top screw\r
681         translate([0,0,gnomon_radius/2.0])\r
682             rotate([90,0,0]) cylinder(r=Screw_hole_diameter/2, h=2*gnomon_thickness, center=true, $fn=100);\r
683         // Flat surface for the top screw & washer/nut\r
684         translate([0,-gnomon_thickness*(1+0.5/2+0.25/2-0.01)+2,gnomon_radius/2.0])\r
685             rotate([90,0,0]) cylinder(r=1.5*Washer_Diameter/2, h=2*gnomon_thickness, center=true, $fn=100);\r
686         translate([0,gnomon_thickness*(1+0.5/2+0.25/2-0.01)-2,gnomon_radius/2.0])\r
687             rotate([90,0,0]) cylinder(r=1.5*Washer_Diameter/2, h=2*gnomon_thickness, center=true, $fn=100);\r
688         // Holes for the two bottom screws\r
689         translate([Connector_x_offset+1.1*Base_diameter/6,0,gnomon_radius/2.0])\r
690             rotate([0,0,0]) cylinder(r=Screw_hole_diameter/2, h=2*gnomon_thickness, center=true, $fn=100);\r
691         translate([Connector_x_offset-1.1*Base_diameter/6,0,gnomon_radius/2.0])\r
692             rotate([0,0,0]) cylinder(r=Screw_hole_diameter/2, h=2*gnomon_thickness, center=true, $fn=100);        \r
693        // Flat surfaces for the two bottom screws\r
694         translate([Connector_x_offset+1.1*Base_diameter/6,0,gnomon_radius*1.63-Base_Wall_thickness+Base_Wall_thickness])\r
695             rotate([0,0,0]) cylinder(r=1.5*Washer_Diameter/2, h=2*gnomon_thickness, center=true, $fn=100);\r
696         translate([Connector_x_offset-1.1*Base_diameter/6,0,gnomon_radius*1.63-Base_Wall_thickness+Base_Wall_thickness])\r
697             rotate([0,0,0]) cylinder(r=1.5*Washer_Diameter/2, h=2*gnomon_thickness, center=true, $fn=100);\r
698         }\r
699 \r
700 }\r
701 \r
702 \r
703 /* ************************************************************************/\r
704 module Block_jar_lid_bottom_old() {\r
705     //Dimensions for a Bonne Maman jam jar\r
706     Lid_diameter_outside = 88;\r
707     Lid_diameter_inside = 82;\r
708     Lid_thickness = 3.0;\r
709     Lid_skirt_height_under_teeth = 0;\r
710     Lid_skirt_full_height = 15 +Lid_thickness +Lid_skirt_height_under_teeth;\r
711     Teeth_thickness = 2.0;\r
712     Teeth_depth = 1.7;\r
713     Teeth_length = 10.0;\r
714     Connector_x_offset = 10;\r
715     Base_diameter = 70;\r
716     gnomon_thickness = 2*gnomon_radius;\r
717     Screw_hole_diameter = 6.5;\r
718     \r
719     translate([Connector_x_offset, 0,0]) {\r
720         //The skirt of the lid\r
721         difference(){\r
722             translate([0,0,-Lid_skirt_full_height/2]) rotate([0,0,0]) cylinder(r=Lid_diameter_outside/2 ,h=Lid_skirt_full_height, center=true, $fn=100);\r
723             translate([0,0,-Lid_skirt_full_height/2]) rotate([0,0,0]) cylinder(r=Lid_diameter_inside/2 ,h=2*Lid_skirt_full_height, center=true, $fn=100);\r
724         }\r
725         //The Teeth\r
726         translate([0,0,-Lid_skirt_full_height+Teeth_thickness/2+Lid_skirt_height_under_teeth]) intersection(){\r
727             difference(){\r
728                 rotate([0,0,0]) cylinder(r=(0.5*Lid_diameter_inside+0.5*Lid_diameter_outside)/2 ,h=Teeth_thickness, center=true, $fn=100);\r
729                 rotate([0,0,0]) cylinder(r=Lid_diameter_inside/2-Teeth_depth ,h=2*Teeth_thickness, center=true, $fn=100);\r
730             }\r
731             union(){\r
732                 rotate([0,0,0]) cube([2*Lid_diameter_outside,Teeth_length,2*Teeth_thickness], center=true);\r
733                 rotate([0,0,60]) cube([2*Lid_diameter_outside,Teeth_length,2*Teeth_thickness], center=true);\r
734                 rotate([0,0,120]) cube([2*Lid_diameter_outside,Teeth_length,2*Teeth_thickness], center=true);        \r
735             }\r
736         }\r
737         //The flat part of the lid\r
738         difference(){\r
739         translate([0,0,-Lid_thickness/2]) rotate([0,0,0]) cylinder(r=Lid_diameter_outside/2 ,h=Lid_thickness, center=true, $fn=100);\r
740         // Holes for the two screws\r
741         translate([1.1*Base_diameter/6,0,gnomon_radius/2.0])\r
742             rotate([0,0,0]) cylinder(r=Screw_hole_diameter/2, h=2*gnomon_thickness, center=true, $fn=100);\r
743         translate([-1.1*Base_diameter/6,0,gnomon_radius/2.0])\r
744             rotate([0,0,0]) cylinder(r=Screw_hole_diameter/2, h=2*gnomon_thickness, center=true, $fn=100);      \r
745         }\r
746 \r
747     }\r
748 }\r
749 \r
750 /* ************************************************************************/\r
751 module Block_jar_lid_bottom() {\r
752     //Dimensions for a Bonne Maman jam jar\r
753     Lid_diameter_outside = 88;\r
754     Lid_diameter_inside = 82;\r
755     Lid_thickness = 3.0;\r
756     Lid_skirt_height_under_teeth = 0;\r
757     Lid_skirt_full_height = 15 +Lid_thickness +Lid_skirt_height_under_teeth;\r
758     Teeth_thickness = 2.0;\r
759     Teeth_depth = 1.7;\r
760     Teeth_length = 10.0;\r
761     Connector_x_offset = 10;\r
762     Base_diameter = 70;\r
763     gnomon_thickness = 2*gnomon_radius;\r
764     Screw_hole_diameter = 6.5;\r
765     Logo_font_size = 6;\r
766     Logo_negative_depth = 2;\r
767     Logo_positive_depth = 2;\r
768     Logo_inside_cylinder_depth = 0;\r
769     Support_horizontal_gap = 0.2;\r
770     Support_vertical_gap = 0.1; // should 1 layer thickness\r
771     Support_thickness = 1.2;\r
772     Support_height_above = 5; // for an easier removal\r
773     \r
774     translate([Connector_x_offset, 0,0]) {\r
775         //The skirt of the lid\r
776         difference(){\r
777             union(){\r
778                 //Outside shape for the skirt\r
779                 hull(){\r
780                     translate([0,0,-Lid_skirt_full_height+1/2]) rotate([0,0,0]) cylinder(r=Lid_diameter_outside/2*1.035 ,h=1, center=true, $fn=12); // factor 1.035 because it has 12 faces: Lid_diameter_outside/2 is the minimum distance, instead of the maximum distance\r
781                     translate([0,0,-Lid_thickness-1/2]) rotate([0,0,0]) cylinder(r=Lid_diameter_outside/2 ,h=1, center=true, $fn=100);\r
782                 }\r
783             // Add the MOJOPTIX Logo (positive shape)\r
784             rotate([0,0,90]) translate([0,-Lid_diameter_outside/2+Logo_negative_depth+20,-Lid_skirt_full_height/2]) rotate([90,0,0]) linear_extrude(20) text("MOJOPTIX",size=Logo_font_size,halign="center", valign="center",font="Comic Sans MS:style=Bold"); \r
785             rotate([0,0,-30]) translate([0,-Lid_diameter_outside/2+Logo_negative_depth+20,-Lid_skirt_full_height/2]) rotate([90,0,0]) linear_extrude(20) text("MOJOPTIX",size=Logo_font_size,halign="center", valign="center",font="Comic Sans MS:style=Bold");\r
786             rotate([0,0,210]) translate([0,-Lid_diameter_outside/2+Logo_negative_depth+20,-Lid_skirt_full_height/2]) rotate([90,0,0]) linear_extrude(20) text("MOJOPTIX",size=Logo_font_size,halign="center", valign="center",font="Comic Sans MS:style=Bold");                \r
787             }\r
788             //Trim the Positive shape of the MOJOPTIX Logo with a tube\r
789             difference(){\r
790                 cylinder(r=10*Lid_diameter_outside/2+Logo_positive_depth,h=1000,center=true, $fn=100);                \r
791                 cylinder(r=Lid_diameter_outside/2+Logo_positive_depth,h=1000,center=true, $fn=100);\r
792             }            \r
793             // Add the MOJOPTIX Logo (negative shape)\r
794 /*            difference(){\r
795                 union(){*/\r
796                     rotate([0,0,90]) translate([0,-Lid_diameter_outside/2+Logo_negative_depth,-Lid_skirt_full_height/2]) rotate([90,0,0]) linear_extrude(100) text("MOJOPTIX",size=Logo_font_size,halign="center", valign="center",font="Comic Sans MS:style=Bold");\r
797                     rotate([0,0,-30]) translate([0,-Lid_diameter_outside/2+Logo_negative_depth,-Lid_skirt_full_height/2]) rotate([90,0,0]) linear_extrude(100) text("MOJOPTIX",size=Logo_font_size,halign="center", valign="center",font="Comic Sans MS:style=Bold");\r
798                     rotate([0,0,210]) translate([0,-Lid_diameter_outside/2+Logo_negative_depth,-Lid_skirt_full_height/2]) rotate([90,0,0]) linear_extrude(100) text("MOJOPTIX",size=Logo_font_size,halign="center", valign="center",font="Comic Sans MS:style=Bold");\r
799 /*                }\r
800                 //Trim the Negative shape of the MOJOPTIX Logo with a cylinder\r
801                 cylinder(r=Lid_diameter_outside/2-Logo_inside_cylinder_depth,h=1000,center=true, $fn=100);\r
802             }*/\r
803             //Inside shape for the skirt\r
804             translate([0,0,-Lid_skirt_full_height/2]) rotate([0,0,0]) cylinder(r=Lid_diameter_inside/2 ,h=2*Lid_skirt_full_height, center=true, $fn=100);\r
805         }            \r
806         //The Teeth\r
807         translate([0,0,-Lid_skirt_full_height+Teeth_thickness/2+Lid_skirt_height_under_teeth]) intersection(){\r
808             difference(){\r
809                 rotate([0,0,0]) cylinder(r=(0.5*Lid_diameter_inside+0.5*Lid_diameter_outside)/2 ,h=Teeth_thickness, center=true, $fn=100);\r
810                 rotate([0,0,0]) cylinder(r=Lid_diameter_inside/2-Teeth_depth ,h=2*Teeth_thickness, center=true, $fn=100);\r
811             }\r
812             union(){\r
813                 rotate([0,0,0]) cube([2*Lid_diameter_outside,Teeth_length,2*Teeth_thickness], center=true);\r
814                 rotate([0,0,60]) cube([2*Lid_diameter_outside,Teeth_length,2*Teeth_thickness], center=true);\r
815                 rotate([0,0,120]) cube([2*Lid_diameter_outside,Teeth_length,2*Teeth_thickness], center=true);        \r
816             }\r
817         }\r
818 \r
819         //The flat part of the lid\r
820         difference(){\r
821             translate([0,0,-Lid_thickness]) rotate_extrude(convexity = 10, $fn = 100) {\r
822                 square([Lid_diameter_outside/2-Lid_thickness,Lid_thickness], center=false);\r
823                 intersection(){\r
824                     translate([Lid_diameter_outside/2-Lid_thickness+epsilon_thickness,0,-Lid_thickness]) scale([1,1]) circle(r=Lid_thickness, center=true);\r
825                     square([Lid_diameter_outside/2+epsilon_thickness,Lid_thickness+epsilon_thickness], center=false);\r
826                 }\r
827             }\r
828         // Holes for the two screws\r
829         translate([1.1*Base_diameter/6,0,gnomon_radius/2.0])\r
830             rotate([0,0,0]) cylinder(r=Screw_hole_diameter/2, h=2*gnomon_thickness, center=true, $fn=100);\r
831         translate([-1.1*Base_diameter/6,0,gnomon_radius/2.0])\r
832             rotate([0,0,0]) cylinder(r=Screw_hole_diameter/2, h=2*gnomon_thickness, center=true, $fn=100);      \r
833         // A single line on the 1st layer to have a custom scarring (instead of some scarring at a random place)\r
834         translate([0,0,0]) cube([100,0.1,0.5], center=true);\r
835         }\r
836 \r
837 \r
838         // Support structure for the teeth\r
839         if (FLAG_bottom_lid_support == 1) {\r
840             color("red") difference(){\r
841                 translate([0,0,-Lid_skirt_full_height/2-Lid_thickness/2-Support_vertical_gap-Support_height_above/2]) rotate([0,0,0]) cylinder(r=Lid_diameter_inside/2-Teeth_depth-Support_horizontal_gap,h=Lid_skirt_full_height-Lid_thickness+Support_height_above, center=true, $fn=100);\r
842                 translate([0,0,-Lid_skirt_full_height/2-Lid_thickness]) rotate([0,0,0]) cylinder(r=Lid_diameter_inside/2-Teeth_depth-Support_horizontal_gap-Support_thickness ,h=2*Lid_skirt_full_height+2*Support_height_above, center=true, $fn=100);\r
843                 cube([2,1000,1000],center=true);\r
844             }\r
845             \r
846         }\r
847     }\r
848 \r
849 \r
850     \r
851 \r
852 \r
853 }\r
854 \r
855 \r
856 /* ************************************************************************/\r
857 /* ************************************************************************/\r
858 module Gnomon_Digits(nn) {\r
859 /*    translate([112.5/nn,0,0]) Block_hours_tens(); \r
860     translate([85/nn,0,0]) build_spacer_block(10/nn); \r
861     translate([57.5/nn,0,0])  Block_hours_units();\r
862     translate([30/nn,0,0]) build_spacer_block(10/nn);\r
863 \r
864     translate([12.5/nn,0,0]) Block_semicolon();\r
865 \r
866     translate([-22.5/nn,0,0])    Block_minutes_tens();\r
867     translate([-50/nn,0,0]) build_spacer_block(10/nn);\r
868     translate([-77.5/nn,0,0])   Block_minutes_units();    \r
869 */\r
870     translate([112.5/nn,0,0]) Block_hours_tens(); \r
871     translate([89/nn,0,0]) build_spacer_block(2/nn); \r
872     translate([65.5/nn,0,0])  Block_hours_units();\r
873     translate([38/nn,0,0]) build_spacer_block(10/nn);\r
874 \r
875     translate([20.5/nn,0,0]) Block_semicolon();\r
876 \r
877     translate([-14.5/nn,0,0])    Block_minutes_tens();\r
878     translate([-42/nn,0,0]) build_spacer_block(10/nn);\r
879     translate([-69.5/nn,0,0])   Block_minutes_units();    \r
880      \r
881 }\r
882 \r
883 /* ************************************************************************/\r
884 module Gnomon_Rounded_Top(nn) {\r
885     translate([-120/nn,0,0]) build_round_top_block();   \r
886 }\r
887 /* ************************************************************************/\r
888 module Gnomon_Bottom_Connector(nn) {\r
889     translate([155/nn,0,0]) Block_rotating_base_upper();\r
890 }\r
891 /* ************************************************************************/\r
892 module Central_Connector(nn) {\r
893     color("red") translate([205/nn,0,0]) Block_rotating_base_mid();\r
894 }\r
895 /* ************************************************************************/\r
896 module Jar_Lid_Top(nn) {\r
897     translate([265/nn,0,0]) Block_jar_lid_top();\r
898 }\r
899 /* ************************************************************************/\r
900 module Jar_Lid_Bottom(nn) {\r
901 //    color("blue"){\r
902         translate([265/nn,0,-24/nn]) Block_jar_lid_bottom();\r
903 //    }\r
904 }\r
905 \r
906 \r
907 /* ************************************************************************/\r
908 module Gnomon(nn) {\r
909     color("green"){\r
910     if (FLAG_northern_hemisphere==1){\r
911         translate([5,0,0])    Gnomon_Digits(nn);\r
912         translate([11,0,0])   Gnomon_Rounded_Top(nn);\r
913         translate([0,0,0])    Gnomon_Bottom_Connector(nn);        \r
914     }\r
915     else {\r
916         translate([37.25,0,0]) rotate([0,0,180]) Gnomon_Digits(nn);\r
917         translate([11,0,0])   Gnomon_Rounded_Top(nn);\r
918         translate([0,0,0])    Gnomon_Bottom_Connector(nn); \r
919     }\r
920 }}\r
921 \r
922 /* ************************************************************************/\r
923 /* MAIN *******************************************************************/\r
924 /* ************************************************************************/\r
925 \r
926 // Choose what you want to print/display:\r
927 // 1: the gnomon\r
928 if (FLAG_PRINT == 1) Gnomon(nn);\r
929 // 2: the central connector piece\r
930 if (FLAG_PRINT == 2) translate([-8,0,0]) Central_Connector(nn);\r
931 // 3: the top part of the lid\r
932 if (FLAG_PRINT == 3) translate([-14,0,0]) Jar_Lid_Top(nn);\r
933 // 4: the bottom part of the lid\r
934 if (FLAG_PRINT == 4) translate([-9,0,3.75]) rotate([180,0,0]) Jar_Lid_Bottom(nn);\r
935 // 10: everything\r
936 if (FLAG_PRINT == 10) \r
937     {\r
938     Gnomon(nn);\r
939     translate([-8,0,0]) Central_Connector(nn);\r
940     translate([-14,0,0]) Jar_Lid_Top(nn);\r
941     translate([-9,0,3.75]) Jar_Lid_Bottom(nn); \r
942     }