13f059491758f1b2dea05a859bc9cd3b5f3e337a
[3dmodels/seg_digit.git] / seg_digit.scad
1 /*
2  * seg_digit.scad : 7 segment and 16 segment digit generation library
3  * 
4  * Author : Jose Ignacio Croce Busquets <jose@crossforests.com>
5  *
6  * Date : 15-FEB-2014
7  *
8  * Usage
9  * The module contains the following public methods
10  *
11  * segment_a(size, on = true)
12  * segment_b(size, on = true)
13  * segment_c(size, on = true)
14  * segment_d(size, on = true)
15  * segment_e(size, on = true)
16  * segment_f(size, on = true)
17  * segment_g(size, on = true) Write the corresponding segment from a 7
18  *                            segment display
19  *                            size = segment size
20  *                            on = on-relief/low-relief flag
21  *
22  * segment_dp(digit_size, on = true)
23  *                            Write the decimal point for a 7 segment display
24  *                            digit_size = whole digit size
25  *                            on = on-relief/low-relief flag
26  */
27
28 /* Segment length based on digit height */
29 function segment_length(height) = height / 2;
30
31 /* digit height based on segment length */
32 function digit_height(seglen) = 2 * seglen;
33
34 /* Segment radius based on segment length */
35 function segment_radius(seglen) = seglen / 10;
36
37 /* Position (horiz) for next digit based on digit length */
38 function digit_spacing(height) = segment_length(height)
39                                + 6 * segment_radius(segment_length(height));
40
41 /* Draws A segment (top)
42  *  size segment size
43  *  on   on-relief/low-relief flag
44  */
45 module segment_a(size, on = true)
46 {
47  translate(v = [ 0, digit_height(size), 0 ])
48    segment(size, on = on);
49 }
50
51 /* Draws A1 segment (top)
52  *  size segment size
53  *  on   on-relief/low-relief flag
54  */
55 module segment_a1(size, on = true)
56 {
57  translate(v = [ 0, digit_height(size), 0 ])
58    segment(size /2 , r = segment_radius(size), on = on);
59 }
60
61 /* Draws A2 segment (top)
62  *  size segment size
63  *  on   on-relief/low-relief flag
64  */
65 module segment_a2(size, on = true)
66 {
67  translate(v = [ size / 2, digit_height(size), 0 ])
68    segment(size /2 , r = segment_radius(size), on = on);
69 }
70
71 /* Draws B segment (right top)
72  *  size segment size
73  *  on   on-relief/low-relief flag
74  */
75 module segment_b(size, on = true)
76 {
77  translate(v = [ 0, size, 0 ])
78    segment_c(size, on = on);
79 }
80
81 /* Draws C segment (right bottom)
82  *  size segment size
83  *  on   on-relief/low-relief flag
84  */
85 module segment_c(size, on = true)
86 {
87  translate(v = [ size, size, 0 ])
88    rotate(a = [ 0, 0, 270 ])
89      segment(size, on = on);
90 }
91
92 /* Draws D segment (bottom)
93  *  size segment size
94  *  on   on-relief/low-relief flag
95  */
96 module segment_d(size, on = true)
97 {
98  segment(size, on = on);
99 }
100
101 /* Draws D1 segment (top)
102  *  size segment size
103  *  on   on-relief/low-relief flag
104  */
105 module segment_d1(size, on = true)
106 {
107  segment(size /2 , r = segment_radius(size), on = on);
108 }
109
110 /* Draws D2 segment (top)
111  *  size segment size
112  *  on   on-relief/low-relief flag
113  */
114 module segment_d2(size, on = true)
115 {
116  translate(v = [ size / 2, 0, 0 ])
117    segment(size /2 , r = segment_radius(size), on = on);
118 }
119
120 /* Draws E segment (left bottom)
121  *  size segment size
122  *  on   on-relief/low-relief flag
123  */
124 module segment_e(size, on = true)
125 {
126  rotate(a = [ 0, 0, 90 ])
127    segment(size, on = on);
128 }
129
130 /* Draws F segment (left top)
131  *  size segment size
132  *  on   on-relief/low-relief flag
133  */
134 module segment_f(size, on = true)
135 {
136  translate(v = [ 0, size, 0 ])
137    segment_e(size, on = on);
138 }
139
140 /* Draws G segment (middle)
141  *  size segment size
142  *  on   on-relief/low-relief flag
143  */
144 module segment_g(size, on = true)
145 {
146  translate(v = [ 0, size, 0 ])
147    segment_d(size, on = on);
148 }
149
150 /* Draws G1 segment (top)
151  *  size segment size
152  *  on   on-relief/low-relief flag
153  */
154 module segment_g1(size, on = true)
155 {
156  translate(v = [ 0, size, 0 ])
157    segment(size /2 , r = segment_radius(size), on = on);
158 }
159
160 /* Draws G2 segment (top)
161  *  size segment size
162  *  on   on-relief/low-relief flag
163  */
164 module segment_g2(size, on = true)
165 {
166  translate(v = [ size / 2, size, 0 ])
167    segment(size /2 , r = segment_radius(size), on = on);
168 }
169
170 /* Draws H segment (upper left diagonal)
171  *  size segment size
172  *  on   on-relief/low-relief flag
173  */
174 module segment_h(size, on = true)
175 {
176  translate(v = [ size / 2, size, 0 ])
177    mirror([ 1, 0, 0 ])
178      diag_segment(size, on = on);
179 }
180
181 /* Draws I segment (middle top)
182  *  size segment size
183  *  on   on-relief/low-relief flag
184  */
185 module segment_i(size, on = true)
186 {
187  translate(v = [ -size / 2, 0, 0 ])
188    segment_b(size, on = on);
189 }
190
191 /* Draws J segment (upper right diagonal)
192  *  size segment size
193  *  on   on-relief/low-relief flag
194  */
195 module segment_j(size, on = true)
196 {
197  translate(v = [ size / 2, size, 0 ])
198    diag_segment(size, on = on);
199 }
200
201 /* Draws K segment (lower right diagonal)
202  *  size segment size
203  *  on   on-relief/low-relief flag
204  */
205 module segment_k(size, on = true)
206 {
207  translate(v = [ size, 0, 0 ])
208    mirror([ 1, 0, 0 ])
209      diag_segment(size, on = on);
210 }
211
212 /* Draws L segment (middle bottom)
213  *  size segment size
214  *  on   on-relief/low-relief flag
215  */
216 module segment_l(size, on = true)
217 {
218  translate(v = [ -size / 2, 0, 0 ])
219    segment_c(size, on = on);
220 }
221
222 /* Draws M segment (lower left diagonal)
223  *  size segment size
224  *  on   on-relief/low-relief flag
225  */
226 module segment_m(size, on = true)
227 {
228  diag_segment(size, on = on);
229 }
230
231 /*
232  * Place the decimal point at the end of the character
233  * size segment size
234  * on on-relief/low-relief flag
235  */
236 module segment_p(size, on = true)
237 {
238  radius = segment_radius(size);
239  translate(v = [ size + radius, 0, 0 ])
240    decimal_point(size, on = on);
241 }
242
243 //---------------------------------------------------------------------------
244 // End of public modules - Just jump to the examples
245 //---------------------------------------------------------------------------
246
247 /*
248  * Draws a decimal point
249  * size segment size
250  * on on-relief/low-relief flag
251  */
252 module decimal_point(size, on = true)
253 {
254  radius = segment_radius(size);
255  if (on)
256  {
257   translate(v = [ radius, 0, 0 ])
258     polyhedron(points = [ [ -radius, -radius,      0 ]
259                         , [ -radius,  radius,      0 ]
260                         , [  radius,  radius,      0 ]
261                         , [  radius, -radius,      0 ]
262                         , [       0,       0, radius ]
263                         ]
264           , triangles = [ [ 0, 1, 4 ]
265                         , [ 1, 2, 4 ]
266                         , [ 2, 3, 4 ]
267                         , [ 0, 4, 3 ]
268                         , [ 0, 3, 1 ]
269                         , [ 1, 3, 2 ]
270                         ]);
271  } else {
272   translate(v = [ radius, 0, 0 ])
273   {
274    polyhedron(points = [ [ -radius, -radius,       0 ]
275                        , [ -radius,  radius,       0 ]
276                        , [  radius,  radius,       0 ]
277                        , [  radius, -radius,       0 ]
278                        , [       0,       0, -radius ]
279                        ]
280          , triangles = [ [ 0, 4, 1 ]
281                        , [ 1, 4, 2 ]
282                        , [ 2, 4, 3 ]
283                        , [ 0, 3, 4 ]
284                        , [ 0, 1, 3 ]
285                        , [ 1, 2, 3 ]
286                        ]);
287    translate(v = [ 0, 0, radius / 2 ])
288      cube(size= [ 2 * radius, 2 * radius, radius ], center = true);
289   }
290  }
291 }
292
293 /* Draws a single segment
294  *  size segment size
295  *  r    segment radius (default = segment_radius(h))
296  *  on   on-relief/low-relief flag
297  */
298 module segment(size, r = 0, on = true)
299 {
300  radius = (r == 0) ? segment_radius(size) : r;
301  length = (size > 2 * radius) ? size - 2 * radius : 0;
302  if (on)
303  {
304   polyhedron(points = [ [                   0,       0,      0 ]
305                       , [     radius         ,  radius,      0 ]
306                       , [     radius + length,  radius,      0 ]
307                       , [ 2 * radius + length,       0,      0 ]
308                       , [     radius + length, -radius,      0 ]
309                       , [     radius         , -radius,      0 ]
310                       , [     radius         ,       0, radius ]
311                       , [     radius + length,       0, radius ]
312                       ]
313         , triangles = [ [ 0, 1, 6 ]
314                       , [ 1, 2, 6 ]
315                       , [ 2, 7, 6 ]
316                       , [ 2, 3, 7 ]
317                       , [ 3, 4, 7 ]
318                       , [ 4, 5, 7 ]
319                       , [ 5, 6, 7 ]
320                       , [ 0, 6, 5 ]
321                       , [ 0, 5, 1 ]
322                       , [ 1, 5, 4 ]
323                       , [ 1, 4, 2 ]
324                       , [ 2, 4, 3 ]
325                       ]);
326  } else {
327   polyhedron(points = [ [                   0,       0,       0 ]
328                       , [     radius         ,  radius,       0 ]
329                       , [     radius + length,  radius,       0 ]
330                       , [ 2 * radius + length,       0,       0 ]
331                       , [     radius + length, -radius,       0 ]
332                       , [     radius         , -radius,       0 ]
333                       , [     radius         ,       0, -radius ]
334                       , [     radius + length,       0, -radius ]
335                       ]
336         , triangles = [ [ 0, 6, 1 ]
337                       , [ 1, 6, 2 ]
338                       , [ 2, 6, 7 ]
339                       , [ 2, 7, 3 ]
340                       , [ 3, 7, 4 ]
341                       , [ 4, 7, 5 ]
342                       , [ 5, 7, 6 ]
343                       , [ 0, 5, 6 ]
344                       , [ 0, 1, 5 ]
345                       , [ 1, 4, 5 ]
346                       , [ 1, 2, 4 ]
347                       , [ 2, 3, 4 ]
348                       ]);
349   linear_extrude(height = radius)
350     polygon(points = [ [ 0                  ,        0]
351                      , [     radius         ,  radius ]
352                      , [     radius + length,  radius ]
353                      , [ 2 * radius + length,       0 ]
354                      , [     radius + length, -radius ]
355                      , [     radius         , -radius ]
356                      ]
357            , paths = [ [ 0, 1, 2, 3, 4, 5 ] ]);
358  }
359 }
360
361 /* Draws a diagonal segment
362  *  size segment size
363  *  r    segment radius (default = segment_radius(h))
364  *  on   on-relief/low-relief flag
365  */
366 module diag_segment(size, r = 0, on = true)
367 {
368  radius = (r == 0) ? segment_radius(size) : r;
369  length = (size > 2 * radius) ? size - 2 * radius : 0;
370  if (on)
371  {
372   polyhedron(points = [
373                     [                   radius,               radius,      0 ]
374                   , [                   radius,        2.41 * radius,      0 ]
375                   , [ size / 2 - 2.41 * radius, size -        radius,      0 ]
376                   , [ size / 2 -        radius, size -        radius,      0 ]
377                   , [ size / 2 -        radius, size - 2.41 * radius,      0 ]
378                   , [            2.41 * radius,               radius,      0 ]
379                   , [            1.70 * radius,        1.70 * radius, radius ]
380                   , [ size / 2 - 1.70 * radius, size - 1.70 * radius, radius ]
381                       ]
382         , triangles = [ [ 0, 1, 6 ]
383                       , [ 1, 2, 6 ]
384                       , [ 2, 7, 6 ]
385                       , [ 2, 3, 7 ]
386                       , [ 3, 4, 7 ]
387                       , [ 4, 5, 7 ]
388                       , [ 5, 6, 7 ]
389                       , [ 0, 6, 5 ]
390                       , [ 0, 5, 1 ]
391                       , [ 1, 5, 4 ]
392                       , [ 1, 4, 2 ]
393                       , [ 2, 4, 3 ]
394                       ]);
395  } else {
396   polyhedron(points = [
397                    [                   radius,               radius,       0 ]
398                  , [                   radius,        2.41 * radius,       0 ]
399                  , [ size / 2 - 2.41 * radius, size -        radius,       0 ]
400                  , [ size / 2 -        radius, size -        radius,       0 ]
401                  , [ size / 2 -        radius, size - 2.41 * radius,       0 ]
402                  , [            2.41 * radius,               radius,       0 ]
403                  , [            1.70 * radius,        1.70 * radius, -radius ]
404                  , [ size / 2 - 1.70 * radius, size - 1.70 * radius, -radius ]
405                       ]
406         , triangles = [ [ 0, 1, 6 ]
407                       , [ 1, 2, 6 ]
408                       , [ 2, 7, 6 ]
409                       , [ 2, 3, 7 ]
410                       , [ 3, 4, 7 ]
411                       , [ 4, 5, 7 ]
412                       , [ 5, 6, 7 ]
413                       , [ 0, 6, 5 ]
414                       , [ 0, 5, 1 ]
415                       , [ 1, 5, 4 ]
416                       , [ 1, 4, 2 ]
417                       , [ 2, 4, 3 ]
418                       ]);
419   linear_extrude(height = radius)
420     polygon(points = [ [                   radius,               radius ]
421                      , [                   radius,        2.41 * radius ]
422                      , [ size / 2 - 2.41 * radius, size -        radius ]
423                      , [ size / 2 -        radius, size -        radius ]
424                      , [ size / 2 -        radius, size - 2.41 * radius ]
425                      , [            2.41 * radius,               radius ]
426                      ]
427            , paths = [ [ 0, 1, 2, 3, 4, 5 ] ]);
428  }
429 }
430
431 //---------------------------------------------------------------------------
432 // Examples
433 //---------------------------------------------------------------------------
434
435 ex_seglen = 100;        // segment length for all examples
436
437 // Base for on-relief examples
438 translate(v = [ 0
439               , -2 * digit_height(ex_seglen)
440               , -2 * segment_radius(digit_height(ex_seglen)) ])
441   cube(size = [ 2 * digit_spacing(digit_height(ex_seglen))
442               , 4 * digit_height(ex_seglen)
443               , 2 * segment_radius(digit_height(ex_seglen))
444               ]);
445
446 // On relief examples
447
448 // 7 segment on-relief example
449 translate(v = [ digit_spacing(digit_height(ex_seglen)) / 2
450               , digit_height(ex_seglen) / 2
451               , 0 ])
452 {
453  segment_a(ex_seglen);
454  segment_b(ex_seglen);
455  segment_c(ex_seglen);
456  segment_d(ex_seglen);
457  segment_e(ex_seglen);
458  segment_f(ex_seglen);
459  segment_g(ex_seglen);
460  segment_p(ex_seglen);
461 }
462
463 // 16 segment on-relief example
464 translate(v = [ digit_spacing(digit_height(ex_seglen)) / 2
465               , -1.5 * digit_height(ex_seglen)
466               , 0 ])
467 {
468  segment_a1(ex_seglen);
469  segment_a2(ex_seglen);
470  segment_b(ex_seglen);
471  segment_c(ex_seglen);
472  segment_d1(ex_seglen);
473  segment_d2(ex_seglen);
474  segment_e(ex_seglen);
475  segment_f(ex_seglen);
476  segment_g1(ex_seglen);
477  segment_g2(ex_seglen);
478  segment_h(ex_seglen);
479  segment_i(ex_seglen);
480  segment_j(ex_seglen);
481  segment_k(ex_seglen);
482  segment_l(ex_seglen);
483  segment_m(ex_seglen);
484  segment_p(ex_seglen);
485 }
486
487 // Low relief examples
488 // Low relief effect is performed by substracting from the base
489 translate(v = [ 2 * digit_spacing(digit_height(ex_seglen)), 0, 0 ])
490   difference()
491   {
492     // Base for low-relief examples
493    translate(v = [ 0
494                  , -2 * digit_height(ex_seglen)
495                  , -2 * segment_radius(digit_height(ex_seglen)) ])
496       cube(size = [ 2 * digit_spacing(digit_height(ex_seglen))
497                   , 4 * digit_height(ex_seglen)
498                   , 2 * segment_radius(digit_height(ex_seglen))
499                   ]);
500
501     // 7 segment low-relief example
502     translate(v = [ digit_spacing(digit_height(ex_seglen)) / 2
503                   , digit_height(ex_seglen) / 2
504                   , 0 ])
505     {
506      segment_a(ex_seglen, on = false);
507      segment_b(ex_seglen, on = false);
508      segment_c(ex_seglen, on = false);
509      segment_d(ex_seglen, on = false);
510      segment_e(ex_seglen, on = false);
511      segment_f(ex_seglen, on = false);
512      segment_g(ex_seglen, on = false);
513      segment_p(ex_seglen, on = false);
514     }
515
516     // 16 segment on-relief example
517     translate(v = [ digit_spacing(digit_height(ex_seglen)) / 2
518                   , -1.5 * digit_height(ex_seglen)
519                   , 0 ])
520     {
521      segment_a1(ex_seglen, on = false);
522      segment_a2(ex_seglen, on = false);
523      segment_b(ex_seglen, on = false);
524      segment_c(ex_seglen, on = false);
525      segment_d1(ex_seglen, on = false);
526      segment_d2(ex_seglen, on = false);
527      segment_e(ex_seglen, on = false);
528      segment_f(ex_seglen, on = false);
529      segment_g1(ex_seglen, on = false);
530      segment_g2(ex_seglen, on = false);
531      segment_h(ex_seglen, on = false);
532      segment_i(ex_seglen, on = false);
533      segment_j(ex_seglen, on = false);
534      segment_k(ex_seglen, on = false);
535      segment_l(ex_seglen, on = false);
536      segment_m(ex_seglen, on = false);
537      segment_p(ex_seglen, on = false);
538     }
539
540   }
541
542 /* EOF : seg_digit.scad */