Compare commits
11 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
8c2b4a20fe | ||
|
1529759406 | ||
|
c4a986aa21 | ||
|
ebee729d08 | ||
|
90e7f1a315 | ||
|
e39af154bb | ||
|
933fea687c | ||
|
a7803b1efb | ||
|
1255e71271 | ||
|
b11c5914b3 | ||
|
ac60057801 |
BIN
libtest.png
Before Width: | Height: | Size: 819 KiB After Width: | Height: | Size: 818 KiB |
105
readme.md
@@ -20,23 +20,23 @@ See [usage](docs/usage.md) for requirements, installation instructions and a usa
|
||||
<th align="left"> Vitamins A-I </th><th align="left"> Vitamins J-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 = "#Axials">Axials</a> </td><td> <a href = "#Jack">Jack</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 = "#Ball_bearings">Ball_bearings</a> </td><td> <a href = "#KP_pillow_blocks">KP_pillow_blocks</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 = "#Batteries">Batteries</a> </td><td> <a href = "#LDRs">LDRs</a> </td><td> <a href = "#Rockers">Rockers</a> </td><td> <a href = "#Cable_grommets">Cable_grommets</a> </td><td> <a href = "#Dogbones">Dogbones</a> </td><td> <a href = "#Global">Global</a> </td></tr>
|
||||
<tr><td> <a href = "#Belts">Belts</a> </td><td> <a href = "#LED_meters">LED_meters</a> </td><td> <a href = "#Rod">Rod</a> </td><td> <a href = "#Carriers">Carriers</a> </td><td> <a href = "#Fillet">Fillet</a> </td><td> <a href = "#Polyholes">Polyholes</a> </td></tr>
|
||||
<tr><td> <a href = "#Blowers">Blowers</a> </td><td> <a href = "#LEDs">LEDs</a> </td><td> <a href = "#SCS_bearing_blocks">SCS_bearing_blocks</a> </td><td> <a href = "#Corner_block">Corner_block</a> </td><td> <a href = "#Gears">Gears</a> </td><td> <a href = "#Rounded_rectangle">Rounded_rectangle</a> </td></tr>
|
||||
<tr><td> <a href = "#Bulldogs">Bulldogs</a> </td><td> <a href = "#Leadnuts">Leadnuts</a> </td><td> <a href = "#SK_brackets">SK_brackets</a> </td><td> <a href = "#Door_hinge">Door_hinge</a> </td><td> <a href = "#Hanging_hole">Hanging_hole</a> </td><td> <a href = "#Sphere">Sphere</a> </td></tr>
|
||||
<tr><td> <a href = "#Buttons">Buttons</a> </td><td> <a href = "#Light_strips">Light_strips</a> </td><td> <a href = "#SMDs">SMDs</a> </td><td> <a href = "#Door_latch">Door_latch</a> </td><td> <a href = "#Horiholes">Horiholes</a> </td><td> <a href = "#Teardrops">Teardrops</a> </td></tr>
|
||||
<tr><td> <a href = "#Cable_strips">Cable_strips</a> </td><td> <a href = "#Linear_bearings">Linear_bearings</a> </td><td> <a href = "#SSRs">SSRs</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 = "#Cameras">Cameras</a> </td><td> <a href = "#Magnets">Magnets</a> </td><td> <a href = "#Screws">Screws</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 = "#Circlips">Circlips</a> </td><td> <a href = "#Mains_sockets">Mains_sockets</a> </td><td> <a href = "#Sealing_strip">Sealing_strip</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 = "#Components">Components</a> </td><td> <a href = "#Microswitches">Microswitches</a> </td><td> <a href = "#Sheets">Sheets</a> </td><td> <a href = "#Foot">Foot</a> </td><td> <a href = "#Quadrant">Quadrant</a> </td><td></td></tr>
|
||||
<tr><td> <a href = "#DIP">DIP</a> </td><td> <a href = "#Microview">Microview</a> </td><td> <a href = "#Spades">Spades</a> </td><td> <a href = "#Handle">Handle</a> </td><td> <a href = "#Round">Round</a> </td><td></td></tr>
|
||||
<tr><td> <a href = "#D_connectors">D_connectors</a> </td><td> <a href = "#Modules">Modules</a> </td><td> <a href = "#Spools">Spools</a> </td><td> <a href = "#PCB_mount">PCB_mount</a> </td><td> <a href = "#Rounded_cylinder">Rounded_cylinder</a> </td><td></td></tr>
|
||||
<tr><td> <a href = "#Displays">Displays</a> </td><td> <a href = "#Nuts">Nuts</a> </td><td> <a href = "#Springs">Springs</a> </td><td> <a href = "#PSU_shroud">PSU_shroud</a> </td><td> <a href = "#Rounded_polygon">Rounded_polygon</a> </td><td></td></tr>
|
||||
<tr><td> <a href = "#Extrusion_brackets">Extrusion_brackets</a> </td><td> <a href = "#O_ring">O_ring</a> </td><td> <a href = "#Stepper_motors">Stepper_motors</a> </td><td> <a href = "#Printed_box">Printed_box</a> </td><td> <a href = "#Sector">Sector</a> </td><td></td></tr>
|
||||
<tr><td> <a href = "#Extrusions">Extrusions</a> </td><td> <a href = "#Opengrab">Opengrab</a> </td><td> <a href = "#Swiss_clips">Swiss_clips</a> </td><td> <a href = "#Ribbon_clamp">Ribbon_clamp</a> </td><td> <a href = "#Sweep">Sweep</a> </td><td></td></tr>
|
||||
<tr><td> <a href = "#Fans">Fans</a> </td><td> <a href = "#PCB">PCB</a> </td><td> <a href = "#Toggles">Toggles</a> </td><td> <a href = "#SSR_shroud">SSR_shroud</a> </td><td> <a href = "#Thread">Thread</a> </td><td></td></tr>
|
||||
<tr><td> <a href = "#Fuseholder">Fuseholder</a> </td><td> <a href = "#PCBs">PCBs</a> </td><td> <a href = "#Transformers">Transformers</a> </td><td> <a href = "#Screw_knob">Screw_knob</a> </td><td> <a href = "#Tube">Tube</a> </td><td></td></tr>
|
||||
<tr><td> <a href = "#Geared_steppers">Geared_steppers</a> </td><td> <a href = "#PSUs">PSUs</a> </td><td> <a href = "#Tubings">Tubings</a> </td><td> <a href = "#Socket_box">Socket_box</a> </td><td></td><td></td></tr>
|
||||
<tr><td> <a href = "#Batteries">Batteries</a> </td><td> <a href = "#LDRs">LDRs</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 = "#Belts">Belts</a> </td><td> <a href = "#LED_meters">LED_meters</a> </td><td> <a href = "#Rod">Rod</a> </td><td> <a href = "#Carriers">Carriers</a> </td><td> <a href = "#Dogbones">Dogbones</a> </td><td> <a href = "#Polyholes">Polyholes</a> </td></tr>
|
||||
<tr><td> <a href = "#Blowers">Blowers</a> </td><td> <a href = "#LEDs">LEDs</a> </td><td> <a href = "#SCS_bearing_blocks">SCS_bearing_blocks</a> </td><td> <a href = "#Corner_block">Corner_block</a> </td><td> <a href = "#Fillet">Fillet</a> </td><td> <a href = "#Rounded_rectangle">Rounded_rectangle</a> </td></tr>
|
||||
<tr><td> <a href = "#Bulldogs">Bulldogs</a> </td><td> <a href = "#Leadnuts">Leadnuts</a> </td><td> <a href = "#SK_brackets">SK_brackets</a> </td><td> <a href = "#Door_hinge">Door_hinge</a> </td><td> <a href = "#Gears">Gears</a> </td><td> <a href = "#Sphere">Sphere</a> </td></tr>
|
||||
<tr><td> <a href = "#Buttons">Buttons</a> </td><td> <a href = "#Light_strips">Light_strips</a> </td><td> <a href = "#SMDs">SMDs</a> </td><td> <a href = "#Door_latch">Door_latch</a> </td><td> <a href = "#Hanging_hole">Hanging_hole</a> </td><td> <a href = "#Teardrops">Teardrops</a> </td></tr>
|
||||
<tr><td> <a href = "#Cable_strips">Cable_strips</a> </td><td> <a href = "#Linear_bearings">Linear_bearings</a> </td><td> <a href = "#SSRs">SSRs</a> </td><td> <a href = "#Fan_guard">Fan_guard</a> </td><td> <a href = "#Horiholes">Horiholes</a> </td><td></td></tr>
|
||||
<tr><td> <a href = "#Cameras">Cameras</a> </td><td> <a href = "#Magnets">Magnets</a> </td><td> <a href = "#Screws">Screws</a> </td><td> <a href = "#Fixing_block">Fixing_block</a> </td><td> <a href = "#Layout">Layout</a> </td><td></td></tr>
|
||||
<tr><td> <a href = "#Circlips">Circlips</a> </td><td> <a href = "#Mains_sockets">Mains_sockets</a> </td><td> <a href = "#Sealing_strip">Sealing_strip</a> </td><td> <a href = "#Flat_hinge">Flat_hinge</a> </td><td> <a href = "#Maths">Maths</a> </td><td></td></tr>
|
||||
<tr><td> <a href = "#Components">Components</a> </td><td> <a href = "#Microswitches">Microswitches</a> </td><td> <a href = "#Sheets">Sheets</a> </td><td> <a href = "#Foot">Foot</a> </td><td> <a href = "#Offset">Offset</a> </td><td></td></tr>
|
||||
<tr><td> <a href = "#DIP">DIP</a> </td><td> <a href = "#Microview">Microview</a> </td><td> <a href = "#Spades">Spades</a> </td><td> <a href = "#Handle">Handle</a> </td><td> <a href = "#Quadrant">Quadrant</a> </td><td></td></tr>
|
||||
<tr><td> <a href = "#D_connectors">D_connectors</a> </td><td> <a href = "#Modules">Modules</a> </td><td> <a href = "#Spools">Spools</a> </td><td> <a href = "#PCB_mount">PCB_mount</a> </td><td> <a href = "#Round">Round</a> </td><td></td></tr>
|
||||
<tr><td> <a href = "#Displays">Displays</a> </td><td> <a href = "#Nuts">Nuts</a> </td><td> <a href = "#Springs">Springs</a> </td><td> <a href = "#PSU_shroud">PSU_shroud</a> </td><td> <a href = "#Rounded_cylinder">Rounded_cylinder</a> </td><td></td></tr>
|
||||
<tr><td> <a href = "#Extrusion_brackets">Extrusion_brackets</a> </td><td> <a href = "#O_ring">O_ring</a> </td><td> <a href = "#Stepper_motors">Stepper_motors</a> </td><td> <a href = "#Printed_box">Printed_box</a> </td><td> <a href = "#Rounded_polygon">Rounded_polygon</a> </td><td></td></tr>
|
||||
<tr><td> <a href = "#Extrusions">Extrusions</a> </td><td> <a href = "#Opengrab">Opengrab</a> </td><td> <a href = "#Swiss_clips">Swiss_clips</a> </td><td> <a href = "#Ribbon_clamp">Ribbon_clamp</a> </td><td> <a href = "#Sector">Sector</a> </td><td></td></tr>
|
||||
<tr><td> <a href = "#Fans">Fans</a> </td><td> <a href = "#PCB">PCB</a> </td><td> <a href = "#Toggles">Toggles</a> </td><td> <a href = "#SSR_shroud">SSR_shroud</a> </td><td> <a href = "#Sweep">Sweep</a> </td><td></td></tr>
|
||||
<tr><td> <a href = "#Fuseholder">Fuseholder</a> </td><td> <a href = "#PCBs">PCBs</a> </td><td> <a href = "#Transformers">Transformers</a> </td><td> <a href = "#Screw_knob">Screw_knob</a> </td><td> <a href = "#Thread">Thread</a> </td><td></td></tr>
|
||||
<tr><td> <a href = "#Geared_steppers">Geared_steppers</a> </td><td> <a href = "#PSUs">PSUs</a> </td><td> <a href = "#Tubings">Tubings</a> </td><td> <a href = "#Socket_box">Socket_box</a> </td><td> <a href = "#Tube">Tube</a> </td><td></td></tr>
|
||||
<tr><td> <a href = "#Green_terminals">Green_terminals</a> </td><td> <a href = "#Panel_meters">Panel_meters</a> </td><td> <a href = "#Variacs">Variacs</a> </td><td> <a href = "#Strap_handle">Strap_handle</a> </td><td></td><td></td></tr>
|
||||
<tr><td> <a href = "#Hot_ends">Hot_ends</a> </td><td> <a href = "#Pillars">Pillars</a> </td><td> <a href = "#Veroboard">Veroboard</a> </td><td></td><td></td><td></td></tr>
|
||||
<tr><td> <a href = "#Hygrometer">Hygrometer</a> </td><td> <a href = "#Pin_headers">Pin_headers</a> </td><td> <a href = "#Washers">Washers</a> </td><td></td><td></td><td></td></tr>
|
||||
@@ -2332,14 +2332,14 @@ PCBs and perfboard with optional components. The shape can be a rectangle with o
|
||||
| 1 | ```pcb(EnviroPlus)``` | Enviro+ |
|
||||
| 1 | ```pcb(ExtruderPCB)``` | Extruder connection PCB |
|
||||
| 1 | ```pcb(Keyes5p1)``` | Keyes5.1 Arduino Uno expansion board |
|
||||
| 1 | ```pcb(MP1584EN)``` | MP1584EN 3A buck converter |
|
||||
| 1 | ```pcb(MT3608)``` | MT3608 boost converter module |
|
||||
| 1 | ```pcb(Melzi)``` | Melzi electronics |
|
||||
| 5 | | Micro SD card |
|
||||
| 4 | | Micro SD card |
|
||||
| 1 | ```molex_254(2)``` | Molex KK header 2 way |
|
||||
| 1 | ```molex_254(3)``` | Molex KK header 3 way |
|
||||
| 16 | ```nut(M2_nut, nyloc = true)``` | Nut M2 x 1.6mm nyloc |
|
||||
| 34 | ```nut(M2p5_nut, nyloc = true)``` | Nut M2.5 x 2.2mm nyloc |
|
||||
| 16 | ```nut(M3_nut, nyloc = true)``` | Nut M3 x 2.4mm nyloc |
|
||||
| 12 | ```nut(M3_nut, nyloc = true)``` | Nut M3 x 2.4mm nyloc |
|
||||
| 12 | ```nut(M4_nut, nyloc = true)``` | Nut M4 x 3.2mm nyloc |
|
||||
| 1 | ```pcb(PI_IO)``` | PI_IO V2 |
|
||||
| 1 | ```pcb(PSU12V1A)``` | PSU 12V 1A |
|
||||
@@ -2355,24 +2355,21 @@ PCBs and perfboard with optional components. The shape can be a rectangle with o
|
||||
| 1 | ```pcb(RPI0)``` | Raspberry Pi Zero |
|
||||
| 12 | ```screw(M2_cap_screw, 16)``` | Screw M2 cap x 16mm |
|
||||
| 4 | ```screw(M2_cap_screw, 20)``` | Screw M2 cap x 20mm |
|
||||
| 2 | ```screw(M2p5_cap_screw, 16)``` | Screw M2.5 cap x 16mm |
|
||||
| 4 | ```screw(M2p5_cap_screw, 20)``` | Screw M2.5 cap x 20mm |
|
||||
| 4 | ```screw(M2p5_cap_screw, 25)``` | Screw M2.5 cap x 25mm |
|
||||
| 2 | ```screw(M2p5_cap_screw, 20)``` | Screw M2.5 cap x 20mm |
|
||||
| 8 | ```screw(M2p5_cap_screw, 25)``` | Screw M2.5 cap x 25mm |
|
||||
| 8 | ```screw(M2p5_cap_screw, 30)``` | Screw M2.5 cap x 30mm |
|
||||
| 4 | ```screw(M2p5_pan_screw, 20)``` | Screw M2.5 pan x 20mm |
|
||||
| 12 | ```screw(M2p5_pan_screw, 25)``` | Screw M2.5 pan x 25mm |
|
||||
| 4 | ```screw(M3_cap_screw, 16)``` | Screw M3 cap x 16mm |
|
||||
| 8 | ```screw(M3_cap_screw, 30)``` | Screw M3 cap x 30mm |
|
||||
| 4 | ```screw(M3_cap_screw, 35)``` | Screw M3 cap x 35mm |
|
||||
| 12 | ```screw(M4_cap_screw, 35)``` | Screw M4 cap x 35mm |
|
||||
| 1 | ```pcb(TP4056)``` | TP4056 Li-lon Battery charger module |
|
||||
| 3 | ```terminal_35(2)``` | Terminal block 2 way 3.5mm |
|
||||
| 2 | ```green_terminal(gt_2p54, 4)``` | Terminal block 4 way 0.1" |
|
||||
| 1 | | USB A to Mini B lead |
|
||||
| 1 | ```pcb(WD2002SJ)``` | WD2002SJ Buck Boost DC-DC converter |
|
||||
| 16 | ```washer(M2_washer)``` | Washer M2 x 5mm x 0.3mm |
|
||||
| 34 | ```washer(M2p5_washer)``` | Washer M2.5 x 5.9mm x 0.5mm |
|
||||
| 16 | ```washer(M3_washer)``` | Washer M3 x 7mm x 0.5mm |
|
||||
| 12 | ```washer(M3_washer)``` | Washer M3 x 7mm x 0.5mm |
|
||||
| 12 | ```washer(M4_washer)``` | Washer M4 x 9mm x 0.8mm |
|
||||
| 1 | ```pcb(ZC_A0591)``` | ZC-A0591 ULN2003 driver PCB |
|
||||
|
||||
@@ -2383,22 +2380,21 @@ PCBs and perfboard with optional components. The shape can be a rectangle with o
|
||||
| 4 | pcb_spacer2070.stl |
|
||||
| 4 | pcb_spacer2080.stl |
|
||||
| 4 | pcb_spacer2090.stl |
|
||||
| 4 | pcb_spacer25100.stl |
|
||||
| 4 | pcb_spacer25110.stl |
|
||||
| 4 | pcb_spacer25120.stl |
|
||||
| 4 | pcb_spacer25130_2.stl |
|
||||
| 4 | pcb_spacer25130.stl |
|
||||
| 4 | pcb_spacer25140_2.stl |
|
||||
| 4 | pcb_spacer25150_2.stl |
|
||||
| 4 | pcb_spacer25180.stl |
|
||||
| 4 | pcb_spacer25160_2.stl |
|
||||
| 4 | pcb_spacer25190.stl |
|
||||
| 2 | pcb_spacer2570.stl |
|
||||
| 4 | pcb_spacer30160.stl |
|
||||
| 4 | pcb_spacer25200.stl |
|
||||
| 2 | pcb_spacer2580.stl |
|
||||
| 4 | pcb_spacer30170.stl |
|
||||
| 4 | pcb_spacer30230.stl |
|
||||
| 4 | pcb_spacer30180.stl |
|
||||
| 4 | pcb_spacer3050.stl |
|
||||
| 4 | pcb_spacer40200.stl |
|
||||
| 4 | pcb_spacer40210.stl |
|
||||
| 4 | pcb_spacer40220.stl |
|
||||
| 4 | pcb_spacer40230.stl |
|
||||
|
||||
|
||||
<a href="#top">Top</a>
|
||||
@@ -5245,6 +5241,36 @@ Bezier curves and function to get and adjust the length or minimum z point.
|
||||

