X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ijackson/git?a=blobdiff_plain;f=th-1068443%2Fth-1149469%2FSundial_Digital_V1.1_cleansed.scad;fp=th-1068443%2Fth-1149469%2FSundial_Digital_V1.1_cleansed.scad;h=4e99fe51e9d8b2d65d21cfbc30f57beef77f80d1;hb=288116548d8c36bc7f0839415d7246251f57c163;hp=0000000000000000000000000000000000000000;hpb=4c16e5c87a0fa9083c49b4249467843884c46538;p=dl-things.git diff --git a/th-1068443/th-1149469/Sundial_Digital_V1.1_cleansed.scad b/th-1068443/th-1149469/Sundial_Digital_V1.1_cleansed.scad new file mode 100644 index 0000000..4e99fe5 --- /dev/null +++ b/th-1068443/th-1149469/Sundial_Digital_V1.1_cleansed.scad @@ -0,0 +1,942 @@ + +//*************************************************************// +// [EN] --- DIGITAL SUNDIAL +// [FR] --- CADRAN SOLAIRE NUMERIQUE +//*************************************************************// +// +// Author: Mojoptix +// website: www.mojoptix.com +// Email: julldozer@mojoptix.com +// Date: 13 october 2015 +// License: Creative Commons CC-BY (Attribution) +// +//*************************************************************// +// Optimized by Margu on 24 november 2015 +//*************************************************************// +// +// [EN] The episode #001 of the video podcast Mojoptix describes this sundial in details: +// http://www.mojoptix.com/fr/2015/10/12/ep-001-cadran-solaire-numerique +// + +// +// [FR] L'episode #001 du podcast video mojoptix decrit ce cadran solaire en detail: +// http://www.mojoptix.com/fr/2015/10/12/ep-001-cadran-solaire-numerique +// + +//*************************************************************// + + +// Choose what you want to print/display: +// 1: the gnomon +// 2: the central connector piece +// 3: the top part of the lid +// 4: the bottom part of the lid +// 10: display everything +FLAG_PRINT = 1; + +FLAG_northern_hemisphere = 1; // set to 1 for Northen Hemisphere, set to 0 for Southern Hemisphere + +FLAG_gnomon_brim = 0; // Add a brim to the gnomon +FLAG_bottom_lid_support = 1; // Add some support structure for the lid teeth + + + +/* ************************************************************************/ +/* PARAMETERS *************************************************************/ +/*************************************************************************/ +epsilon_thickness = 0.02; // used to ensure openscad is not confused by almost identical surfaces + +gnomon_brim_thickness = 0.3; +gnomon_brim_width = 10; +gnomon_brim_gap = 0.1; + +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 + +gnomon_radius = 30; // (change at your own risks !) + +pixel_size_x = gnomon_radius*8.0/40.0; +pixel_size_y = gnomon_radius*1.0/40.0; +pixel_pitch_x = gnomon_radius*10.0/40.0; +pixel_pitch_y = gnomon_radius*10.0/40.0; + +grid_pixel_depth = 0.1; + +nn = 40.0/gnomon_radius; + +/* ************************************************************************/ +/* FONT *******************************************************************/ +/* ************************************************************************/ +/* index in the array 0 1 2 3 4 5 6 7 8 9 10 11 12 + Characters: 0 1 2 3 4 5 6 7 8 9 : {full white} {full dark} +Note: + 1st coordinate in the array: the index in the array (see above) + 2nd coordinate in the array: the Y (!!) coordinate + 3nd coordinate in the array: the X coordinate +*/ +font_nb_pixel_x = 4; // 4 pixels wide +font_nb_pixel_y = 6; // 6 pixels high + +font_char = [[ + [0,1,1,0], //index 0: character "0" + [1,0,0,1], + [1,0,1,1], + [1,1,0,1], + [1,0,0,1], + [0,1,1,0], + ],[ + [0,1,0,0], //index 1: character "1" + [1,1,0,0], + [0,1,0,0], + [0,1,0,0], + [0,1,0,0], + [1,1,1,0], + ],[ + [0,1,1,0], //index 2: character "2" + [1,0,0,1], + [0,0,0,1], + [0,1,1,0], + [1,0,0,0], + [1,1,1,1], + ],[ + [0,1,1,0], //index 3: character "3" + [1,0,0,1], + [0,0,1,1], + [0,0,0,1], + [1,0,0,1], + [0,1,1,0], + ],[ + [1,0,0,1], //index 4: character "4" + [1,0,0,1], + [1,0,0,1], + [1,1,1,1], + [0,0,0,1], + [0,0,0,1], + ],[ + [1,1,1,1], //index 5: character "5" + [1,0,0,0], + [1,1,1,0], + [0,0,0,1], + [0,0,0,1], + [1,1,1,0], + ],[ + [0,1,1,1], //index 6: character "6" + [1,0,0,0], + [1,1,1,0], + [1,0,0,1], + [1,0,0,1], + [0,1,1,0], + ],[ + [1,1,1,1], //index 7: character "7" + [0,0,0,1], + [0,0,0,1], + [0,0,1,0], + [0,1,0,0], + [1,0,0,0], + ],[ + [0,1,1,0], //index 8: character "8" + [1,0,0,1], + [0,1,1,0], + [1,0,0,1], + [1,0,0,1], + [0,1,1,0], + ],[ + [0,1,1,0], //index 9: character "9" + [1,0,0,1], + [1,0,0,1], + [0,1,1,1], + [0,0,0,1], + [1,1,1,0], + ],[ + [0,0,0,0], //index 10: character ":" + [0,0,0,0], + [0,1,0,0], + [0,0,0,0], + [0,1,0,0], + [0,0,0,0], + ],[ + [1,1,1,1], //index 11: character {full white} + [1,1,1,1], + [1,1,1,1], + [1,1,1,1], + [1,1,1,1], + [1,1,1,1], + ],[ + [0,0,0,0], //index 12: character {full dark} + [0,0,0,0], + [0,0,0,0], + [0,0,0,0], + [0,0,0,0], + [0,0,0,0], + ], +// Added by Margu : we add some "characters" to display the transitions +// "0"-"1" transition character has pixels lit only if both corresponding digits are lit (boolean And operation) +// and so on ... + [ + [0,1,0,0], //index 13: character {"0" to "1" transition} + [1,0,0,0], + [0,0,0,0], + [0,1,0,0], + [0,0,0,0], + [0,1,1,0], + ],[ + [0,1,0,0], //index 14: character {"1" to "2" transition} + [1,0,0,0], + [0,0,0,0], + [0,1,0,0], + [0,0,0,0], + [0,1,1,0], + ],[ + [0,1,1,0], //index 15: character {"2" to "3" transition} + [1,0,0,1], + [0,0,0,1], + [0,0,0,0], + [1,0,0,0], + [0,1,1,0], + ],[ + [0,0,0,0], //index 16: character {"3" to "4" transition} + [1,0,0,1], + [0,0,0,1], + [0,0,0,1], + [0,0,0,1], + [0,0,0,0], + ],[ + [1,0,0,1], //index 17: character {"4" to "5" transition} + [1,0,0,0], + [1,0,0,0], + [0,0,0,1], + [0,0,0,1], + [0,0,0,0], + ],[ + [0,1,1,1], //index 18: character {"5" to "6" transition} + [1,0,0,0], + [1,1,1,0], + [0,0,0,1], + [0,0,0,1], + [0,1,1,0], + ],[ + [0,1,1,1], //index 19: character {"6" to "7" transition} + [0,0,0,0], + [0,0,0,0], + [0,0,0,0], + [0,0,0,0], + [0,0,0,0], + ],[ + [1,1,1,1], //index 20: character {"7" to "8" transition} + [0,0,0,1], // not used, so wrong values !!! + [0,0,0,1], + [0,0,1,0], + [0,1,0,0], + [1,0,0,0], + ],[ + [0,1,1,0], //index 20: character {"8" to "9" transition} + [1,0,0,1], // not used, so wrong values !!! + [0,1,1,0], + [1,0,0,1], + [1,0,0,1], + [0,1,1,0], + ],[ + [0,1,1,0], //index 22: character {"9" to "0" transition} + [1,0,0,1], + [1,0,0,1], + [0,1,0,1], + [0,0,0,1], + [0,1,1,0], + ],[ + [0,1,1,0], //index 23: character {"0" to "2" transition} + [1,0,0,1], + [0,0,0,1], + [0,1,0,0], + [1,0,0,0], + [0,1,1,0], + ],[ + [0,0,0,0], //index 24: character {"2" to "4" transition} + [1,0,0,1], + [0,0,0,1], + [0,1,1,0], + [0,0,0,0], + [0,0,0,1], + ],[ + [0,0,0,0], //index 25: character {"4" to "0" transition} + [1,0,0,1], + [1,0,0,1], + [1,1,0,1], + [0,0,0,1], + [0,0,0,0], + ] + ]; + + +/* ************************************************************************/ +/* MODULES ****************************************************************/ +/* ************************************************************************/ + +/* ************************************************************************/ +module extrude_pixel(direction_angle_x,direction_angle_y, pixel_wall_angle_x, pixel_wall_angle_y) { +/* Extrude a pixel in a given direction. + input: + direction_angle_x: extrusion angle (from the normal to the pixel) in the x direction + direction_angle_y: extrusion angle (from the normal to the pixel) in the y direction + Return a (positive) solid that can then be substracted from another solid + (Origin at the center of the base pixel) +*/ + // compute geometry + top_pixel_location_z = 2*gnomon_radius; // ie: somewhere outside the gnomon +// top_pixel_location_x = top_pixel_location_z * tan(direction_angle_x); +// top_pixel_location_y = top_pixel_location_z * tan(direction_angle_y); + top_pixel_size_x = pixel_size_x +2*top_pixel_location_z*tan(pixel_wall_angle_x); // account for the non_vertical pixel walls + top_pixel_size_y = pixel_size_y +2*top_pixel_location_z*tan(pixel_wall_angle_y); + // build (positive) geometry: extrude vertically then rotate + union() { rotate([direction_angle_y,direction_angle_x,0]) // rotate the whole extrusion in the chosen direction + hull(){ + rotate([-direction_angle_y,-direction_angle_x,0]) // derotate the base pixel (to keep it flat at the bottom) + cube([pixel_size_x,pixel_size_y,epsilon_thickness], center=true); + translate([0,0,top_pixel_location_z]) + cube([top_pixel_size_x, top_pixel_size_y,epsilon_thickness], center=true); + } + } +} + + +/* ************************************************************************/ +module extrude_character(font_index, direction_angle_x, direction_angle_y, pixel_wall_angle_x, pixel_wall_angle_y) { +/* Extrude a (pixelated) character in a given direction: + input: + font_index: the index of the character in the font array + direction_angle_x: extrusion angle (from the normal to the pixel) in the x direction + direction_angle_y: extrusion angle (from the normal to the pixel) in the y direction + Return a (positive) solid that can then be substracted from another solid + (Origin at the center of the base character) +*/ + for (tx=[0:(font_nb_pixel_x-1)]){ + for (ty=[0:(font_nb_pixel_y-1)]){ + if(FLAG_mirror_x_characters==0) { // Note: y is the 2nd coordinate, x is the 3rd (see definition of the Font) + if(font_char[font_index][ty][tx]==1) { + translate([(tx-(font_nb_pixel_x-1)/2)*pixel_pitch_x, (ty-(font_nb_pixel_y-1)/2)*pixel_pitch_y,0]){ + extrude_pixel(direction_angle_x,direction_angle_y, pixel_wall_angle_x, pixel_wall_angle_y); + } + } + } + else { // mirror the characters across x + if(font_char[font_index][ty][font_nb_pixel_x-1-tx]==1) { + translate([(tx-(font_nb_pixel_x-1)/2)*pixel_pitch_x, (ty-(font_nb_pixel_y-1)/2)*pixel_pitch_y,0]){ + extrude_pixel(direction_angle_x,direction_angle_y, pixel_wall_angle_x, pixel_wall_angle_y); + } + } + } + + }} +} + + +/* ************************************************************************/ +module build_create_pixel_grid(pixel_depth, ID_column_OFF=[]) { +/* Create a grid where each intersection row/column is a potential pixel + Input: + pixel_depth: the depth of the pixel grid + ID_column_OFF: list all the columns that should be left OFF (eg not built), exemple: [0,1] + Return a (positive) solid that can then be substracted from another solid + (Origin at the center of the base character) +*/ + if (len(ID_column_OFF)