mirror of
https://github.com/nophead/NopSCADlib.git
synced 2025-08-31 19:13:33 +02:00
Single backtick now used for all code quotes.
This commit is contained in:
@@ -22,14 +22,14 @@
|
||||
//
|
||||
include <../global_defs.scad>
|
||||
|
||||
function bezier(t, v) = //! Returns a point at distance ```t``` [0 - 1] along the curve with control points ```v```
|
||||
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)])
|
||||
: v[0] * (1 - t) + v[1] * (t);
|
||||
|
||||
function bezier_path(v, steps = 100) = //! Returns a Bezier path from control points ```v``` with ```steps``` segments
|
||||
function bezier_path(v, steps = 100) = //! Returns a Bezier path from control points `v` with `steps` segments
|
||||
[for(i = [0 : steps], t = i / steps) bezier(t, v)];
|
||||
|
||||
function bezier_length(v, delta = 0.01, t = 0, length = 0) = //! Calculate the length of a Bezier curve from control points ```v```
|
||||
function bezier_length(v, delta = 0.01, t = 0, length = 0) = //! Calculate the length of a Bezier curve from control points `v`
|
||||
t > 1 ? length
|
||||
: bezier_length(v, delta, t + delta, length + norm(bezier(t, v) - bezier(t + delta, v)));
|
||||
|
||||
@@ -37,7 +37,7 @@ function adjust_bezier(v, r) =
|
||||
let(extension = (v[1] - v[0]) * (r - 1))
|
||||
[v[0], v[1] + extension, v[2] + extension, v[3]];
|
||||
|
||||
function 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```
|
||||
function 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`
|
||||
let(l1 = l1 != undef ? l1 : bezier_length(adjust_bezier(v, r1)),
|
||||
l2 = l2 != undef ? l2 : bezier_length(adjust_bezier(v, r2))
|
||||
) abs(l1 - l) < eps ? adjust_bezier(v, r1)
|
||||
@@ -45,10 +45,10 @@ function adjust_bezier_length(v, l, eps = 0.001, r1 = 1.0, r2 = 1.5, l1, l2) = /
|
||||
abs(r - r1) < abs(r - r2) ? adjust_bezier_length(v, l, eps, r, r1, undef, l1)
|
||||
: adjust_bezier_length(v, l, eps, r, r2, undef, l2);
|
||||
|
||||
function bezier_min_z(v, steps = 100, z = inf, i = 0) = //! Calculate the minimum z coordinate of a Bezier curve from control points ```v```
|
||||
function bezier_min_z(v, steps = 100, z = inf, i = 0) = //! Calculate the minimum z coordinate of a Bezier curve from control points `v`
|
||||
i <= steps ? bezier_min_z(v, steps, min(z, bezier(i / steps, v).z), i + 1) : z;
|
||||
|
||||
function 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```
|
||||
function 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`
|
||||
let(z1 = z1 != undef ? z1 : bezier_min_z(adjust_bezier(v, r1)),
|
||||
z2 = z2 != undef ? z2 : bezier_min_z(adjust_bezier(v, r2))
|
||||
) abs(z1 - z) < eps ? adjust_bezier(v, r1)
|
||||
|
@@ -20,25 +20,25 @@
|
||||
//
|
||||
//! 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
|
||||
//! 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>.
|
||||
//! `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.
|
||||
//! 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_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.
|
||||
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```.
|
||||
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
|
||||
|
@@ -18,24 +18,24 @@
|
||||
//
|
||||
|
||||
//
|
||||
//! Bill Of Materials generation via echo and the ```bom.py``` script. Also handles exploded assembly views and posing.
|
||||
//! Bill Of Materials generation via echo and the `bom.py` script. Also handles exploded assembly views and posing.
|
||||
//! Assembly instructions can precede the module definition that makes the assembly.
|
||||
//!
|
||||
//! Assembly views shown in the instructions can be large or small and this is deduced by looking at the size of the printed parts involved and if any routed
|
||||
//! parts are used.
|
||||
//! This heuristic isn't always correct, so the default can be overridden by setting the ```big``` parameter of ```assembly``` to ```true``` or ```false```.
|
||||
//! This heuristic isn't always correct, so the default can be overridden by setting the `big` parameter of `assembly` to `true` or `false`.
|
||||
//!
|
||||
//! The example below shows how to define a vitamin and incorporate it into an assembly with sub-assemblies and make an exploded view.
|
||||
//! The resulting flat BOM is shown but heirachical BOMs are also generated for real projects.
|
||||
//
|
||||
function bom_mode(n = 1) = $_bom >= n && (is_undef($on_bom) || $on_bom); //! Current BOM mode, 0 = none, 1 = printed and routed parts and assemblies, 2 includes vitamins as well
|
||||
function exploded() = is_undef($exploded_parent) ? $exploded : 0; //! Returns the value of ```$exploded``` if it is defined, else ```0```
|
||||
function exploded() = is_undef($exploded_parent) ? $exploded : 0; //! Returns the value of `$exploded` if it is defined, else `0`
|
||||
function show_supports() = !$preview || exploded(); //! True if printed support material should be shown
|
||||
|
||||
module no_explode() let($exploded_parent = true) children(); //! Prevent children being exploded
|
||||
module no_pose() let($posed = true) children(); //! Force children not to be posed even if parent is
|
||||
|
||||
module explode(d, explode_children = false, offset = [0,0,0]) { //! Explode children by specified Z distance or vector ```d```, option to explode grand children
|
||||
module explode(d, explode_children = false, offset = [0,0,0]) { //! Explode children by specified Z distance or vector `d`, option to explode grand children
|
||||
v = is_list(d) ? d : [0, 0, d];
|
||||
o = is_list(offset) ? offset : [0, 0, offset];
|
||||
if($exploded && is_undef($exploded_parent) && norm(v)) {
|
||||
@@ -55,7 +55,7 @@ module explode(d, explode_children = false, offset = [0,0,0]) { //! Explode
|
||||
children();
|
||||
}
|
||||
|
||||
module pose(a = [55, 0, 25], t = [0, 0, 0], exploded = undef) //! Pose an STL or assembly for rendering to png by specifying rotation ```a``` and translation ```t```, ```exploded = true for``` just the exploded view or ```false``` for unexploded only.
|
||||
module pose(a = [55, 0, 25], t = [0, 0, 0], exploded = undef) //! Pose an STL or assembly for rendering to png by specifying rotation `a` and translation `t`, `exploded = true for` just the exploded view or `false` for unexploded only.
|
||||
if(is_undef($pose) || !is_undef($posed) || (!is_undef(exploded) && exploded != !!exploded()))
|
||||
children();
|
||||
else
|
||||
@@ -67,7 +67,7 @@ module pose(a = [55, 0, 25], t = [0, 0, 0], exploded = undef) //! Pose an
|
||||
translate(-t)
|
||||
children();
|
||||
|
||||
module pose_hflip(exploded = undef) //! Pose an STL or assembly for rendering to png by flipping around the Y axis, ```exploded = true for``` just the exploded view or ```false``` for unexploded only.
|
||||
module pose_hflip(exploded = undef) //! Pose an STL or assembly for rendering to png by flipping around the Y axis, `exploded = true for` just the exploded view or `false` for unexploded only.
|
||||
if(is_undef($pose) || !is_undef($posed) || (!is_undef(exploded) && exploded != !!exploded()))
|
||||
children();
|
||||
else
|
||||
@@ -75,7 +75,7 @@ module pose_hflip(exploded = undef) //! Pose an STL or assembly for render
|
||||
hflip()
|
||||
children();
|
||||
|
||||
module pose_vflip(exploded = undef) //! Pose an STL or assembly for rendering to png by flipping around the X axis, ```exploded = true for``` just the exploded view or ```false``` for unexploded only.
|
||||
module pose_vflip(exploded = undef) //! Pose an STL or assembly for rendering to png by flipping around the X axis, `exploded = true for` just the exploded view or `false` for unexploded only.
|
||||
if(is_undef($pose) || !is_undef($posed) || (!is_undef(exploded) && exploded != !!exploded()))
|
||||
children();
|
||||
else
|
||||
@@ -84,7 +84,7 @@ module pose_vflip(exploded = undef) //! Pose an STL or assembly for render
|
||||
children();
|
||||
|
||||
|
||||
module assembly(name, big = undef) { //! Name an assembly that will appear on the BOM, there needs to a module named ```<name>_assembly``` to make it. ```big``` can force big or small assembly diagrams.
|
||||
module assembly(name, big = undef) { //! Name an assembly that will appear on the BOM, there needs to a module named `<name>_assembly` to make it. `big` can force big or small assembly diagrams.
|
||||
if(bom_mode()) {
|
||||
args = is_undef(big) ? "" : str("(big=", big, ")");
|
||||
echo(str("~", name, "_assembly", args, "{"));
|
||||
@@ -101,20 +101,20 @@ module assembly(name, big = undef) { //! Name an assembly that will appear on
|
||||
echo(str("~}", name, "_assembly"));
|
||||
}
|
||||
|
||||
module stl_colour(colour = pp1_colour, alpha = 1) { //! Colour an stl where it is placed in an assembly. ```alpha``` can be used to make it appear transparent.
|
||||
module stl_colour(colour = pp1_colour, alpha = 1) { //! Colour an stl where it is placed in an assembly. `alpha` can be used to make it appear transparent.
|
||||
$stl_colour = colour;
|
||||
color(colour, alpha)
|
||||
children();
|
||||
}
|
||||
|
||||
module stl(name) { //! Name an stl that will appear on the BOM, there needs to a module named ```<name>_stl``` to make it
|
||||
module stl(name) { //! Name an stl that will appear on the BOM, there needs to a module named `<name>_stl` to make it
|
||||
if(bom_mode()) {
|
||||
colour = is_undef($stl_colour) ? pp1_colour : $stl_colour;
|
||||
echo(str("~", name, ".stl(colour='", colour, "')"));
|
||||
}
|
||||
}
|
||||
|
||||
module dxf(name) { //! Name a dxf that will appear on the BOM, there needs to a module named ```<name>_dxf``` to make it
|
||||
module dxf(name) { //! Name a dxf that will appear on the BOM, there needs to a module named `<name>_dxf` to make it
|
||||
if(bom_mode()) {
|
||||
if(is_undef($dxf_colour))
|
||||
echo(str("~", name, ".dxf"));
|
||||
@@ -123,9 +123,9 @@ module dxf(name) { //! Name a dxf that will appear on the B
|
||||
}
|
||||
}
|
||||
|
||||
function value_string(value) = is_string(value) ? str("\"", value, "\"") : str(value); //! Convert ```value``` to a string or quote it if it is already a string
|
||||
function value_string(value) = is_string(value) ? str("\"", value, "\"") : str(value); //! Convert `value` to a string or quote it if it is already a string
|
||||
|
||||
function arg(value, default, name = "") = //! Create string for arg if not default, helper for ```vitamin()```
|
||||
function arg(value, default, name = "") = //! Create string for arg if not default, helper for `vitamin()`
|
||||
value == default ? ""
|
||||
: name ? str(", ", name, " = ", value_string(value))
|
||||
: str(", ", value_string(value));
|
||||
|
@@ -29,11 +29,11 @@ function mm(x) = x;
|
||||
function cm(x) = x * 10.0; //! cm to mm conversion
|
||||
function m(x) = x * 1000.0; //! m to mm conversion
|
||||
|
||||
function sqr(x) = x * x; //! Returns the square of ```x```
|
||||
function sqr(x) = x * x; //! Returns the square of `x`
|
||||
function echoit(x) = echo(x) x; //! Echo expression and return it, useful for debugging
|
||||
function no_point(str) = chr([for(c = str(str)) if(c == ".") ord("p") else ord(c)]);//! Replace decimal point in string with 'p'
|
||||
function in(list, x) = !!len([for(v = list) if(v == x) true]); //! Returns true if ```x``` is an element in the ```list```
|
||||
function Len(x) = is_list(x) ? len(x) : 0; //! Returns the length of a list or 0 if ```x``` is not a list
|
||||
function in(list, x) = !!len([for(v = list) if(v == x) true]); //! Returns true if `x` is an element in the `list`
|
||||
function Len(x) = is_list(x) ? len(x) : 0; //! Returns the length of a list or 0 if `x` is not a list
|
||||
function r2sides(r) = $fn ? $fn : ceil(max(min(360/ $fa, r * 2 * PI / $fs), 5)); //! Replicates the OpenSCAD logic to calculate the number of sides from the radius
|
||||
function r2sides4n(r) = floor((r2sides(r) + 3) / 4) * 4; //! Round up the number of sides to a multiple of 4 to ensure points land on all axes
|
||||
function limit(x, min, max) = max(min(x, max), min); //! Force x in range min <= x <= max
|
||||
@@ -52,14 +52,14 @@ function slice(list, start = 0, end = undef) = let( //! Slice a list or string w
|
||||
) is_string(list) ? slice_str(list, start, end) : [for(i = [start : 1 : end - 1]) list[i]];
|
||||
|
||||
|
||||
module render_if(render = true, convexity = 2) //! Renders an object if ```render``` is true, otherwise leaves it unrendered
|
||||
module render_if(render = true, convexity = 2) //! Renders an object if `render` is true, otherwise leaves it unrendered
|
||||
if (render)
|
||||
render(convexity = convexity)
|
||||
children();
|
||||
else
|
||||
children();
|
||||
|
||||
module extrude_if(h, center = true) //! Extrudes 2D object to 3D when ```h``` is nonzero, otherwise leaves it 2D
|
||||
module extrude_if(h, center = true) //! Extrudes 2D object to 3D when `h` is nonzero, otherwise leaves it 2D
|
||||
if(h)
|
||||
linear_extrude(h, center = center, convexity = 2) // 3D
|
||||
children();
|
||||
@@ -81,7 +81,7 @@ module semi_circle(r, d = undef) //! A semi circle in the pos
|
||||
square([2 * sq, sq]);
|
||||
}
|
||||
|
||||
module right_triangle(width, height, h, center = true) //! A right angled triangle with the 90° corner at the origin. 3D when ```h``` is nonzero, otherwise 2D
|
||||
module right_triangle(width, height, h, center = true) //! A right angled triangle with the 90° corner at the origin. 3D when `h` is nonzero, otherwise 2D
|
||||
extrude_if(h, center = center)
|
||||
polygon(points = [[0,0], [width, 0], [0, height]]);
|
||||
|
||||
|
@@ -20,29 +20,28 @@
|
||||
//
|
||||
//! Rectangle with rounded corners.
|
||||
//
|
||||
module rounded_square(size, r, center = true) //! Like ```square()``` but with with rounded corners
|
||||
module rounded_square(size, r, center = true) //! Like `square()` but with with rounded corners
|
||||
{
|
||||
$fn = r2sides4n(r);
|
||||
offset(r) offset(-r) square(size, center = center);
|
||||
}
|
||||
|
||||
module rounded_rectangle(size, r, center = true, xy_center = true) //! Like ```cube()``` but corners rounded in XY plane and separate centre options for xy and z.
|
||||
module rounded_rectangle(size, r, center = true, xy_center = true) //! Like `cube()` but corners rounded in XY plane and separate centre options for xy and z.
|
||||
{
|
||||
linear_extrude(size.z, center = center)
|
||||
rounded_square([size.x, size.y], r, xy_center);
|
||||
}
|
||||
|
||||
module rounded_rectangle_xz(size, r, center = true, xy_center = true) //! Like ```cube()``` but corners rounded in XZ plane and separate centre options for xy and z.
|
||||
module rounded_rectangle_xz(size, r, center = true, xy_center = true) //! Like `cube()` but corners rounded in XZ plane and separate centre options for xy and z.
|
||||
{
|
||||
translate([xy_center ? 0 : size.x / 2, xy_center ? 0 : size.y / 2, center ? 0 : size.z / 2])
|
||||
rotate([90, 0, 0])
|
||||
rounded_rectangle([size.x, size.z, size.y], r, center = true, xy_center = true);
|
||||
}
|
||||
|
||||
module rounded_rectangle_yz(size, r, center = true, xy_center = true) //! Like ```cube()``` but corners rounded in YX plane and separate centre options for xy and z.
|
||||
module rounded_rectangle_yz(size, r, center = true, xy_center = true) //! Like `cube()` but corners rounded in YX plane and separate centre options for xy and z.
|
||||
{
|
||||
translate([xy_center ? 0 : size.x / 2, xy_center ? 0 : size.y / 2, center ? 0 : size.z / 2])
|
||||
rotate([90, 0, 90])
|
||||
rounded_rectangle([size.y, size.z, size.x], r, center = true, xy_center = true);
|
||||
}
|
||||
|
||||
|
@@ -20,7 +20,7 @@
|
||||
//! Redefines `sphere()` to always have a vertex on all six half axes I.e. vertices at the poles and the equator and `$fn` a multiple of four.
|
||||
//! This ensures `hull` and `minkowski` results have the correct dimensions when spheres are placed at the corners.
|
||||
|
||||
module sphere(r = 1, d = undef) { //! Override ```sphere``` so that has vertices on all three axes. Has the advantage of giving correct dimensions when hulled
|
||||
module sphere(r = 1, d = undef) { //! Override `sphere` so that has vertices on all three axes. Has the advantage of giving correct dimensions when hulled
|
||||
R = is_undef(d) ? r : d / 2;
|
||||
rotate_extrude($fn = r2sides4n(R))
|
||||
rotate(-90)
|
||||
|
@@ -24,7 +24,7 @@
|
||||
//! Using teardrop_plus() or setting the plus option on other modules will elongate the teardrop vertically by the layer height, so when sliced the staircase tips
|
||||
//! do not intrude into the circle. See <https://hydraraptor.blogspot.com/2020/07/horiholes-2.html>
|
||||
//
|
||||
module teardrop(h, r, center = true, truncate = true, chamfer = 0, plus = false) { //! For making horizontal holes that don't need support material, set ```truncate = false``` to make traditional RepRap teardrops that don't even need bridging
|
||||
module teardrop(h, r, center = true, truncate = true, chamfer = 0, plus = false) { //! For making horizontal holes that don't need support material, set `truncate = false` to make traditional RepRap teardrops that don't even need bridging
|
||||
module teardrop_2d(r, truncate) {
|
||||
er = layer_height / 2 - eps; // Extrustion edge radius
|
||||
R = plus ? r + er : r; // Corrected radius
|
||||
|
@@ -24,17 +24,17 @@
|
||||
//! <https://khkgears.net/new/gear_knowledge/gear_technical_reference/calculation_gear_dimensions.html>
|
||||
//! and <https://www.tec-science.com/mechanical-power-transmission/involute-gear/calculation-of-involute-gears/>
|
||||
//!
|
||||
//! ```involute_gear_profile()``` returns a polygon that can have the bore and spokes, etc, subtracted from it before linear extruding it to 3D.
|
||||
//! Helical gears can be made using ```twist``` and bevel gears using ```scale``` parameters of ```linear_extrude()```.
|
||||
//! `involute_gear_profile()` returns a polygon that can have the bore and spokes, etc, subtracted from it before linear extruding it to 3D.
|
||||
//! Helical gears can be made using `twist` and bevel gears using `scale` parameters of `linear_extrude()`.
|
||||
//!
|
||||
//! Gears with less than 19 teeth (when pressure angle is 20) are profile shifted to avoid undercutting the tooth root. 7 teeth is considered
|
||||
//! the practical minimum.
|
||||
//!
|
||||
//! The clearance between tip and root defaults to module / 6, but can be overridden by setting the ```clearance``` parameter.
|
||||
//! The clearance between tip and root defaults to module / 6, but can be overridden by setting the `clearance` parameter.
|
||||
//!
|
||||
//! The origin of the rack is the left end of the pitch line and its width is below the pitch line. I.e. it does not include the addendum.
|
||||
//!
|
||||
//! ```involute_worm_profile()``` returns a tooth profile that can be passed to ```thread()``` to make worms.
|
||||
//! `involute_worm_profile()` returns a tooth profile that can be passed to `thread()` to make worms.
|
||||
//
|
||||
include <core/core.scad>
|
||||
use <maths.scad>
|
||||
|
@@ -22,7 +22,7 @@
|
||||
//
|
||||
include <../utils/core/core.scad>
|
||||
|
||||
module hanging_hole(z, ir, h = 100, h2 = 100) { //! Hole radius ```ir``` hanging at the specified ```z``` value above a void who's shape is given by a 2D child
|
||||
module hanging_hole(z, ir, h = 100, h2 = 100) { //! Hole radius `ir` hanging at the specified `z` value above a void who's shape is given by a 2D child
|
||||
module polyhole(r, h, n = 8) {
|
||||
if(h > 0)
|
||||
rotate(180 / n) {
|
||||
|
@@ -20,7 +20,7 @@
|
||||
//
|
||||
//! 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 omitted.
|
||||
//! `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 omitted.
|
||||
//
|
||||
include <../utils/core/core.scad>
|
||||
|
||||
|
@@ -22,11 +22,11 @@
|
||||
//
|
||||
include <../global_defs.scad>
|
||||
|
||||
function layout_offset(widths, i, gap = 2) = //! Calculate the offset for the ```i```th item
|
||||
function layout_offset(widths, i, gap = 2) = //! Calculate the offset for the `i`th item
|
||||
i == 0 ? widths[0] / 2
|
||||
: layout_offset(widths, i - 1, gap) + widths[i - 1] / 2 + gap + widths[i] / 2;
|
||||
|
||||
module layout(widths, gap = 2, no_offset = false) //! Layout children passing ```$i```
|
||||
module layout(widths, gap = 2, no_offset = false) //! Layout children passing `$i`
|
||||
translate([no_offset ? -widths[0] / 2 : 0, 0])
|
||||
for($i = [0 : 1 : len(widths) - 1])
|
||||
translate([layout_offset(widths, $i, gap), 0])
|
||||
|
@@ -33,7 +33,7 @@ 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```
|
||||
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
|
||||
: [0, 0, v])
|
||||
[ [1, 0, 0, u.x],
|
||||
@@ -41,7 +41,7 @@ function translate(v) = let(u = is_list(v) ? len(v) == 2 ? [v.x, v.y, 0] //! Gen
|
||||
[0, 0, 1, u.z],
|
||||
[0, 0, 0, 1] ];
|
||||
|
||||
function 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```
|
||||
function 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`
|
||||
is_undef(v) ? let(av = is_list(a) ? a : [0, 0, a],
|
||||
cx = cos(av[0]),
|
||||
cy = cos(av[1]),
|
||||
@@ -80,7 +80,7 @@ function rot2_z(a) = //! Generate a 2x2 matrix to rotate around z
|
||||
[ [ c, -s],
|
||||
[ s, c] ];
|
||||
|
||||
function scale(v) = let(s = is_list(v) ? v : [v, v, 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
|
||||
function scale(v) = let(s = is_list(v) ? v : [v, v, 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
|
||||
[
|
||||
[s.x, 0, 0, 0],
|
||||
[0, s.y, 0, 0],
|
||||
@@ -88,11 +88,11 @@ function scale(v) = let(s = is_list(v) ? v : [v, v, v]) //! Generate a 4x4 matr
|
||||
[0, 0, 0, 1]
|
||||
];
|
||||
|
||||
function vec3(v) = [v.x, v.y, v.z]; //! Return a 3 vector with the first three elements of ```v```
|
||||
function vec4(v) = [v.x, v.y, v.z, 1]; //! Return a 4 vector with the first three elements of ```v```
|
||||
function vec3(v) = [v.x, v.y, v.z]; //! Return a 3 vector with the first three elements of `v`
|
||||
function vec4(v) = [v.x, v.y, v.z, 1]; //! Return a 4 vector with the first three elements of `v`
|
||||
function transform(v, m) = vec3(m * [v.x, v.y, v.z, 1]); //! Apply 4x4 transform to a 3 vector by extending it and cropping it again
|
||||
function transform_points(path, m) = [for(p = path) transform(p, m)]; //! Apply transform to a path
|
||||
function unit(v) = let(n = norm(v)) n ? v / n : v; //! Convert ```v``` to a unit vector
|
||||
function unit(v) = let(n = norm(v)) n ? v / n : v; //! Convert `v` to a unit vector
|
||||
|
||||
function transpose(m) = [ for(j = [0 : len(m[0]) - 1]) [ for(i = [0 : len(m) - 1]) m[i][j] ] ]; //! Transpose an arbitrary size matrix
|
||||
|
||||
|
@@ -24,7 +24,7 @@
|
||||
//! If `chamfer_base` is true then the bottom edge is made suitable for 3D printing by chamfering when the angle gets shallower than 45 degrees.
|
||||
include <../utils/core/core.scad>
|
||||
|
||||
module offset_3D(r, chamfer_base = false) { //! Offset 3D shape by specified radius ```r```, positive or negative.
|
||||
module offset_3D(r, chamfer_base = false) { //! Offset 3D shape by specified radius `r`, positive or negative.
|
||||
module ball(r)
|
||||
if(chamfer_base)
|
||||
rotate_extrude()
|
||||
|
@@ -22,7 +22,7 @@
|
||||
//
|
||||
include <../utils/core/core.scad>
|
||||
|
||||
module quadrant(w, r, center = false) { //! Draw a square with one rounded corner, can be centered on the arc centre, when ```center``` is ```true```.
|
||||
module quadrant(w, r, center = false) { //! Draw a square with one rounded corner, can be centered on the arc centre, when `center` is `true`.
|
||||
h = is_list(w) ? w.y : w;
|
||||
w = is_list(w) ? w.x : w;
|
||||
offset_w = center ? r - w : 0;
|
||||
|
@@ -40,7 +40,7 @@ module rounded_corner(r, h, r2, ir = 0) { //! 2D version
|
||||
}
|
||||
}
|
||||
|
||||
module rounded_cylinder(r, h, r2, ir = 0, angle = 360) //! Rounded cylinder given radius ```r```, height ```h```, optional internal radius ```ir``` and optional ```angle```
|
||||
module rounded_cylinder(r, h, r2, ir = 0, angle = 360) //! Rounded cylinder given radius `r`, height `h`, optional internal radius `ir` and optional `angle`
|
||||
{
|
||||
rotate_extrude(angle = angle)
|
||||
rounded_corner(r, h, r2, ir);
|
||||
|
@@ -48,7 +48,7 @@ function rounded_polygon_tangents(points) = //! Compute the straight sections ne
|
||||
function sumv(v, i = 0, sum = 0) = i == len(v) ? sum : sumv(v, i + 1, sum + v[i]);
|
||||
|
||||
// the cross product of 2D vectors is the area of the parallelogram between them. We use the sign of this to decide if the angle is bigger than 180.
|
||||
function rounded_polygon_length(points, tangents) = //! Calculate the length given the point list and the list of tangents computed by ``` rounded_polygon_tangents```
|
||||
function rounded_polygon_length(points, tangents) = //! Calculate the length given the point list and the list of tangents computed by ` rounded_polygon_tangents`
|
||||
let(
|
||||
len = len(points),
|
||||
indices = [0 : len - 1],
|
||||
|
@@ -22,7 +22,7 @@
|
||||
//
|
||||
include <../utils/core/core.scad>
|
||||
|
||||
module sector(r, start_angle, end_angle) { //! Create specified sector given radius ```r```, ```start_angle``` and ```end_angle```
|
||||
module sector(r, start_angle, end_angle) { //! Create specified sector given radius `r`, `start_angle` and `end_angle`
|
||||
R = r * sqrt(2) + 1;
|
||||
|
||||
if(end_angle > start_angle)
|
||||
|
@@ -172,10 +172,10 @@ function arc_points(r, a = [90, 0, 180], al = 90) = //! Generate the points of a
|
||||
let(sides = ceil(r2sides(r) * al / 360), tf = rotate(a))
|
||||
[for(i = [0 : sides]) let(t = i * al / sides) transform([r * sin(t), r * cos(t), 0], tf)];
|
||||
|
||||
function before(path1, path2) = //! Translate ```path1``` so its end meets the start of ```path2``` and then concatenate
|
||||
function before(path1, path2) = //! Translate `path1` so its end meets the start of `path2` and then concatenate
|
||||
let(end = len(path1) - 1, offset = path2[0] - path1[end])
|
||||
concat([for(i = [0 : end - 1]) path1[i] + offset], path2);
|
||||
|
||||
function after(path1, path2) = //! Translate ```path2``` so its start meets the end of ```path1``` and then concatenate
|
||||
function after(path1, path2) = //! Translate `path2` so its start meets the end of `path1` and then concatenate
|
||||
let(end1 = len(path1) - 1, end2 = len(path2) - 1, offset = path1[end1] - path2[0])
|
||||
concat(path1, [for(i = [1 : end2]) path2[i] + offset]);
|
||||
|
@@ -20,7 +20,7 @@
|
||||
//
|
||||
//! Utilities for making threads with sweep. They can be used to model screws, nuts, studding, leadscrews, etc, and also to make printed threads.
|
||||
//!
|
||||
//! The ends can be tapered, flat or chamfered by setting the ```top``` and ```bot``` parameters to -1 for tapered, 0 for a flat cut and positive to
|
||||
//! The ends can be tapered, flat or chamfered by setting the `top` and `bot` parameters to -1 for tapered, 0 for a flat cut and positive to
|
||||
//! specify a chamfer angle.
|
||||
//!
|
||||
//! Threads are by default solid, so the male version is wrapped around a cylinder and the female inside a tube. This can be suppressed to just get the helix, for
|
||||
@@ -32,8 +32,8 @@
|
||||
//! a cylinder. To get around this a colour can be passed to thread that is used to colour the cylinder and then toned down to colour the helix.
|
||||
//!
|
||||
//! Making the ends requires a CGAL intersection, which make threads relatively slow. For this reason they are generally disabled when using the GUI but can
|
||||
//! be enabled by setting ```$show_threads``` to ```true```. When the tests are run, by default, threads are enabled only for things that feature them like screws.
|
||||
//! This behaviour can be changed by setting a ```NOPSCADLIB_SHOW_THREADS``` environment variable to ```false``` to disable all threads and ```true``` to enable all threads.
|
||||
//! be enabled by setting `$show_threads` to `true`. When the tests are run, by default, threads are enabled only for things that feature them like screws.
|
||||
//! This behaviour can be changed by setting a `NOPSCADLIB_SHOW_THREADS` environment variable to `false` to disable all threads and `true` to enable all threads.
|
||||
//! The same variable also affects the generation of assembly diagrams.
|
||||
//!
|
||||
//! Threads obey the $fn, $fa, $fs variables.
|
||||
|
@@ -28,11 +28,11 @@ module ring(or, ir) //! Create a ring with specified external and internal radii
|
||||
circle4n(ir);
|
||||
}
|
||||
|
||||
module tube(or, ir, h, center = true) //! Create a tube with specified external and internal radii and height ```h```
|
||||
module tube(or, ir, h, center = true) //! Create a tube with specified external and internal radii and height `h`
|
||||
linear_extrude(h, center = center, convexity = 5)
|
||||
ring(or, ir);
|
||||
|
||||
module woven_tube(or, ir, h, center= true, colour = grey(30), colour2, warp = 2, weft) {//! Create a woven tube with specified external and internal radii, height ```h```, colours, warp and weft
|
||||
module woven_tube(or, ir, h, center= true, colour = grey(30), colour2, warp = 2, weft) {//! Create a woven tube with specified external and internal radii, height `h`, colours, warp and weft
|
||||
colour2 = colour2 ? colour2 : colour * 0.8;
|
||||
weft = weft ? weft : warp;
|
||||
warp_count = max(floor(PI * or / warp), 0.5);
|
||||
@@ -68,4 +68,3 @@ module woven_tube(or, ir, h, center= true, colour = grey(30), colour2, warp = 2,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user