diff --git a/printed/drag_chain.scad b/printed/drag_chain.scad index 237e58d..49447da 100644 --- a/printed/drag_chain.scad +++ b/printed/drag_chain.scad @@ -54,8 +54,8 @@ function drag_chain_outer_size(type) = //! Link outer dimensions [s.x + z, s.y + 4 * drag_chain_wall(type) + 2 * clearance, z]; -module drag_chain_link(type) { - stl(str(drag_chain_name(type), "_drag_chain_link")); +module drag_chain_link(type, start = false, end = false) { + stl(str(drag_chain_name(type), "_drag_chain_link", start ? "_start" : end ? "_end" : "")); s = drag_chain_size(type); wall = drag_chain_wall(type); @@ -64,11 +64,14 @@ module drag_chain_link(type) { os = drag_chain_outer_size(type); r = os.z / 2; pin_r = r / 2; - inner_x = s.x - wall; - roof_x = 2 * r - twall; - floor_x = 2 * r; - cam_r = inner_x - clearance - r; + inner_x_normal = s.x - wall; + inner_x = start ? 0 : s.x - inner_x_normal; + roof_x_normal = 2 * r - twall; + roof_x = start ? 0 : roof_x_normal; + floor_x = start ? 0 : 2 * r; + cam_r = inner_x_normal - clearance - r; cam_x = min(sqrt(max(sqr(cam_r) - sqr(r - twall), 0)), r); + outer_end_x = end ? os.x : s.x - clearance; for(side = [-1, 1]) rotate([90, 0, 0]) { @@ -77,15 +80,20 @@ module drag_chain_link(type) { linear_extrude(wall, center = true) difference() { hull() { - translate([r, r]) - rotate(180) - teardrop(r = r, h = 0); + if(start) + translate([floor_x, 0]) + square([eps, os.z]); + else + translate([r, r]) + rotate(180) + teardrop(r = r, h = 0); - translate([s.x - clearance - eps, 0]) + translate([outer_end_x - eps, 0]) square([eps, os.z]); } - translate([r, r]) - horihole(pin_r, r); + if(!start) + translate([r, r]) + horihole(pin_r, r); } // Inner cheeks translate_z(side * (s.y / 2 + wall / 2)) @@ -93,52 +101,61 @@ module drag_chain_link(type) { difference() { union() { hull() { - translate([s.x + r, r]) - rotate(180) - teardrop(r = r, h = 0); + if(!end) { + translate([s.x + r, r]) + rotate(180) + teardrop(r = r, h = 0); - translate([s.x + r, twall]) - square([cam_x, eps]); + translate([s.x + r, twall]) + square([cam_x, eps]); + } + else + translate([s.x + 2 * r - eps, 0]) + square([eps, os.z]); translate([inner_x, 0]) square([eps, os.z]); } } // Cutout for top wall - intersection() { - translate([s.x, 0]) - square([3 * r, twall]); // When straight + if(!end) + intersection() { + translate([s.x, 0]) + square([3 * r, twall]); // When straight - translate([s.x + r, r]) - rotate(-45) - translate([-r + roof_x, -r - twall]) // When bent fully - square(os.z); - } + translate([s.x + r, r]) + rotate(-45) + translate([-r + roof_x_normal, -r - twall]) // When bent fully + square(os.z); + } } - // Pin - translate([s.x + r, r, side * (s.y / 2 + wall + clearance)]) - horicylinder(r = pin_r, z = r, h = 2 * wall); + // Pin + if(!end) + translate([s.x + r, r, side * (s.y / 2 + wall + clearance)]) + horicylinder(r = pin_r, z = r, h = 2 * wall); - // Cheek joint - translate([inner_x, 0, side * (s.y / 2 + wall) - 0.5]) - cube([s.x - clearance - inner_x, os.z, 1]); + // Cheek joint + translate([inner_x, 0, side * (s.y / 2 + wall) - 0.5]) + cube([outer_end_x - inner_x, os.z, 1]); } - // Roof - translate([roof_x, -s.y / 2 - 0.5]) - cube([s.x + r - roof_x - twall - clearance, s.y + 1, twall]); + // Roof, actually the floor when printed + roof_end = end ? s.x + 2 * r : s.x + r - twall - clearance; + translate([roof_x, -s.y / 2 - wall]) + cube([roof_end - roof_x , s.y + 2 * wall, twall]); translate([roof_x, -os.y / 2 + 0.5]) - cube([s.x - roof_x - clearance, os.y - 1, twall]); + cube([s.x - clearance - roof_x, os.y - 1, twall]); - // Base - translate([floor_x, -s.y / 2 - 0.5, os.z - bwall]) - cube([s.x + r - floor_x, s.y + 1, bwall]); + // Base, actually the roof when printed + floor_end = end ? s.x + 2 * r : s.x + r; + translate([floor_x, -s.y / 2 - wall, os.z - bwall]) + cube([floor_end - floor_x, s.y + 2 * wall, bwall]); translate([floor_x, -os.y / 2 + 0.5, os.z - bwall]) cube([s.x - floor_x - clearance, os.y -1, bwall]); - if(show_supports()) { + if(show_supports() && !end) { for(side = [-1, 1]) { w = 2.1 * extrusion_width; translate([s.x + r + cam_x - w / 2, side * (s.y / 2 + wall / 2), twall / 2]) @@ -167,13 +184,7 @@ module drag_chain_assembly(type, pos = 0) { //! Drag chain assembly zb = z / 2; // z of bottom track c = [actual_travel / 2 + pos / 2, 0, r + zb]; // centre of bend - module link(n) // Position and colour link with origin at the hinge hole - translate([-z / 2, 0, -z / 2]) - stl_colour(n % 2 ? pp1_colour : pp2_colour) - drag_chain_link(type); - - - points = [ // Calculate lits of hinge points + points = [ // Calculate list of hinge points for(i = 0, p = [0, 0, z / 2 + 2 * r]; i < links + 5; i = i + 1, dx = p.z > c.z ? s.x : -s.x, @@ -183,10 +194,24 @@ module drag_chain_assembly(type, pos = 0) { //! Drag chain assembly : q) // Circular section p ]; + npoints = len(points); - assembly(str(drag_chain_name(type), "_drag_chain")) - for(i = [0 : len(points) - 2]) let(v = points[i+1] - points[i]) + module link(n) // Position and colour link with origin at the hinge hole + translate([-z / 2, 0, -z / 2]) + stl_colour(n % 2 ? pp1_colour : pp2_colour) + drag_chain_link(type, start = n == -1, end = n == npoints - 1); + + assembly(str(drag_chain_name(type), "_drag_chain")) { + for(i = [0 : npoints - 2]) let(v = points[i+1] - points[i]) translate(points[i]) rotate([0, -atan2(v.z, v.x), 0]) link(i); + + translate(points[0] - [s.x, 0, 0]) + link(-1); + + translate(points[npoints - 1]) + hflip() + link(npoints - 1); + } } diff --git a/readme.md b/readme.md index 40a6cb2..56dfe99 100644 --- a/readme.md +++ b/readme.md @@ -28,20 +28,20 @@ See [usage](docs/usage.md) for requirements, installation instructions and a usa