1
0
mirror of https://github.com/nophead/NopSCADlib.git synced 2025-09-03 20:32:35 +02:00

Compare commits

...

10 Commits

Author SHA1 Message Date
Chris Palmer
42fccc1afb Added bezier_join().
Moved path_length() from sweep.scad to maths.scad.
2022-02-23 11:53:02 +00:00
Chris Palmer
76aa613093 Updated changelog. 2022-02-15 22:20:46 +00:00
Chris Palmer
0e2778e13d Cables can now have a list of wire colours.
Added a constructor for cables.
2022-02-15 21:51:09 +00:00
Chris Palmer
50e23e5f81 Added silkscreen text to PCBs. 2022-02-15 21:49:25 +00:00
Chris Palmer
59eeb2c5d4 Trimmed the ribbon clamp tape. 2022-02-15 10:52:38 +00:00
Chris Palmer
7ea4dbe6cb Fixed double application of r2sides() in rounded_path().
Added check for radius too big for corner in rounded_path().
Spiral paths can now have 0 twists.
2022-02-15 10:44:13 +00:00
Chris Palmer
0d062c24fa Updated changelog. 2022-02-11 09:11:05 +00:00
Chris Palmer
95b6771811 Added printed cable clips. 2022-02-11 09:08:51 +00:00
Chris Palmer
ed46cbb147 Fixed cable_bundle() bugs and added test.
Added cable_bundle_positions().
Can now mark cables as ribbon to force a flat layout.
2022-02-11 09:07:34 +00:00
Chris Palmer
14ba135169 Updated changelog. 2022-02-09 22:05:58 +00:00
23 changed files with 414 additions and 70 deletions

View File