|
||||
|
||||
|
||||
<a href="#top">Top</a>
|
||||
|
||||
---
|
||||
<a name="Catenary"></a>
|
||||
## Catenary
|
||||
Catenary curve to model hanging wires, etc.
|
||||
|
||||
Although the equation of the curve is simply ```y = a cosh(x / a)``` there is no explicit formula to calculate the constant ```a``` or the range of ```x``` given the
|
||||
length of the cable and the end point coordinates. See <https://en.wikipedia.org/wiki/Catenary#Determining_parameters>. The Newton-Raphson method is used to find
|
||||
```a``` numerically, see <https://en.wikipedia.org/wiki/Newton%27s_method>.
|
||||
|
||||
The coordinates of the lowest point on the curve can be retrieved by calling ```catenary_points()``` with ```steps``` equal to zero.
|
||||
|
||||
|
||||
[utils/catenary.scad](utils/catenary.scad) Implementation.
|
||||
|
||||
[tests/catenary.scad](tests/catenary.scad) Code for this example.
|
||||
|
||||
### Functions
|
||||
| Function | Description |
|
||||
|:--- |:--- |
|
||||
| ```catenary(t, a)``` | Parametric catenary function linear along the length of the curve. |
|
||||
| ```catenary_ds_by_da(d, a)``` | First derivative of the length with respect to ```a```. |
|
||||
| ```catenary_find_a(d, l, a = 1, best_e = inf, best_a = 1)``` | Find the catenary constant ```a```, given half the horizontal span and the length. |
|
||||
| ```catenary_points(l, x, y, steps = 100)``` | Returns a list of 2D points on the curve that goes from the origin to ```(x,y)``` and has length ```l```. |
|
||||
| ```catenary_s(d, a)``` | Length of a symmetric catenary with width ```2d```. |
|
||||
|
||||

