Merge remote-tracking branch 'origin/pr/20'

This commit is contained in:
Chow Loong Jin 2019-07-23 22:28:19 +08:00
commit 7a0e555029
2 changed files with 243 additions and 2 deletions

View File

@ -34,6 +34,38 @@ module bold_2d(bold,width=0.2,resolution=8) {
}
}
module polytext(charstring,size,font,line=0,justify=1,align=-1
,bold=false,bold_width=0.2,bold_resolution=8
,underline=false,underline_start=[0,0],underline_width=1.0
,outline=false,outline_width=0.2,outline_resolution=8
,strike=false,strike_start=[-0.5,0],strike_width=1.0
) {
line_length=len(charstring)*font[0][0];
line_shift_x=-line_length/2+justify*line_length/2;
char_width=font[0][0];
char_height=font[0][1];
char_shift_height=-char_height/2-align*char_height/2;
char_thickness=font[0][2];
char_index_map=search(charstring,font[2],1,1);
for(i=[0:len(char_index_map)-1]) assign( thisCharIndex=char_index_map[i], x_pos=i*size+line_shift_x*size/char_width) {
translate([x_pos,line*size+char_shift_height*size/char_height]) scale([size/char_width,size/char_height]) {
if(char_thickness==0)
bold_2d(bold,width=bold_width,resolution=bold_resolution)
outline_2d(outline,points=font[2][thisCharIndex][6][0],paths=font[2][thisCharIndex][6][1]
,width=outline_width,resolution=outline_resolution);
if( charstring[i] != " " ) {
if(underline) translate(underline_start)
square(size=[char_width-2*underline_start[0],underline_width],center=false);
if(strike) translate([strike_start[0],char_height/2+strike_start[1]])
square(size=[char_width-2*strike_start[0],strike_width],center=false);
}
if(char_thickness>0)
polyhedron(points=font[2][thisCharIndex][6][0],triangles=font[2][thisCharIndex][6][1]);
}
}
}
function 8bit_polyfont(dx=0.1,dy=0.1) = [
[8,8,0,"fixed"],["Decimal Byte","Caret Notation","Character Escape Code","Abbreviation","Name","Bound Box","[points,paths]"]
,[
@ -516,3 +548,191 @@ function 8bit_polyfont(dx=0.1,dy=0.1) = [
,[127,"^?","", "DEL","Delete",[[0,0],[8,8]],[]]
] ];
// From http://www.brailleauthority.org/sizespacingofbraille/
//
// Section 3.2 of Specification 800 (Braille Books and Pamphlets) February 2008 reads as follows:
// Size and Spacing
// 3.2.1 The nominal height of braille dots shall be 0.019 inches [0.48 mm] and shall be uniform within any given transcription.
// 3.2.2 The nominal base diameter of braille dots shall be 0.057 inches [1.44 mm].
// 3.2.3 Cell spacing of dots shall conform to the following:
// 3.2.3.1 The nominal distance from center to center of adjacent dots (horizontally or vertically, but not diagonally)
// in the same cell shall be 0.092 inches [2.340 mm].
// 3.2.3.2 The nominal distance from center to center of corresponding dots in adjacent cells shall be 0.245 inches [6.2 mm].
// 3.2.4 The nominal line spacing of braille cells from center to center of nearest corresponding dots in adjacent lines shall
// be 0.400 inches [1.000 cm].
//
// Additional References:
// http://www.loc.gov/nls/specs/800.pdf
// http://www.tiresias.org/research/reports/braille_cell.htm
module braille_ascii_spec800(inString,dot_backing=true,cell_backing=false,justify=1,align=-1,dot_h=0.48,dot_d=1.44,dot_spacing=2.340,cell_d2d_spacing=6.2, line_d2d_spacing=10.0, echo_translate=true) {
// justify:
// -1 : left side
// 0 : center
// 1 : right side (default)
// align:
// -1 : bottom braille cell edge - shift up (default)
// 0 : center braille cell
// 1 : top braille cell edge - shift down
thisFont=braille_ascii_font(dot_h=dot_h,dot_d=dot_d,dot_spacing=dot_spacing
,cell_d2d_spacing=cell_d2d_spacing,line_d2d_spacing=line_d2d_spacing);
x_shift=thisFont[0][0];
y_shift=thisFont[0][1];
theseIndicies=search(inString,thisFont[2],1,1);
for( i=[0:len(theseIndicies)-1]) translate([i*x_shift-(1-justify)*x_shift*len(theseIndicies)/2,-y_shift*(align+1)/2])
assign(dotPattern=thisFont[2][theseIndicies[i]][6]) {
if(dot_backing) translate([cell_d2d_spacing/2-dot_spacing/2-dot_d/2,line_d2d_spacing/2-dot_spacing-dot_d/2,-dot_h])
cube(size=[dot_spacing+dot_d,2*dot_spacing+dot_d,dot_h],center=false);
if(cell_backing) translate([0,0,-dot_h])
cube(size=[x_shift,y_shift,dot_h],center=false);
if(echo_translate) echo(str(inString[i]," maps to '",thisFont[2][theseIndicies[i]][4],"'"));
for(dotIndex=dotPattern) {
translate([cell_d2d_spacing/2-dot_spacing/2+floor((dotIndex-1)/3)*dot_spacing
, line_d2d_spacing/2-dot_spacing+(2-(dotIndex-1)%3)*dot_spacing])
scale([dot_d,dot_d,2*dot_h]) sphere($fn=8,r=0.5);
}
}
}
// Encoding from http://en.wikipedia.org/wiki/Braille_ASCII
// Dot Pattern:
// 1 4
// 2 5
// 3 6
function braille_ascii_font(dot_h=0.48,dot_d=1.44,dot_spacing=2.340,cell_d2d_spacing=6.2,line_d2d_spacing=10.0) = [
[cell_d2d_spacing,line_d2d_spacing,0,"bump"],["Decimal Byte","Caret Notation","Character Escape Code","Abbreviation","Name","Bound Box","[bump_list]"]
,[
[ 0,"^@","\0","NUL","Null character",[[0,0],[2,3]],[]]
,[ 1,"^A","", "SOH","Start of Header",[[0,0],[2,3]],[]]
,[ 2,"^B","", "STX","Start of Text",[[0,0],[2,3]],[]]
,[ 3,"^C","", "ETX","End of Text",[[0,0],[2,3]],[]]
,[ 4,"^D","", "EOT","End of Transmission",[[0,0],[2,3]],[]]
,[ 5,"^E","", "ENQ","Enquiry",[[0,0],[2,3]],[]]
,[ 6,"^F","", "ACK","Acknowledgment",[[0,0],[2,3]],[]]
,[ 7,"^G","\a","BEL","Bell",[[0,0],[2,3]],[]]
,[ 8,"^H","\b","BS", "Backspace",[[0,0],[2,3]],[]]
,[ 9,"^I","\t","HT", "Horizontal Tab",[[0,0],[2,3]],[]]
,[ 10,"^J","\n","LF", "Line Feed",[[0,0],[2,3]],[]]
,[ 11,"^K","\v","VT", "Vertical Tab",[[0,0],[2,3]],[]]
,[ 12,"^L","\f","FF", "Form feed",[[0,0],[2,3]],[]]
,[ 13,"^M","\r","CR", "Carriage return",[[0,0],[2,3]],[]]
,[ 14,"^N","", "SO", "Shift Out",[[0,0],[2,3]],[]]
,[ 15,"^O","", "SI", "Shift In",[[0,0],[2,3]],[]]
,[ 16,"^P","", "DLE","Data Link Escape",[[0,0],[2,3]],[]]
,[ 17,"^Q","", "DC1","Device Control 1",[[0,0],[2,3]],[]]
,[ 18,"^R","", "DC2","Device Control 2",[[0,0],[2,3]],[]]
,[ 19,"^S","", "DC3","Device Control 3",[[0,0],[2,3]],[]]
,[ 20,"^T","", "DC4","Device Control 4",[[0,0],[2,3]],[]]
,[ 21,"^U","", "NAK","Negative Acknowledgement",[[0,0],[2,3]],[]]
,[ 22,"^V","", "SYN","Synchronous Idle",[[0,0],[2,3]],[]]
,[ 23,"^W","", "ETB","End of Transmission Block",[[0,0],[2,3]],[]]
,[ 24,"^X","", "CAN","Cancel",[[0,0],[2,3]],[]]
,[ 25,"^Y","", "EM", "End of Medium",[[0,0],[2,3]],[]]
,[ 26,"^Z","", "SUB","Substitute",[[0,0],[2,3]],[]]
,[ 27,"^[","\e","ESC","Escape",[[0,0],[2,3]],[]]
,[ 28,"^\\","", "FS", "File Separator",[[0,0],[2,3]],[]]
,[ 29,"^]","", "GS", "Group Separator",[[0,0],[2,3]],[]]
,[ 30,"^^","", "RS", "Record Separator",[[0,0],[2,3]],[]]
,[ 31,"^_","", "US", "Unit Separator",[[0,0],[2,3]],[]]
,[ 32," "," ", "", "Space",[[0,0],[2,3]],[]]
,[ 33,"!","!", "", "the",[[0,0],[2,3]],[ 2,3,4,6 ]]
,[ 34,"\"","\"","", "(contraction)",[[0,0],[2,3]],[ 5 ]]
,[ 35,"#","#", "", "(number prefix)",[[0,0],[2,3]],[ 3,4,5,6 ]]
,[ 36,"$","$", "", "ed",[[0,0],[2,3]],[ 1,2,4,6 ]]
,[ 37,"%","%", "", "sh",[[0,0],[2,3]],[ 1,4,6 ]]
,[ 38,"&","&", "", "and",[[0,0],[2,3]],[ 1,2,3,4,6 ]]
,[ 39,"'","'", "", "",[[0,0],[2,3]],[ 3 ]]
,[ 40,"(","(", "", "of",[[0,0],[2,3]],[ 1,2,3,5,6 ]]
,[ 41,")",")", "", "with",[[0,0],[2,3]],[ 2,3,4,5,6 ]]
,[ 42,"*","*", "", "ch",[[0,0],[2,3]],[ 1,6 ]]
,[ 43,"+","+", "", "ing",[[0,0],[2,3]],[ 3,4,6 ]]
,[ 44,",",",", "", "(uppercase prefix)",[[0,0],[2,3]],[ 6 ]]
,[ 45,"-","-", "", "",[[0,0],[2,3]],[ 3,6 ]]
,[ 46,".",".", "", "(italic prefix)",[[0,0],[2,3]],[ 4,6 ]]
,[ 47,"/","/", "", "st",[[0,0],[2,3]],[ 3,4 ]]
,[ 48,"0","0", "", "\"",[[0,0],[2,3]],[ 3,5,6 ]]
,[ 49,"1","1", "", ",",[[0,0],[2,3]],[ 2 ]]
,[ 50,"2","2", "", ";",[[0,0],[2,3]],[ 2,3 ]]
,[ 51,"3","3", "", ":",[[0,0],[2,3]],[ 2,5 ]]
,[ 52,"4","4", "", ".",[[0,0],[2,3]],[ 2,5,6 ]]
,[ 53,"5","5", "", "en",[[0,0],[2,3]],[ 2,6 ]]
,[ 54,"6","6", "", "!",[[0,0],[2,3]],[ 2,3,5 ]]
,[ 55,"7","7", "", "( or )",[[0,0],[2,3]],[ 2,3,5,6 ]]
,[ 56,"8","8", "", "\" or ?",[[0,0],[2,3]],[ 2,3,6 ]]
,[ 57,"9","9", "", "in",[[0,0],[2,3]],[ 3,5 ]]
,[ 58,":",":", "", "wh",[[0,0],[2,3]],[ 1,5,6 ]]
,[ 59,";",";", "", "(letter prefix)",[[0,0],[2,3]],[ 5,6 ]]
,[ 60,"<","<", "", "gh",[[0,0],[2,3]],[ 1,2,6 ]]
,[ 61,"=","=", "", "for",[[0,0],[2,3]],[ 1,2,3,4,5,6 ]]
,[ 62,">",">", "", "ar",[[0,0],[2,3]],[ 3,4,5 ]]
,[ 63,"?","?", "", "th",[[0,0],[2,3]],[ 1,4,5,6 ]]
,[ 64,"@","@", "", "(accent prefix)",[[0,0],[2,3]],[ 4 ]]
,[ 65,"A","A", "", "a",[[0,0],[2,3]],[ 1 ]]
,[ 66,"B","B", "", "b",[[0,0],[2,3]],[ 1,2 ]]
,[ 67,"C","C", "", "c",[[0,0],[2,3]],[ 1,4 ]]
,[ 68,"D","D", "", "d",[[0,0],[2,3]],[ 1,4,5 ]]
,[ 69,"E","E", "", "e",[[0,0],[2,3]],[ 1,5 ]]
,[ 70,"F","F", "", "f",[[0,0],[2,3]],[ 1,2,4 ]]
,[ 71,"G","G", "", "g",[[0,0],[2,3]],[ 1,2,4,5 ]]
,[ 72,"H","H", "", "h",[[0,0],[2,3]],[ 1,2,5 ]]
,[ 73,"I","I", "", "i",[[0,0],[2,3]],[ 2,4 ]]
,[ 74,"J","J", "", "j",[[0,0],[2,3]],[ 2,4,5 ]]
,[ 75,"K","K", "", "k",[[0,0],[2,3]],[ 1,3 ]]
,[ 76,"L","L", "", "l",[[0,0],[2,3]],[ 1,2,3 ]]
,[ 77,"M","M", "", "m",[[0,0],[2,3]],[ 1,3,4 ]]
,[ 78,"N","N", "", "n",[[0,0],[2,3]],[ 1,3,4,5 ]]
,[ 79,"O","O", "", "o",[[0,0],[2,3]],[ 1,3,5 ]]
,[ 80,"P","P", "", "p",[[0,0],[2,3]],[ 1,2,3,4 ]]
,[ 81,"Q","Q", "", "q",[[0,0],[2,3]],[ 1,2,3,4,5 ]]
,[ 82,"R","R", "", "r",[[0,0],[2,3]],[ 1,2,3,5 ]]
,[ 83,"S","S", "", "s",[[0,0],[2,3]],[ 2,3,4 ]]
,[ 84,"T","T", "", "t",[[0,0],[2,3]],[ 2,3,4,5 ]]
,[ 85,"U","U", "", "u",[[0,0],[2,3]],[ 1,3,6 ]]
,[ 86,"V","V", "", "v",[[0,0],[2,3]],[ 1,2,3,6 ]]
,[ 87,"W","W", "", "w",[[0,0],[2,3]],[ 2,4,5,6 ]]
,[ 88,"X","X", "", "x",[[0,0],[2,3]],[ 1,3,4,6 ]]
,[ 89,"Y","Y", "", "y",[[0,0],[2,3]],[ 1,3,4,5,6 ]]
,[ 90,"Z","Z", "", "z",[[0,0],[2,3]],[ 1,3,5,6 ]]
,[ 91,"[","[", "", "ow",[[0,0],[2,3]],[ 2,4,6 ]] // ]]
,[ 92,"\\","\\","", "ou",[[0,0],[2,3]],[ 1,2,5,6 ]] // [[
,[ 93,"]","]", "", "er",[[0,0],[2,3]],[ 1,2,4,5,6 ]]
,[ 94,"^","^", "", "(contraction)",[[0,0],[2,3]],[ 4,5 ]]
,[ 95,"_","_", "", "(contraction)",[[0,0],[2,3]],[ 4,5,6 ]]
,[ 96,"`","`", "", "",[[0,0],[2,3]],[
]]
// Repeating upper-case patterns for lower-case letters.
,[ 97,"a","a", "", "a",[[0,0],[2,3]],[ 1 ]]
,[ 98,"b","b", "", "b",[[0,0],[2,3]],[ 1,2 ]]
,[ 99,"c","c", "", "c",[[0,0],[2,3]],[ 1,4 ]]
,[100,"d","d", "", "d",[[0,0],[2,3]],[ 1,4,5 ]]
,[101,"e","e", "", "e",[[0,0],[2,3]],[ 1,5 ]]
,[102,"f","f", "", "f",[[0,0],[2,3]],[ 1,2,4 ]]
,[103,"g","g", "", "g",[[0,0],[2,3]],[ 1,2,4,5 ]]
,[104,"h","h", "", "h",[[0,0],[2,3]],[ 1,2,5 ]]
,[105,"i","i", "", "i",[[0,0],[2,3]],[ 2,4 ]]
,[106,"j","j", "", "j",[[0,0],[2,3]],[ 2,4,5 ]]
,[107,"k","k", "", "k",[[0,0],[2,3]],[ 1,3 ]]
,[108,"l","l", "", "l",[[0,0],[2,3]],[ 1,2,3 ]]
,[109,"m","m", "", "m",[[0,0],[2,3]],[ 1,3,4 ]]
,[110,"n","n", "", "n",[[0,0],[2,3]],[ 1,3,4,5 ]]
,[111,"o","o", "", "o",[[0,0],[2,3]],[ 1,3,5 ]]
,[112,"p","p", "", "p",[[0,0],[2,3]],[ 1,2,3,4 ]]
,[113,"q","q", "", "q",[[0,0],[2,3]],[ 1,2,3,4,5 ]]
,[114,"r","r", "", "r",[[0,0],[2,3]],[ 1,2,3,5 ]]
,[115,"s","s", "", "s",[[0,0],[2,3]],[ 2,3,4 ]]
,[116,"t","t", "", "t",[[0,0],[2,3]],[ 2,3,4,5 ]]
,[117,"u","u", "", "u",[[0,0],[2,3]],[ 1,3,6 ]]
,[118,"v","v", "", "v",[[0,0],[2,3]],[ 1,2,3,6 ]]
,[119,"w","w", "", "w",[[0,0],[2,3]],[ 2,4,5,6 ]]
,[120,"x","x", "", "x",[[0,0],[2,3]],[ 1,3,4,6 ]]
,[121,"y","y", "", "y",[[0,0],[2,3]],[ 1,3,4,5,6 ]]
,[122,"z","z", "", "z",[[0,0],[2,3]],[ 1,3,5,6 ]]
,[123,"{","{", "", "",[[0,0],[2,3]],[
]]
,[124,"|","|", "", "",[[0,0],[2,3]],[
]]
,[125,"}","}", "", "",[[0,0],[2,3]],[
]]
,[126,"~","~", "", "",[[0,0],[2,3]],[
]]
,[127,"^?","", "DEL","Delete",[[0,0],[2,3]],[]]
] ];

View File

@ -14,41 +14,62 @@
// Circular pitch: Length of the arc from one tooth to the next
// Clearance: Radial distance between top of tooth on one gear to bottom of gap on another.
function pitch_circular2diameter(number_of_teeth,circular_pitch) = number_of_teeth * circular_pitch / 180;
function pitch_diametral2diameter(number_of_teeth,diametral_pitch) = number_of_teeth / diametral_pitch;
module gear(number_of_teeth,
circular_pitch=false, diametral_pitch=false,
pressure_angle=20, clearance = 0)
pressure_angle=20, clearance = 0,
verbose=false)
{
if(verbose) {
echo("gear arguments:");
echo(str(" number_of_teeth: ", number_of_teeth));
echo(str(" circular_pitch: ", circular_pitch));
echo(str(" diametral_pitch: ", diametral_pitch));
echo(str(" pressure_angle: ", pressure_angle));
echo(str(" clearance: ", clearance));
}
if (circular_pitch==false && diametral_pitch==false) echo("MCAD ERROR: gear module needs either a diametral_pitch or circular_pitch");
if(verbose) echo("gear calculations:");
//Convert diametrial pitch to our native circular pitch
circular_pitch = (circular_pitch!=false?circular_pitch:180/diametral_pitch);
// Pitch diameter: Diameter of pitch circle.
pitch_diameter = number_of_teeth * circular_pitch / 180;
pitch_diameter = pitch_circular2diameter(number_of_teeth,circular_pitch);
if(verbose) echo (str(" pitch_diameter: ", pitch_diameter));
pitch_radius = pitch_diameter/2;
// Base Circle
base_diameter = pitch_diameter*cos(pressure_angle);
if(verbose) echo (str(" base_diameter: ", base_diameter));
base_radius = base_diameter/2;
// Diametrial pitch: Number of teeth per unit length.
pitch_diametrial = number_of_teeth / pitch_diameter;
if(verbose) echo (str(" pitch_diametrial: ", pitch_diametrial));
// Addendum: Radial distance from pitch circle to outside circle.
addendum = 1/pitch_diametrial;
if(verbose) echo (str(" addendum: ", addendum));
//Outer Circle
outer_radius = pitch_radius+addendum;
outer_diameter = outer_radius*2;
if(verbose) echo (str(" outer_diameter: ", outer_diameter));
// Dedendum: Radial distance from pitch circle to root diameter
dedendum = addendum + clearance;
if(verbose) echo (str(" dedendum: ", dedendum));
// Root diameter: Diameter of bottom of tooth spaces.
root_radius = pitch_radius-dedendum;
root_diameter = root_radius * 2;
if(verbose) echo (str(" root_diameter: ", root_diameter));
half_thick_angle = 360 / (4 * number_of_teeth);
if(verbose) echo (str(" half_thick_angle: ", half_thick_angle));
union()
{