diff --git a/readme.md b/readme.md index de813ea..b22c8d1 100644 --- a/readme.md +++ b/readme.md @@ -4382,7 +4382,7 @@ If a washer is given a child, usually a screw or a nut, then it is placed on its --- ## Wire -Just a BOM entry at the moment and cable bundle size functions for holes, plus cable ties. +Utilities for adding wires to the BOM and optionally drawing them and cable bundle size functions for holes, plus cable ties. [vitamins/wire.scad](vitamins/wire.scad) Implementation. @@ -4391,21 +4391,25 @@ Just a BOM entry at the moment and cable bundle size functions for holes, plus c ### Functions | Function | Description | |:--- |:--- | -| `cable(wires, size, colours, ribbon = false)` | Cable constructor | -| `cable_bundle(cable)` | Arrangement of a bundle in a flat cable clip | +| `cable(wires, size, colours, ribbon = false, tlen = 25)` | Cable constructor | +| `cable_bundle(cable)` | Dimensions of the bounding rectangle of a bundle of wires in a flat cable clip | | `cable_bundle_positions(cable)` | Positions of wires in a bundle to go through a cable strip | | `cable_height(cable)` | Height in flat clip | | `cable_is_ribbon(cable)` | Is a ribbon cable? | | `cable_radius(cable)` | Radius of a bundle of wires, see . | +| `cable_tlen(cable)` | Twisted cable twist length | +| `cable_twisted_radius(cable)` | Approximate radius of a cable when twisted | | `cable_width(cable)` | Width in flat clip | | `cable_wire_colours(cable)` | Individual wire colours | | `cable_wire_size(cable)` | Size of each wire in a bundle | | `cable_wires(cable)` | Number of wires in a bundle | +| `twisted_cable(cable, path, irot = 0, frot = 0)` | Return the paths for a twisted cable, `irot` is the initial rotation and frot the final rotation | | `wire_hole_radius(cable)` | Radius of a hole to accept a bundle of wires, rounded up to standard metric drill size | ### Modules | Module | Description | |:--- |:--- | +| `cable(cable, paths)` | Draw a cable, given a list of paths | | `cable_tie(cable_r, thickness)` | A ziptie threaded around cable radius `cable_r` and through a panel with specified `thickness`. | | `cable_tie_holes(cable_r, h = 100)` | Holes to thread a ziptie through a panel to make a cable tie. | | `mouse_hole(cable, h = 100, teardrop = false)` | A mouse hole to allow a panel to go over a wire bundle. | @@ -4417,13 +4421,13 @@ Just a BOM entry at the moment and cable bundle size functions for holes, plus c ### Vitamins | Qty | Module call | BOM entry | | ---:|:--- |:---| -| 1 | | Wire black 7/0.2mm strands, length 90mm | -| 1 | | Wire blue 7/0.2mm strands, length 90mm | -| 1 | | Wire brown 7/0.2mm strands, length 90mm | -| 1 | | Wire green 7/0.2mm strands, length 90mm | -| 1 | | Wire orange 7/0.2mm strands, length 90mm | -| 1 | | Wire red 7/0.2mm strands, length 90mm | -| 1 | | Wire yellow 7/0.2mm strands, length 90mm | +| 1 | | Wire black 7/0.2mm strands, length 60mm | +| 1 | | Wire blue 7/0.2mm strands, length 60mm | +| 1 | | Wire brown 7/0.2mm strands, length 60mm | +| 1 | | Wire green 7/0.2mm strands, length 60mm | +| 1 | | Wire orange 7/0.2mm strands, length 60mm | +| 1 | | Wire red 7/0.2mm strands, length 60mm | +| 1 | | Wire yellow 7/0.2mm strands, length 60mm | | 1 | `ziptie(small_ziptie)` | Ziptie 2.5mm x 100mm min length | diff --git a/tests/png/cable_clip.png b/tests/png/cable_clip.png index 4d6dc67..2f3b6db 100644 Binary files a/tests/png/cable_clip.png and b/tests/png/cable_clip.png differ diff --git a/tests/png/wire.png b/tests/png/wire.png index a5ba39c..901235a 100644 Binary files a/tests/png/wire.png and b/tests/png/wire.png differ diff --git a/tests/wire.scad b/tests/wire.scad index f50ea34..1057518 100644 --- a/tests/wire.scad +++ b/tests/wire.scad @@ -17,18 +17,25 @@ // If not, see . // include <../utils/core/core.scad> +use <../utils/sweep.scad> +use <../utils/bezier.scad> use <../vitamins/wire.scad> -bundle = [7, 1.4]; +twist_len = 25; // [5 : 50] +wires = 7; // [1 : 7] +irot = -60; // [-90 : 0] +/* [Hidden] */ +wire_d = 1.4; +bundle = cable(wires, wire_d); bundle_r = cable_radius(bundle); thickness = 2; w = 60; d = 20; -h = 40; -wire_l = 90; +h = 10; +wire_l = 60; mouse_y = 10; cable_pitch = 7; @@ -49,6 +56,7 @@ module wires() { translate([bundle_r - d / 2, 0]) { colour = ["black", "brown", "red", "orange", "yellow", "blue", "purple"][i]; wire(colour, 7, wire_l); + color(colour) cylinder(d = d, h = wire_l, center = true); } @@ -66,7 +74,7 @@ module wires() { mouse_hole(bundle, 0, true); for(i = [1 : 6]) - let(cable = [i, 1.4], bundle = cable_bundle(cable)) + let(cable = cable(i, wire_d), bundle = cable_bundle(cable)) translate([mouse_y + cable_pitch * i - bundle.x / 2, -eps]) square([bundle.x, bundle.y]); } @@ -81,18 +89,28 @@ module wires() { cable_tie_holes(bundle_r, 0); } } + translate([-15, mouse_y]) cable_tie(bundle_r, thickness); - for(i = [1 : 6]) let(cable = [i, 1.4]) - translate([0, mouse_y + cable_pitch * i]) - let(positions = cable_bundle_positions(cable)) - for(i = [0 : len(positions) - 1]) - let(p = positions[i]) - translate([0, p.x, p.y]) - rotate([0, 90, 0]) - color([grey(10), "blue", "red", "orange", "yellow", "green"][i]) - cylinder(d = cable_wire_size(cable), h = 60, center = true); + for(i = [1 : 6]) let(cable = cable(i, wire_d, [grey(10), "blue", "red", "orange", "yellow", "green"], tlen = twist_len)) + translate([0, mouse_y + cable_pitch * i]) { + tr = cable_twisted_radius(cable); + bend_r = 5; + x = -d + thickness - bend_r; + path = [ + [-5, 0, tr], + [x, 0, tr], + bend_r, [x, 0, -25] + ]; + rpath = rounded_path(path); + tpaths = twisted_cable(cable, rpath, irot = irot, frot = -irot); + positions = cable_bundle_positions(cable); + + ends = [for(p = positions) [[30, p.x, p.y], [0, p.x, p.y]]]; + paths = [for(i = [0 : len(tpaths) - 1]) bezier_join(ends[i], tpaths[i], 1.3, 3)]; + cable(cable, paths, $fn = 32); + } } if($preview) diff --git a/vitamins/wire.scad b/vitamins/wire.scad index d14126d..b413f3d 100644 --- a/vitamins/wire.scad +++ b/vitamins/wire.scad @@ -18,9 +18,11 @@ // // -//! Just a BOM entry at the moment and cable bundle size functions for holes, plus cable ties. +//! Utilities for adding wires to the BOM and optionally drawing them and cable bundle size functions for holes, plus cable ties. // include <../utils/core/core.scad> +use <../utils/sweep.scad> +use <../utils/maths.scad> include module wire(colour, strands, length, strand = 0.2) //! Add stranded wire to the BOM @@ -35,15 +37,16 @@ module ribbon_cable(ways, length) //! Add ribbon cable to the function cable_wires(cable) = cable[0]; //! Number of wires in a bundle function cable_wire_size(cable) = cable[1]; //! Size of each wire in a bundle function cable_is_ribbon(cable) = len(cable) > 2 && cable[2]; //! Is a ribbon cable? -function cable_wire_colours(cable) = assert(len(cable[3]) == cable_wires(cable)) cable[3]; //! Individual wire colours -function cable(wires, size, colours, ribbon = false) = [wires, size, ribbon, colours]; //! Cable constructor +function cable_wire_colours(cable) = assert(len(cable[3]) >= cable_wires(cable)) cable[3]; //! Individual wire colours +function cable_tlen(cable) = cable[4]; //! Twisted cable twist length +function cable(wires, size, colours, ribbon = false, tlen = 25) = [wires, size, ribbon, colours, tlen]; //! Cable constructor // numbers from http://mathworld.wolfram.com/CirclePacking.html function cable_radius(cable) = [0, 1, 2, 2.15, 2.41, 2.7, 3, 3, 3.3][cable_wires(cable)] * cable_wire_size(cable) / 2; //! Radius of a bundle of wires, see . function wire_hole_radius(cable) = ceil(4 * cable_radius(cable) + 1) / 4; //! Radius of a hole to accept a bundle of wires, rounded up to standard metric drill size -function cable_bundle(cable) = //! Arrangement of a bundle in a flat cable clip +function cable_bundle(cable) = //! Dimensions of the bounding rectangle of a bundle of wires in a flat cable clip (cable_is_ribbon(cable) ? [cable_wires(cable), 1] : [[0,0], [1,1], [2,1], [2, 1 + sin(60)], [2,2], [3, 1 + sin(60)], [3,2]][cable_wires(cable)]) * cable_wire_size(cable); @@ -53,12 +56,42 @@ function cable_bundle_positions(cable) = let( //! Positions of wires in a bundle top = wires - bottom ) [for(i = [0 : 1 : bottom - 1]) [i - (bottom - 1) / 2, 0.5], - for(i = [0 : 1 : top - 1]) [i - (top - 1) / 2, top == bottom ? 1.5 : 0.5 + sin(60)] + for(i = [top - 1 : -1 : 0]) [i - (top - 1) / 2, top == bottom ? 1.5 : 0.5 + sin(60)] ] * cable_wire_size(cable); function cable_width(cable) = cable_bundle(cable).x; //! Width in flat clip function cable_height(cable) = cable_bundle(cable).y; //! Height in flat clip +function cable_twisted_radius(cable) = let( //! Approximate radius of a cable when twisted + tlen = cable_tlen(cable), // Twist length + a = cable_wire_size(cable) / 2, // Ellipse minor axis + R = cable_radius(cable) - a, // Radius of wire centres when not twisted + angle = atan2(tlen, 2 * PI * R), // Slope angle of the spiral + b = a / sin(angle), // Ellipse major axis + grad = tan(180 / cable_wires(cable)), // Gradient at contact point between elipses + x = a^2 / sqrt(a^2 + (b / grad)^2), // Contact point of the ellipse tangent + y = b * sqrt(1 - x^2 / a^2) + ) R ? x + y / grad + a : a; // Where the tangent meets the X axis plus radius + +function twisted_cable(cable, path, irot = 0, frot = 0) = let( //! Return the paths for a twisted cable, `irot` is the initial rotation and frot the final rotation + tlen = cable_tlen(cable), // Twist length + r = cable_wire_size(cable) / 2, + pitch = cable_twisted_radius(cable) - r, + wires = cable_wires(cable), + bottom = wires > 4 ? 3 : 2, + irot = irot + 90 - 180 * (bottom - 1) / wires + ) + spiral_paths(path, wires, pitch, round(path_length(path) / tlen) - frot / 360, irot); + +module cable(cable, paths) { //! Draw a cable, given a list of paths + wires = cable_wires(cable); + assert(len(paths) == wires); + r = cable_wire_size(cable) / 2; + for(i = [0 : wires - 1]) + color(cable_wire_colours(cable)[i]) + sweep(paths[i], circle_points(r), convexity = 5); +} + module mouse_hole(cable, h = 100, teardrop = false) { //! A mouse hole to allow a panel to go over a wire bundle. r = wire_hole_radius(cable);