|
||||
|
||||
|
||||
<a href="#top">Top</a>
|
||||
|
||||
---
|
||||
@@ -5361,6 +5387,8 @@ Method to print holes in mid air. See <https://hydraraptor.blogspot.com/2014/03/
|
||||
## Horiholes
|
||||
Utilities for depicting the staircase slicing of horizontal holes made with [`teardrop_plus()`](#teardrops), see <https://hydraraptor.blogspot.com/2020/07/horiholes-2.html>
|
||||
|
||||
horicylinder() makes cylinders that fit inside a round hole. Layers that are less than 2 filaments wide and layers that need more than a 45 degree overhang are ommitted.
|
||||
|
||||
|
||||
[utils/horiholes.scad](utils/horiholes.scad) Implementation.
|
||||
|
||||
@@ -5369,11 +5397,13 @@ Utilities for depicting the staircase slicing of horizontal holes made with [`te
|
||||
### Functions
|
||||
| Function | Description |
|
||||
|:--- |:--- |
|
||||
| ```teardrop_minus_x(r, y, h)``` | Calculate the ordinate of a compensated teardrop given y and layer height. |
|
||||
| ```teardrop_plus_x(r, y, h)``` | Calculate the ordinate of a compensated teardrop given y and layer height. |
|
||||
|
||||
### Modules
|
||||
| Module | Description |
|
||||
|:--- |:--- |
|
||||
| ```horicylinder(r, z, h = 0, center = true)``` | For making horizontal cylinders that don't need support material and are correct dimensions |
|
||||
| ```horihole(r, z, h = 0, center = true)``` | For making horizontal holes that don't need support material and are correct dimensions |
|
||||
|
||||

|
||||
@@ -5420,7 +5450,14 @@ Maths utilities for manipulating vectors and matrices.
|
||||
| Function | Description |
|
||||
|:--- |:--- |
|
||||
| ```angle_between(v1, v2)``` | Return the angle between two vectors |
|
||||
| ```argcosh(x)``` | inverse hyperbolic cosine |
|
||||
| ```argcoth(x)``` | inverse hyperbolic cotangent |
|
||||
| ```argsinh(x)``` | inverse hyperbolic sine |
|
||||
| ```argtanh(x)``` | inverse hyperbolic tangent |
|
||||
| ```augment(m)``` | Augment a matrix by adding an identity matrix to the right |
|
||||
| ```circle_intersect(c1, r1, c2, r2)``` | Calculate one point where two circles in the X-Z plane intersect, clockwise around c1 |
|
||||
| ```cosh(x)``` | hyperbolic cosine |
|
||||
| ```coth(x)``` | hyperbolic cotangent |
|
||||
| ```degrees(radians)``` | Convert degrees to radians |
|
||||
| ```euler(R)``` | Convert a rotation matrix to a Euler rotation vector. |
|
||||
| ```identity(n, x = 1)``` | Construct an arbitrary size identity matrix |
|
||||
@@ -5433,9 +5470,11 @@ Maths utilities for manipulating vectors and matrices.
|
||||
| ```rotate(a, v)``` | Generate a 4x4 rotation matrix, ```a``` can be a vector of three angles or a single angle around ```z```, or around axis ```v``` |
|
||||
| ```rowswap(m, i, j)``` | Swap two rows of a matrix |
|
||||
| ```scale(v)``` | Generate a 4x4 matrix that scales by ```v```, which can be a vector of xyz factors or a scalar to scale all axes equally |
|
||||
| ```sinh(x)``` | hyperbolic sine |
|
||||
| ```solve(m, i = 0, j = 0)``` | Solve each row ensuring diagonal is not zero |
|
||||
| ```solve_row(m, i)``` | Make diagonal one by dividing the row by it and subtract from other rows to make column zero |
|
||||
| ```sqr(x)``` | Square x |
|
||||
| ```tanh(x)``` | hyperbolic tangent |
|
||||
| ```transform(v, m)``` | Apply 4x4 transform to a 3 vector by extending it and cropping it again |
|
||||
| ```transform_points(path, m)``` | Apply transform to a path |
|
||||
| ```translate(v)``` | Generate a 4x4 translation matrix, ```v``` can be ```[x, y]```, ```[x, y, z]``` or ```z``` |
|
||||
|
56
tests/catenary.scad
Normal file
@@ -0,0 +1,56 @@
|
||||
//
|
||||
// NopSCADlib Copyright Chris Palmer 2020
|
||||
// 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/>.
|
||||
//
|
||||
l = 250; // [1: 1000]
|
||||
x = 200; // [1: 1000]
|
||||
y = 50; //[-500 : 500]
|
||||
|
||||
include <../utils/core/core.scad>
|
||||
use <../utils/catenary.scad>
|
||||
use <../utils/sweep.scad>
|
||||
use <../utils/annotation.scad>
|
||||
|
||||
module catenaries() {
|
||||
//
|
||||
// catenary curve path from control points
|
||||
//
|
||||
curve = [for(p = catenary_points(l, x, y)) [p.x, p.y, 0]];
|
||||
//
|
||||
// Draw the curve
|
||||
//
|
||||
r = 0.5;
|
||||
sweep(curve, circle_points(r, $fn = 64));
|
||||
//
|
||||
// Minimum Z
|
||||
//
|
||||
min_z = catenary_points(l, x, y, 0);
|
||||
|
||||
color("blue") {
|
||||
translate([min_z.x, min_z.y + r])
|
||||
rotate([-90, 0, 0])
|
||||
arrow();
|
||||
|
||||
translate([min_z.x, min_z.y - r])
|
||||
rotate([90, 0, 0])
|
||||
arrow();
|
||||
}
|
||||
}
|
||||
|
||||
if($preview)
|
||||
rotate(is_undef($bom) ? 0 : [70, 0, 315])
|
||||
catenaries();
|
@@ -69,9 +69,13 @@ module horiholes() {
|
||||
color(silver)
|
||||
cylinder(r = $r, h = eps, center = true, $fn = 360);
|
||||
|
||||
hole_positions()
|
||||
color("blue")
|
||||
horicylinder(r = $r, z = $z, h = 2 * eps, center = true, $fn = 360);
|
||||
|
||||
hole_positions()
|
||||
color("red")
|
||||
linear_extrude(2 * eps, center = true)
|
||||
linear_extrude(3 * eps, center = true)
|
||||
intersection() {
|
||||
difference() {
|
||||
square(8, center = true);
|
||||
|
@@ -69,6 +69,33 @@ module maths() {
|
||||
// Test Euler
|
||||
//
|
||||
assert(euler(rotate(r)) == r, "euler() failed");
|
||||
//
|
||||
// Circle intersect
|
||||
//
|
||||
r1 = 10;
|
||||
c1 = [50, 0, 10];
|
||||
r2 = 20;
|
||||
c2 = [67, 0, 0];
|
||||
p1 = circle_intersect(c1, r1, c2, r2);
|
||||
p2 = circle_intersect(c2, r2, c1, r1);
|
||||
|
||||
rotate(90) {
|
||||
color(grey(90))
|
||||
translate(c1) rotate([90, 0, 0]) cylinder(r = r1, h = 4 * eps, center = true);
|
||||
|
||||
color(grey(80))
|
||||
translate(c2) rotate([90, 0, 0]) cylinder(r = r2, h = eps, center = true);
|
||||
|
||||
color("red")
|
||||
translate(p1) rotate([90, 0, 0]) cylinder(r = 0.1, h = 6 * eps, center = true);
|
||||
|
||||
color("blue")
|
||||
translate(p2) rotate([90, 0, 0]) cylinder(r = 0.1, h = 6 * eps, center = true);
|
||||
|
||||
translate(p1) arrow();
|
||||
|
||||
translate(p2) vflip() arrow();
|
||||
}
|
||||
}
|
||||
|
||||
rotate(45)
|
||||
|
BIN
tests/png/catenary.png
Normal file
After Width: | Height: | Size: 38 KiB |
Before Width: | Height: | Size: 40 KiB After Width: | Height: | Size: 45 KiB |
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 31 KiB |
Before Width: | Height: | Size: 156 KiB After Width: | Height: | Size: 152 KiB |
Before Width: | Height: | Size: 137 KiB After Width: | Height: | Size: 137 KiB |
52
utils/catenary.scad
Normal file
@@ -0,0 +1,52 @@
|
||||
//
|
||||
// NopSCADlib Copyright Chris Palmer 2020
|
||||
// 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/>.
|
||||
//
|
||||
|
||||
//
|
||||
//! Catenary curve to model hanging wires, etc.
|
||||
//!
|
||||
//! Although the equation of the curve is simply ```y = a cosh(x / a)``` there is no explicit formula to calculate the constant ```a``` or the range of ```x``` given the
|
||||
//! length of the cable and the end point coordinates. See <https://en.wikipedia.org/wiki/Catenary#Determining_parameters>. The Newton-Raphson method is used to find
|
||||
//! ```a``` numerically, see <https://en.wikipedia.org/wiki/Newton%27s_method>.
|
||||
//!
|
||||
//! The coordinates of the lowest point on the curve can be retrieved by calling ```catenary_points()``` with ```steps``` equal to zero.
|
||||
//
|
||||
include <core/core.scad>
|
||||
use <maths.scad>
|
||||
|
||||
function catenary(t, a) = let(u = argsinh(t)) a * [u, cosh(u)]; //! Parametric catenary function linear along the length of the curve.
|
||||
function catenary_s(d, a) = 2 * a * sinh(d / a); //! Length of a symmetric catenary with width ```2d```.
|
||||
function catenary_ds_by_da(d, a) = 2 * sinh(d / a) - 2 * d / a * cosh(d / a); //! First derivative of the length with respect to ```a```.
|
||||
|
||||
function catenary_find_a(d, l, a = 1, best_e = inf, best_a = 1) = //! Find the catenary constant ```a```, given half the horizontal span and the length.
|
||||
assert(l > 2 * d, "Not long enough to span the gap") assert(d) let(error = abs(catenary_s(d, a) - l))
|
||||
error >= best_e && error < 0.0001 ? best_a
|
||||
: catenary_find_a(d, l, max(a - (catenary_s(d, a) - l) / catenary_ds_by_da(d, a), d / argsinh(1e99)), error, a);
|
||||
|
||||
function catenary_points(l, x, y, steps = 100) = //! Returns a list of 2D points on the curve that goes from the origin to ```(x,y)``` and has length ```l```.
|
||||
let(
|
||||
d = x / 2,
|
||||
a = catenary_find_a(d, sqrt(sqr(l) - sqr(y))), // Find a to get the correct length
|
||||
offset = argsinh(y / catenary_s(d, a)),
|
||||
t0 = sinh(-d / a + offset),
|
||||
t1 = sinh( d / a + offset),
|
||||
h = a * cosh(-d / a + offset) - a,
|
||||
lowest = offset > d / a ? [0, 0] : offset < -d / a ? [x, y] : [d - offset * a, -h],
|
||||
p0 = catenary(t0, a)
|
||||
)
|
||||
steps ? [for(t = [t0 : (t1 - t0) / steps : t1]) catenary(t, a) - p0] : lowest;
|
@@ -19,6 +19,8 @@
|
||||
|
||||
//
|
||||
//! Utilities for depicting the staircase slicing of horizontal holes made with [`teardrop_plus()`](#teardrops), see <https://hydraraptor.blogspot.com/2020/07/horiholes-2.html>
|
||||
//!
|
||||
//! horicylinder() makes cylinders that fit inside a round hole. Layers that are less than 2 filaments wide and layers that need more than a 45 degree overhang are ommitted.
|
||||
//
|
||||
include <../utils/core/core.scad>
|
||||
|
||||
@@ -53,3 +55,29 @@ module horihole(r, z, h = 0, center = true) { //! For making horizontal holes th
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function teardrop_minus_x(r, y, h) = //! Calculate the ordinate of a compensated teardrop given y and layer height.
|
||||
let(fr = h / 2,
|
||||
hpot = r - fr,
|
||||
x2 = sqr(hpot) - sqr(y),
|
||||
x = x2 > 0 ? sqrt(x2) : 0,
|
||||
X = y >= -hpot / sqrt(2) ? x + fr : 0
|
||||
)
|
||||
X >= extrusion_width ? X : 0;
|
||||
|
||||
module horicylinder(r, z, h = 0, center = true) { //! For making horizontal cylinders that don't need support material and are correct dimensions
|
||||
bot_layer = floor((z - r) / layer_height);
|
||||
top_layer = ceil((z + r) / layer_height);
|
||||
render(convexity = 5)
|
||||
extrude_if(h, center)
|
||||
for(i = [bot_layer : top_layer]) {
|
||||
Z = i * layer_height;
|
||||
y = Z - z + layer_height / 2;
|
||||
x = teardrop_minus_x(r, y, layer_height);
|
||||
if(x >= extrusion_width)
|
||||
hull()
|
||||
for(end = [-1, 1])
|
||||
translate([end * (x - layer_height / 2), y])
|
||||
circle(d = layer_height, $fn = 32);
|
||||
}
|
||||
}
|
||||
|
@@ -24,6 +24,14 @@ function sqr(x) = x * x; //! Square x
|
||||
function radians(degrees) = degrees * PI / 180; //! Convert radians to degrees
|
||||
function degrees(radians) = radians * 180 / PI; //! Convert degrees to radians
|
||||
|
||||
function sinh(x) = (exp(x) - exp(-x)) / 2; //! hyperbolic sine
|
||||
function cosh(x) = (exp(x) + exp(-x)) / 2; //! hyperbolic cosine
|
||||
function tanh(x) = sinh(x) / cosh(x); //! hyperbolic tangent
|
||||
function coth(x) = cosh(x) / sinh(x); //! hyperbolic cotangent
|
||||
function argsinh(x) = ln(x + sqrt(sqr(x) + 1)); //! inverse hyperbolic sine
|
||||
function argcosh(x) = ln(x + sqrt(sqr(x) - 1)); //! inverse hyperbolic cosine
|
||||
function argtanh(x) = ln((1 + x) / (1 - x)) / 2;//! inverse hyperbolic tangent
|
||||
function argcoth(x) = ln((x + 1) / (x - 1)) / 2;//! inverse hyperbolic cotangent
|
||||
|
||||
function translate(v) = let(u = is_list(v) ? len(v) == 2 ? [v.x, v.y, 0] //! Generate a 4x4 translation matrix, ```v``` can be ```[x, y]```, ```[x, y, z]``` or ```z```
|
||||
: v
|
||||
@@ -138,3 +146,10 @@ function invert(m) = let(n =len(m), m = solve(augment(m))) [ //! Invert a matrix
|
||||
each m[i][j]
|
||||
]
|
||||
];
|
||||
|
||||
function circle_intersect(c1, r1, c2, r2) = //! Calculate one point where two circles in the X-Z plane intersect, clockwise around c1
|
||||
let(
|
||||
v = c1 - c2, // Line between centres
|
||||
d = norm(v), // Distance between centres
|
||||
a = atan2(v.z, v.x) - acos((sqr(d) + sqr(r2) - sqr(r1)) / (2 * d * r2)) // Cosine rule to find angle from c2
|
||||
) c2 + r2 * [cos(a), 0, sin(a)]; // Point on second circle
|
||||
|
@@ -161,13 +161,13 @@ module al_clad_resistor(type, value, leads = true) { //! Draw an aluminium clad
|
||||
}
|
||||
linear_extrude(thickness)
|
||||
difference() {
|
||||
for(end = [-1, 1])
|
||||
translate([end * (length - tab) / 2, end * (width - width / 2) / 2])
|
||||
square([tab, width / 2], center = true);
|
||||
union()
|
||||
for(end = [-1, 1])
|
||||
translate([end * (length - tab) / 2, end * (width - width / 2) / 2])
|
||||
square([tab, width / 2], center = true);
|
||||
|
||||
al_clad_resistor_hole_positions(type)
|
||||
circle(d = al_clad_hole(type));
|
||||
|
||||
}
|
||||
if(leads) {
|
||||
translate_z(height / 2)
|
||||
|
@@ -137,19 +137,26 @@ module insert_lug(insert, wall, counter_bore = 0, extension = 0, corner_r = 0, f
|
||||
boss_h = insert_hole_length(insert);
|
||||
boss_h2 = boss_h + counter_bore;
|
||||
|
||||
module shape()
|
||||
intersection() {
|
||||
module shape() {
|
||||
module _shape()
|
||||
hull() {
|
||||
circle(boss_r);
|
||||
|
||||
translate([boss_r + extension - eps, 0])
|
||||
square([eps, 2 * boss_r], center = true);
|
||||
}
|
||||
if(corner_r)
|
||||
|
||||
if(corner_r)
|
||||
intersection() {
|
||||
_shape();
|
||||
|
||||
translate([boss_r + extension - corner_r, 0])
|
||||
rotate(-45)
|
||||
quadrant(w = 100, r = corner_r - eps, center = true);
|
||||
}
|
||||
}
|
||||
else
|
||||
_shape();
|
||||
}
|
||||
|
||||
translate_z(-boss_h)
|
||||
linear_extrude(boss_h)
|
||||
|
@@ -179,23 +179,27 @@ module jhead_hot_end_assembly(type, filament, naked = false) { //! Assembly with
|
||||
//
|
||||
// heater block
|
||||
//
|
||||
rotate(90)
|
||||
translate([-nozzle_x(heater), 0, inset - insulator_length - heater_height(heater) / 2]) {
|
||||
intersection() {
|
||||
group() {
|
||||
translate([resistor_x(heater), -exploded() * 15, 0])
|
||||
rotate([90, 0, 0])
|
||||
sleeved_resistor(resistor, PTFE20, bare = -10);
|
||||
module heater_components() {
|
||||
translate([resistor_x(heater), -exploded() * 15, 0])
|
||||
rotate([90, 0, 0])
|
||||
sleeved_resistor(resistor, PTFE20, bare = -10);
|
||||
|
||||
translate([-heater_length(heater) / 2 + resistor_length(thermistor) / 2 - exploded() * 10, thermistor_y(heater), 0])
|
||||
rotate([90, 0, -90])
|
||||
sleeved_resistor(thermistor, PTFE07, heatshrink = HSHRNK16);
|
||||
}
|
||||
|
||||
rotate(90)
|
||||
translate([-nozzle_x(heater), 0, inset - insulator_length - heater_height(heater) / 2])
|
||||
if(exploded())
|
||||
heater_components();
|
||||
else
|
||||
intersection() {
|
||||
heater_components();
|
||||
|
||||
translate([-heater_length(heater) / 2 + resistor_length(thermistor) / 2 - exploded() * 10, thermistor_y(heater), 0])
|
||||
rotate([90, 0, -90])
|
||||
sleeved_resistor(thermistor, PTFE07, heatshrink = HSHRNK16);
|
||||
}
|
||||
if(!exploded())
|
||||
if(naked)
|
||||
color("grey") cylinder(r = 12, h = 100, center = true);
|
||||
else
|
||||
cube(1, true); // hide the wires when not exploded
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -77,7 +77,6 @@ module panel_meter(type) { //! Draw panel mounted LCD meter module
|
||||
tab_z = pmeter_tab_z(type);
|
||||
pcb = pmeter_pcb(type);
|
||||
ap2 = pmeter_inner_ap(type);
|
||||
pcb_h = pmeter_pcb_h(type) - bezel.z;
|
||||
buttons = pmeter_buttons(type);
|
||||
|
||||
color("#94A7AB")
|
||||
@@ -146,15 +145,16 @@ module panel_meter(type) { //! Draw panel mounted LCD meter module
|
||||
translate(pmeter_inner_ap_o(type))
|
||||
square([ap2.x, ap2.y], center = true);
|
||||
}
|
||||
if(pcb)
|
||||
if(pcb) {
|
||||
vflip()
|
||||
translate_z(h - pcb_thickness(pcb) - pmeter_pcb_z(type))
|
||||
pcb(pcb);
|
||||
|
||||
if(pcb_h > 0)
|
||||
%translate_z(-pcb_h / 2 - eps)
|
||||
cube([size.x - 2 * t - eps, size.y - 2 * t - eps, pcb_h], center = true);
|
||||
|
||||
pcb_h = pmeter_pcb_h(type) - bezel.z;
|
||||
if(pcb_h > 0)
|
||||
%translate_z(-pcb_h / 2 - eps)
|
||||
cube([size.x - 2 * t - eps, size.y - 2 * t - eps, pcb_h], center = true);
|
||||
}
|
||||
if(buttons)
|
||||
for(b = buttons)
|
||||
panel_meter_button(b);
|
||||
|
@@ -44,7 +44,7 @@ DSP5005 = ["DSP5005", "Ruideng DSP5005 Power supply module", [7
|
||||
DSN_VC288PCB = ["", "", 41, 21, 1, 0, 0, 0, "green", false, [], [[ 5, -3, 0, "jst_xh", 3], ], []];
|
||||
|
||||
DSN_VC288 = ["DSN_VC288","DSN-VC288 DC 100V 10A Voltmeter ammeter", [45.3, 26, 17.4], [47.8, 28.8, 2.5], 0, [1, 1.8], [36, 18, 2.5], [], 0, 2,
|
||||
[], 0, DSN_VC288PCB, 5];
|
||||
[], 0, DSN_VC288PCB, 5, 0];
|
||||
|
||||
panel_meters = [DSN_VC288, PZEM021, PZEM001, DSP5005];
|
||||
|
||||
|
@@ -385,6 +385,11 @@ WD2002SJ = ["WD2002SJ", "WD2002SJ Buck Boost DC-DC converter", 78, 47, 1.6, 0, 3
|
||||
],
|
||||
[]];
|
||||
|
||||
MP1584EN = ["MP1584EN", "MP1584EN 3A buck converter", 22, 17, 1.2, 0, 1, [2, 2], "green", false,
|
||||
[[1.75, 1.75], [1.75, -1.75], [-1.75, 1.75], [-1.75, -1.75], [-1.75, -4.4], [-1.75, 4.48], [1.75, -4.4], [1.75, 4.4]],
|
||||
[]
|
||||
];
|
||||
|
||||
PERF80x20 = ["PERF80x20", "Perfboard 80 x 20mm", 80, 20, 1.6, 0, 2.3, 0, "green", true, [[2,2],[-2,2],[2,-2],[-2,-2]], [], [], [5.87, 3.49]];
|
||||
|
||||
PERF70x50 = ["PERF70x50", "Perfboard 70 x 50mm", 70, 50, 1.6, 0, 2.3, 0, "green", true, [[2,2],[-2,2],[2,-2],[-2,-2]], [], [], [5.87, 3.49]];
|
||||
@@ -410,7 +415,7 @@ RAMPSEndstop = ["RAMPSEndstop", "RAMPS Endstop Switch",
|
||||
[]];
|
||||
|
||||
|
||||
pcbs = [TP4056, MT3608, RAMPSEndstop, ExtruderPCB, PI_IO, ZC_A0591, RPI0, EnviroPlus, ArduinoUno3, ArduinoLeonardo, Keyes5p1, PSU12V1A, WD2002SJ, RPI3, RPI4, DuetE, Duex2, Duex5, Melzi];
|
||||
pcbs = [MP1584EN, TP4056, MT3608, RAMPSEndstop, ExtruderPCB, PI_IO, ZC_A0591, RPI0, EnviroPlus, ArduinoUno3, ArduinoLeonardo, Keyes5p1, PSU12V1A, WD2002SJ, RPI3, RPI4, DuetE, Duex2, Duex5];
|
||||
|
||||
perfboards = [PERF74x51, PERF70x50, PERF60x40, PERF70x30, PERF80x20];
|
||||
|
||||
|
@@ -62,9 +62,10 @@ module smd_led(type, colour, cutout) { //! Draw an SMD LED with specified ```col
|
||||
intersection() {
|
||||
square([size.x, size.y], center = true);
|
||||
|
||||
for(end = [-1, 1])
|
||||
translate([end * size.x / 2, 0])
|
||||
ring(or = r, ir = r / 2);
|
||||
union()
|
||||
for(end = [-1, 1])
|
||||
translate([end * size.x / 2, 0])
|
||||
ring(or = r, ir = r / 2);
|
||||
}
|
||||
|
||||
color(colour, 0.9)
|
||||
|
@@ -89,7 +89,7 @@ module NEMA(type, shaft_angle = 0) { //! Draw specified NEMA stepper motor
|
||||
tube(or = boss_rad, ir = shaft_rad + 2, h = boss_height * 2); // raised boss
|
||||
|
||||
linear_extrude(eps)
|
||||
cap_shape(true);
|
||||
cap_shape(1);
|
||||
}
|
||||
|
||||
color(stepper_cap_colour) // aluminium end caps
|
||||
|