From 7cc3d0a17c611b6dae1446e6ee29232fba460634 Mon Sep 17 00:00:00 2001 From: mmcwilliams Date: Wed, 19 Aug 2020 01:35:44 -0400 Subject: [PATCH] Add spindle code to v3. Render the top and bottom spindle. --- 100ft_v3/gnal_100ft.scad | 4 + 50ft_v3/gnal_50ft.scad | 4 + libraries/Triangles.scad | 215 +++++++++++++++++++++++++++++++++++++++ libraries/gnal_v3.scad | 182 +++++++++++++++++++++++++++++++++ scripts/v3.sh | 2 +- 5 files changed, 406 insertions(+), 1 deletion(-) create mode 100644 libraries/Triangles.scad diff --git a/100ft_v3/gnal_100ft.scad b/100ft_v3/gnal_100ft.scad index 7a7a7db..d801ef0 100644 --- a/100ft_v3/gnal_100ft.scad +++ b/100ft_v3/gnal_100ft.scad @@ -299,4 +299,8 @@ if (PART == "spiral") { gnal_spiral_bottom_insert_16(); } else if (PART == "spacer_16") { gnal_spacer_16(); +} else if (PART == "spindle_top") { + gnal_spindle_top(); +} else if (PART == "spindle_bottom") { + gnal_spindle_bottom(); } diff --git a/50ft_v3/gnal_50ft.scad b/50ft_v3/gnal_50ft.scad index 0ab9d0f..a78fc33 100644 --- a/50ft_v3/gnal_50ft.scad +++ b/50ft_v3/gnal_50ft.scad @@ -220,4 +220,8 @@ if (PART == "spiral") { gnal_spiral_bottom_insert_16(); } else if (PART == "spacer_16") { gnal_spacer_16(); +} else if (PART == "spindle_top") { + gnal_spindle_top(); +} else if (PART == "spindle_bottom") { + gnal_spindle_bottom(); } diff --git a/libraries/Triangles.scad b/libraries/Triangles.scad new file mode 100644 index 0000000..2d027b3 --- /dev/null +++ b/libraries/Triangles.scad @@ -0,0 +1,215 @@ +/* +Triangles.scad + Author: Tim Koopman + https://github.com/tkoopman/Delta-Diamond/blob/master/OpenSCAD/Triangles.scad + + angleCA + /|\ + a / H \ c + / | \ + angleAB ------- angleBC + b + +Standard Parameters + center: true/false + If true same as centerXYZ = [true, true, true] + + centerXYZ: Vector of 3 true/false values [CenterX, CenterY, CenterZ] + center must be left undef + + height: The 3D height of the Triangle. Ignored if heights defined + + heights: Vector of 3 height values heights @ [angleAB, angleBC, angleCA] + If CenterZ is true each height will be centered individually, this means + the shape will be different depending on CenterZ. Most times you will want + CenterZ to be true to get the shape most people want. +*/ + +/* +Triangle + a: Length of side a + b: Length of side b + angle: angle at point angleAB +*/ +module Triangle( + a, b, angle, height=1, heights=undef, + center=undef, centerXYZ=[false,false,false]) +{ + // Calculate Heights at each point + heightAB = ((heights==undef) ? height : heights[0])/2; + heightBC = ((heights==undef) ? height : heights[1])/2; + heightCA = ((heights==undef) ? height : heights[2])/2; + centerZ = (center || (center==undef && centerXYZ[2]))?0:max(heightAB,heightBC,heightCA); + + // Calculate Offsets for centering + offsetX = (center || (center==undef && centerXYZ[0]))?((cos(angle)*a)+b)/3:0; + offsetY = (center || (center==undef && centerXYZ[1]))?(sin(angle)*a)/3:0; + + pointAB1 = [-offsetX,-offsetY, centerZ-heightAB]; + pointAB2 = [-offsetX,-offsetY, centerZ+heightAB]; + pointBC1 = [b-offsetX,-offsetY, centerZ-heightBC]; + pointBC2 = [b-offsetX,-offsetY, centerZ+heightBC]; + pointCA1 = [(cos(angle)*a)-offsetX,(sin(angle)*a)-offsetY, centerZ-heightCA]; + pointCA2 = [(cos(angle)*a)-offsetX,(sin(angle)*a)-offsetY, centerZ+heightCA]; + + polyhedron( + points=[ pointAB1, pointBC1, pointCA1, + pointAB2, pointBC2, pointCA2 ], + faces=[ + [0, 1, 2], + [3, 5, 4], + [0, 3, 1], + [1, 3, 4], + [1, 4, 2], + [2, 4, 5], + [2, 5, 0], + [0, 5, 3] ] ); +} + +/* +Isosceles Triangle + Exactly 2 of the following paramaters must be defined. + If all 3 defined H will be ignored. + b: length of side b + angle: angle at points angleAB & angleBC. +*/ +module Isosceles_Triangle( + b, angle, H=undef, height=1, heights=undef, + center=undef, centerXYZ=[true, false, false]) +{ + valid = (angle!=undef)?((angle < 90) && (b!=undef||H!=undef)) : (b!=undef&&H!=undef); + ANGLE = (angle!=undef) ? angle : atan(H / (b/2)); + a = (b==undef)?(H/sin((180-(angle*2))/2)) : + (b / cos(ANGLE))/2; + B = (b==undef)? (cos(angle)*a)*2:b; + if (valid) + { + Triangle(a=a, b=B, angle=ANGLE, height=height, heights=heights, + center=center, centerXYZ=centerXYZ); + } else { + echo("Invalid Isosceles_Triangle. Must specify any 2 of b, angle and H, and if angle used angle must be less than 90"); + } +} + +/* +Right Angled Triangle + Create a Right Angled Triangle where the hypotenuse will be calculated. + + |\ + a| \ + | \ + ---- + b + a: length of side a + b: length of side b +*/ +module Right_Angled_Triangle( + a, b, height=1, heights=undef, + center=undef, centerXYZ=[false, false, false]) +{ + Triangle(a=a, b=b, angle=90, height=height, heights=heights, + center=center, centerXYZ=centerXYZ); +} + +/* +Wedge + Is same as Right Angled Triangle with 2 different heights, and rotated. + Good for creating support structures. +*/ +module Wedge(a, b, w1, w2) +{ + rotate([90,0,0]) + Right_Angled_Triangle(a, b, heights=[w1, w2, w1], centerXYZ=[false, false, true]); +} + +/* +Equilateral Triangle + Create a Equilateral Triangle. + + l: Length of all sides (a, b & c) + H: Triangle size will be based on the this 2D height + When using H, l is ignored. +*/ +module Equilateral_Triangle( + l=10, H=undef, height=1, heights=undef, + center=undef, centerXYZ=[true,false,false]) +{ + L = (H==undef)?l:H/sin(60); + Triangle(a=L,b=L,angle=60,height=height, heights=heights, + center=center, centerXYZ=centerXYZ); +} + +/* +Trapezoid + Create a Basic Trapezoid (Based on Isosceles_Triangle) + + d + /----\ + / | \ + a / H \ c + / | \ + angle ------------ angle + b + + b: Length of side b + angle: Angle at points angleAB & angleBC + H: The 2D height at which the triangle should be cut to create the trapezoid + heights: If vector of size 3 (Standard for triangles) both cd & da will be the same height, if vector have 4 values [ab,bc,cd,da] than each point can have different heights. +*/ +module Trapezoid( + b, angle=60, H, height=1, heights=undef, + center=undef, centerXYZ=[true,false,false]) +{ + validAngle = (angle < 90); + adX = H / tan(angle); + + // Calculate Heights at each point + heightAB = ((heights==undef) ? height : heights[0])/2; + heightBC = ((heights==undef) ? height : heights[1])/2; + heightCD = ((heights==undef) ? height : heights[2])/2; + heightDA = ((heights==undef) ? height : ((len(heights) > 3)?heights[3]:heights[2]))/2; + + // Centers + centerX = (center || (center==undef && centerXYZ[0]))?0:b/2; + centerY = (center || (center==undef && centerXYZ[1]))?0:H/2; + centerZ = (center || (center==undef && centerXYZ[2]))?0:max(heightAB,heightBC,heightCD,heightDA); + + // Points + y = H/2; + bx = b/2; + dx = (b-(adX*2))/2; + + pointAB1 = [centerX-bx, centerY-y, centerZ-heightAB]; + pointAB2 = [centerX-bx, centerY-y, centerZ+heightAB]; + pointBC1 = [centerX+bx, centerY-y, centerZ-heightBC]; + pointBC2 = [centerX+bx, centerY-y, centerZ+heightBC]; + pointCD1 = [centerX+dx, centerY+y, centerZ-heightCD]; + pointCD2 = [centerX+dx, centerY+y, centerZ+heightCD]; + pointDA1 = [centerX-dx, centerY+y, centerZ-heightDA]; + pointDA2 = [centerX-dx, centerY+y, centerZ+heightDA]; + + validH = (adX < b/2); + + if (validAngle && validH) + { + polyhedron( + points=[ pointAB1, pointBC1, pointCD1, pointDA1, + pointAB2, pointBC2, pointCD2, pointDA2 ], + triangles=[ + [0, 1, 2], + [0, 2, 3], + [4, 6, 5], + [4, 7, 6], + [0, 4, 1], + [1, 4, 5], + [1, 5, 2], + [2, 5, 6], + [2, 6, 3], + [3, 6, 7], + [3, 7, 0], + [0, 7, 4] ] ); + } else { + if (!validAngle) echo("Trapezoid invalid, angle must be less than 90"); + else echo("Trapezoid invalid, H is larger than triangle"); + } +} \ No newline at end of file diff --git a/libraries/gnal_v3.scad b/libraries/gnal_v3.scad index 162ebef..1908e75 100644 --- a/libraries/gnal_v3.scad +++ b/libraries/gnal_v3.scad @@ -2,6 +2,7 @@ include <./path_extrude.scad>; include <./threads.scad>; +include <./Triangles.scad>; /** * THREADS @@ -426,4 +427,185 @@ module triangle_void_3 (i) { translate([-(length / 2) - 5, 0, 0]) rotate([0, 0, -ANGLE_C]) cube([10, width * 2, height + 1], center = true); } } +} + +/** + * Spindles + **/ + +module gnal_spindle_bottom_base ( HEX = false) { + D = 8.45 * 2; + H = 20; + //for grip + BUMP = 2; //diameter + BUMPS = 6; + TOP_D = 19; + TOP_H = 9.5; + TOP_OFFSET = -24.5; + + union() { + translate([0, 0, -15]) { + cylinder(r = D / 2, h = H, center = true, $fn = FINE); + } + //hex version + if (HEX) { + translate([0, 0, TOP_OFFSET]) { + cylinder(r = 11.1, h = TOP_H, center = true, $fn = 6); + } + } else { + translate([0, 0, TOP_OFFSET]) { + cylinder(r = TOP_D / 2, h = TOP_H, center = true, $fn = FINE); + } + } + for (i = [0 : BUMPS]) { + rotate([0, 0, (360 / BUMPS) * i]) { + translate([0, 8.9, TOP_OFFSET]) { + cylinder(r = BUMP, h = TOP_H, center = true, $fn = 60); + } + } + } + } +} + +module outer_screw (LEN) { + OD = 10; + PITCH = 1.5; + THREAD = 1.6; + + difference () { + translate([0, 0, -7.1]) metric_thread (diameter=OD, pitch=PITCH, thread_size = THREAD, length=LEN); + //bevel top of screw + translate([0, 0, LEN - 8]) difference() { + cylinder(r = 8, h = 3, center = true, $fn = FINE); + cylinder(r1 = 6, r2 = 3, h = 3.01, center = true, $fn = FINE); + } + } +} + +module gnal_spindle_bottom (ALT = false, HEX = false) { + OD = 13.6 + .5; + PITCH = 1.5; + THREAD = 1.6; + IN_LEN = 21; + + LEN = 17.1; + ALT_LEN = 27.1; + difference () { + gnal_spindle_bottom_base(HEX); + //inner screw negative + translate([0, 0, -30]) union() { + metric_thread (diameter=OD, pitch=PITCH, thread_size = THREAD, length = IN_LEN); + translate([0, 0, 0.2]) { + metric_thread (diameter=OD, pitch=PITCH, thread_size = THREAD, length = IN_LEN); + } + } + } + + difference () { + //outer screw + if (ALT) { + outer_screw(ALT_LEN); + } else { + outer_screw(LEN); + } + //hollow center + cylinder(r = 3.8 / 2, h = 100, center = true, $fn = 60); + } +} + +module gnal_spindle_top () { + D = 50; + THICKNESS = 2.5; + H = 19.5; + ROUND = 8; + + HANDLE_D = 13.25; + HANDLE_BASE = 16; + HANDLE_TOP = 13; + HANDLE_H = 54.5; + + NOTCHES = 17; + NOTCH = 1.5; + FINE = 200; + + difference () { + //cup + translate([0, 0, ROUND - 2]) minkowski () { + cylinder(r = (D / 2) - ROUND, h = (H * 2) - ROUND, center = true, $fn = FINE); + sphere(r = ROUND, $fn = FINE); + } + translate([0, 0, ROUND - 2 + THICKNESS]) minkowski () { + cylinder(r = (D / 2) - THICKNESS - ROUND, h = (H * 2) - ROUND, center = true, $fn = 200); + sphere(r = ROUND, $fn = FINE); + } + //hollow out cup + translate([0, 0, H + ROUND - 4 - 3]) { + cylinder(r = (D / 2) + 1, h = H * 2, center = true); + } + + //inner cup bevel + translate([0, 0, (H / 2) - ROUND - 1]) { + cylinder(r1 = (D / 2) - 2.5, r2 = (D / 2) - 2.5 + 1, h = 1, center = true, $fn = FINE); + } + //outer cup bevel + translate([0, 0, (H / 2) - ROUND - 1]) { + difference () { + cylinder(r = (D / 2) + .25, h = 1, center = true, $fn = FINE); + cylinder(r2 = (D / 2) - .8, r1 = (D / 2) - .8 + 1, h = 1, center = true, $fn = FINE); + } + } + //hole in cup + translate([21, 0, -10]) cylinder(r = 3 / 2, h = 40, center = true, $fn = 40); + } + + //reference cylinder + //translate([0, 0, -6.6]) color("red") cylinder(r = 50 / 2, h = 19.57, center = true); + + //handle + translate([0, 0, -15]) { + difference() { + cylinder(r1 = HANDLE_BASE / 2, r2 = HANDLE_TOP / 2, h = HANDLE_H, $fn = FINE); + //ring negative + translate([0, 0, 31 + 14.5]) { + difference () { + cylinder(r = HANDLE_D / 2 + 2, h = 20, center = true); + cylinder(r = HANDLE_D / 2 - .5, h = 20 + 1, center = true); + } + } + //handle notches + for(i = [0 : NOTCHES]) { + rotate([0, 0, i * (360 / NOTCHES)]) { + translate([0, HANDLE_D / 2 - .5, 31 + 14.5]) { + rotate([0.75, 0, 0]) rotate([0, 0, 45]) { + Right_Angled_Triangle(a = NOTCH, b = NOTCH, height = 20, centerXYZ=[true, true, true]); + } + } + } + } + //bevel handle at top + translate([0, 0, 54.01]) { + difference () { + cylinder(r = 13 / 2, h = 1, center = true); + cylinder(r1 = 12.5 / 2, r2 = 11.5 / 2, h = 1.01, center = true); + } + } + } + + } + //attach handle with pyramid cylinder + translate ([0, 0, -13.7]) { + cylinder(r1 = 16 / 2 + 2, r2 = 16 / 2 - .1, h = 3, center = true, $fn = FINE); + } + //plate under cup + translate([0, 0, -17.75]) { + cylinder(r = 31.5 / 2, h = 1, center = true, $fn = FINE); + } + //screw + translate([0, 0, -37.5]) { + metric_thread (diameter=13.6, pitch=1.5 ,thread_size = 1.6, length = 21); + } + //cylinder plug + translate([0, 0, -37.5 + (21 / 2) - 1]) { + cylinder(r = 12 / 2, h = 21, center = true, $fn = FINE); + } } \ No newline at end of file diff --git a/scripts/v3.sh b/scripts/v3.sh index ff2f9c9..4e8022c 100644 --- a/scripts/v3.sh +++ b/scripts/v3.sh @@ -9,7 +9,7 @@ DIST=./stl IMG=./img NOTES=./notes/${V}.csv -FILES=( "spacer" "top" "spiral" "quarter_a" "quarter_b" "quarter_c" "quarter_d" "insert_s8" "insert_16" "spacer_16" ) +FILES=( "spindle_top" "spindle_bottom" "spacer" "top" "spiral" "quarter_a" "quarter_b" "quarter_c" "quarter_d" "insert_s8" "insert_16" "spacer_16" ) SIZES=( "50ft" "100ft" ) mkdir -p $DIST