@@ -3,6 +3,37 @@
This changelog is generated by `changelog.py` using manually added semantic version tags to classify commits as breaking changes, additions or fixes.
### [v19.20.0](https://github.com/nophead/NopSCADlib/releases/tag/v19.20.0 "show release") Additions [...](https://github.com/nophead/NopSCADlib/compare/v19.9.1...v19.20.0 "diff with v19.9.1")
* 2022-02-15 [`0e2778e`](https://github.com/nophead/NopSCADlib/commit/0e2778e13de2e68fc21a7b4c706aada27a17842c "show commit") [C.P.](# "Chris Palmer") Cables can now have a list of wire colours.
Added a constructor for cables.
* 2022-02-15 [`50e23e5`](https://github.com/nophead/NopSCADlib/commit/50e23e5f818077e3661e25852dc959c34e6c8b4a "show commit") [C.P.](# "Chris Palmer") Added silkscreen text to PCBs.
#### [v19.9.1](https://github.com/nophead/NopSCADlib/releases/tag/v19.9.1 "show release") Fixes [...](https://github.com/nophead/NopSCADlib/compare/v19.9.0...v19.9.1 "diff with v19.9.0")
* 2022-02-15 [`59eeb2c`](https://github.com/nophead/NopSCADlib/commit/59eeb2c5d4c7cf9da1f219c2b01fabcf450085f3 "show commit") [C.P.](# "Chris Palmer") Trimmed the ribbon clamp tape.
* 2022-02-15 [`7ea4dbe`](https://github.com/nophead/NopSCADlib/commit/7ea4dbe6cbbc23256d23f7aea87e8aac8d1000a9 "show commit") [C.P.](# "Chris Palmer") Fixed double application of `r2sides()` in `rounded_path()`.
Added check for radius too big for corner in `rounded_path()`.
Spiral paths can now have 0 twists.
### [v19.9.0](https://github.com/nophead/NopSCADlib/releases/tag/v19.9.0 "show release") Additions [...](https://github.com/nophead/NopSCADlib/compare/v19.8.1...v19.9.0 "diff with v19.8.1")
* 2022-02-11 [`95b6771`](https://github.com/nophead/NopSCADlib/commit/95b6771811fd48af46b5c2d426c42c04cd8e5af3 "show commit") [C.P.](# "Chris Palmer") Added printed cable clips.
* 2022-02-11 [`ed46cbb`](https://github.com/nophead/NopSCADlib/commit/ed46cbb1470587d4fa3ee4e0e8e0513c82693b1b "show commit") [C.P.](# "Chris Palmer") Fixed `cable_bundle()` bugs and added test.
Added `cable_bundle_positions()`.
Can now mark cables as ribbon to force a flat layout.
#### [v19.8.1](https://github.com/nophead/NopSCADlib/releases/tag/v19.8.1 "show release") Fixes [...](https://github.com/nophead/NopSCADlib/compare/v19.8.0...v19.8.1 "diff with v19.8.0")
* 2022-02-09 [`2a2b7d8`](https://github.com/nophead/NopSCADlib/commit/2a2b7d8bd60f0ea8ad2c428593e7aea1dfa06e9c "show commit") [C.P.](# "Chris Palmer") Added a second example project.
### [v19.8.0](https://github.com/nophead/NopSCADlib/releases/tag/v19.8.0 "show release") Additions [...](https://github.com/nophead/NopSCADlib/compare/v19.7.0...v19.8.0 "diff with v19.7.0")
* 2022-02-09 [`055b4e7`](https://github.com/nophead/NopSCADlib/commit/055b4e7102ffcc39dc376330636efa79739a6555 "show commit") [C.P.](# "Chris Palmer") Added SOT23 and SOT223 SMD packages.
`smd_capacitors` can now have a value.
Wire links can now have zero length to create a vertical wire.
* 2022-02-09 [`00d6efc`](https://github.com/nophead/NopSCADlib/commit/00d6efc3154bbd5597a3336bc8bdaf550e42f56a "show commit") [C.P.](# "Chris Palmer") Added veroboard constructor.
Documented `solder_meniscus` and made it parametric.
### [v19.7.0](https://github.com/nophead/NopSCADlib/releases/tag/v19.7.0 "show release") Additions [...](https://github.com/nophead/NopSCADlib/compare/v19.6.0...v19.7.0 "diff with v19.6.0")
* 2022-02-08 [`1f55097`](https://github.com/nophead/NopSCADlib/commit/1f55097bdd3e4d0164a48dd7ebb3fc5370250ac4 "show commit") [C.P.](# "Chris Palmer") Support for twisted cables.
Sweep now distbutes twists in proportion to segments lengths.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 979 KiB

After

Width:  |  Height:  |  Size: 982 KiB

View File

@@ -51,6 +51,7 @@ use <tests/blowers.scad>
use <tests/box_sections.scad>
use <tests/bulldogs.scad>
use <tests/buttons.scad>
use <tests/cable_clip.scad>
use <tests/cable_strips.scad>
use <tests/cameras.scad>
use <tests/camera_housing.scad>
@@ -154,19 +155,46 @@ translate([x5 + 50, cable_grommets_y])
translate([x5 + 95, cable_grommets_y])
press_fits();
translate([x5, cable_grommets_y + 60])
fixing_blocks_y = cable_grommets_y + 60;
translate([x5, fixing_blocks_y])
fixing_blocks();
translate([x5, cable_grommets_y + 90])
corner_blocks_y = fixing_blocks_y + 30;
translate([x5, corner_blocks_y])
corner_blocks();
translate([x5, cable_grommets_y + 160])
feet_y = corner_blocks_y + 70;
translate([x5, feet_y])
feet();
translate([x5 + 70, cable_grommets_y + 160])
translate([x5 + 70, feet_y])
screw_knobs();
translate([x5, cable_grommets_y + 470]) {
knobs_y = feet_y + 40;
translate([640, knobs_y])
printed_pulley_test();
translate([x5, knobs_y])
knobs();
clips_y = knobs_y + 50;
translate([x5, clips_y])
cable_clips();
strap_y = clips_y + 50;
translate([x5 + 60, strap_y])
strap_handles();
handle_y = strap_y + 50;
translate([x5, handle_y])
handle();
pocket_y = handle_y + 70;
translate([x5 + 65, pocket_y])
pocket_handles();
hinge_y = pocket_y + 100;
translate([x5, hinge_y]) {
door_hinges()
door_latches();
@@ -174,29 +202,14 @@ translate([x5, cable_grommets_y + 470]) {
flat_hinges();
}
translate([x5, cable_grommets_y + 380])
no_explode() socket_boxes();
pbox_y = hinge_y + 70;
translate([900, pbox_y])
printed_boxes();
translate([640, cable_grommets_y + 200])
printed_pulley_test();
translate([x5, cable_grommets_y + 200])
knobs();
translate([x5 + 60, cable_grommets_y + 250])
strap_handles();
translate([x5, cable_grommets_y + 300])
handle();
translate([950, 600])
box_y = pbox_y + 150;
translate([950, box_y])
box_test();
translate([900, 750])
pocket_handles();
translate([900, 850])
printed_boxes();
translate([950, 1400])
rotate(-90)
@@ -427,6 +440,9 @@ translate([x2, extrusions_y])
translate([400, transformers_y])
transformers();
translate([x4 + 50, transformers_y])
no_explode() socket_boxes();
belts_y = 0;
rails_y = belts_y + 200;

117
printed/cable_clip.scad Normal file
View File

@@ -0,0 +1,117 @@
//
// NopSCADlib Copyright Chris Palmer 2022
// nop.head@gmail.com
// hydraraptor.blogspot.com
//
// This file is part of NopSCADlib.
//
// NopSCADlib is free software: you can redistribute it and/or modify it under the terms of the
// GNU General Public License as published by the Free Software Foundation, either version 3 of
// the License, or (at your option) any later version.
//
// NopSCADlib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
// without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// See the GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along with NopSCADlib.
// If not, see <https://www.gnu.org/licenses/>.
//
//
//! Cable clips to order. Can be for one or two cables of different sizes.
//
include <../core.scad>
use <../vitamins/wire.scad>
use <../utils/fillet.scad>
wall = 2;
function cable_clip_width(screw) = max(wall + 2 * screw_clearance_radius(screw) + wall, washer_diameter(screw_washer(screw))); //! Width given the `screw`.
function cable_clip_height(cable) = cable_height(cable) + wall; //! Height given the `cable`.
function cable_clip_extent(screw, cable) = screw_clearance_radius(screw) + wall + cable_width(cable) + wall; //! How far it extends from the screw.
function cable_clip_offset(screw, cable) = screw_clearance_radius(screw) + wall + cable_width(cable) / 2; //! The offset of the cable from the screw
module single_cable_clip(screw, cable, h = 0) {
screw_dia = 2 * screw_clearance_radius(screw);
height = cable_clip_width(screw);
depth = h ? h : cable_height(cable) + wall;
w = cable_width(cable);
width = wall + w + wall + screw_dia + wall;
hole_x = wall + w + wall + screw_dia / 2;
rad = min(wall + cable_wire_size(cable) / 2, depth / 2);
r = extrusion_width - eps;
translate([-hole_x, 0]) difference() {
linear_extrude(height)
difference() {
hull() {
rounded_square([width, 1], r, center = false);
translate([width - 1, 0])
rounded_square([1, depth], r, center = false);
translate([rad, depth - rad])
circle(r = rad);
}
translate([wall + cable_width(cable) / 2, 0]) {
hull() {
for(p = cable_bundle_positions(cable))
translate(p)
circle(d = cable_wire_size(cable));
square([w, eps], center = true);
}
for(side = [-1, 1])
translate([side * w / 2, 0])
hflip(side < 0)
fillet(r = r, h = 0);
}
}
translate([hole_x, depth / 2, height / 2])
rotate([90,0,0])
teardrop_plus(h = depth + 1, r = screw_dia / 2, center = true);
}
}
module double_cable_clip(screw, cable1, cable2) {
h = max(cable_clip_height(cable1), cable_clip_height(cable2));
union() {
single_cable_clip(screw, cable1, h);
mirror([1,0,0]) single_cable_clip(screw, cable2, h);
}
}
module cable_clip(screw, cable1, cable2 = 0) { //! Create the STL for a single cable or two cable clip
function clip_str(screw) = str("cable_clip_", screw_radius(screw) * 20);
function cable_str(cable) = str("_", cable_wires(cable), "_", round(cable_wire_size(cable) * 10));
if(cable2) {
stl(str(clip_str(screw), cable_str(cable1), cable_str(cable2)));
double_cable_clip(screw, cable1, cable2);
}
else {
stl(str(clip_str(screw), cable_str(cable1)));
single_cable_clip(screw, cable1);
}
}
module cable_clip_assembly(screw, thickness, cable1, cable2 = 0) { //! Cable clip with the fasteners
height = max(cable_clip_height(cable1), cable2 ? cable_clip_height(cable2) : 0);
stl_colour(pp1_colour) render()
translate([0, cable_clip_width(screw) / 2]) rotate([90, 0, 0])
cable_clip(screw, cable1, cable2);
translate_z(height)
screw_and_washer(screw, screw_length(screw, height + thickness, 2, nyloc = true));
translate_z(-thickness)
vflip()
nut_and_washer(screw_nut(screw), true);
}

View File

@@ -105,7 +105,7 @@ assembly(let(screw_d = screw_radius(screw) * 2)str("ribbon_clamp_", str_ways(way
module ribbon_clamp_fastened_assembly(ways, thickness, screw = screw) { //! Clamp with fasteners in place
tape_l = floor(ribbon_clamp_slot(ways));
tape_width = 25;
tape_width = ribbon_clamp_width(screw) + 2;
tape_thickness = 0.5;
vitamin(str(": Tape self amalgamating silicone ",tape_l," x 25mm"));

105
readme.md
View File

@@ -23,30 +23,31 @@ A list of changes classified as breaking, additions or fixes is maintained in [C
<th align="left"> Vitamins A-H </th><th align="left"> Vitamins I-Q </th><th align="left"> Vitamins R-Z </th><th align="left"> Printed </th><th align="left"> Utilities </th><th align="left"> Core Utilities </th></tr>
<tr><td> <a href = "#7_segments">7_segments</a> </td><td> <a href = "#IECs">IECs</a> </td><td> <a href = "#Rails">Rails</a> </td><td> <a href = "#Box">Box</a> </td><td> <a href = "#Annotation">Annotation</a> </td><td> <a href = "#BOM">BOM</a> </td></tr>
<tr><td> <a href = "#Axials">Axials</a> </td><td> <a href = "#Inserts">Inserts</a> </td><td> <a href = "#Ring_terminals">Ring_terminals</a> </td><td> <a href = "#Butt_box">Butt_box</a> </td><td> <a href = "#Bezier">Bezier</a> </td><td> <a href = "#Clip">Clip</a> </td></tr>
<tr><td> <a href = "#BLDC_motors">BLDC_motors</a> </td><td> <a href = "#Jack">Jack</a> </td><td> <a href = "#Rockers">Rockers</a> </td><td> <a href = "#Cable_grommets">Cable_grommets</a> </td><td> <a href = "#Catenary">Catenary</a> </td><td> <a href = "#Global">Global</a> </td></tr>
<tr><td> <a href = "#Ball_bearings">Ball_bearings</a> </td><td> <a href = "#LDRs">LDRs</a> </td><td> <a href = "#Rod">Rod</a> </td><td> <a href = "#Camera_housing">Camera_housing</a> </td><td> <a href = "#Core_xy">Core_xy</a> </td><td> <a href = "#Polyholes">Polyholes</a> </td></tr>
<tr><td> <a href = "#Batteries">Batteries</a> </td><td> <a href = "#LED_meters">LED_meters</a> </td><td> <a href = "#SK_brackets">SK_brackets</a> </td><td> <a href = "#Carriers">Carriers</a> </td><td> <a href = "#Dogbones">Dogbones</a> </td><td> <a href = "#Rounded_rectangle">Rounded_rectangle</a> </td></tr>
<tr><td> <a href = "#Bearing_blocks">Bearing_blocks</a> </td><td> <a href = "#LEDs">LEDs</a> </td><td> <a href = "#SMDs">SMDs</a> </td><td> <a href = "#Corner_block">Corner_block</a> </td><td> <a href = "#Fillet">Fillet</a> </td><td> <a href = "#Sphere">Sphere</a> </td></tr>
<tr><td> <a href = "#Belts">Belts</a> </td><td> <a href = "#Leadnuts">Leadnuts</a> </td><td> <a href = "#SSRs">SSRs</a> </td><td> <a href = "#Door_hinge">Door_hinge</a> </td><td> <a href = "#Gears">Gears</a> </td><td> <a href = "#Teardrops">Teardrops</a> </td></tr>
<tr><td> <a href = "#Blowers">Blowers</a> </td><td> <a href = "#Light_strips">Light_strips</a> </td><td> <a href = "#Screws">Screws</a> </td><td> <a href = "#Door_latch">Door_latch</a> </td><td> <a href = "#Hanging_hole">Hanging_hole</a> </td><td></td></tr>
<tr><td> <a href = "#Box_sections">Box_sections</a> </td><td> <a href = "#Linear_bearings">Linear_bearings</a> </td><td> <a href = "#Sealing_strip">Sealing_strip</a> </td><td> <a href = "#Drag_chain">Drag_chain</a> </td><td> <a href = "#Horiholes">Horiholes</a> </td><td></td></tr>
<tr><td> <a href = "#Bulldogs">Bulldogs</a> </td><td> <a href = "#Magnets">Magnets</a> </td><td> <a href = "#Servo_motors">Servo_motors</a> </td><td> <a href = "#Fan_guard">Fan_guard</a> </td><td> <a href = "#Layout">Layout</a> </td><td></td></tr>
<tr><td> <a href = "#Buttons">Buttons</a> </td><td> <a href = "#Mains_sockets">Mains_sockets</a> </td><td> <a href = "#Shaft_couplings">Shaft_couplings</a> </td><td> <a href = "#Fixing_block">Fixing_block</a> </td><td> <a href = "#Maths">Maths</a> </td><td></td></tr>
<tr><td> <a href = "#Cable_strips">Cable_strips</a> </td><td> <a href = "#Microswitches">Microswitches</a> </td><td> <a href = "#Sheets">Sheets</a> </td><td> <a href = "#Flat_hinge">Flat_hinge</a> </td><td> <a href = "#Offset">Offset</a> </td><td></td></tr>
<tr><td> <a href = "#Cameras">Cameras</a> </td><td> <a href = "#Microview">Microview</a> </td><td> <a href = "#Spades">Spades</a> </td><td> <a href = "#Foot">Foot</a> </td><td> <a href = "#Quadrant">Quadrant</a> </td><td></td></tr>
<tr><td> <a href = "#Circlips">Circlips</a> </td><td> <a href = "#Modules">Modules</a> </td><td> <a href = "#Spools">Spools</a> </td><td> <a href = "#Handle">Handle</a> </td><td> <a href = "#Round">Round</a> </td><td></td></tr>
<tr><td> <a href = "#Components">Components</a> </td><td> <a href = "#Nuts">Nuts</a> </td><td> <a href = "#Springs">Springs</a> </td><td> <a href = "#Knob">Knob</a> </td><td> <a href = "#Rounded_cylinder">Rounded_cylinder</a> </td><td></td></tr>
<tr><td> <a href = "#DIP">DIP</a> </td><td> <a href = "#O_ring">O_ring</a> </td><td> <a href = "#Stepper_motors">Stepper_motors</a> </td><td> <a href = "#PCB_mount">PCB_mount</a> </td><td> <a href = "#Rounded_polygon">Rounded_polygon</a> </td><td></td></tr>
<tr><td> <a href = "#D_connectors">D_connectors</a> </td><td> <a href = "#Opengrab">Opengrab</a> </td><td> <a href = "#Swiss_clips">Swiss_clips</a> </td><td> <a href = "#PSU_shroud">PSU_shroud</a> </td><td> <a href = "#Rounded_triangle">Rounded_triangle</a> </td><td></td></tr>
<tr><td> <a href = "#Displays">Displays</a> </td><td> <a href = "#PCB">PCB</a> </td><td> <a href = "#Terminals">Terminals</a> </td><td> <a href = "#Pocket_handle">Pocket_handle</a> </td><td> <a href = "#Sector">Sector</a> </td><td></td></tr>
<tr><td> <a href = "#Extrusion_brackets">Extrusion_brackets</a> </td><td> <a href = "#PCBs">PCBs</a> </td><td> <a href = "#Toggles">Toggles</a> </td><td> <a href = "#Press_fit">Press_fit</a> </td><td> <a href = "#Sweep">Sweep</a> </td><td></td></tr>
<tr><td> <a href = "#Extrusions">Extrusions</a> </td><td> <a href = "#PSUs">PSUs</a> </td><td> <a href = "#Transformers">Transformers</a> </td><td> <a href = "#Printed_box">Printed_box</a> </td><td> <a href = "#Thread">Thread</a> </td><td></td></tr>
<tr><td> <a href = "#Fans">Fans</a> </td><td> <a href = "#Panel_meters">Panel_meters</a> </td><td> <a href = "#Tubings">Tubings</a> </td><td> <a href = "#Printed_pulleys">Printed_pulleys</a> </td><td> <a href = "#Tube">Tube</a> </td><td></td></tr>
<tr><td> <a href = "#Fuseholder">Fuseholder</a> </td><td> <a href = "#Pillars">Pillars</a> </td><td> <a href = "#Variacs">Variacs</a> </td><td> <a href = "#Ribbon_clamp">Ribbon_clamp</a> </td><td></td><td></td></tr>
<tr><td> <a href = "#Geared_steppers">Geared_steppers</a> </td><td> <a href = "#Pillow_blocks">Pillow_blocks</a> </td><td> <a href = "#Veroboard">Veroboard</a> </td><td> <a href = "#SSR_shroud">SSR_shroud</a> </td><td></td><td></td></tr>
<tr><td> <a href = "#Green_terminals">Green_terminals</a> </td><td> <a href = "#Pin_headers">Pin_headers</a> </td><td> <a href = "#Washers">Washers</a> </td><td> <a href = "#Screw_knob">Screw_knob</a> </td><td></td><td></td></tr>
<tr><td> <a href = "#Hot_ends">Hot_ends</a> </td><td> <a href = "#Potentiometers">Potentiometers</a> </td><td> <a href = "#Wire">Wire</a> </td><td> <a href = "#Socket_box">Socket_box</a> </td><td></td><td></td></tr>
<tr><td> <a href = "#Hygrometer">Hygrometer</a> </td><td> <a href = "#Pulleys">Pulleys</a> </td><td> <a href = "#Zipties">Zipties</a> </td><td> <a href = "#Strap_handle">Strap_handle</a> </td><td></td><td></td></tr>
<tr><td> <a href = "#BLDC_motors">BLDC_motors</a> </td><td> <a href = "#Jack">Jack</a> </td><td> <a href = "#Rockers">Rockers</a> </td><td> <a href = "#Cable_clip">Cable_clip</a> </td><td> <a href = "#Catenary">Catenary</a> </td><td> <a href = "#Global">Global</a> </td></tr>
<tr><td> <a href = "#Ball_bearings">Ball_bearings</a> </td><td> <a href = "#LDRs">LDRs</a> </td><td> <a href = "#Rod">Rod</a> </td><td> <a href = "#Cable_grommets">Cable_grommets</a> </td><td> <a href = "#Core_xy">Core_xy</a> </td><td> <a href = "#Polyholes">Polyholes</a> </td></tr>
<tr><td> <a href = "#Batteries">Batteries</a> </td><td> <a href = "#LED_meters">LED_meters</a> </td><td> <a href = "#SK_brackets">SK_brackets</a> </td><td> <a href = "#Camera_housing">Camera_housing</a> </td><td> <a href = "#Dogbones">Dogbones</a> </td><td> <a href = "#Rounded_rectangle">Rounded_rectangle</a> </td></tr>
<tr><td> <a href = "#Bearing_blocks">Bearing_blocks</a> </td><td> <a href = "#LEDs">LEDs</a> </td><td> <a href = "#SMDs">SMDs</a> </td><td> <a href = "#Carriers">Carriers</a> </td><td> <a href = "#Fillet">Fillet</a> </td><td> <a href = "#Sphere">Sphere</a> </td></tr>
<tr><td> <a href = "#Belts">Belts</a> </td><td> <a href = "#Leadnuts">Leadnuts</a> </td><td> <a href = "#SSRs">SSRs</a> </td><td> <a href = "#Corner_block">Corner_block</a> </td><td> <a href = "#Gears">Gears</a> </td><td> <a href = "#Teardrops">Teardrops</a> </td></tr>
<tr><td> <a href = "#Blowers">Blowers</a> </td><td> <a href = "#Light_strips">Light_strips</a> </td><td> <a href = "#Screws">Screws</a> </td><td> <a href = "#Door_hinge">Door_hinge</a> </td><td> <a href = "#Hanging_hole">Hanging_hole</a> </td><td></td></tr>
<tr><td> <a href = "#Box_sections">Box_sections</a> </td><td> <a href = "#Linear_bearings">Linear_bearings</a> </td><td> <a href = "#Sealing_strip">Sealing_strip</a> </td><td> <a href = "#Door_latch">Door_latch</a> </td><td> <a href = "#Horiholes">Horiholes</a> </td><td></td></tr>
<tr><td> <a href = "#Bulldogs">Bulldogs</a> </td><td> <a href = "#Magnets">Magnets</a> </td><td> <a href = "#Servo_motors">Servo_motors</a> </td><td> <a href = "#Drag_chain">Drag_chain</a> </td><td> <a href = "#Layout">Layout</a> </td><td></td></tr>
<tr><td> <a href = "#Buttons">Buttons</a> </td><td> <a href = "#Mains_sockets">Mains_sockets</a> </td><td> <a href = "#Shaft_couplings">Shaft_couplings</a> </td><td> <a href = "#Fan_guard">Fan_guard</a> </td><td> <a href = "#Maths">Maths</a> </td><td></td></tr>
<tr><td> <a href = "#Cable_strips">Cable_strips</a> </td><td> <a href = "#Microswitches">Microswitches</a> </td><td> <a href = "#Sheets">Sheets</a> </td><td> <a href = "#Fixing_block">Fixing_block</a> </td><td> <a href = "#Offset">Offset</a> </td><td></td></tr>
<tr><td> <a href = "#Cameras">Cameras</a> </td><td> <a href = "#Microview">Microview</a> </td><td> <a href = "#Spades">Spades</a> </td><td> <a href = "#Flat_hinge">Flat_hinge</a> </td><td> <a href = "#Quadrant">Quadrant</a> </td><td></td></tr>
<tr><td> <a href = "#Circlips">Circlips</a> </td><td> <a href = "#Modules">Modules</a> </td><td> <a href = "#Spools">Spools</a> </td><td> <a href = "#Foot">Foot</a> </td><td> <a href = "#Round">Round</a> </td><td></td></tr>
<tr><td> <a href = "#Components">Components</a> </td><td> <a href = "#Nuts">Nuts</a> </td><td> <a href = "#Springs">Springs</a> </td><td> <a href = "#Handle">Handle</a> </td><td> <a href = "#Rounded_cylinder">Rounded_cylinder</a> </td><td></td></tr>
<tr><td> <a href = "#DIP">DIP</a> </td><td> <a href = "#O_ring">O_ring</a> </td><td> <a href = "#Stepper_motors">Stepper_motors</a> </td><td> <a href = "#Knob">Knob</a> </td><td> <a href = "#Rounded_polygon">Rounded_polygon</a> </td><td></td></tr>
<tr><td> <a href = "#D_connectors">D_connectors</a> </td><td> <a href = "#Opengrab">Opengrab</a> </td><td> <a href = "#Swiss_clips">Swiss_clips</a> </td><td> <a href = "#PCB_mount">PCB_mount</a> </td><td> <a href = "#Rounded_triangle">Rounded_triangle</a> </td><td></td></tr>
<tr><td> <a href = "#Displays">Displays</a> </td><td> <a href = "#PCB">PCB</a> </td><td> <a href = "#Terminals">Terminals</a> </td><td> <a href = "#PSU_shroud">PSU_shroud</a> </td><td> <a href = "#Sector">Sector</a> </td><td></td></tr>
<tr><td> <a href = "#Extrusion_brackets">Extrusion_brackets</a> </td><td> <a href = "#PCBs">PCBs</a> </td><td> <a href = "#Toggles">Toggles</a> </td><td> <a href = "#Pocket_handle">Pocket_handle</a> </td><td> <a href = "#Sweep">Sweep</a> </td><td></td></tr>
<tr><td> <a href = "#Extrusions">Extrusions</a> </td><td> <a href = "#PSUs">PSUs</a> </td><td> <a href = "#Transformers">Transformers</a> </td><td> <a href = "#Press_fit">Press_fit</a> </td><td> <a href = "#Thread">Thread</a> </td><td></td></tr>
<tr><td> <a href = "#Fans">Fans</a> </td><td> <a href = "#Panel_meters">Panel_meters</a> </td><td> <a href = "#Tubings">Tubings</a> </td><td> <a href = "#Printed_box">Printed_box</a> </td><td> <a href = "#Tube">Tube</a> </td><td></td></tr>
<tr><td> <a href = "#Fuseholder">Fuseholder</a> </td><td> <a href = "#Pillars">Pillars</a> </td><td> <a href = "#Variacs">Variacs</a> </td><td> <a href = "#Printed_pulleys">Printed_pulleys</a> </td><td></td><td></td></tr>
<tr><td> <a href = "#Geared_steppers">Geared_steppers</a> </td><td> <a href = "#Pillow_blocks">Pillow_blocks</a> </td><td> <a href = "#Veroboard">Veroboard</a> </td><td> <a href = "#Ribbon_clamp">Ribbon_clamp</a> </td><td></td><td></td></tr>
<tr><td> <a href = "#Green_terminals">Green_terminals</a> </td><td> <a href = "#Pin_headers">Pin_headers</a> </td><td> <a href = "#Washers">Washers</a> </td><td> <a href = "#SSR_shroud">SSR_shroud</a> </td><td></td><td></td></tr>
<tr><td> <a href = "#Hot_ends">Hot_ends</a> </td><td> <a href = "#Potentiometers">Potentiometers</a> </td><td> <a href = "#Wire">Wire</a> </td><td> <a href = "#Screw_knob">Screw_knob</a> </td><td></td><td></td></tr>
<tr><td> <a href = "#Hygrometer">Hygrometer</a> </td><td> <a href = "#Pulleys">Pulleys</a> </td><td> <a href = "#Zipties">Zipties</a> </td><td> <a href = "#Socket_box">Socket_box</a> </td><td></td><td></td></tr>
<tr><td></td><td></td><td></td><td> <a href = "#Strap_handle">Strap_handle</a> </td><td></td><td></td></tr>
</table>
---
@@ -4390,10 +4391,14 @@ 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_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 <http://mathworld.wolfram.com/CirclePacking.html>. |
| `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 |
| `wire_hole_radius(cable)` | Radius of a hole to accept a bundle of wires, rounded up to standard metric drill size |
@@ -4684,6 +4689,51 @@ fixing_blocks along the sides.
| 12 | fixing_block_M30_assembly |
<a href="#top">Top</a>
---
<a name="Cable_clip"></a>
## Cable_clip
Cable clips to order. Can be for one or two cables of different sizes.
[printed/cable_clip.scad](printed/cable_clip.scad) Implementation.
[tests/cable_clip.scad](tests/cable_clip.scad) Code for this example.
### Functions
| Function | Description |
|:--- |:--- |
| `cable_clip_extent(screw, cable)` | How far it extends from the screw. |
| `cable_clip_height(cable)` | Height given the `cable`. |
| `cable_clip_offset(screw, cable)` | The offset of the cable from the screw |
| `cable_clip_width(screw)` | Width given the `screw`. |
### Modules
| Module | Description |
|:--- |:--- |
| `cable_clip(screw, cable1, cable2 = 0)` | Create the STL for a single cable or two cable clip |
| `cable_clip_assembly(screw, thickness, cable1, cable2 = 0)` | Cable clip with the fasteners |
![cable_clip](tests/png/cable_clip.png)
### Vitamins
| Qty | Module call | BOM entry |
| ---:|:--- |:---|
| 5 | `nut(M3_nut, nyloc = true)` | Nut M3 x 2.4mm nyloc |
| 2 | `screw(M3_dome_screw, 12)` | Screw M3 dome x 12mm |
| 3 | `screw(M3_dome_screw, 16)` | Screw M3 dome x 16mm |
| 10 | `washer(M3_washer)` | Washer M3 x 7mm x 0.5mm |
### Printed
| Qty | Filename |
| ---:|:--- |
| 1 | cable_clip_30_10_13.stl |
| 1 | cable_clip_30_1_14_2_14.stl |
| 1 | cable_clip_30_1_60.stl |
| 1 | cable_clip_30_3_14_4_14.stl |
| 1 | cable_clip_30_5_14_6_14.stl |
<a href="#top">Top</a>
---
@@ -6080,6 +6130,10 @@ Annotation used in this documentation
## Bezier
Bezier curves and function to get and adjust the length or minimum z point.
`bezier_join()` joins two paths with a Bezier curve that starts tangential to the end of `path1` and ends tangential to the end of `path2`.
To do this the outer control points are the path ends and the inner two control points are along the tangents to the path ends.
The only degree of freedom is how far along those tangents, which are the `d` and optional `d2` parameters.
[utils/bezier.scad](utils/bezier.scad) Implementation.
[tests/bezier.scad](tests/bezier.scad) Code for this example.
@@ -6090,6 +6144,7 @@ Bezier curves and function to get and adjust the length or minimum z point.
| `adjust_bezier_length(v, l, eps = 0.001, r1 = 1.0, r2 = 1.5, l1, l2)` | Adjust Bezier control points `v` to get the required curve length `l` |
| `adjust_bezier_z(v, z, eps = 0.001, r1 = 1, r2 = 1.5, z1, z2)` | Adjust Bezier control points `v` to get the required minimum `z` |
| `bezier(t, v)` | Returns a point at distance `t` [0 - 1] along the curve with control points `v` |
| `bezier_join(path1, path2, d, d2 = undef)` | Join two paths with a Bezier curve, control points are the path ends are `d` and `d2` from the ends in the same direction. |
| `bezier_length(v, delta = 0.01, t = 0, length = 0)` | Calculate the length of a Bezier curve from control points `v` |
| `bezier_min_z(v, steps = 100, z = inf, i = 0)` | Calculate the minimum z coordinate of a Bezier curve from control points `v` |
| `bezier_path(v, steps = 100)` | Returns a Bezier path from control points `v` with `steps` segments |
@@ -6380,6 +6435,7 @@ Maths utilities for manipulating vectors and matrices.
| `map(v, func)` | make a new vector where the func function argument is applied to each element of the vector v |
| `mapi(v, func)` | make a new vector where the func function argument is applied to each element of the vector v. The func will get the index number as first argument, and the element as second argument. |
| `nearly_zero(x)` | True if x is close to zero |
| `path_length(path, i = 0, length = 0)` | Calculated the length along a path |
| `quadratic_real_roots(a, b, c)` | Returns real roots of a quadratic equation, biggest first. Returns empty list if no real roots |
| `radians(degrees)` | Convert radians to degrees |
| `reduce(v, func, unity)` | reduce a vector v to a single entity by applying the func function recursively to the reduced value so far and the next element, starting with unity as the initial reduced value |
@@ -6600,7 +6656,6 @@ Each vertex, apart from the first and the last, has an associated radius and the
| `cap(facets, segment = 0, end)` | Create the mesh for an end cap |
| `circle_points(r = 1, z = 0, dir = -1)` | Generate the points of a circle, setting z makes a single turn spiral |
| `helical_twist_per_segment(r, pitch, sides)` | Calculate the twist around Z that rotate_from_to() introduces |
| `path_length(path, i = 0, length = 0)` | Calculated the length along a path |
| `rectangle_points(w, h)` | Generate the points of a rectangle |
| `rounded_path(path)` | Convert a rounded_path, consisting of a start coordinate, vertex / radius pairs and then an end coordinate, to a path of points for sweep. |
| `rounded_path_vertices(path)` | Show the unrounded version of a rounded_path for debug |

View File

@@ -89,6 +89,7 @@ test_pcb = ["test_pcb", "Test PCB",
[ 8, 155, 180, "usb_B"],
[ 25, 200, 0, "buzzer", 4.5, 8.5],
[ 25, 218, 0, "buzzer"],
[ 38, 190, -90, "text", 25, 4, "Silkscreen", "Liberation Sans:style=Bold"],
[ 8, 190, 180, "jack"],
[ 6, 200, 180, "barrel_jack"],
[ 5, 218, 180, "hdmi"],

View File

@@ -77,6 +77,17 @@ module beziers() {
translate(control_points[1] - [0, 0, 2])
label(str("bezier_length = ", length, ", bezier_min_z = ", bezier_min_z(curve)), valign = "top");
path1 = [[20, 20, 0], [40, 20, 0]];
path2 = [[70, 40, -5], [60, 40, 0]];
color("green")
for(p = concat(path1, path2))
translate(p)
sphere(1);
color("orange")
sweep(bezier_join(path1, path2, 10), circle_points(0.5, $fn = 64));
}
if($preview)

59
tests/cable_clip.scad Normal file
View File

@@ -0,0 +1,59 @@
//
// NopSCADlib Copyright Chris Palmer 2022
// nop.head@gmail.com
// hydraraptor.blogspot.com
//
// This file is part of NopSCADlib.
//
// NopSCADlib is free software: you can redistribute it and/or modify it under the terms of the
// GNU General Public License as published by the Free Software Foundation, either version 3 of
// the License, or (at your option) any later version.
//
// NopSCADlib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
// without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// See the GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along with NopSCADlib.
// If not, see <https://www.gnu.org/licenses/>.
//
include <../core.scad>
use <../printed/cable_clip.scad>
use <../vitamins/wire.scad>
sheet_thickness = 3;
cables = [
for(i = [1 : 6]) [i, 1.4], [1, 6], 0, [10, inch(0.05), true], 0
];
screw = M3_dome_screw;
module cable_clips() {
for(i = [0 : ceil(len(cables) / 2) - 1])
translate([i * 25, 0]) {
cable1 = cables[2 * i];
cable2 = cables[2 * i + 1];
if($preview) {
cable_clip_assembly(screw, sheet_thickness, cable1, cable2);
for(j = [0 : 1])
let(cable = cables[2 * i + j])
if(cable)
let(positions = cable_bundle_positions(cable))
for(i = [0 : len(positions) - 1])
let(p = positions[i])
translate([p.x + [-1, 1][j] * cable_clip_offset(screw, cable), 0, p.y])
rotate([90, 0, 0])
color([grey(20), "blue", "red", "orange", "yellow", "green", "brown", "purple", "grey", "white"][i])
cylinder(d = cable_wire_size(cable), h = 30, center = true);
}
else
cable_clip(screw, cable1, cable2);
}
}
cable_clips();

Binary file not shown.

Before

Width:  |  Height:  |  Size: 84 KiB

After

Width:  |  Height:  |  Size: 85 KiB

BIN
tests/png/cable_clip.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 131 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 182 KiB

After

Width:  |  Height:  |  Size: 184 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 90 KiB

After

Width:  |  Height:  |  Size: 94 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 113 KiB

After

Width:  |  Height:  |  Size: 114 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 129 KiB

After

Width:  |  Height:  |  Size: 129 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 71 KiB

After

Width:  |  Height:  |  Size: 128 KiB

View File

@@ -25,13 +25,15 @@ bundle = [7, 1.4];
bundle_r = cable_radius(bundle);
thickness = 2;
w = 50;
w = 60;
d = 20;
h = 40;
wire_l = 90;
mouse_y = 10;
cable_pitch = 7;
module wires() {
translate_z(bundle_r)
translate([0, mouse_y, bundle_r])
rotate([0, 90, 0]) {
n = cable_wires(bundle);
d = cable_wire_size(bundle);
@@ -58,24 +60,39 @@ module wires() {
rotate([90, 0, 90])
linear_extrude(thickness)
difference() {
translate([-w / 2, 0])
square([w, h]);
square([w, h]);
mouse_hole(bundle, 0, true);
translate([mouse_y, 0])
mouse_hole(bundle, 0, true);
for(i = [1 : 6])
let(cable = [i, 1.4], bundle = cable_bundle(cable))
translate([mouse_y + cable_pitch * i - bundle.x / 2, -eps])
square([bundle.x, bundle.y]);
}
translate_z(-thickness)
linear_extrude(thickness)
difference() {
translate([thickness -d, -w / 2])
translate([thickness -d, 0])
square([d, w]);
translate([-15, 0])
translate([-15, mouse_y])
cable_tie_holes(bundle_r, 0);
}
}
translate([-15, 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);
}
if($preview)

View File

@@ -19,8 +19,13 @@
//
//! Bezier curves and function to get and adjust the length or minimum z point.
//!
//! `bezier_join()` joins two paths with a Bezier curve that starts tangential to the end of `path1` and ends tangential to the end of `path2`.
//! To do this the outer control points are the path ends and the inner two control points are along the tangents to the path ends.
//! The only degree of freedom is how far along those tangents, which are the `d` and optional `d2` parameters.
//
include <../global_defs.scad>
include <maths.scad>
function bezier(t, v) = //! Returns a point at distance `t` [0 - 1] along the curve with control points `v`
(len(v) > 2) ? bezier(t, [for (i = [0 : len(v) - 2]) v[i] * (1 - t) + v[i + 1] * (t)])
@@ -55,3 +60,16 @@ function adjust_bezier_z(v, z, eps = 0.001, r1 = 1, r2 = 1.5, z1, z2) = //! Adju
: let(r = r1 + (z - z1) * (r2 - r1) / (z2 - z1))
abs(r - r1) < abs(r - r2) ? adjust_bezier_z(v, z, eps, r, r1, undef, z1)
: adjust_bezier_z(v, z, eps, r, r2, undef, z2);
function bezier_join(path1, path2, d, d2 = undef) = let( //! Join two paths with a Bezier curve, control points are the path ends are `d` and `d2` from the ends in the same direction.
d2 = is_undef(d2) ? d : d2,
l = len(path1),
p0 = path1[l - 1],
p1 = p0 + unit(p0 - path1[l - 2]) * d,
p3 = path2[0],
p2 = p3 + unit(path2[0] - path2[1]) * d2,
v = [p0, p1, p2, p3],
segs = path_length(v) / $fs,
path = [for(i = [1 : segs - 1], t = i / segs) bezier(t, v)],
len = len(path)
) concat(path1, path, path2);

View File

@@ -187,3 +187,7 @@ function cubic_real_roots(a, b, c, d) = //! Returns real roots of cubic equation
) roots == 1 ? [x] :
roots == 2 ? [3 * q /p + inflection, -3 * q / p / 2 + inflection] :
[for(i = [0 : roots - 1]) 2 * sqrt(-p / 3) * cos(acos(3 * q * sqrt(-3 / p) / p / 2) - i * 120) + inflection];
function path_length(path, i = 0, length = 0) = //! Calculated the length along a path
i >= len(path) - 1 ? length
: path_length(path, i + 1, length + norm(path[i + 1] - path[i]));

View File

@@ -177,10 +177,6 @@ module sweep(path, profile, loop = false, twist = 0, convexity = 1) { //! Draw a
polyhedron(points = mesh[0], faces = mesh[1], convexity = convexity);
}
function path_length(path, i = 0, length = 0) = //! Calculated the length along a path
i >= len(path) - 1 ? length
: path_length(path, i + 1, length + norm(path[i + 1] - path[i]));
function circle_points(r = 1, z = 0, dir = -1) = //! Generate the points of a circle, setting z makes a single turn spiral
let(sides = r2sides(r))
[for(i = [0 : sides - 1]) let(a = dir * i * 360 / sides) [r * cos(a), r * sin(a), z * i / sides]];
@@ -215,12 +211,16 @@ function rounded_path(path) = //! Convert a rounded_path, consisting of a start
p0 - p1, // Calculate vectors between vertices
v2 = p2 - p1,
a = angle_between(v1, -v2), // Angle turned through
arc_start = p1 + unit(v1) * r * tan(a / 2), // Calc the start position
d = r * tan(a / 2), // Distance from vertex to tangents
room = min(norm(v1), norm(v2)), // Maximum distance
arc_start = assert(d <= room,
str("Can't fit radius ", r, " into corner at vertex path[", i, "] = ", p1, " only room for radius ", room / tan(a / 2)))
p1 + unit(v1) * d, // Calc the start position
z_axis = unit(cross(v1, v2)), // z_axis is perpendicular to both vectors
centre = arc_start + unit(cross(z_axis, v1)) * r, // Arc center is a radius away, and perpendicular to v1 and the z_axis.
x_axis = arc_start - centre, // Make the x_axis along the radius to the start point, includes radius a scale factor
y_axis = cross(x_axis, z_axis), // y_axis perpendicular to the other two
sides = r2sides(ceil(r2sides(r) * a / 360)) // Sides needed to make the arc
sides = ceil(r2sides(r) * a / 360) // Sides needed to make the arc
)
for(j = [0 : sides], t = a * j / sides) // For each vertex in the arc
cos(t) * x_axis + sin(t) * y_axis + centre, // Circular arc in the tiled xy plane.
@@ -240,7 +240,7 @@ function segmented_path(path, min_segment) = [ //! Add points to a path to enfo
];
function spiral_paths(path, n, r, twists, start_angle) = let( //! Create a new paths which sprial around the given path. Use for making twisted cables
segment = path_length(path) / twists / r2sides(2 * r),
segment = twists ? path_length(path) / twists / r2sides(2 * r) : inf,
transforms = sweep_transforms(segmented_path(path, segment), twist = 360 * twists),
initial = [r, 0, 0, 1] * rotate(start_angle)
) [for(i = [0 : n - 1]) let(initial = [r, 0, 0, 1] * rotate(start_angle + i * 360 / n)) [for(t = transforms) initial * t]];

View File

@@ -1091,6 +1091,8 @@ module pcb_component(comp, cutouts = false, angle = undef) { //! Draw pcb compon
if(show(comp, "smd_sot")) smd_sot(comp[4], comp[5]);
if(show(comp, "vero_pin")) vero_pin(param(4, false));
if(show(comp, "terminal")) terminal_block(comp[5], comp[4]);
if(show(comp, "text")) color("white") linear_extrude(eps) resize([comp[4], comp[5]]) text(comp[6], font = param(7, "Liberation Mono"), valign = "center", halign = "center");
}
}
}

View File

@@ -153,7 +153,7 @@ module smd_sot(type, value) { //! Draw an SMD transistor
ls = smd_sot_lead_size(type);
r = ls.z;
gullwing = rounded_path([[0, 0, ls.z / 2], [0, ls.y - ls.z, ls.z / 2], r, [0, ls.y -ls.z + z1 - ls.z, z1 - ls.z / 2], r, [0, span / 2, z1 - ls.z / 2]]);
gullwing = rounded_path([[0, 0, ls.z / 2], [0, ls.y - ls.z, ls.z / 2], r, [0, ls.y -ls.z + z1 - ls.z, z1 - ls.z / 2], r, [0, span / 2, z1 - ls.z / 2]], $fn = 32);
color(grey(20))
hull()

View File

@@ -34,6 +34,9 @@ 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
// 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 <http://mathworld.wolfram.com/CirclePacking.html>.
@@ -41,10 +44,20 @@ function cable_radius(cable) = [0, 1, 2, 2.15, 2.41, 2.7, 3, 3, 3.3][cable_wires
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
[[0,0], [1,1], [2,1], [2, 0.5 + sin(60)], [2,2], [3, 0.5 + sin(60)], [3,2]][cable_wires(cable)];
(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);
function cable_width(cable) = cable_bundle(cable)[0] * cable_wire_size(cable); //! Width in flat clip
function cable_height(cable) = cable_bundle(cable)[1] * cable_wire_size(cable); //! Height in flat clip
function cable_bundle_positions(cable) = let( //! Positions of wires in a bundle to go through a cable strip
wires = cable_wires(cable),
bottom = cable_is_ribbon(cable) ? wires : wires < 3 ? wires : ceil(wires / 2),
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)]
] * 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
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);