1
0
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:
Chris Palmer
2020-12-24 16:04:59 +00:00
parent 04b98a3786
commit 4cac382581
49 changed files with 2459 additions and 2459 deletions

View File

@@ -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)

View File

@@ -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

View File

@@ -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));

View File

@@ -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&deg; 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&deg; corner at the origin. 3D when `h` is nonzero, otherwise 2D
extrude_if(h, center = center)
polygon(points = [[0,0], [width, 0], [0, height]]);

View File

@@ -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);
}

View File

@@ -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)

View File

@@ -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

View File

@@ -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>

View File

@@ -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) {

View File

@@ -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>

View File

@@ -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])

View File

@@ -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

View File

@@ -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()

View File

@@ -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;

View File

@@ -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);

View File

@@ -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],

View File

@@ -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)

View File

@@ -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]);

View File

@@ -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.

View File

@@ -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,
}
}
}