Purged wiki history.

Revar Desmera 2024-12-14 02:23:46 -08:00
commit 0c32a86af2
2809 changed files with 78034 additions and 0 deletions

4
.gitignore vendored Normal file

@ -0,0 +1,4 @@
FAILED.scad
.DS_Store
.*.swp

62
.source_hashes Normal file

@ -0,0 +1,62 @@
attachments.scad|ed1b7e7469bb6897c581e944d13ebbf68ee3549e2673412557928e5acc2e0a4b
ball_bearings.scad|90fbae940694587dcd6e2b387bbafc6193f40a134a920fb9bec152279a9455d8
beziers.scad|71ebd9bd02ed80517759c8765591f54b3e654032d618f930d2e60bd3e9e6f0fc
bottlecaps.scad|60e8a2f50da6834506bc7f19326f845b92a0d453d73604e7fe5e3d0f899afe5f
color.scad|7d7d0629ab3e993162d2c8e9f3108403e70e71bbf68a2a87babacc225492517d
comparisons.scad|d01b151dbb63ba6d8caebbcbad2502ee460049555693904042be66fda4991d4d
constants.scad|f128f99e81a57797b2609013c34ce57dcbd6c8d0d505cc6eb53fdccc5c08cd78
coords.scad|04977fdf01a852eb134d3df8def4f673fa32b7ce8c5ade4295974aa1b28c800d
cubetruss.scad|cab1e92de3950a119f35b606806f6d1e5769994876a93fed5e63871bcc755bc2
distributors.scad|3b70f043379e3120f8603dc9d30a83249874a8857431e3149cc4b5c846268c73
drawing.scad|5c4012c738fb786c41d7918739b3ee47e57ac82ce5ed8ea89e424abd91d7cb0a
fnliterals.scad|f33c0ace34b6896a3da7982923c96098a5f2b53c15e803b486379e990feaed97
gears.scad|0a969113f31f8e76ade5841ae99cfbd6d30b007586321c7d89a85a26c187e4d7
geometry.scad|476564012b9bb791126425ff3ebc0d364b3dc9b90ff6b7112e20d0ae24ed7b70
hinges.scad|c41119495b1f2f2cb436741e90ac25a858cc0cbff0af9d0ab2f88368edc2ee95
joiners.scad|5e760d8c57b860e00db2202057007158506f0bafb0397b07748091d891d954d3
linalg.scad|e21b3cf6e2928c8db2959a36d3689514bef6f9f84d53ff57b0c5168aa6ad04b7
linear_bearings.scad|84bb5aaccd5d62c87d701495a62b2c493b8155339aea13fed525a5acb2cab771
lists.scad|ff696d39f527990e007db6e06eae0e386f55e2313c639207694ffb7513eb1c73
masks2d.scad|e224d86cb5e518b20de502eb0c9e0ca8faef8c6ef7f52f4e094a3bcc805ffbae
masks3d.scad|f7f7c51da060134504f3cbf9dac0b2e427ff7a2c077171e02fca64c847d9429c
math.scad|8a39f3ad48eee89fbb19e84cdb89e8dcac90db29ce08366c5ecc8987e7d5b3a9
modular_hose.scad|d5a6b1f8f0b285ac8381bde02ef6f56ec1fba296b985869535988f8b26572902
mutators.scad|8eb2b8c61c599062b032d8a3928d7cbca6fb2a6cd707f8c7b5fca809a65445ab
nema_steppers.scad|5215c596df492d8318c7eec67977db24c39249d987aabfffb07e9f311f23d0fd
partitions.scad|2f4bd6286185b9688ff2db1302316f99667468b55db305ad00577e0d45f09371
paths.scad|4f3cc6584f9002fb9d3b046fd58c013a580c13bf2fec3a18c299b4d2066e9869
polyhedra.scad|153d4e6b712b89365a0c56317ce3ba16721ca9e66c2becd3b93dbaa350c44e80
regions.scad|2668ba314a151130104ba08b7a7d7979a2a56cee72aca97a591a7725d420d0b9
rounding.scad|c0d96fc2109e2508c6ef212e37dbcd39f9b884d2ae3e755cd18782dd4799421a
screw_drive.scad|b168fd4a1b5fc2d6d01ff2764916259d01f039fa085ec67e4b6a6cc3ffd7cdaa
screws.scad|5add45614a759bfabc14a9576eb6adee4a7fbb9889807e8bec4559d6c541f641
shapes2d.scad|4cfb38494ac388381c5633905c10961d0805c58f96847b4c26a05360b594a5be
shapes3d.scad|bbf2eba68b368da0593bcbd2ddcc58993b11c7ab7dd2a7a4bee91a850ba3debf
skin.scad|529df1301f2d44206ac1e3082bf270889769a6633d9dbab08efe460e0628aba0
sliders.scad|6e3d953e4a70e0a7b2d896f09ddf92d2ae983e398f20e866a815fdcc9f426456
strings.scad|f9aac5e21015780b282fb781b45bea52eec40208b39a879ee0a67d2d5bfb9c7f
structs.scad|3258cae7fba9150a7102caa1042c7245431059d9258f603b6bcf8cb47b14e3c2
threading.scad|2d217b9e815a52047f4c267938265d3b876ab3460c1c5b9d5999c8c0adefd29c
transforms.scad|94abcae06c3e02ac246a324b5b77cb8576feaf7bd970e9614fd1503abab60062
trigonometry.scad|f041bf6a4c87fbc7d1a18e613e6cde16e8403a6cc6b9dd6ff10c3c76fa6c20f8
tripod_mounts.scad|84ca3571397041e19d04afaaf9362590c8fafeaeaf5963ca7c9dcfaaeb141c22
turtle3d.scad|84f0ff9785b0f68ca6506d4525370df438553a0c33be6635328f774cb0fd3eca
utility.scad|c72330e4c7c51fd961da76026e8f62d55ee3075e589caf7f87c8fc33abac9a83
vectors.scad|f743c84cfc1fa1fa2c17183e0ed1ce9881a5f56f2533146f910141fc1b2ebac9
version.scad|6ae0b751a4ca9b96c17f54b3424b6c48849295b95c4d1606b02028ba82a31c4c
vnf.scad|7b1a7e709dbb414d9cf3cbf5e33c04a02139ff7516d32ca97783137b55c1b681
walls.scad|56d520292def7384af49483778f9a6cd596c33a0f01390b9532f7cc0f3cd17ee
wiring.scad|8f9d019d25813d5f08e832b33d11c3479916bb0dea696be189b40fe08ff971f2
tutorials/Shapes2d.md|e8bc1856d7c729ab9c668c4a6c4d913e77fca8afdbc2123ef839d8fdfc43bc07
tutorials/Shapes3d.md|5db39d6af026eee53e091550d0fa3e2f8649c0dcf5ae424bdfbd326da38c5e56
tutorials/FractalTree.md|8b3ad6d71348fa328a30f34a7b470119eeafff2e76e9f2edf2fd161004ce7e81
tutorials/Attachments.md|62d6a5a8d8ca84f1d43bc895e6acba59d80eaeab7efcfd4ef46a5fbcbc5f3a18
tutorials/Mutators.md|076a7e000d72f528a5218645ef4b6a91b50753b4ca10f0731ece1a9275dcce73
tutorials/VNF.md|eef71807b7bcde8e1cfa53520aa2e17a91c0bf70b08afef6d7d3573baa0136ac
tutorials/Distributors.md|96e39d262dfb845b88da465b3acbe780e33b308ed04d40a71b19f7aa0023d071
tutorials/Paths.md|3cb5d6a33b82e25413f6d669eb119e2aeca74fda6a353f5f3a6b2a793312c779
tutorials/Rounding_the_Cube.md|1c1ac04b399d552fcbaa0bd62902eae5c04931ee9c610299be87904af3488cb4
tutorials/Transforms.md|58257c3d4e4c7d182a2d236c536631a63d5ef31142fad57c04024a403b7b7ad9
miscellaneous.scad|0fe3f8c79805e5533d92422ae43634c7c909661ce01d3119a0ddac18c8a00e53
tutorials/Beziers_for_Beginners.md|c9928da454ff6e42098c1c80a15ea09104e0460e3066d42764d75ff0c6ab0f87
nurbs.scad|4fab764929556ec3e7954dacdd8030239abd0d1852bc6411278c1e1efdd5d3ba

980
AlphaIndex.md Normal file

@ -0,0 +1,980 @@
# Alphabetical Index
An index of Functions, Modules, and Constants by name.
[0](#0) [A](#a) [B](#b) [C](#c) [D](#d) [E](#e) [F](#f) [G](#g) [H](#h) [I](#i) [J](#j) [K](#k) [L](#l) [M](#m) [N](#n) [O](#o) [P](#p) [Q](#q) [R](#r) [S](#s) [T](#t) [U](#u) [V](#v) [W](#w) [X](#x) [Y](#y) [Z](#z)
## 0
- [`$slop`](constants.scad#constant-slop) Const The slop amount to make printed items fit closely. `0.0` by default.
## A
- [`accumulate()`](fnliterals.scad#function-accumulate) Func Applies a 2-arg function cumulatively to the items of a list, returning a list of every result.
- [`acme_threaded_nut()`](threading.scad#module-acme_threaded_nut) Mod Creates an ACME threaded nut. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup>
- [`acme_threaded_rod()`](threading.scad#module-acme_threaded_rod) Mod Creates an ACME threaded rod. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup>
- [`acosh()`](math.scad#function-acosh) Func Returns the hyperbolic arc-cosine of the given value.
- [`add_scalar()`](vectors.scad#function-add_scalar) Func Adds a scalar value to every item in a vector.
- [`adj_ang_to_hyp()`](trigonometry.scad#function-adj_ang_to_hyp) Func Returns the hypotenuse length from the length of the adjacent and the angle.
- [`adj_ang_to_opp()`](trigonometry.scad#function-adj_ang_to_opp) Func Returns the opposite side length from the length of the adjacent side and the angle.
- [`hyp_adj_to_ang()`](trigonometry.scad#function-hyp_adj_to_ang) Func Returns the angle from the lengths of the hypotenuse and the adjacent side.
- [`hyp_adj_to_opp()`](trigonometry.scad#function-hyp_adj_to_opp) Func Returns the opposite side length from the lengths of the hypotenuse and the adjacent side.
- [`adj_opp_to_ang()`](trigonometry.scad#function-adj_opp_to_ang) Func Returns the angle from the lengths of the adjacent and opposite sides.
- [`adj_opp_to_hyp()`](trigonometry.scad#function-adj_opp_to_hyp) Func Returns the hypotenuse length from the lengths of the adjacent and opposite sides.
- [`align()`](attachments.scad#module-align) Mod Position children with alignment to parent edges. <sup title="Can transform children.">[<abbr>Trans</abbr>]</sup>
- [`align_polygon()`](geometry.scad#function-align_polygon) Func Find best alignment of a 2d polygon to a reference 2d polygon over a set of transformations.
- [`all()`](utility.scad#function-all) Func Returns true if all items in the argument list are true.
- [`all_defined()`](utility.scad#function-all_defined) Func Returns true if all items in the given array are defined.
- [`all_equal()`](comparisons.scad#function-all_equal) Func Returns true if all items in a list are approximately equal to each other.
- [`all_integer()`](utility.scad#function-all_integer) Func Returns true if all of the numbers in the argument are integers.
- [`all_negative()`](comparisons.scad#function-all_negative) Func Returns true if the value(s) given are less than zero.
- [`all_nonnegative()`](comparisons.scad#function-all_nonnegative) Func Returns true if the value(s) given are greater than or equal to zero.
- [`all_nonpositive()`](comparisons.scad#function-all_nonpositive) Func Returns true if the value(s) given are less than or equal to zero.
- [`all_nonzero()`](comparisons.scad#function-all_nonzero) Func Returns true if the value(s) given are not aproximately zero.
- [`all_positive()`](comparisons.scad#function-all_positive) Func Returns true if the value(s) given are greater than zero.
- [`all_zero()`](comparisons.scad#function-all_zero) Func Returns true if the value(s) given are aproximately zero.
- [`altaz_to_xyz()`](coords.scad#function-altaz_to_xyz) Func Convert altitude/azimuth/range to 3D cartesian coordinates. <sup title="Can return a Path.">[<abbr>Path</abbr>]</sup>
- [`anchor_arrow()`](attachments.scad#module-anchor_arrow) Mod Shows a 3d anchor orientation arrow. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup>
- [`anchor_arrow2d()`](attachments.scad#module-anchor_arrow2d) Mod Shows a 2d anchor orientation arrow. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup>
- [`adj_ang_to_hyp()`](trigonometry.scad#function-adj_ang_to_hyp) Func Returns the hypotenuse length from the length of the adjacent and the angle.
- [`adj_ang_to_opp()`](trigonometry.scad#function-adj_ang_to_opp) Func Returns the opposite side length from the length of the adjacent side and the angle.
- [`hyp_ang_to_adj()`](trigonometry.scad#function-hyp_ang_to_adj) Func Returns the adjacent side length from the length of the hypotenuse and the angle.
- [`hyp_ang_to_opp()`](trigonometry.scad#function-hyp_ang_to_opp) Func Returns the opposite side length from the length of the hypotenuse and the angle.
- [`opp_ang_to_adj()`](trigonometry.scad#function-opp_ang_to_adj) Func Returns the adjacent side length from the length of the opposite side and the angle.
- [`opp_ang_to_hyp()`](trigonometry.scad#function-opp_ang_to_hyp) Func Returns the hypotenuse length from the length of the opposite side and the angle.
- [`any()`](utility.scad#function-any) Func Returns true if any item in the argument list is true.
- [`any_defined()`](utility.scad#function-any_defined) Func Returns true if any item in the argument list is not `undef`.
- [`apply()`](transforms.scad#function-apply) Func Applies a transformation matrix to a point, list of points, array of points, or a VNF. <sup title="Can return a Path.">[<abbr>Path</abbr>]</sup> <sup title="Can return a VNF.">[<abbr>VNF</abbr>]</sup> <sup title="Can return a transformation matrix.">[<abbr>Mat</abbr>]</sup>
- [`apply_folding_hinges_and_snaps()`](hinges.scad#module-apply_folding_hinges_and_snaps) Mod Adds snap shapes and removes living hinges from a child shape. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup>
- [`approx()`](comparisons.scad#function-approx) Func Returns true if two values are equal to within a small epsilon value.
- [`arc()`](drawing.scad#functionmodule-arc) Func/Mod Draws a 2D pie-slice or returns 2D or 3D path forming an arc. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup> <sup title="Can return a Path.">[<abbr>Path</abbr>]</sup>
- [`arc_copies()`](distributors.scad#functionmodule-arc_copies) Func/Mod Distributes duplicates of children along an arc. <sup title="Can return a list of transformation matrices.">[<abbr>MatList</abbr>]</sup> <sup title="Can transform children.">[<abbr>Trans</abbr>]</sup>
- [`are_ends_equal()`](comparisons.scad#function-are_ends_equal) Func Returns true if the first and last items in a list are approximately equal.
- [`are_points_on_plane()`](geometry.scad#function-are_points_on_plane) Func Determine if all of the listed points are on a plane.
- [`are_polygons_equal()`](geometry.scad#function-are_polygons_equal) Func Check if two polygons (not necessarily in the same point order) are equal.
- [`are_regions_equal()`](regions.scad#function-are_regions_equal) Func Returns true if given regions are the same polygons.
- [`asinh()`](math.scad#function-asinh) Func Returns the hyperbolic arc-sine of the given value.
- [`assert_approx()`](utility.scad#module-assert_approx) Mod Assert that a value is approximately what was expected.
- [`assert_equal()`](utility.scad#module-assert_equal) Mod Assert that a value is expected.
- [`associate_vertices()`](skin.scad#function-associate_vertices) Func Create vertex association to control how [`skin()`](#functionmodule-skin) links vertices. <sup title="Can return a list of Paths.">[<abbr>PathList</abbr>]</sup>
- [`atanh()`](math.scad#function-atanh) Func Returns the hyperbolic arc-tangent of the given value.
- [`attach()`](attachments.scad#module-attach) Mod Attaches children to a parent object at an anchor point and with anchor orientation. <sup title="Can transform children.">[<abbr>Trans</abbr>]</sup>
- [`attach_geom()`](attachments.scad#function-attach_geom) Func Returns the internal geometry description of an attachable object.
- [`attachable()`](attachments.scad#module-attachable) Mod Manages the anchoring, spin, orientation, and attachments for an object.
- [`auto_profile_shift()`](gears.scad#function-auto_profile_shift) Func Returns the recommended profile shift for a gear.
## B
- [`BACK`](constants.scad#constant-back) Const The backwards (Y+) direction vector constant `[0,1,0]`.
- [`back()`](transforms.scad#functionmodule-back) Func/Mod Translates children backwards (Y+). <sup title="Can transform children.">[<abbr>Trans</abbr>]</sup> <sup title="Can return a Path.">[<abbr>Path</abbr>]</sup> <sup title="Can return a VNF.">[<abbr>VNF</abbr>]</sup> <sup title="Can return a transformation matrix.">[<abbr>Mat</abbr>]</sup>
- [`back_half()`](partitions.scad#functionmodule-back_half) Func/Mod Masks the front half of an object along the X-Z plane, leaving the back half. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup> <sup title="Can return a VNF.">[<abbr>VNF</abbr>]</sup> <sup title="Can return a Path.">[<abbr>Path</abbr>]</sup> <sup title="Can return a Region.">[<abbr>Region</abbr>]</sup>
- [`back_substitute()`](linalg.scad#function-back_substitute) Func Solve an upper triangular system, Rx=b.
- [`ball_bearing()`](ball_bearings.scad#module-ball_bearing) Mod Creates a standardized ball bearing assembly. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup>
- [`ball_bearing_info()`](ball_bearings.scad#function-ball_bearing_info) Func Returns size info for a standardized ball bearing assembly.
- [`ball_screw_rod()`](threading.scad#module-ball_screw_rod) Mod Creates a ball screw rod. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup>
- [`bent_cutout_mask()`](rounding.scad#module-bent_cutout_mask) Mod Create a mask for making a round-edged cutout in a cylindrical shell. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup>
- [`bevel_gear()`](gears.scad#functionmodule-bevel_gear) Func/Mod Creates a straight, zerol, or spiral bevel gear. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup> <sup title="Can return a VNF.">[<abbr>VNF</abbr>]</sup>
- [`bevel_pitch_angle()`](gears.scad#function-bevel_pitch_angle) Func Returns the pitch cone angle for a bevel gear.
- [`bez_begin()`](beziers.scad#function-bez_begin) Func Calculates starting bezier path control points.
- [`bez_end()`](beziers.scad#function-bez_end) Func Calculates ending bezier path control points.
- [`bez_joint()`](beziers.scad#function-bez_joint) Func Calculates control points for a disjointed corner bezier path joint.
- [`bez_tang()`](beziers.scad#function-bez_tang) Func Calculates control points for a smooth bezier path joint.
- [`bezier_closest_point()`](beziers.scad#function-bezier_closest_point) Func Finds the closest position on a bezier curve to a given point.
- [`bezier_curvature()`](beziers.scad#function-bezier_curvature) Func Returns the curvature at one or more given positions along a bezier curve.
- [`bezier_curve()`](beziers.scad#function-bezier_curve) Func Computes a specified number of points on a bezier curve. <sup title="Can return a Path.">[<abbr>Path</abbr>]</sup>
- [`bezier_derivative()`](beziers.scad#function-bezier_derivative) Func Evaluates the derivative of the bezier curve at the given point or points.
- [`bezier_length()`](beziers.scad#function-bezier_length) Func Approximate the length of part of a bezier curve.
- [`bezier_line_intersection()`](beziers.scad#function-bezier_line_intersection) Func Calculates where a bezier curve intersects a line.
- [`bezier_patch_flat()`](beziers.scad#function-bezier_patch_flat) Func Creates a flat bezier patch.
- [`bezier_patch_normals()`](beziers.scad#function-bezier_patch_normals) Func Computes surface normals for one or more places on a bezier surface patch.
- [`bezier_patch_points()`](beziers.scad#function-bezier_patch_points) Func Computes one or more specified points across a bezier surface patch.
- [`bezier_patch_reverse()`](beziers.scad#function-bezier_patch_reverse) Func Reverses the orientation of a bezier patch.
- [`bezier_points()`](beziers.scad#function-bezier_points) Func Computes one or more specified points along a bezier curve. <sup title="Can return a Path.">[<abbr>Path</abbr>]</sup>
- [`bezier_sheet()`](beziers.scad#function-bezier_sheet) Func Creates a thin sheet from a bezier patch by extruding in normal to the patch <sup title="Can return a VNF.">[<abbr>VNF</abbr>]</sup>
- [`bezier_tangent()`](beziers.scad#function-bezier_tangent) Func Calculates unit tangent vectors along the bezier curve at one or more given positions.
- [`bezier_vnf()`](beziers.scad#function-bezier_vnf) Func Generates a (probably non-manifold) VNF for one or more bezier surface patches. <sup title="Can return a VNF.">[<abbr>VNF</abbr>]</sup>
- [`bezier_vnf_degenerate_patch()`](beziers.scad#function-bezier_vnf_degenerate_patch) Func Generates a VNF for a degenerate bezier surface patch. <sup title="Can return a VNF.">[<abbr>VNF</abbr>]</sup>
- [`bezpath_close_to_axis()`](beziers.scad#function-bezpath_close_to_axis) Func Closes a 2D bezier path to the specified axis. <sup title="Can return a Path.">[<abbr>Path</abbr>]</sup>
- [`bezpath_closest_point()`](beziers.scad#function-bezpath_closest_point) Func Finds the closest point on a bezier path to a given point.
- [`bezpath_curve()`](beziers.scad#function-bezpath_curve) Func Converts bezier path into a path of points. <sup title="Can return a Path.">[<abbr>Path</abbr>]</sup>
- [`bezpath_length()`](beziers.scad#function-bezpath_length) Func Approximate the length of a bezier path.
- [`bezpath_offset()`](beziers.scad#function-bezpath_offset) Func Forms a closed bezier path loop with a translated and reversed copy of itself. <sup title="Can return a Path.">[<abbr>Path</abbr>]</sup>
- [`bezpath_points()`](beziers.scad#function-bezpath_points) Func Computes one or more specified points along a bezier path. <sup title="Can return a Path.">[<abbr>Path</abbr>]</sup>
- [`binomial()`](math.scad#function-binomial) Func Returns the binomial coefficients of the integer `n`.
- [`binomial_coefficient()`](math.scad#function-binomial_coefficient) Func Returns the `k`-th binomial coefficient of the integer `n`.
- [`binsearch()`](fnliterals.scad#function-binsearch) Func Does a binary search of a sorted list to find the index of a given value.
- [`block_matrix()`](linalg.scad#function-block_matrix) Func Make a new matrix from a block of matrices.
- [`bosl_required()`](version.scad#module-bosl_required) Mod Asserts that the current version of the library is at least the given version.
- [`bosl_version()`](version.scad#function-bosl_version) Func Returns the BOSL2 version as a list.
- [`bosl_version_num()`](version.scad#function-bosl_version_num) Func Returns the BOSL2 version as a float.
- [`bosl_version_str()`](version.scad#function-bosl_version_str) Func Returns the BOSL2 version as a string.
- [`BOTTOM`](constants.scad#constant-bottom) Const The down-wards (Z-) direction vector constant `[0,0,-1]`.
- [`bottle_adapter_cap_to_cap()`](bottlecaps.scad#module-bottle_adapter_cap_to_cap) Mod Creates a generic adaptor between a cap and a cap. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup>
- [`bottle_adapter_neck_to_cap()`](bottlecaps.scad#module-bottle_adapter_neck_to_cap) Mod Creates a generic adaptor between a neck and a cap. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup>
- [`bottle_adapter_neck_to_neck()`](bottlecaps.scad#module-bottle_adapter_neck_to_neck) Mod Creates a generic adaptor between a neck and a neck. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup>
- [`BOTTOM`](constants.scad#constant-bottom) Const The down-wards (Z-) direction vector constant `[0,0,-1]`.
- [`bottom_half()`](partitions.scad#functionmodule-bottom_half) Func/Mod Masks the top half of an object along the X-Y plane, leaving the bottom half. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup> <sup title="Can return a VNF.">[<abbr>VNF</abbr>]</sup> <sup title="Can return a Path.">[<abbr>Path</abbr>]</sup> <sup title="Can return a Region.">[<abbr>Region</abbr>]</sup>
- [`bounding_box()`](miscellaneous.scad#module-bounding_box) Mod Creates the smallest bounding box that contains all the children. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup>
- [`bselect()`](lists.scad#function-bselect) Func Select list items using boolean index list.
- [`buttress_threaded_nut()`](threading.scad#module-buttress_threaded_nut) Mod Creates a buttress-threaded nut. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup>
- [`buttress_threaded_rod()`](threading.scad#module-buttress_threaded_rod) Mod Creates a buttress-threaded rod. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup>
## C
- [`c_conj()`](math.scad#function-c_conj) Func Returns the complex conjugate of the input.
- [`c_div()`](math.scad#function-c_div) Func Divides two complex numbers.
- [`c_ident()`](math.scad#function-c_ident) Func Returns an n by n complex identity matrix.
- [`c_imag()`](math.scad#function-c_imag) Func Returns the imaginary part of a complex number, vector or matrix..
- [`c_mul()`](math.scad#function-c_mul) Func Multiplies two complex numbers.
- [`c_norm()`](math.scad#function-c_norm) Func Returns the norm of a complex number or vector.
- [`c_real()`](math.scad#function-c_real) Func Returns the real part of a complex number, vector or matrix..
- [`catenary()`](drawing.scad#function-catenary) Func Returns a 2D Catenary chain or arch path. <sup title="Can return a Path.">[<abbr>Path</abbr>]</sup>
- [`ccw_polygon()`](geometry.scad#function-ccw_polygon) Func Return counter-clockwise version of a polygon.
- [`CENTER`](constants.scad#constant-center) Const The center vector constant `[0,0,0]`.
- [`CENTER`](constants.scad#constant-center) Const The center vector constant `[0,0,0]`.
- [`centroid()`](geometry.scad#function-centroid) Func Compute centroid of a 2d or 3d polygon or a VNF.
- [`chain_hull()`](miscellaneous.scad#module-chain_hull) Mod Performs the union of hull operations between consecutive pairs of children. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup>
- [`chamfer_corner_mask()`](masks3d.scad#module-chamfer_corner_mask) Mod Creates a shape to chamfer a 90° corner. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup>
- [`chamfer_cylinder_mask()`](masks3d.scad#module-chamfer_cylinder_mask) Mod Creates a shape to chamfer the end of a cylinder. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup>
- [`chamfer_edge_mask()`](masks3d.scad#module-chamfer_edge_mask) Mod Creates a shape to chamfer a 90° edge. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup>
- [`cholesky()`](linalg.scad#function-cholesky) Func Compute the Cholesky factorization of a matrix.
- [`circle()`](shapes2d.scad#functionmodule-circle) Func/Mod Creates the approximation of a circle. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup> <sup title="Can return a Path.">[<abbr>Path</abbr>]</sup> <sup title="Extends the OpenScad keyword of the same name.">[<abbr>Ext</abbr>]</sup>
- [`circle_2tangents()`](geometry.scad#function-circle_2tangents) Func Given two 2d or 3d rays, find a circle tangent to both.
- [`circle_3points()`](geometry.scad#function-circle_3points) Func Find a circle passing through three 2d or 3d points.
- [`circle_circle_intersection()`](geometry.scad#function-circle_circle_intersection) Func Find the intersection points of two 2d circles.
- [`circle_circle_tangents()`](geometry.scad#function-circle_circle_tangents) Func Find tangents to a pair of circles in 2d.
- [`circle_line_intersection()`](geometry.scad#function-circle_line_intersection) Func Find the intersection points between a 2d circle and a line, ray or segment.
- [`circle_point_tangents()`](geometry.scad#function-circle_point_tangents) Func Given a circle and point, find tangents to circle passing through the point.
- [`circular_pitch()`](gears.scad#function-circular_pitch) Func Returns tooth density expressed as "circular pitch".
- [`clockwise_polygon()`](geometry.scad#function-clockwise_polygon) Func Return clockwise version of a polygon.
- [`closest_point()`](vectors.scad#function-closest_point) Func Finds the closest point in a list of points.
- [`color_overlaps()`](color.scad#module-color_overlaps) Mod Shows ghostly children, with overlaps highlighted in color. <sup title="Can transform children.">[<abbr>Trans</abbr>]</sup>
- [`color_this()`](color.scad#module-color_this) Mod Sets the color for children at the current level only. <sup title="Can transform children.">[<abbr>Trans</abbr>]</sup>
- [`column()`](linalg.scad#function-column) Func Extract a column from a matrix.
- [`combinations()`](lists.scad#function-combinations) Func Returns a list of all combinations of the list entries.
- [`compare_lists()`](comparisons.scad#function-compare_lists) Func Compares two lists of values, possibly of different type.
- [`compare_vals()`](comparisons.scad#function-compare_vals) Func Compares two values, possibly of different type.
- [`complex()`](math.scad#function-complex) Func Replaces scalars in a list or matrix with complex number 2-vectors.
- [`constrain()`](math.scad#function-constrain) Func Returns a value constrained between `minval` and `maxval`, inclusive.
- [`conv_hull()`](attachments.scad#module-conv_hull) Mod Performs a hull operation on the children using tags to determine what happens.
- [`convex_collision()`](geometry.scad#function-convex_collision) Func Check whether the convex hulls of two point lists intersect.
- [`convex_distance()`](geometry.scad#function-convex_distance) Func Compute distance between convex hull of two point lists.
- [`convex_offset_extrude()`](rounding.scad#module-convex_offset_extrude) Mod Make a solid from geometry where offset changes along the object's length. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup>
- [`convolve()`](math.scad#function-convolve) Func Returns the convolution of `p` and `q`.
- [`corner_mask()`](attachments.scad#module-corner_mask) Mod Attaches a 3d mask shape to the given corners of the parent. <sup title="Can transform children.">[<abbr>Trans</abbr>]</sup>
- [`corner_profile()`](attachments.scad#module-corner_profile) Mod Rotationally extrudes a 2d edge profile into corner mask on the given corners of the parent. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup>
- [`corrugated_wall()`](walls.scad#module-corrugated_wall) Mod Makes a corrugated rectangular wall. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup>
- [`cosh()`](math.scad#function-cosh) Func Returns the hyperbolic cosine of the given value.
- [`count()`](math.scad#function-count) Func Creates a list of incrementing numbers.
- [`crown_gear()`](gears.scad#functionmodule-crown_gear) Func/Mod Creates a crown gear that can mesh with a spur gear. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup> <sup title="Can return a VNF.">[<abbr>VNF</abbr>]</sup>
- [`CENTER`](constants.scad#constant-center) Const The center vector constant `[0,0,0]`.
- [`cube()`](shapes3d.scad#functionmodule-cube) Func/Mod Creates a cube with anchors for attaching children. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup> <sup title="Can return a VNF.">[<abbr>VNF</abbr>]</sup> <sup title="Extends the OpenScad keyword of the same name.">[<abbr>Ext</abbr>]</sup>
- [`cubetruss()`](cubetruss.scad#module-cubetruss) Mod Creates a multi-cube straight cubetruss shape. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup>
- [`cubetruss_clip()`](cubetruss.scad#module-cubetruss_clip) Mod Creates a clip for the end of a cubetruss to snap-lock it to another cubetruss. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup>
- [`cubetruss_corner()`](cubetruss.scad#module-cubetruss_corner) Mod Creates a multi-cube corner cubetruss shape. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup>
- [`cubetruss_dist()`](cubetruss.scad#function-cubetruss_dist) Func Returns the length of a cubetruss truss.
- [`cubetruss_foot()`](cubetruss.scad#module-cubetruss_foot) Mod Creates a foot that can connect two cubetrusses. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup>
- [`cubetruss_joiner()`](cubetruss.scad#module-cubetruss_joiner) Mod Creates a joiner that can connect two cubetrusses end-to-end. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup>
- [`cubetruss_segment()`](cubetruss.scad#module-cubetruss_segment) Mod Creates a single cubetruss cube. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup>
- [`cubetruss_support()`](cubetruss.scad#module-cubetruss_support) Mod Creates a cubetruss support structure shape. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup>
- [`cubetruss_uclip()`](cubetruss.scad#module-cubetruss_uclip) Mod Creates a joiner that can connect two cubetrusses end-to-end. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup>
- [`cuboid()`](shapes3d.scad#module-cuboid) Mod Creates a cube with chamfering and roundovers. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup>
- [`cumprod()`](math.scad#function-cumprod) Func Returns the running cumulative product of a list of values.
- [`cumsum()`](math.scad#function-cumsum) Func Returns the running cumulative sum of a list of values.
- [`cyl()`](shapes3d.scad#functionmodule-cyl) Func/Mod Creates an attachable cylinder with roundovers and chamfering. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup> <sup title="Can return a VNF.">[<abbr>VNF</abbr>]</sup>
- [`cylinder()`](shapes3d.scad#functionmodule-cylinder) Func/Mod Creates an attachable cylinder. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup> <sup title="Can return a VNF.">[<abbr>VNF</abbr>]</sup> <sup title="Extends the OpenScad keyword of the same name.">[<abbr>Ext</abbr>]</sup>
- [`cylindrical_extrude()`](miscellaneous.scad#module-cylindrical_extrude) Mod Extrudes 2D children outwards around a cylinder. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup>
- [`cylindrical_heightfield()`](shapes3d.scad#functionmodule-cylindrical_heightfield) Func/Mod Generates a cylindrical 3d surface from a 2D grid of values. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup> <sup title="Can return a VNF.">[<abbr>VNF</abbr>]</sup>
- [`cylindrical_to_xyz()`](coords.scad#function-cylindrical_to_xyz) Func Convert cylindrical coordinates to cartesian coordinates. <sup title="Can return a Path.">[<abbr>Path</abbr>]</sup>
## D
- [`dashed_stroke()`](drawing.scad#functionmodule-dashed_stroke) Func/Mod Draws a dashed line along a path or region boundry. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup> <sup title="Can return a list of Paths.">[<abbr>PathList</abbr>]</sup>
- [`debug_bezier()`](beziers.scad#module-debug_bezier) Mod Shows a bezier path and its associated control points. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup>
- [`debug_bezier_patches()`](beziers.scad#module-debug_bezier_patches) Mod Shows a bezier surface patch and its associated control points. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup>
- [`debug_nurbs()`](nurbs.scad#module-debug_nurbs) Mod Shows a NURBS curve and its control points, knots and weights <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup>
- [`debug_polygon()`](drawing.scad#module-debug_polygon) Mod Draws an annotated polygon. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup>
- [`debug_region()`](regions.scad#module-debug_region) Mod Draws an annotated region. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup>
- [`debug_vnf()`](vnf.scad#module-debug_vnf) Mod A replacement for `vnf_polyhedron()` to help with debugging. <sup title="Can return a VNF.">[<abbr>VNF</abbr>]</sup>
- [`deduplicate()`](comparisons.scad#function-deduplicate) Func Returns a list with all consecutive duplicate values removed.
- [`deduplicate_indexed()`](comparisons.scad#function-deduplicate_indexed) Func Takes a list of indices into a list of values, and returns a list of indices whose values are not consecutively the same.
- [`default()`](utility.scad#function-default) Func Returns a default value if the argument is 'undef', else returns the argument.
- [`default_tag()`](attachments.scad#module-default_tag) Mod Sets a default tag for all children.
- [`deltas()`](math.scad#function-deltas) Func Returns the deltas between a list of values.
- [`deprecate()`](utility.scad#module-deprecate) Mod Display a console note that a module is deprecated and suggest a replacement.
- [`deriv()`](math.scad#function-deriv) Func Returns the first derivative estimate of a list of data.
- [`deriv2()`](math.scad#function-deriv2) Func Returns the second derivative estimate of a list of data.
- [`deriv3()`](math.scad#function-deriv3) Func Returns the third derivative estimate of a list of data.
- [`det2()`](linalg.scad#function-det2) Func Compute determinant of 2x2 matrix.
- [`det3()`](linalg.scad#function-det3) Func Compute determinant of 3x3 matrix.
- [`det4()`](linalg.scad#function-det4) Func Compute determinant of 4x4 matrix.
- [`determinant()`](linalg.scad#function-determinant) Func compute determinant of an arbitrary square matrix.
- [`diagonal_matrix()`](linalg.scad#function-diagonal_matrix) Func Make a diagonal matrix.
- [`diametral_pitch()`](gears.scad#function-diametral_pitch) Func Returns tooth density expressed as "diametral pitch".
- [`diff()`](attachments.scad#module-diff) Mod Performs a differencing operation using tags rather than hierarchy to control what happens.
- [`difference()`](regions.scad#functionmodule-difference) Func/Mod Performs a Boolean difference operation. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup> <sup title="Can return a Region.">[<abbr>Region</abbr>]</sup>
- [`distribute()`](distributors.scad#module-distribute) Mod Distributes each child, individually, out along an arbitrary line. <sup title="Can transform children.">[<abbr>Trans</abbr>]</sup>
- [`dovetail()`](joiners.scad#module-dovetail) Mod Creates a possibly tapered dovetail shape. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup>
- [`BOTTOM`](constants.scad#constant-bottom) Const The down-wards (Z-) direction vector constant `[0,0,-1]`.
- [`down()`](transforms.scad#functionmodule-down) Func/Mod Translates children downwards (Z-). <sup title="Can transform children.">[<abbr>Trans</abbr>]</sup> <sup title="Can return a Path.">[<abbr>Path</abbr>]</sup> <sup title="Can return a VNF.">[<abbr>VNF</abbr>]</sup> <sup title="Can return a transformation matrix.">[<abbr>Mat</abbr>]</sup>
- [`downcase()`](strings.scad#function-downcase) Func Lowercases all characters in a string.
## E
- [`echo_matrix()`](linalg.scad#functionmodule-echo_matrix) Func/Mod Print a matrix neatly to the console.
- [`echo_struct()`](structs.scad#functionmodule-echo_struct) Func/Mod Echoes the struct to the console in a formatted manner.
- [`EDGE()`](constants.scad#function-edge) Func Named edge anchor constants
- [`edge_mask()`](attachments.scad#module-edge_mask) Mod Attaches a 3D mask shape to the given edges of the parent. <sup title="Can transform children.">[<abbr>Trans</abbr>]</sup>
- [`edge_profile()`](attachments.scad#module-edge_profile) Mod Extrudes a 2d edge profile into a mask on the given edges of the parent. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup>
- [`edge_profile_asym()`](attachments.scad#module-edge_profile_asym) Mod Extrudes an asymmetric 2D profile into a mask on the given edges and corners of the parent. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup>
- [`egg()`](shapes2d.scad#functionmodule-egg) Func/Mod Creates an egg-shaped 2d object. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup> <sup title="Can return a Path.">[<abbr>Path</abbr>]</sup>
- [`ellipse()`](shapes2d.scad#functionmodule-ellipse) Func/Mod Creates the approximation of an ellipse or a circle. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup> <sup title="Can return a Path.">[<abbr>Path</abbr>]</sup>
- [`ends_with()`](strings.scad#function-ends_with) Func Returns true if the string ends with a given substring.
- [`enveloping_worm()`](gears.scad#functionmodule-enveloping_worm) Func/Mod Creates a double-enveloping worm that will mate with a worm gear. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup> <sup title="Can return a VNF.">[<abbr>VNF</abbr>]</sup>
- [`EPSILON`](math.scad#constant-epsilon) Const A tiny value to compare floating point values. `1e-9`
- [`exclusive_or()`](regions.scad#functionmodule-exclusive_or) Func/Mod Performs a Boolean exclusive-or operation. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup> <sup title="Can return a Region.">[<abbr>Region</abbr>]</sup>
- [`exponential_rands()`](math.scad#function-exponential_rands) Func Returns a list of random numbers with an exponential distribution.
- [`expose_anchors()`](attachments.scad#module-expose_anchors) Mod Used to show a transparent object with solid color anchor arrows.
- [`extrude_from_to()`](miscellaneous.scad#module-extrude_from_to) Mod Extrudes 2D children between two points in 3D space. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup>
## F
- [`f_1arg()`](fnliterals.scad#function-f_1arg) Func Creates a factory for a 2-arg function literal, where you can optionally pre-fill the arg.
- [`f_2arg()`](fnliterals.scad#function-f_2arg) Func Creates a factory for a 2-arg function literal, where you can optionally pre-fill the args.
- [`f_2arg_simple()`](fnliterals.scad#function-f_2arg_simple) Func Creates a factory for a 2-arg function literal, where you can optionally pre-fill the args.
- [`f_3arg()`](fnliterals.scad#function-f_3arg) Func Creates a factory for a 3-arg function literal, where you can optionally pre-fill the args.
- [`f_abs()`](fnliterals.scad#function-f_abs) Func Returns a function to calculate the absolute value of a given number.
- [`f_acos()`](fnliterals.scad#function-f_acos) Func Returns a function to calculate the arccosine of a value.
- [`f_add()`](fnliterals.scad#function-f_add) Func Returns a function to add `a` and `b`.
- [`f_and()`](fnliterals.scad#function-f_and) Func Returns a function to check if both `a` and `b` are true.
- [`f_approx()`](fnliterals.scad#function-f_approx) Func Returns a function to compare if `a` is approximately equal to `b`.
- [`f_asin()`](fnliterals.scad#function-f_asin) Func Returns a function to calculate the arcsine of a value.
- [`f_atan()`](fnliterals.scad#function-f_atan) Func Returns a function to calculate the arctangent of a value.
- [`f_atan2()`](fnliterals.scad#function-f_atan2) Func Returns a function to calculate the arctangent of `y` and `x`
- [`f_ceil()`](fnliterals.scad#function-f_ceil) Func Returns a function to calculate the integer ceiling of a given number.
- [`f_chr()`](fnliterals.scad#function-f_chr) Func Returns a function to get a string character from its ordinal number.
- [`f_cmp()`](fnliterals.scad#function-f_cmp) Func Returns a function to compare values.
- [`f_cos()`](fnliterals.scad#function-f_cos) Func Returns a function to calculate the cosine of a value.
- [`f_cross()`](fnliterals.scad#function-f_cross) Func Returns a function to calculate the norm of a given vector.
- [`f_div()`](fnliterals.scad#function-f_div) Func Returns a function to divide `a` by `b`.
- [`f_eq()`](fnliterals.scad#function-f_eq) Func Returns a function to compare if `a` is exactly equal to `b`.
- [`f_even()`](fnliterals.scad#function-f_even) Func Returns a function to check if `a` is an even number.
- [`f_exp()`](fnliterals.scad#function-f_exp) Func Returns a function to calculate the natural exponent of a given number.
- [`f_floor()`](fnliterals.scad#function-f_floor) Func Returns a function to calculate the integer floor of a given number.
- [`f_gt()`](fnliterals.scad#function-f_gt) Func Returns a function to compare if `a` is greater than `b`.
- [`f_gte()`](fnliterals.scad#function-f_gte) Func Returns a function to compare if `a` is greater than or equal to `b`.
- [`f_is_bool()`](fnliterals.scad#function-f_is_bool) Func Returns a function to determine if a value is a boolean.
- [`f_is_def()`](fnliterals.scad#function-f_is_def) Func Returns a function to determine if a value is not `undef`.
- [`f_is_finite()`](fnliterals.scad#function-f_is_finite) Func Returns a function to determine if a value is a number type that is finite.
- [`f_is_function()`](fnliterals.scad#function-f_is_function) Func Returns a function to determine if a value is a function literal.
- [`f_is_int()`](fnliterals.scad#function-f_is_int) Func Returns a function to determine if a value is an integer number.
- [`f_is_list()`](fnliterals.scad#function-f_is_list) Func Returns a function to determine if a value is a list.
- [`f_is_nan()`](fnliterals.scad#function-f_is_nan) Func Returns a function to determine if a value is a number type that is Not a Number (NaN).
- [`f_is_num()`](fnliterals.scad#function-f_is_num) Func Returns a function to determine if a value is a number.
- [`f_is_patch()`](fnliterals.scad#function-f_is_patch) Func Returns a function to determine if a value is a Bezier Patch structure.
- [`f_is_path()`](fnliterals.scad#function-f_is_path) Func Returns a function to determine if a value is a Path (a list of points).
- [`f_is_range()`](fnliterals.scad#function-f_is_range) Func Returns a function to determine if a value is a range.
- [`f_is_region()`](fnliterals.scad#function-f_is_region) Func Returns a function to determine if a value is a Region (a list of Paths).
- [`f_is_string()`](fnliterals.scad#function-f_is_string) Func Returns a function to determine if a value is a string.
- [`f_is_undef()`](fnliterals.scad#function-f_is_undef) Func Returns a function to determine if a value is `undef`.
- [`f_is_vector()`](fnliterals.scad#function-f_is_vector) Func Returns a function to determine if a value is a list of numbers.
- [`f_is_vnf()`](fnliterals.scad#function-f_is_vnf) Func Returns a function to determine if a value is a VNF structure.
- [`f_len()`](fnliterals.scad#function-f_len) Func Returns a function to calculate the length of a string or list.
- [`f_ln()`](fnliterals.scad#function-f_ln) Func Returns a function to calculate the natural logarithm of a given number.
- [`f_log()`](fnliterals.scad#function-f_log) Func Returns a function to calculate the base 10 logarithm of a given number.
- [`f_lt()`](fnliterals.scad#function-f_lt) Func Returns a function to compare if `a` is less than `b`.
- [`f_lte()`](fnliterals.scad#function-f_lte) Func Returns a function to compare if `a` is less than or equal to `b`.
- [`f_max()`](fnliterals.scad#function-f_max) Func Returns a function to calculate the maximum value of a list.
- [`f_max2()`](fnliterals.scad#function-f_max2) Func Returns a function to calculate the maximum of two values.
- [`f_max3()`](fnliterals.scad#function-f_max3) Func Returns a function to calculate the maximum of three values.
- [`f_min()`](fnliterals.scad#function-f_min) Func Returns a function to calculate the minimum value of a list.
- [`f_min2()`](fnliterals.scad#function-f_min2) Func Returns a function to calculate the minimum of two values.
- [`f_min3()`](fnliterals.scad#function-f_min3) Func Returns a function to calculate the minimum of three values.
- [`f_mod()`](fnliterals.scad#function-f_mod) Func Returns a function to calculate the modulo of `a` divided by `b`.
- [`f_mul()`](fnliterals.scad#function-f_mul) Func Returns a function to multiply `a` by `b`.
- [`f_nand()`](fnliterals.scad#function-f_nand) Func Returns a function to check if `a` and `b` are not both true.
- [`f_napprox()`](fnliterals.scad#function-f_napprox) Func Returns a function to compare if `a` is not approximately equal to `b`.
- [`f_neg()`](fnliterals.scad#function-f_neg) Func Returns a function to calculate `-a`
- [`f_neq()`](fnliterals.scad#function-f_neq) Func Returns a function to compare if `a` is not exactly equal to `b`.
- [`f_nor()`](fnliterals.scad#function-f_nor) Func Returns a function to check if neither `a` nor `b` are true.
- [`f_norm()`](fnliterals.scad#function-f_norm) Func Returns a function to calculate the norm of a given vector.
- [`f_not()`](fnliterals.scad#function-f_not) Func Returns a function to check if `a` is not true.
- [`f_odd()`](fnliterals.scad#function-f_odd) Func Returns a function to check if `a` is an odd number.
- [`f_or()`](fnliterals.scad#function-f_or) Func Returns a function to check if either `a` or `b` is true.
- [`f_ord()`](fnliterals.scad#function-f_ord) Func Returns a function to get the ordinal number of a string character.
- [`f_pow()`](fnliterals.scad#function-f_pow) Func Returns a function to calculate `a` to the power of `b`.
- [`f_round()`](fnliterals.scad#function-f_round) Func Returns a function to calculate the integer rounding of a given number.
- [`f_sign()`](fnliterals.scad#function-f_sign) Func Returns a function to calculate the sign of a given number.
- [`f_sin()`](fnliterals.scad#function-f_sin) Func Returns a function to calculate the sine of a value.
- [`f_sqr()`](fnliterals.scad#function-f_sqr) Func Returns a function to calculate the square of a given number.
- [`f_sqrt()`](fnliterals.scad#function-f_sqrt) Func Returns a function to calculate the square root of a given number.
- [`f_str()`](fnliterals.scad#function-f_str) Func Returns a function to get the string representation of an arbitrary value.
- [`f_str2()`](fnliterals.scad#function-f_str2) Func Returns a function to concatenate the string representations of two arbitrary values.
- [`f_str3()`](fnliterals.scad#function-f_str3) Func Returns a function to concatenate the string representations of three arbitrary values.
- [`f_sub()`](fnliterals.scad#function-f_sub) Func Returns a function to subtract `a` from `b`.
- [`f_tan()`](fnliterals.scad#function-f_tan) Func Returns a function to calculate the tangent of a value.
- [`f_xor()`](fnliterals.scad#function-f_xor) Func Returns a function to check if either `a` or `b`, but not both, are true.
- [`FACE()`](constants.scad#function-face) Func Named face anchor constants
- [`face_mask()`](attachments.scad#module-face_mask) Mod Ataches a 3d mask shape to the given faces of the parent. <sup title="Can transform children.">[<abbr>Trans</abbr>]</sup>
- [`face_profile()`](attachments.scad#module-face_profile) Mod Extrudes a 2D edge profile into a mask for all edges and corners of the given faces on the parent. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup>
- [`factorial()`](math.scad#function-factorial) Func Returns the factorial of the given integer.
- [`fillet()`](shapes3d.scad#module-fillet) Mod Creates a smooth fillet between two faces. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup> <sup title="Can return a VNF.">[<abbr>VNF</abbr>]</sup>
- [`filter()`](fnliterals.scad#function-filter) Func Returns just the list items which the given function returns true for.
- [`find_all()`](fnliterals.scad#function-find_all) Func Returns the indices of all items in a list that a given function returns true for.
- [`find_approx()`](comparisons.scad#function-find_approx) Func Finds the indexes of the item(s) in the given list that are aproximately the given value.
- [`find_first()`](fnliterals.scad#function-find_first) Func Returns the index of the first item in a list, after `start`, that a given function returns true for.
- [`first_defined()`](utility.scad#function-first_defined) Func Returns the first value in the argument list that is not 'undef'.
- [`flatten()`](lists.scad#function-flatten) Func Flattens a list of sublists into a single list.
- [`for_n()`](fnliterals.scad#function-for_n) Func Iteratively calls a work function `n` times, returning the final result.
- [`force_list()`](lists.scad#function-force_list) Func Coerces non-list values into a list.
- [`force_path()`](paths.scad#function-force_path) Func Checks that path is a region with one component. <sup title="Can return a Path.">[<abbr>Path</abbr>]</sup>
- [`force_region()`](regions.scad#function-force_region) Func Given a polygon returns a region. <sup title="Can return a Region.">[<abbr>Region</abbr>]</sup>
- [`force_tag()`](attachments.scad#module-force_tag) Mod Assigns a tag to a non-attachable object.
- [`format()`](strings.scad#function-format) Func Formats multiple values into a string with a given format.
- [`format_fixed()`](strings.scad#function-format_fixed) Func Formats a float into a string with a fixed number of decimal places.
- [`format_float()`](strings.scad#function-format_float) Func Formats a float into a string with a given number of significant digits.
- [`format_int()`](strings.scad#function-format_int) Func Formats an integer into a string, with possible leading zeros.
- [`FRONT`](constants.scad#constant-front) Const The front-wards (Y-) direction vector constant `[0,-1,0]`.
- [`frame_map()`](transforms.scad#functionmodule-frame_map) Func/Mod Rotates and possibly skews children from one frame of reference to another. <sup title="Can transform children.">[<abbr>Trans</abbr>]</sup> <sup title="Can return a Path.">[<abbr>Path</abbr>]</sup> <sup title="Can return a VNF.">[<abbr>VNF</abbr>]</sup> <sup title="Can return a transformation matrix.">[<abbr>Mat</abbr>]</sup>
- [`frame_ref()`](attachments.scad#module-frame_ref) Mod Shows axis orientation arrows. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup>
- [`FRONT`](constants.scad#constant-front) Const The front-wards (Y-) direction vector constant `[0,-1,0]`.
- [`front_half()`](partitions.scad#functionmodule-front_half) Func/Mod Masks the back half of an object along the X-Z plane, leaving the front half. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup> <sup title="Can return a VNF.">[<abbr>VNF</abbr>]</sup> <sup title="Can return a Path.">[<abbr>Path</abbr>]</sup> <sup title="Can return a Region.">[<abbr>Region</abbr>]</sup>
- [`full_flatten()`](lists.scad#function-full_flatten) Func Recursively flattens nested sublists into a single list of non-list values.
- [`furthest_point()`](vectors.scad#function-furthest_point) Func Finds the furthest point in a list of points.
- [`FRONT`](constants.scad#constant-front) Const The front-wards (Y-) direction vector constant `[0,-1,0]`.
- [`fwd()`](transforms.scad#functionmodule-fwd) Func/Mod Translates children forwards (Y-). <sup title="Can transform children.">[<abbr>Trans</abbr>]</sup> <sup title="Can return a Path.">[<abbr>Path</abbr>]</sup> <sup title="Can return a VNF.">[<abbr>VNF</abbr>]</sup> <sup title="Can return a transformation matrix.">[<abbr>Mat</abbr>]</sup>
## G
- [`gaussian_rands()`](math.scad#function-gaussian_rands) Func Returns a list of random numbers with a gaussian distribution.
- [`gcd()`](math.scad#function-gcd) Func Returns the Greatest Common Divisor/Factor of two integers.
- [`gear_dist()`](gears.scad#function-gear_dist) Func Returns the distance between two gear centers for spur gears or parallel axis helical gears.
- [`gear_dist_skew()`](gears.scad#function-gear_dist_skew) Func Returns the distance between two helical gear centers with skew axes.
- [`gear_shorten()`](gears.scad#function-gear_shorten) Func Returns the tip shortening parameter for profile shifted parallel axis gears.
- [`gear_shorten_skew()`](gears.scad#function-gear_shorten_skew) Func Returns the tip shortening parameter for profile shifted skew axis helical gears.
- [`gear_skew_angle()`](gears.scad#function-gear_skew_angle) Func Returns corrected skew angle between two profile shifted helical gears.
- [`generic_airplane()`](attachments.scad#module-generic_airplane) Mod Shows a generic airplane shape, useful for viewing orientations. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup>
- [`generic_bottle_cap()`](bottlecaps.scad#module-generic_bottle_cap) Mod Creates a generic cap for a bottle. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup>
- [`generic_bottle_neck()`](bottlecaps.scad#module-generic_bottle_neck) Mod Creates a generic neck for a bottle. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup>
- [`generic_threaded_nut()`](threading.scad#module-generic_threaded_nut) Mod Creates a generic threaded nut. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup>
- [`generic_threaded_rod()`](threading.scad#module-generic_threaded_rod) Mod Creates a generic threaded rod. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup>
- [`get_anchor()`](utility.scad#function-get_anchor) Func Returns the correct anchor from `anchor` and `center`.
- [`get_profile_shift()`](gears.scad#function-get_profile_shift) Func Returns total profile shift needed to achieve a desired spacing between two gears
- [`get_radius()`](utility.scad#function-get_radius) Func Given various radii and diameters, returns the most specific radius.
- [`get_slop()`](constants.scad#function-get_slop) Func Returns the $slop value.
- [`ghost()`](color.scad#module-ghost) Mod Sets % modifier for attachable children and their descendents. <sup title="Can transform children.">[<abbr>Trans</abbr>]</sup>
- [`ghost_this()`](color.scad#module-ghost_this) Mod Apply % modifier to children at a single level. <sup title="Can transform children.">[<abbr>Trans</abbr>]</sup>
- [`glued_circles()`](shapes2d.scad#functionmodule-glued_circles) Func/Mod Creates a shape of two circles joined by a curved waist. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup> <sup title="Can return a Path.">[<abbr>Path</abbr>]</sup>
- [`grid_copies()`](distributors.scad#functionmodule-grid_copies) Func/Mod Places copies of children in an [X,Y] grid. <sup title="Can return a list of transformation matrices.">[<abbr>MatList</abbr>]</sup> <sup title="Can transform children.">[<abbr>Trans</abbr>]</sup>
- [`group_data()`](comparisons.scad#function-group_data) Func Groups list data by integer group numbers.
- [`group_sort()`](comparisons.scad#function-group_sort) Func Returns a sorted list of groups of values.
## H
- [`half_joiner()`](joiners.scad#functionmodule-half_joiner) Func/Mod Creates a half-joiner shape to mate with a [`half_joiner2()`](#functionmodule-half\_joiner2) shape.. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup> <sup title="Can return a VNF.">[<abbr>VNF</abbr>]</sup>
- [`half_joiner2()`](joiners.scad#functionmodule-half_joiner2) Func/Mod Creates a half\_joiner2 shape to mate with a [`half_joiner()`](#functionmodule-half\_joiner) shape.. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup> <sup title="Can return a VNF.">[<abbr>VNF</abbr>]</sup>
- [`half_joiner_clear()`](joiners.scad#functionmodule-half_joiner_clear) Func/Mod Creates a mask to clear space for a [`half_joiner()`](#functionmodule-half\_joiner). <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup> <sup title="Can return a VNF.">[<abbr>VNF</abbr>]</sup>
- [`half_of()`](partitions.scad#functionmodule-half_of) Func/Mod Masks half of an object at a cut plane. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup> <sup title="Can return a VNF.">[<abbr>VNF</abbr>]</sup> <sup title="Can return a Path.">[<abbr>Path</abbr>]</sup> <sup title="Can return a Region.">[<abbr>Region</abbr>]</sup>
- [`hashmap()`](fnliterals.scad#function-hashmap) Func Creates a hashmap manipulation function.
- [`heightfield()`](shapes3d.scad#functionmodule-heightfield) Func/Mod Generates a 3D surface from a 2D grid of values. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup> <sup title="Can return a VNF.">[<abbr>VNF</abbr>]</sup>
- [`helix()`](drawing.scad#function-helix) Func Creates a 2d spiral or 3d helical path. <sup title="Can return a Path.">[<abbr>Path</abbr>]</sup>
- [`hex_drive_mask()`](screw_drive.scad#module-hex_drive_mask) Mod Creates a mask for a hex drive recess. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup>
- [`hex_panel()`](walls.scad#module-hex_panel) Mod Create a hexagon braced panel of any shape <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup>
- [`hexagon()`](shapes2d.scad#functionmodule-hexagon) Func/Mod Creates a regular hexagon. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup> <sup title="Can return a Path.">[<abbr>Path</abbr>]</sup>
- [`hide()`](attachments.scad#module-hide) Mod Hides attachable children with the given tags.
- [`hide_this()`](attachments.scad#module-hide_this) Mod Hides attachable children at the current level
- [`highlight()`](color.scad#module-highlight) Mod Sets # modifier for attachable children and their descendents. <sup title="Can transform children.">[<abbr>Trans</abbr>]</sup>
- [`highlight_this()`](color.scad#module-highlight_this) Mod Apply # modifier to children at a single level. <sup title="Can transform children.">[<abbr>Trans</abbr>]</sup>
- [`hirth()`](joiners.scad#module-hirth) Mod Creates a Hirth face spline that locks together two cylinders. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup>
- [`hsl()`](color.scad#functionmodule-hsl) Func/Mod Sets the color of children to a specified hue, saturation, lightness and optional alpha channel value. <sup title="Can transform children.">[<abbr>Trans</abbr>]</sup>
- [`hstack()`](linalg.scad#function-hstack) Func Make a new matrix by stacking matrices horizontally.
- [`hsv()`](color.scad#functionmodule-hsv) Func/Mod Sets the color of children to a hue, saturation, value and optional alpha channel value. <sup title="Can transform children.">[<abbr>Trans</abbr>]</sup>
- [`hull()`](geometry.scad#function-hull) Func Convex hull of a list of 2d or 3d points. <sup title="Extends the OpenScad keyword of the same name.">[<abbr>Ext</abbr>]</sup>
- [`hull2d_path()`](geometry.scad#function-hull2d_path) Func Convex hull of a list of 2d points.
- [`hull3d_faces()`](geometry.scad#function-hull3d_faces) Func Convex hull of a list of 3d points.
- [`hull_points()`](geometry.scad#module-hull_points) Mod Convex hull of a list of 2d or 3d points.
- [`hull_region()`](regions.scad#functionmodule-hull_region) Func/Mod Compute convex hull of region or 2d path <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup> <sup title="Can return a Path.">[<abbr>Path</abbr>]</sup>
- [`hyp_adj_to_ang()`](trigonometry.scad#function-hyp_adj_to_ang) Func Returns the angle from the lengths of the hypotenuse and the adjacent side.
- [`hyp_adj_to_opp()`](trigonometry.scad#function-hyp_adj_to_opp) Func Returns the opposite side length from the lengths of the hypotenuse and the adjacent side.
- [`hyp_ang_to_adj()`](trigonometry.scad#function-hyp_ang_to_adj) Func Returns the adjacent side length from the length of the hypotenuse and the angle.
- [`hyp_ang_to_opp()`](trigonometry.scad#function-hyp_ang_to_opp) Func Returns the opposite side length from the length of the hypotenuse and the angle.
- [`hyp_opp_to_adj()`](trigonometry.scad#function-hyp_opp_to_adj) Func Returns the adjacent side length from the lengths of the hypotenuse and the opposite side.
- [`hyp_opp_to_ang()`](trigonometry.scad#function-hyp_opp_to_ang) Func Returns the angle from the lengths of the hypotenuse and the opposite side.
- [`hypot()`](math.scad#function-hypot) Func Returns the hypotenuse length of a 2D or 3D triangle.
## I
- [`IDENT`](constants.scad#constant-ident) Const A constant containing the 3D identity transformation matrix. <sup title="Can return a transformation matrix.">[<abbr>Mat</abbr>]</sup>
- [`ident()`](linalg.scad#function-ident) Func Return identity matrix.
- [`idx()`](lists.scad#function-idx) Func Returns a range useful for iterating over a list.
- [`in_list()`](lists.scad#function-in_list) Func Returns true if a value is in a list.
- [`INCH`](constants.scad#constant-inch) Const A constant containing the number of millimeters in an inch. `25.4`
- [`INF`](math.scad#constant-inf) Const The floating point value for Infinite.
- [`intersect()`](attachments.scad#module-intersect) Mod Perform an intersection operation on children using tags rather than hierarchy to control what happens.
- [`intersection()`](regions.scad#functionmodule-intersection) Func/Mod Performs a Boolean intersection operation. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup> <sup title="Can return a Region.">[<abbr>Region</abbr>]</sup>
- [`is_1region()`](paths.scad#function-is_1region) Func Returns true if path is a region with one component.
- [`is_bezier_patch()`](beziers.scad#function-is_bezier_patch) Func Returns true if the given item is a bezier patch.
- [`is_bool_list()`](utility.scad#function-is_bool_list) Func Returns true if the argument list contains only booleans.
- [`is_collinear()`](geometry.scad#function-is_collinear) Func Determine if points are collinear.
- [`is_consistent()`](utility.scad#function-is_consistent) Func Returns true if the argument is a list with consistent structure and finite numerical data.
- [`is_coplanar()`](geometry.scad#function-is_coplanar) Func Check if 3d points are coplanar and not collinear.
- [`is_decreasing()`](comparisons.scad#function-is_decreasing) Func Returns true if exery item in a list is less than the previous item.
- [`is_def()`](utility.scad#function-is_def) Func Returns true if `x` is not `undef`.
- [`is_digit()`](strings.scad#function-is_digit) Func Returns true if all characters in the string are decimal digits.
- [`is_finite()`](utility.scad#function-is_finite) Func Returns true if the argument is a finite number.
- [`is_func()`](utility.scad#function-is_func) Func Returns true if the argument is a function literal.
- [`is_hexdigit()`](strings.scad#function-is_hexdigit) Func Returns true if all characters in the string are hexidecimal digits.
- [`is_homogeneous()`](lists.scad#function-is_homogeneous) Func Returns true if all members of a list are of the same type.
- [`is_homogeneous()`](lists.scad#function-is_homogeneous) Func Returns true if all members of a list are of the same type.
- [`is_increasing()`](comparisons.scad#function-is_increasing) Func Returns true if every item in a list is greater than the previous item.
- [`is_int()`](utility.scad#function-is_int) Func Returns true if the argument is an integer.
- [`is_int()`](utility.scad#function-is_int) Func Returns true if the argument is an integer.
- [`is_letter()`](strings.scad#function-is_letter) Func Returns true if all characters in the string are letters.
- [`is_lower()`](strings.scad#function-is_lower) Func Returns true if all characters in the string are lowercase.
- [`is_matrix()`](linalg.scad#function-is_matrix) Func Check if input is a numeric matrix, optionally of specified size
- [`is_matrix_symmetric()`](linalg.scad#function-is_matrix_symmetric) Func Checks if matrix is symmetric
- [`is_nan()`](utility.scad#function-is_nan) Func Return true if the argument is "not a number".
- [`is_nurbs_patch()`](nurbs.scad#function-is_nurbs_patch) Func Returns true if the given item looks like a NURBS patch.
- [`is_path()`](paths.scad#function-is_path) Func Returns True if 'list' is a path.
- [`is_path_simple()`](paths.scad#function-is_path_simple) Func Returns true if a path has no self intersections.
- [`is_point_on_line()`](geometry.scad#function-is_point_on_line) Func Determine if a point is on a line, ray or segment.
- [`is_polygon_clockwise()`](geometry.scad#function-is_polygon_clockwise) Func Determine if a 2d polygon winds clockwise.
- [`is_polygon_convex()`](geometry.scad#function-is_polygon_convex) Func Check if a polygon is convex.
- [`is_range()`](utility.scad#function-is_range) Func Returns true if the argument is a range.
- [`is_region()`](regions.scad#function-is_region) Func Returns true if the input appears to be a region.
- [`is_region_simple()`](regions.scad#function-is_region_simple) Func Returns true if the input is a region with no corner contact.
- [`is_rotation()`](linalg.scad#function-is_rotation) Func Check if a transformation matrix represents a rotation.
- [`is_str()`](utility.scad#function-is_str) Func Returns true if the argument is a string.
- [`is_struct()`](structs.scad#function-is_struct) Func Returns true if the value is a struct.
- [`is_type()`](utility.scad#function-is_type) Func Returns true if the type of 'x' is one of those in the list `types`.
- [`is_upper()`](strings.scad#function-is_upper) Func Returns true if all characters in the string are uppercase.
- [`is_valid_region()`](regions.scad#function-is_valid_region) Func Returns true if the input is a valid region.
- [`is_vector()`](vectors.scad#function-is_vector) Func Returns true if the given value is a vector.
- [`is_vnf()`](vnf.scad#function-is_vnf) Func Returns true given a VNF-like structure.
- [`is_vnf_list()`](vnf.scad#function-is_vnf_list) Func Returns true given a list of VNF-like structures.
- [`ival()`](fnliterals.scad#function-ival) Func Generates a function with signature `(i,x)` that calls `func(i)`
## J
- [`jittered_poly()`](shapes2d.scad#module-jittered_poly) Mod Creates a polygon with extra points for smoother twisted extrusions. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup>
- [`join_prism()`](rounding.scad#functionmodule-join_prism) Func/Mod Join an arbitrary prism to a plane, sphere, cylinder or another arbitrary prism with a fillet. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup> <sup title="Can return a VNF.">[<abbr>VNF</abbr>]</sup>
- [`joiner()`](joiners.scad#module-joiner) Mod Creates a joiner shape that can mate with another rotated joiner shape. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup>
- [`joiner_clear()`](joiners.scad#module-joiner_clear) Mod Creates a mask to clear space for a [`joiner()`](#module-joiner) shape. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup>
## K
- [`keyhole()`](shapes2d.scad#functionmodule-keyhole) Func/Mod Creates a 2D keyhole shape. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup> <sup title="Can return a Path.">[<abbr>Path</abbr>]</sup>
- [`knuckle_hinge()`](hinges.scad#module-knuckle_hinge) Mod Creates a knuckle-hinge shape. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup>
## L
- [`last()`](lists.scad#function-last) Func Returns the last item of a list.
- [`law_of_cosines()`](trigonometry.scad#function-law_of_cosines) Func Applies the Law of Cosines for an arbitrary triangle.
- [`law_of_sines()`](trigonometry.scad#function-law_of_sines) Func Applies the Law of Sines for an arbitrary triangle.
- [`lcm()`](math.scad#function-lcm) Func Returns the Least Common Multiple of two or more integers.
- [`LEFT`](constants.scad#constant-left) Const The left-wards (X-) direction vector constant `[-1,0,0]`.
- [`left()`](transforms.scad#functionmodule-left) Func/Mod Translates children leftwards (X-). <sup title="Can transform children.">[<abbr>Trans</abbr>]</sup> <sup title="Can return a Path.">[<abbr>Path</abbr>]</sup> <sup title="Can return a VNF.">[<abbr>VNF</abbr>]</sup> <sup title="Can return a transformation matrix.">[<abbr>Mat</abbr>]</sup>
- [`left_half()`](partitions.scad#functionmodule-left_half) Func/Mod Masks the right half of an object along the Y-Z plane, leaving the left half. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup> <sup title="Can return a VNF.">[<abbr>VNF</abbr>]</sup> <sup title="Can return a Path.">[<abbr>Path</abbr>]</sup> <sup title="Can return a Region.">[<abbr>Region</abbr>]</sup>
- [`lerp()`](math.scad#function-lerp) Func Linearly interpolates between two values.
- [`lerpn()`](math.scad#function-lerpn) Func Returns exactly `n` values, linearly interpolated between `a` and `b`.
- [`lift_plane()`](coords.scad#function-lift_plane) Func Map a list of 2D points onto a plane in 3D. <sup title="Can return a Path.">[<abbr>Path</abbr>]</sup>
- [`LINE`](constants.scad#constant-line) Const A constant for specifying an unbounded line in various geometry.scad functions. `[false,false]`
- [`line_closest_point()`](geometry.scad#function-line_closest_point) Func Find point on given line, segment or ray that is closest to a given point.
- [`line_copies()`](distributors.scad#functionmodule-line_copies) Func/Mod Places copies of children along an arbitrary line. <sup title="Can return a list of transformation matrices.">[<abbr>MatList</abbr>]</sup> <sup title="Can transform children.">[<abbr>Trans</abbr>]</sup>
- [`line_from_points()`](geometry.scad#function-line_from_points) Func Given a list of collinear points, return the line they define.
- [`line_intersection()`](geometry.scad#function-line_intersection) Func Compute intersection of two lines, segments or rays.
- [`line_normal()`](geometry.scad#function-line_normal) Func Return normal vector to given line.
- [`linear_bearing()`](linear_bearings.scad#module-linear_bearing) Mod Creates a generic linear bearing cartridge. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup>
- [`linear_bearing_housing()`](linear_bearings.scad#module-linear_bearing_housing) Mod Creates a generic linear bearing mount clamp. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup>
- [`linear_solve()`](linalg.scad#function-linear_solve) Func Solve Ax=b or, for overdetermined case, solve the least square problem.
- [`linear_solve3()`](linalg.scad#function-linear_solve3) Func Fast solution to Ax=b where A is 3x3.
- [`linear_sweep()`](skin.scad#functionmodule-linear_sweep) Func/Mod Create a linear extrusion from a path, with optional texturing. <sup title="Can return a VNF.">[<abbr>VNF</abbr>]</sup> <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup>
- [`list()`](lists.scad#function-list) Func Expands a range into a full list.
- [`list_bset()`](lists.scad#function-list_bset) Func Returns a list where values are spread to locations indicated by a boolean index list.
- [`list_head()`](lists.scad#function-list_head) Func Returns the elements at the beginning of a list.
- [`list_insert()`](lists.scad#function-list_insert) Func Inserts values into the middle of a list.
- [`list_pad()`](lists.scad#function-list_pad) Func Extend list to specified length.
- [`list_remove()`](lists.scad#function-list_remove) Func Removes items by index from a list.
- [`list_remove_values()`](lists.scad#function-list_remove_values) Func Removes items by value from a list.
- [`list_rotate()`](lists.scad#function-list_rotate) Func Rotates the ordering of a list.
- [`list_set()`](lists.scad#function-list_set) Func Sets the value of specific list items.
- [`list_shape()`](lists.scad#function-list_shape) Func Returns the dimensions of an array.
- [`list_smallest()`](comparisons.scad#function-list_smallest) Func Returns the `k` smallest values in the list, in arbitrary order.
- [`list_tail()`](lists.scad#function-list_tail) Func Returns the elements at the end of a list.
- [`list_to_matrix()`](lists.scad#function-list_to_matrix) Func Groups items in a list into sublists.
- [`list_unwrap()`](comparisons.scad#function-list_unwrap) Func Removes the last item of a list if its first and last values are equal.
- [`list_wrap()`](comparisons.scad#function-list_wrap) Func Returns a list whose last value is the same as the first.
- [`living_hinge_mask()`](hinges.scad#module-living_hinge_mask) Mod Creates a mask to make a folding "living" hinge. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup>
- [`lmXuu_bearing()`](linear_bearings.scad#module-lmxuu_bearing) Mod Creates a standardized LM*UU linear bearing cartridge. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup>
- [`lmXuu_housing()`](linear_bearings.scad#module-lmxuu_housing) Mod Creates a standardized LM*UU linear bearing mount clamp. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup>
- [`lmXuu_info()`](linear_bearings.scad#function-lmxuu_info) Func Returns the sizes of a standard LM*UU linear bearing cartridge.
- [`log2()`](math.scad#function-log2) Func Returns the log base 2 of the given value.
- [`loop_done()`](utility.scad#function-loop_done) Func Returns true if the argument indicates the current C-style loop is finishing.
- [`loop_while()`](utility.scad#function-loop_while) Func Returns true if both arguments indicate the current C-style loop should continue.
- [`looping()`](utility.scad#function-looping) Func Returns true if the argument indicates the current C-style loop should continue.
## M
- [`make_region()`](regions.scad#function-make_region) Func Converts lists of intersecting polygons into valid regions. <sup title="Can return a Region.">[<abbr>Region</abbr>]</sup>
- [`manfrotto_rc2_plate()`](tripod_mounts.scad#module-manfrotto_rc2_plate) Mod Creates a Manfrotto RC2 tripod quick release mount plate. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup>
- [`map()`](fnliterals.scad#function-map) Func Applies a function to each item in a list.
- [`mask2d_chamfer()`](masks2d.scad#functionmodule-mask2d_chamfer) Func/Mod Produces a 2D chamfer mask shape. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup> <sup title="Can return a Path.">[<abbr>Path</abbr>]</sup>
- [`mask2d_cove()`](masks2d.scad#functionmodule-mask2d_cove) Func/Mod Creates a 2D cove (quarter-round) mask shape. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup> <sup title="Can return a Path.">[<abbr>Path</abbr>]</sup>
- [`mask2d_dovetail()`](masks2d.scad#functionmodule-mask2d_dovetail) Func/Mod Creates a 2D dovetail mask shape. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup> <sup title="Can return a Path.">[<abbr>Path</abbr>]</sup>
- [`mask2d_ogee()`](masks2d.scad#functionmodule-mask2d_ogee) Func/Mod Creates a 2D ogee mask shape. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup> <sup title="Can return a Path.">[<abbr>Path</abbr>]</sup>
- [`mask2d_rabbet()`](masks2d.scad#functionmodule-mask2d_rabbet) Func/Mod Creates a rabbet mask shape. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup> <sup title="Can return a Path.">[<abbr>Path</abbr>]</sup>
- [`mask2d_roundover()`](masks2d.scad#functionmodule-mask2d_roundover) Func/Mod Creates a circular mask shape for rounding edges or beading. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup> <sup title="Can return a Path.">[<abbr>Path</abbr>]</sup>
- [`mask2d_teardrop()`](masks2d.scad#functionmodule-mask2d_teardrop) Func/Mod Creates a 2D teardrop shape with specified max angle from vertical. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup> <sup title="Can return a Path.">[<abbr>Path</abbr>]</sup>
- [`matrix_inverse()`](linalg.scad#function-matrix_inverse) Func General matrix inverse.
- [`matrix_trace()`](linalg.scad#function-matrix_trace) Func Compute the trace of a square matrix.
- [`max_index()`](comparisons.scad#function-max_index) Func Returns the index of the minimal value in the given list.
- [`max_length()`](lists.scad#function-max_length) Func Given a list of sublists, returns the length of the longest sublist.
- [`mean()`](math.scad#function-mean) Func Returns the mean value of a list of values.
- [`median()`](math.scad#function-median) Func Returns the median value of a list of values.
- [`min_index()`](comparisons.scad#function-min_index) Func Returns the index of the minimal value in the given list.
- [`min_length()`](lists.scad#function-min_length) Func Given a list of sublists, returns the length of the shortest sublist.
- [`minkowski_difference()`](miscellaneous.scad#module-minkowski_difference) Mod Removes diff shapes from base shape surface. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup>
- [`mirror()`](transforms.scad#functionmodule-mirror) Func/Mod Reflects children across an arbitrary plane. <sup title="Can transform children.">[<abbr>Trans</abbr>]</sup> <sup title="Can return a Path.">[<abbr>Path</abbr>]</sup> <sup title="Can return a VNF.">[<abbr>VNF</abbr>]</sup> <sup title="Can return a transformation matrix.">[<abbr>Mat</abbr>]</sup> <sup title="Extends the OpenScad keyword of the same name.">[<abbr>Ext</abbr>]</sup>
- [`mirror_copy()`](distributors.scad#functionmodule-mirror_copy) Func/Mod Makes a copy of children mirrored across a given plane. <sup title="Can return a list of transformation matrices.">[<abbr>MatList</abbr>]</sup> <sup title="Can transform children.">[<abbr>Trans</abbr>]</sup>
- [`modang()`](math.scad#function-modang) Func Returns an angle normalized to between -180º and 180º.
- [`modular_hose()`](modular_hose.scad#module-modular_hose) Mod Creates modular hose parts.
- [`modular_hose_radius()`](modular_hose.scad#function-modular_hose_radius) Func Returns the waist radius of the given modular hose size.
- [`module_value()`](gears.scad#function-module_value) Func Returns tooth density expressed as "module"
- [`move()`](transforms.scad#functionmodule-move) Func/Mod Translates children in an arbitrary direction. <sup title="Can transform children.">[<abbr>Trans</abbr>]</sup> <sup title="Can return a Path.">[<abbr>Path</abbr>]</sup> <sup title="Can return a VNF.">[<abbr>VNF</abbr>]</sup> <sup title="Can return a transformation matrix.">[<abbr>Mat</abbr>]</sup>
- [`move_copies()`](distributors.scad#functionmodule-move_copies) Func/Mod Translates copies of all children. <sup title="Can return a list of transformation matrices.">[<abbr>MatList</abbr>]</sup> <sup title="Can transform children.">[<abbr>Trans</abbr>]</sup>
## N
- [`named_anchor()`](attachments.scad#function-named_anchor) Func Creates an anchor data structure.
- [`NAN`](math.scad#constant-nan) Const The floating point value for Not a Number.
- [`narrowing_strut()`](walls.scad#module-narrowing_strut) Mod Makes a strut like an extruded baseball home plate. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup>
- [`nema_motor_info()`](nema_steppers.scad#function-nema_motor_info) Func Returns dimension info for a given NEMA motor size.
- [`nema_mount_mask()`](nema_steppers.scad#module-nema_mount_mask) Mod Creates a standard NEMA mount holes mask. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup>
- [`nema_stepper_motor()`](nema_steppers.scad#module-nema_stepper_motor) Mod Creates a NEMA standard stepper motor model. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup>
- [`no_children()`](utility.scad#module-no_children) Mod Assert that the calling module does not support children.
- [`no_function()`](utility.scad#function-no_function) Func Assert that the argument exists only as a module and not as a function.
- [`no_module()`](utility.scad#module-no_module) Mod Assert that the argument exists only as a function and not as a module.
- [`norm_fro()`](linalg.scad#function-norm_fro) Func Compute Frobenius norm of a matrix
- [`npt_threaded_rod()`](threading.scad#module-npt_threaded_rod) Mod Creates NPT pipe threading. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup>
- [`null_space()`](linalg.scad#function-null_space) Func Return basis for the null space of A.
- [`num_defined()`](utility.scad#function-num_defined) Func Returns the number of defined values in the the argument list.
- [`num_true()`](utility.scad#function-num_true) Func Returns the number of true entries in the arguemnt list.
- [`nurbs_curve()`](nurbs.scad#function-nurbs_curve) Func Computes one more more points on a NURBS curve. <sup title="Can return a Path.">[<abbr>Path</abbr>]</sup>
- [`nurbs_patch_points()`](nurbs.scad#function-nurbs_patch_points) Func Computes specifies point(s) on a NURBS surface patch
- [`nurbs_vnf()`](nurbs.scad#function-nurbs_vnf) Func Generates a (possibly non-manifold) VNF for a single NURBS surface patch. <sup title="Can return a VNF.">[<abbr>VNF</abbr>]</sup>
- [`nut()`](screws.scad#module-nut) Mod Creates a standard nut. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup>
- [`nut_info()`](screws.scad#function-nut_info) Func Returns the dimensions and other info for the given nut.
- [`nut_trap_inline()`](screws.scad#module-nut_trap_inline) Mod Creates an inline nut trap mask. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup>
- [`nut_trap_side()`](screws.scad#module-nut_trap_side) Mod Creates a side nut trap mask. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup>
## O
- [`octagon()`](shapes2d.scad#functionmodule-octagon) Func/Mod Creates a regular octagon. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup> <sup title="Can return a Path.">[<abbr>Path</abbr>]</sup>
- [`octahedron()`](shapes3d.scad#functionmodule-octahedron) Func/Mod Creates an octahedron with axis-aligned points. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup> <sup title="Can return a VNF.">[<abbr>VNF</abbr>]</sup>
- [`offset()`](regions.scad#function-offset) Func Takes a 2D path, polygon or region and returns a path offset by an amount. <sup title="Can return a Path.">[<abbr>Path</abbr>]</sup> <sup title="Can return a Region.">[<abbr>Region</abbr>]</sup> <sup title="Extends the OpenScad keyword of the same name.">[<abbr>Ext</abbr>]</sup>
- [`offset3d()`](miscellaneous.scad#module-offset3d) Mod Expands or contracts the surface of a 3D object. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup>
- [`offset_stroke()`](rounding.scad#functionmodule-offset_stroke) Func/Mod Draws a line along a path with options to specify angles and roundings at the ends. <sup title="Can return a Path.">[<abbr>Path</abbr>]</sup> <sup title="Can return a Region.">[<abbr>Region</abbr>]</sup>
- [`offset_sweep()`](rounding.scad#functionmodule-offset_sweep) Func/Mod Make a solid from a polygon with offset that changes along its length. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup> <sup title="Can return a VNF.">[<abbr>VNF</abbr>]</sup>
- [`one_defined()`](utility.scad#function-one_defined) Func Returns the defined value in the argument list if only a single value is defined.
- [`onion()`](shapes3d.scad#functionmodule-onion) Func/Mod Creates an attachable onion-like shape. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup> <sup title="Can return a VNF.">[<abbr>VNF</abbr>]</sup>
- [`adj_opp_to_ang()`](trigonometry.scad#function-adj_opp_to_ang) Func Returns the angle from the lengths of the adjacent and opposite sides.
- [`adj_opp_to_hyp()`](trigonometry.scad#function-adj_opp_to_hyp) Func Returns the hypotenuse length from the lengths of the adjacent and opposite sides.
- [`opp_ang_to_adj()`](trigonometry.scad#function-opp_ang_to_adj) Func Returns the adjacent side length from the length of the opposite side and the angle.
- [`opp_ang_to_hyp()`](trigonometry.scad#function-opp_ang_to_hyp) Func Returns the hypotenuse length from the length of the opposite side and the angle.
- [`hyp_opp_to_adj()`](trigonometry.scad#function-hyp_opp_to_adj) Func Returns the adjacent side length from the lengths of the hypotenuse and the opposite side.
- [`hyp_opp_to_ang()`](trigonometry.scad#function-hyp_opp_to_ang) Func Returns the angle from the lengths of the hypotenuse and the opposite side.
- [`orient()`](attachments.scad#module-orient) Mod Orients children's tops in the directon of the specified anchor. <sup title="Can transform children.">[<abbr>Trans</abbr>]</sup>
- [`outer_product()`](linalg.scad#function-outer_product) Func Compute the outer product of two vectors.
- [`outer_radius()`](gears.scad#function-outer_radius) Func Returns the outer radius for a gear.
## P
- [`pair()`](lists.scad#function-pair) Func Returns a list of overlapping consecutive pairs in a list.
- [`parent()`](attachments.scad#function-parent) Func Returns a description (transformation state and attachment geometry) of the parent
- [`parse_float()`](strings.scad#function-parse_float) Func Parse a float from a string.
- [`parse_frac()`](strings.scad#function-parse_frac) Func Parse a float from a fraction string.
- [`parse_int()`](strings.scad#function-parse_int) Func Parse an integer from a string.
- [`parse_num()`](strings.scad#function-parse_num) Func Parse a float from a decimal or fraction string.
- [`partition()`](partitions.scad#module-partition) Mod Cuts an object in two with matched joining edges, then separates the parts. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup> <sup title="Can return a VNF.">[<abbr>VNF</abbr>]</sup> <sup title="Can return a Path.">[<abbr>Path</abbr>]</sup> <sup title="Can return a Region.">[<abbr>Region</abbr>]</sup>
- [`partition_cut_mask()`](partitions.scad#module-partition_cut_mask) Mod Creates a mask to cut an object into two subparts that can be reassembled. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup>
- [`partition_mask()`](partitions.scad#module-partition_mask) Mod Creates a mask to remove half an object with the remaining half suitable for reassembly. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup>
- [`path2d()`](coords.scad#function-path2d) Func Convert a path to 2D. <sup title="Can return a Path.">[<abbr>Path</abbr>]</sup>
- [`path3d()`](coords.scad#function-path3d) Func Convert a path to 3D. <sup title="Can return a Path.">[<abbr>Path</abbr>]</sup>
- [`path4d()`](coords.scad#function-path4d) Func Convert a path to 4d. <sup title="Can return a Path.">[<abbr>Path</abbr>]</sup>
- [`path_closest_point()`](paths.scad#function-path_closest_point) Func Returns the closest place on a path to a given point.
- [`path_copies()`](distributors.scad#functionmodule-path_copies) Func/Mod Uniformly distributes copies of children along a path. <sup title="Can return a list of transformation matrices.">[<abbr>MatList</abbr>]</sup> <sup title="Can transform children.">[<abbr>Trans</abbr>]</sup>
- [`path_curvature()`](paths.scad#function-path_curvature) Func Returns the estimated numerical curvature of the path.
- [`path_cut()`](paths.scad#function-path_cut) Func Cuts a path into subpaths at various points. <sup title="Can return a list of Paths.">[<abbr>PathList</abbr>]</sup>
- [`path_cut_points()`](paths.scad#function-path_cut_points) Func Returns a list of cut points at a list of distances from the first point in a path.
- [`path_extrude()`](miscellaneous.scad#module-path_extrude) Mod Extrudes 2D children along a 3D path. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup>
- [`path_extrude2d()`](miscellaneous.scad#module-path_extrude2d) Mod Extrudes 2D children along a 2D path. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup>
- [`path_join()`](rounding.scad#function-path_join) Func Join paths end to end with optional rounding. <sup title="Can return a Path.">[<abbr>Path</abbr>]</sup>
- [`path_length()`](paths.scad#function-path_length) Func Returns the path length.
- [`path_length_fractions()`](paths.scad#function-path_length_fractions) Func Returns the fractional distance of each point along the length of a path.
- [`path_merge_collinear()`](paths.scad#function-path_merge_collinear) Func Removes unnecessary points from a path. <sup title="Can return a Path.">[<abbr>Path</abbr>]</sup>
- [`path_normals()`](paths.scad#function-path_normals) Func Returns normal vectors for each point along a path.
- [`path_segment_lengths()`](paths.scad#function-path_segment_lengths) Func Returns a list of the lengths of segments in a path.
- [`path_sweep()`](skin.scad#functionmodule-path_sweep) Func/Mod Sweep a 2d polygon path along a 2d or 3d path. <sup title="Can return a VNF.">[<abbr>VNF</abbr>]</sup> <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup>
- [`path_sweep2d()`](skin.scad#functionmodule-path_sweep2d) Func/Mod Sweep a 2d polygon path along a 2d path allowing self-intersection. <sup title="Can return a VNF.">[<abbr>VNF</abbr>]</sup> <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup>
- [`path_tangents()`](paths.scad#function-path_tangents) Func Returns tangent vectors for each point along a path.
- [`path_text()`](shapes3d.scad#module-path_text) Mod Creates 2d or 3d text placed along a path. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup>
- [`path_to_bezpath()`](beziers.scad#function-path_to_bezpath) Func Generates a bezier path that passes through all points in a given linear path. <sup title="Can return a Path.">[<abbr>Path</abbr>]</sup>
- [`path_torsion()`](paths.scad#function-path_torsion) Func Returns the estimated numerical torsion of the path.
- [`pco1810_cap()`](bottlecaps.scad#module-pco1810_cap) Mod Creates a cap for a PCO1810 standard bottle. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup>
- [`pco1810_neck()`](bottlecaps.scad#module-pco1810_neck) Mod Creates a neck for a PCO1810 standard bottle. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup>
- [`pco1881_cap()`](bottlecaps.scad#module-pco1881_cap) Mod Creates a cap for a PCO1881 standard bottle. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup>
- [`pco1881_neck()`](bottlecaps.scad#module-pco1881_neck) Mod Creates a neck for a PCO1881 standard bottle. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup>
- [`pentagon()`](shapes2d.scad#functionmodule-pentagon) Func/Mod Creates a regular pentagon. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup> <sup title="Can return a Path.">[<abbr>Path</abbr>]</sup>
- [`permutations()`](lists.scad#function-permutations) Func Returns a list of all permutations of the list entries.
- [`PHI`](math.scad#constant-phi) Const The golden ratio φ (phi). Approximately 1.6180339887
- [`phillips_depth()`](screw_drive.scad#function-phillips_depth) Func Returns the depth a phillips recess needs to be for a given diameter.
- [`phillips_diam()`](screw_drive.scad#function-phillips_diam) Func Returns the diameter of a phillips recess of a given depth.
- [`phillips_mask()`](screw_drive.scad#module-phillips_mask) Mod Creates a mask for a Philips screw drive. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup>
- [`pie_slice()`](shapes3d.scad#functionmodule-pie_slice) Func/Mod Creates a pie slice shape. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup> <sup title="Can return a VNF.">[<abbr>VNF</abbr>]</sup>
- [`pitch_radius()`](gears.scad#function-pitch_radius) Func Returns the pitch radius for a gear.
- [`plane3pt()`](geometry.scad#function-plane3pt) Func Return a plane from 3 points.
- [`plane3pt_indexed()`](geometry.scad#function-plane3pt_indexed) Func Given list of 3d points and 3 indices, return the plane they define.
- [`plane_closest_point()`](geometry.scad#function-plane_closest_point) Func Returns the orthogonal projection of points onto a plane.
- [`plane_from_normal()`](geometry.scad#function-plane_from_normal) Func Return plane defined by normal vector and a point.
- [`plane_from_points()`](geometry.scad#function-plane_from_points) Func Return plane defined by a set of coplanar 3d points, with arbitrary normal direction.
- [`plane_from_polygon()`](geometry.scad#function-plane_from_polygon) Func Given a 3d planar polygon, returns directed plane.
- [`plane_intersection()`](geometry.scad#function-plane_intersection) Func Returns the intersection of two or three planes.
- [`plane_line_angle()`](geometry.scad#function-plane_line_angle) Func Returns the angle between a plane and a 3d line.
- [`plane_line_intersection()`](geometry.scad#function-plane_line_intersection) Func Returns the intersection of a plane and 3d line, segment or ray.
- [`plane_normal()`](geometry.scad#function-plane_normal) Func Returns the normal vector to a plane.
- [`plane_offset()`](geometry.scad#function-plane_offset) Func Returns the signed offset of the plane from the origin.
- [`planetary_gears()`](gears.scad#function-planetary_gears) Func Calculate teeth counts and angles for planetary gear assembly with specified ratio.
- [`point2d()`](coords.scad#function-point2d) Func Convert a vector to 2D.
- [`point3d()`](coords.scad#function-point3d) Func Convert a vector to 3D.
- [`point4d()`](coords.scad#function-point4d) Func Convert a vector to 4d.
- [`point_in_polygon()`](geometry.scad#function-point_in_polygon) Func Checks if a 2d point is inside or on the boundary of a 2d polygon.
- [`point_in_region()`](regions.scad#function-point_in_region) Func Tests if a point is inside, outside, or on the border of a region.
- [`point_line_distance()`](geometry.scad#function-point_line_distance) Func Find shortest distance from point to a line, segment or ray.
- [`point_plane_distance()`](geometry.scad#function-point_plane_distance) Func Determine distance between a point and plane.
- [`pointlist_bounds()`](vectors.scad#function-pointlist_bounds) Func Returns the min and max bounding coordinates for the given list of points.
- [`polar_to_xy()`](coords.scad#function-polar_to_xy) Func Convert 2D polar coordinates to cartesian coordinates. <sup title="Can return a Path.">[<abbr>Path</abbr>]</sup>
- [`poly_add()`](math.scad#function-poly_add) Func Returns the polynomial sum of adding two polynomials.
- [`poly_div()`](math.scad#function-poly_div) Func Returns the polynomial quotient and remainder results of dividing two polynomials.
- [`poly_mult()`](math.scad#function-poly_mult) Func Compute product of two polynomials, returning a polynomial.
- [`poly_roots()`](math.scad#function-poly_roots) Func Returns all complex valued roots of the given real polynomial.
- [`polygon_area()`](geometry.scad#function-polygon_area) Func Calculate area of a 2d or 3d polygon.
- [`polygon_line_intersection()`](geometry.scad#function-polygon_line_intersection) Func Find intersection between 2d or 3d polygon and a line, segment or ray.
- [`polygon_normal()`](geometry.scad#function-polygon_normal) Func Return normal to a polygon.
- [`polygon_parts()`](paths.scad#function-polygon_parts) Func Parses a self-intersecting polygon into a list of non-intersecting polygons. <sup title="Can return a list of Paths.">[<abbr>PathList</abbr>]</sup>
- [`polygon_triangulate()`](geometry.scad#function-polygon_triangulate) Func Divide a polygon into triangles.
- [`polynomial()`](math.scad#function-polynomial) Func Evaluate a polynomial at a real or complex value.
- [`position()`](attachments.scad#module-position) Mod Attaches children to a parent object at an anchor point. <sup title="Can transform children.">[<abbr>Trans</abbr>]</sup>
- [`posmod()`](math.scad#function-posmod) Func Returns the positive modulo of a value.
- [`prismoid()`](shapes3d.scad#functionmodule-prismoid) Func/Mod Creates a rectangular prismoid shape with optional roundovers and chamfering. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup> <sup title="Can return a VNF.">[<abbr>VNF</abbr>]</sup>
- [`product()`](math.scad#function-product) Func Returns the multiplicative product of a list of values.
- [`project_plane()`](coords.scad#function-project_plane) Func Project a set of points onto a specified plane, returning 2D points. <sup title="Can return a Path.">[<abbr>Path</abbr>]</sup>
- [`projection()`](vnf.scad#function-projection) Func Returns projection or intersection of vnf with XY plane <sup title="Can return a VNF.">[<abbr>VNF</abbr>]</sup>
## Q
- [`qr_factor()`](linalg.scad#function-qr_factor) Func Compute QR factorization of a matrix.
- [`quadratic_roots()`](math.scad#function-quadratic_roots) Func Computes roots for the quadratic equation.
- [`quant()`](math.scad#function-quant) Func Returns `x` quantized to the nearest integer multiple of `y`.
- [`quantdn()`](math.scad#function-quantdn) Func Returns `x` quantized down to an integer multiple of `y`.
- [`quantup()`](math.scad#function-quantup) Func Returns `x` quantized uo to an integer multiple of `y`.
## R
- [`rabbit_clip()`](joiners.scad#module-rabbit_clip) Mod Creates a rabbit-eared clip that can snap into a slot. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup>
- [`rack()`](gears.scad#functionmodule-rack) Func/Mod Creates a straight or helical gear rack. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup> <sup title="Can return a VNF.">[<abbr>VNF</abbr>]</sup>
- [`rack2d()`](gears.scad#functionmodule-rack2d) Func/Mod Creates a 2D gear rack. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup> <sup title="Can return a Path.">[<abbr>Path</abbr>]</sup>
- [`rail()`](sliders.scad#module-rail) Mod Creates a V-groove rail. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup>
- [`rainbow()`](color.scad#module-rainbow) Mod Iterates through a list, displaying children in different colors. <sup title="Can transform children.">[<abbr>Trans</abbr>]</sup>
- [`rand_int()`](math.scad#function-rand_int) Func Returns a random integer.
- [`rand_str()`](strings.scad#function-rand_str) Func Create a randomized string.
- [`random_points()`](math.scad#function-random_points) Func Returns a list of random points.
- [`random_polygon()`](math.scad#function-random_polygon) Func Returns the CCW path of a simple random polygon.
- [`RAY`](constants.scad#constant-ray) Const A constant for specifying a ray line in various geometry.scad functions. `[true,false]`
- [`real_roots()`](math.scad#function-real_roots) Func Returns all real roots of the given real polynomial.
- [`recolor()`](color.scad#module-recolor) Mod Sets the color for attachable children and their descendants. <sup title="Can transform children.">[<abbr>Trans</abbr>]</sup>
- [`rect()`](shapes2d.scad#functionmodule-rect) Func/Mod Creates a 2d rectangle with optional corner rounding. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup> <sup title="Can return a Path.">[<abbr>Path</abbr>]</sup>
- [`rect_tube()`](shapes3d.scad#module-rect_tube) Mod Creates a rectangular tube. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup>
- [`reduce()`](fnliterals.scad#function-reduce) Func Applies a 2-arg function cumulatively to the items of a list, returning the final result.
- [`region()`](regions.scad#module-region) Mod Creates the 2D polygons described by the given region or list of polygons. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup>
- [`region_area()`](regions.scad#function-region_area) Func Computes the area of the specified valid region.
- [`region_parts()`](regions.scad#function-region_parts) Func Splits a region into a list of connected regions. <sup title="Can return a list of Regions.">[<abbr>RegList</abbr>]</sup>
- [`regular_ngon()`](shapes2d.scad#functionmodule-regular_ngon) Func/Mod Creates a regular N-sided polygon. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup> <sup title="Can return a Path.">[<abbr>Path</abbr>]</sup>
- [`regular_polyhedron()`](polyhedra.scad#module-regular_polyhedron) Mod Creates a regular polyhedron with optional rounding. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup>
- [`regular_polyhedron_info()`](polyhedra.scad#function-regular_polyhedron_info) Func Returns info used to create a regular polyhedron.
- [`regular_prism()`](shapes3d.scad#functionmodule-regular_prism) Func/Mod Creates a regular prism with roundovers and chamfering <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup> <sup title="Can return a VNF.">[<abbr>VNF</abbr>]</sup>
- [`reindex_polygon()`](geometry.scad#function-reindex_polygon) Func Adjust point indexing of polygon to minimize pointwise distance to a reference polygon.
- [`reorient()`](attachments.scad#function-reorient) Func Calculates the transformation matrix needed to reorient an object. <sup title="Can transform children.">[<abbr>Trans</abbr>]</sup> <sup title="Can return a Path.">[<abbr>Path</abbr>]</sup> <sup title="Can return a VNF.">[<abbr>VNF</abbr>]</sup>
- [`repeat()`](lists.scad#function-repeat) Func Returns a list of repeated copies of a value.
- [`repeat_entries()`](lists.scad#function-repeat_entries) Func Repeats list entries (as uniformly as possible) to make list of specified length.
- [`req_children()`](utility.scad#module-req_children) Mod Assert that the calling module requires children.
- [`resample_path()`](paths.scad#function-resample_path) Func Returns an equidistant set of points along a path. <sup title="Can return a Path.">[<abbr>Path</abbr>]</sup>
- [`restore()`](attachments.scad#module-restore) Mod Restores transformation state and attachment geometry from a description <sup title="Can transform children.">[<abbr>Trans</abbr>]</sup>
- [`reuleaux_polygon()`](shapes2d.scad#functionmodule-reuleaux_polygon) Func/Mod Creates a constant-width shape that is not circular. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup> <sup title="Can return a Path.">[<abbr>Path</abbr>]</sup>
- [`reverse()`](lists.scad#function-reverse) Func Reverses the elements of a list.
- [`reverse_polygon()`](geometry.scad#function-reverse_polygon) Func Reverse winding direction of polygon.
- [`RIGHT`](constants.scad#constant-right) Const The right-wards (X+) direction vector constant `[1,0,0]`.
- [`right()`](transforms.scad#functionmodule-right) Func/Mod Translates children rightwards (X+). <sup title="Can transform children.">[<abbr>Trans</abbr>]</sup> <sup title="Can return a Path.">[<abbr>Path</abbr>]</sup> <sup title="Can return a VNF.">[<abbr>VNF</abbr>]</sup> <sup title="Can return a transformation matrix.">[<abbr>Mat</abbr>]</sup>
- [`right_half()`](partitions.scad#functionmodule-right_half) Func/Mod Masks the left half of an object along the Y-Z plane, leaving the right half. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup> <sup title="Can return a VNF.">[<abbr>VNF</abbr>]</sup> <sup title="Can return a Path.">[<abbr>Path</abbr>]</sup> <sup title="Can return a Region.">[<abbr>Region</abbr>]</sup>
- [`right_triangle()`](shapes2d.scad#functionmodule-right_triangle) Func/Mod Creates a right triangle. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup> <sup title="Can return a Path.">[<abbr>Path</abbr>]</sup>
- [`ring()`](shapes2d.scad#functionmodule-ring) Func/Mod Draws a 2D ring or partial ring or returns a region or path <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup> <sup title="Can return a Region.">[<abbr>Region</abbr>]</sup> <sup title="Can return a Path.">[<abbr>Path</abbr>]</sup>
- [`ring_gear()`](gears.scad#module-ring_gear) Mod Creates a 3D ring gear. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup>
- [`ring_gear2d()`](gears.scad#module-ring_gear2d) Mod Creates a 2D ring gear. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup>
- [`robertson_mask()`](screw_drive.scad#module-robertson_mask) Mod Creates a mask for a Robertson/Square drive recess. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup>
- [`root_find()`](math.scad#function-root_find) Func Finds a root of the given continuous function.
- [`rot()`](transforms.scad#functionmodule-rot) Func/Mod Rotates children in various ways. <sup title="Can transform children.">[<abbr>Trans</abbr>]</sup> <sup title="Can return a Path.">[<abbr>Path</abbr>]</sup> <sup title="Can return a VNF.">[<abbr>VNF</abbr>]</sup> <sup title="Can return a transformation matrix.">[<abbr>Mat</abbr>]</sup>
- [`rot_copies()`](distributors.scad#functionmodule-rot_copies) Func/Mod Rotates copies of children. <sup title="Can return a list of transformation matrices.">[<abbr>MatList</abbr>]</sup> <sup title="Can transform children.">[<abbr>Trans</abbr>]</sup>
- [`rot_decode()`](geometry.scad#function-rot_decode) Func Extract axis and rotation angle from a rotation matrix.
- [`rot_inverse()`](linalg.scad#function-rot_inverse) Func Invert 2d or 3d rotation transformations.
- [`rot_resample()`](skin.scad#function-rot_resample) Func Resample a list of rotation operators. <sup title="Can return a list of transformation matrices.">[<abbr>MatList</abbr>]</sup>
- [`rotate_sweep()`](skin.scad#functionmodule-rotate_sweep) Func/Mod Create a surface of revolution from a path with optional texturing. <sup title="Can return a VNF.">[<abbr>VNF</abbr>]</sup> <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup>
- [`round2d()`](shapes2d.scad#module-round2d) Mod Rounds the corners of 2d objects. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup>
- [`round3d()`](miscellaneous.scad#module-round3d) Mod Rounds arbitrary 3d objects. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup>
- [`round_corners()`](rounding.scad#function-round_corners) Func Round or chamfer the corners of a path (clipping them off). <sup title="Can return a Path.">[<abbr>Path</abbr>]</sup>
- [`rounded_prism()`](rounding.scad#functionmodule-rounded_prism) Func/Mod Make a rounded 3d object by connecting two polygons with the same vertex count. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup> <sup title="Can return a VNF.">[<abbr>VNF</abbr>]</sup>
- [`rounding_corner_mask()`](masks3d.scad#module-rounding_corner_mask) Mod Creates a shape to round 90° corners. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup>
- [`rounding_cylinder_mask()`](masks3d.scad#module-rounding_cylinder_mask) Mod Creates a shape to round the end of a cylinder. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup>
- [`rounding_edge_mask()`](masks3d.scad#module-rounding_edge_mask) Mod Creates a shape to round a 90° edge. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup>
- [`rounding_hole_mask()`](masks3d.scad#module-rounding_hole_mask) Mod Creates a shape to round the edge of a round hole. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup>
- [`ruler()`](shapes3d.scad#module-ruler) Mod Creates a ruler. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup>
## S
- [`same_shape()`](utility.scad#function-same_shape) Func Returns true if the argument lists are numeric and of the same shape.
- [`scalar_vec3()`](utility.scad#function-scalar_vec3) Func Expands a scalar or a list with length less than 3 to a length 3 vector.
- [`scale()`](transforms.scad#functionmodule-scale) Func/Mod Scales children arbitrarily. <sup title="Can transform children.">[<abbr>Trans</abbr>]</sup> <sup title="Can return a Path.">[<abbr>Path</abbr>]</sup> <sup title="Can return a VNF.">[<abbr>VNF</abbr>]</sup> <sup title="Can return a transformation matrix.">[<abbr>Mat</abbr>]</sup> <sup title="Extends the OpenScad keyword of the same name.">[<abbr>Ext</abbr>]</sup>
- [`screw()`](screws.scad#module-screw) Mod Creates a standard screw with optional tolerances. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup>
- [`screw_head()`](screws.scad#module-screw_head) Mod Creates a screw head. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup>
- [`screw_hole()`](screws.scad#module-screw_hole) Mod Creates a screw hole. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup>
- [`screw_info()`](screws.scad#function-screw_info) Func Returns the dimensions and other info for the given screw.
- [`SEGMENT`](constants.scad#constant-segment) Const A constant for specifying a line segment in various geometry.scad functions. `[true,true]`
- [`segment_distance()`](geometry.scad#function-segment_distance) Func Find smallest distance between two line semgnets.
- [`segs()`](utility.scad#function-segs) Func Returns the number of sides for a circle given `$fn`, `$fa`, and `$fs`.
- [`select()`](lists.scad#function-select) Func Returns one or more items from a list, with wrapping.
- [`set_difference()`](lists.scad#function-set_difference) Func Returns a list of unique items that are in list A, but not in list B.
- [`set_intersection()`](lists.scad#function-set_intersection) Func Returns a list of unique items that are in both given lists.
- [`set_union()`](lists.scad#function-set_union) Func Merges two lists, returning a list of unique items.
- [`shape_compare()`](utility.scad#module-shape_compare) Mod Compares two child shapes. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup>
- [`shell2d()`](shapes2d.scad#module-shell2d) Mod Creates a shell from 2D children. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup>
- [`shoulder_screw()`](screws.scad#module-shoulder_screw) Mod Creates a shoulder screw. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup>
- [`show_all()`](attachments.scad#module-show_all) Mod Shows all children and clears tags.
- [`show_anchors()`](attachments.scad#module-show_anchors) Mod Shows anchors for the parent object. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup>
- [`show_int()`](attachments.scad#module-show_int) Mod Shows children with the listed tags which were already shown in the parent context.
- [`show_only()`](attachments.scad#module-show_only) Mod Show only the children with the listed tags.
- [`show_transform_list()`](attachments.scad#module-show_transform_list) Mod Shows a list of transforms and how they connect. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup>
- [`shuffle()`](lists.scad#function-shuffle) Func Randomizes the order of a list.
- [`simple_hash()`](fnliterals.scad#function-simple_hash) Func Returns an integer hash of a given value.
- [`sinh()`](math.scad#function-sinh) Func Returns the hyperbolic sine of the given value.
- [`skew()`](transforms.scad#functionmodule-skew) Func/Mod Skews (or shears) children along various axes. <sup title="Can transform children.">[<abbr>Trans</abbr>]</sup> <sup title="Can return a Path.">[<abbr>Path</abbr>]</sup> <sup title="Can return a VNF.">[<abbr>VNF</abbr>]</sup> <sup title="Can return a transformation matrix.">[<abbr>Mat</abbr>]</sup>
- [`skin()`](skin.scad#functionmodule-skin) Func/Mod Connect a sequence of arbitrary polygons into a 3D object. <sup title="Can return a VNF.">[<abbr>VNF</abbr>]</sup> <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup>
- [`slice()`](lists.scad#function-slice) Func Returns part of a list without wrapping.
- [`slice_profiles()`](skin.scad#function-slice_profiles) Func Linearly interpolates between path profiles. <sup title="Can return a list of Paths.">[<abbr>PathList</abbr>]</sup>
- [`slider()`](sliders.scad#module-slider) Mod Creates a V-groove slider. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup>
- [`smooth_path()`](rounding.scad#function-smooth_path) Func Create smoothed path that passes through all the points of a given path. <sup title="Can return a Path.">[<abbr>Path</abbr>]</sup>
- [`snap_lock()`](hinges.scad#module-snap_lock) Mod Creates a snap-lock shape. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup>
- [`snap_pin()`](joiners.scad#module-snap_pin) Mod Creates a snap-pin that can slot into a [`snap_pin_socket()`](#module-snap\_pin\_socket) to join two parts. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup>
- [`snap_pin_socket()`](joiners.scad#module-snap_pin_socket) Mod Creates a snap-pin socket for a [`snap_pin()`](#module-snap\_pin) to slot into. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup>
- [`snap_socket()`](hinges.scad#module-snap_socket) Mod Creates a snap-lock socket shape. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup>
- [`sort()`](comparisons.scad#function-sort) Func Returns a sorted list.
- [`sortidx()`](comparisons.scad#function-sortidx) Func Returns a list of sorted indices into a list.
- [`sp_cap()`](bottlecaps.scad#module-sp_cap) Mod Creates an SPI threaded bottle cap. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup>
- [`sp_diameter()`](bottlecaps.scad#function-sp_diameter) Func Returns the base diameter of an SPI bottle neck from the nominal diameter and type number.
- [`sp_neck()`](bottlecaps.scad#module-sp_neck) Mod Creates an SPI threaded bottle neck. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup>
- [`sparse_cuboid()`](walls.scad#module-sparse_cuboid) Mod Makes an open cross-braced cuboid <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup>
- [`sparse_wall()`](walls.scad#module-sparse_wall) Mod Makes an open cross-braced rectangular wall. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup>
- [`sparse_wall2d()`](walls.scad#module-sparse_wall2d) Mod Makes an open cross-braced rectangular wall. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup>
- [`sphere()`](shapes3d.scad#functionmodule-sphere) Func/Mod Creates an attachable spherical object. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup> <sup title="Can return a VNF.">[<abbr>VNF</abbr>]</sup> <sup title="Extends the OpenScad keyword of the same name.">[<abbr>Ext</abbr>]</sup>
- [`sphere_copies()`](distributors.scad#functionmodule-sphere_copies) Func/Mod Distributes copies of children over the surface of a sphere. <sup title="Can return a list of transformation matrices.">[<abbr>MatList</abbr>]</sup> <sup title="Can transform children.">[<abbr>Trans</abbr>]</sup>
- [`sphere_line_intersection()`](geometry.scad#function-sphere_line_intersection) Func Find intersection between a sphere and line, ray or segment.
- [`spherical_random_points()`](math.scad#function-spherical_random_points) Func Returns a list of random points on the surface of a sphere.
- [`spherical_to_xyz()`](coords.scad#function-spherical_to_xyz) Func Convert spherical coordinates to 3D cartesian coordinates. <sup title="Can return a Path.">[<abbr>Path</abbr>]</sup>
- [`spheroid()`](shapes3d.scad#functionmodule-spheroid) Func/Mod Creates an attachable spherical object with controllable triangulation. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup> <sup title="Can return a VNF.">[<abbr>VNF</abbr>]</sup>
- [`spiral_sweep()`](skin.scad#functionmodule-spiral_sweep) Func/Mod Sweep a path along a helix. <sup title="Can return a VNF.">[<abbr>VNF</abbr>]</sup> <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup>
- [`split_path_at_self_crossings()`](paths.scad#function-split_path_at_self_crossings) Func Split a 2D path wherever it crosses itself. <sup title="Can return a list of Paths.">[<abbr>PathList</abbr>]</sup>
- [`split_region_at_region_crossings()`](regions.scad#function-split_region_at_region_crossings) Func Splits regions where polygons touch and at intersections.
- [`spur_gear()`](gears.scad#functionmodule-spur_gear) Func/Mod Creates a spur gear, helical gear, or internal ring gear. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup> <sup title="Can return a VNF.">[<abbr>VNF</abbr>]</sup>
- [`spur_gear2d()`](gears.scad#functionmodule-spur_gear2d) Func/Mod Creates a 2D spur gear or internal ring gear. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup> <sup title="Can return a Region.">[<abbr>Region</abbr>]</sup>
- [`sqr()`](math.scad#function-sqr) Func Returns the square of the given value.
- [`square()`](shapes2d.scad#functionmodule-square) Func/Mod Creates a 2D square or rectangle. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup> <sup title="Can return a Path.">[<abbr>Path</abbr>]</sup> <sup title="Extends the OpenScad keyword of the same name.">[<abbr>Ext</abbr>]</sup>
- [`square_threaded_nut()`](threading.scad#module-square_threaded_nut) Mod Creates a square-threaded nut. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup>
- [`square_threaded_rod()`](threading.scad#module-square_threaded_rod) Mod Creates a square-threaded rod. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup>
- [`squircle()`](shapes2d.scad#functionmodule-squircle) Func/Mod Creates a shape between a circle and a square, centered on the origin. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup> <sup title="Can return a Path.">[<abbr>Path</abbr>]</sup>
- [`star()`](shapes2d.scad#functionmodule-star) Func/Mod Creates a star-shaped polygon or returns a star-shaped region. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup> <sup title="Can return a Path.">[<abbr>Path</abbr>]</sup>
- [`starts_with()`](strings.scad#function-starts_with) Func Returns true if the string starts with a given substring.
- [`str_find()`](strings.scad#function-str_find) Func Finds a substring in a string.
- [`str_join()`](strings.scad#function-str_join) Func Joints a list of strings into a single string.
- [`str_pad()`](strings.scad#function-str_pad) Func Pads a string to a given length.
- [`str_replace_char()`](strings.scad#function-str_replace_char) Func Replace given chars in a string with another substring.
- [`str_split()`](strings.scad#function-str_split) Func Splits a longer string wherever a given substring occurs.
- [`str_strip()`](strings.scad#function-str_strip) Func Strips given leading and trailing characters from a string.
- [`stroke()`](drawing.scad#module-stroke) Mod Draws a line along a path or region boundry. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup>
- [`struct_keys()`](structs.scad#function-struct_keys) Func Returns a list of keys for a struct.
- [`struct_remove()`](structs.scad#function-struct_remove) Func Removes one or more keys from a struct.
- [`struct_set()`](structs.scad#function-struct_set) Func Sets one or more key-value pairs in a struct.
- [`struct_val()`](structs.scad#function-struct_val) Func Returns the value for an key in a struct.
- [`subdivide_and_slice()`](skin.scad#function-subdivide_and_slice) Func Resample list of paths to have the same point count and interpolate additional paths. <sup title="Can return a list of Paths.">[<abbr>PathList</abbr>]</sup>
- [`subdivide_path()`](paths.scad#function-subdivide_path) Func Subdivides a path to produce a more finely sampled path. <sup title="Can return a Path.">[<abbr>Path</abbr>]</sup>
- [`submatrix()`](linalg.scad#function-submatrix) Func Extract a submatrix from a matrix
- [`submatrix_set()`](linalg.scad#function-submatrix_set) Func Takes a matrix as input and change values in a submatrix.
- [`substr()`](strings.scad#function-substr) Func Returns a substring from a string.
- [`substr_match()`](strings.scad#function-substr_match) Func Returns true if the string `pattern` matches the string `str`.
- [`suffix()`](strings.scad#function-suffix) Func Returns the last few characters of a string.
- [`sum()`](math.scad#function-sum) Func Returns the sum of a list of values.
- [`sum_of_sines()`](math.scad#function-sum_of_sines) Func Returns the sum of one or more sine waves at a given angle.
- [`supershape()`](shapes2d.scad#functionmodule-supershape) Func/Mod Creates a 2D [Superformula](https://en.wikipedia.org/wiki/Superformula) shape. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup> <sup title="Can return a Path.">[<abbr>Path</abbr>]</sup>
- [`sweep()`](skin.scad#functionmodule-sweep) Func/Mod Construct a 3d object from arbitrary transformations of a 2d polygon path. <sup title="Can return a VNF.">[<abbr>VNF</abbr>]</sup> <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup>
- [`sweep_attach()`](skin.scad#module-sweep_attach) Mod Attach children to sides of a path\_sweep parent object <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup>
## T
- [`tag()`](attachments.scad#module-tag) Mod Assigns a tag to an object
- [`tag_conv_hull()`](attachments.scad#module-tag_conv_hull) Mod Performs a [`conv_hull()`](#module-conv\_hull) and then sets a tag on the result.
- [`tag_diff()`](attachments.scad#module-tag_diff) Mod Performs a [`diff()`](#module-diff) and then sets a tag on the result.
- [`tag_intersect()`](attachments.scad#module-tag_intersect) Mod Performs an [`intersect()`](#module-intersect) and then tags the result.
- [`tag_scope()`](attachments.scad#module-tag_scope) Mod Creates a new tag scope.
- [`tag_this()`](attachments.scad#module-tag_this) Mod Assigns a tag to an object at the current level only.
- [`tanh()`](math.scad#function-tanh) Func Returns the hyperbolic tangent of the given value.
- [`teardrop()`](shapes3d.scad#functionmodule-teardrop) Func/Mod Creates a teardrop shape. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup> <sup title="Can return a VNF.">[<abbr>VNF</abbr>]</sup>
- [`teardrop2d()`](shapes2d.scad#functionmodule-teardrop2d) Func/Mod Creates a 2D teardrop shape. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup> <sup title="Can return a Path.">[<abbr>Path</abbr>]</sup>
- [`teardrop_corner_mask()`](masks3d.scad#module-teardrop_corner_mask) Mod Creates a shape to round a 90° corner but limit the angle of overhang. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup>
- [`teardrop_edge_mask()`](masks3d.scad#module-teardrop_edge_mask) Mod Creates a shape to round a 90° edge but limit the angle of overhang. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup>
- [`text()`](shapes2d.scad#module-text) Mod Creates an attachable block of text. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup>
- [`text3d()`](shapes3d.scad#module-text3d) Mod Creates an attachable 3d text block. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup>
- [`texture()`](skin.scad#function-texture) Func Produce a standard texture.
- [`thinning_triangle()`](walls.scad#module-thinning_triangle) Mod Makes a triangular wall with a thin middle. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup>
- [`thinning_wall()`](walls.scad#module-thinning_wall) Mod Makes a rectangular wall with a thin middle. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup>
- [`thread_helix()`](threading.scad#module-thread_helix) Mod Creates a thread helix to add to a cylinder. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup>
- [`thread_specification()`](screws.scad#function-thread_specification) Func Returns the thread geometry for a given screw.
- [`threaded_nut()`](threading.scad#module-threaded_nut) Mod Creates an UTS/ISO triangular threaded nut. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup>
- [`threaded_rod()`](threading.scad#module-threaded_rod) Mod Creates an UTS/ISO triangular threaded rod. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup>
- [`tilt()`](transforms.scad#functionmodule-tilt) Func/Mod Tilts children towards a direction <sup title="Can transform children.">[<abbr>Trans</abbr>]</sup> <sup title="Can return a Path.">[<abbr>Path</abbr>]</sup> <sup title="Can return a VNF.">[<abbr>VNF</abbr>]</sup> <sup title="Can return a transformation matrix.">[<abbr>Mat</abbr>]</sup>
- [`TOP`](constants.scad#constant-top) Const The top-wards (Z+) direction vector constant `[0,0,1]`.
- [`top_half()`](partitions.scad#functionmodule-top_half) Func/Mod Masks the bottom half of an object along the X-Y plane, leaving the top half. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup> <sup title="Can return a VNF.">[<abbr>VNF</abbr>]</sup> <sup title="Can return a Path.">[<abbr>Path</abbr>]</sup> <sup title="Can return a Region.">[<abbr>Region</abbr>]</sup>
- [`torus()`](shapes3d.scad#functionmodule-torus) Func/Mod Creates an attachable torus. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup> <sup title="Can return a VNF.">[<abbr>VNF</abbr>]</sup>
- [`torx_depth()`](screw_drive.scad#function-torx_depth) Func Returns the typical depth of a torx drive recess.
- [`torx_diam()`](screw_drive.scad#function-torx_diam) Func Returns the diameter of a torx drive.
- [`torx_info()`](screw_drive.scad#function-torx_info) Func Returns the dimensions of a torx drive.
- [`torx_mask()`](screw_drive.scad#module-torx_mask) Mod Creates a mask for a torx drive recess. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup>
- [`torx_mask2d()`](screw_drive.scad#module-torx_mask2d) Mod Creates the 2D cross section for a torx drive recess. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup>
- [`move()`](transforms.scad#functionmodule-move) Func/Mod Translates children in an arbitrary direction. <sup title="Can transform children.">[<abbr>Trans</abbr>]</sup> <sup title="Can return a Path.">[<abbr>Path</abbr>]</sup> <sup title="Can return a VNF.">[<abbr>VNF</abbr>]</sup> <sup title="Can return a transformation matrix.">[<abbr>Mat</abbr>]</sup>
- [`transpose()`](linalg.scad#function-transpose) Func Transpose a matrix
- [`trapezoid()`](shapes2d.scad#functionmodule-trapezoid) Func/Mod Creates a trapezoid with parallel top and bottom sides. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup> <sup title="Can return a Path.">[<abbr>Path</abbr>]</sup>
- [`trapezoidal_threaded_nut()`](threading.scad#module-trapezoidal_threaded_nut) Mod Creates a trapezoidal threaded nut. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup>
- [`trapezoidal_threaded_rod()`](threading.scad#module-trapezoidal_threaded_rod) Mod Creates a trapezoidal threaded rod. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup>
- [`triplet()`](lists.scad#function-triplet) Func Returns a list of overlapping consecutive triplets in a list.
- [`tube()`](shapes3d.scad#module-tube) Mod Creates a cylindrical or conical tube. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup>
- [`turtle()`](drawing.scad#function-turtle) Func Uses [turtle graphics](https://en.wikipedia.org/wiki/Turtle\_graphics) to generate a 2D path. <sup title="Can return a Path.">[<abbr>Path</abbr>]</sup>
- [`turtle3d()`](turtle3d.scad#function-turtle3d) Func Extends [turtle graphics](https://en.wikipedia.org/wiki/Turtle\_graphics) to 3d. Generates a 3D path or returns a list of transforms. <sup title="Can return a list of transformation matrices.">[<abbr>MatList</abbr>]</sup> <sup title="Can return a Path.">[<abbr>Path</abbr>]</sup>
- [`typeof()`](utility.scad#function-typeof) Func Returns a string representing the type of the value.
## U
- [`u_add()`](utility.scad#function-u_add) Func Returns the sum of 2 numbers if both are defined, otherwise returns undef.
- [`u_div()`](utility.scad#function-u_div) Func Returns the quotient of 2 numbers if both are defined, otherwise returns undef.
- [`u_mul()`](utility.scad#function-u_mul) Func Returns the product of 2 numbers if both are defined, otherwise returns undef.
- [`u_sub()`](utility.scad#function-u_sub) Func Returns the difference of 2 numbers if both are defined, otherwise returns undef.
- [`union()`](regions.scad#functionmodule-union) Func/Mod Performs a Boolean union operation. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup> <sup title="Can return a Region.">[<abbr>Region</abbr>]</sup>
- [`unique()`](comparisons.scad#function-unique) Func Returns a sorted list with all duplicates removed.
- [`unique_count()`](comparisons.scad#function-unique_count) Func Returns a sorted list of unique items with counts.
- [`unit()`](vectors.scad#function-unit) Func Returns the unit length of a given vector.
- [`TOP`](constants.scad#constant-top) Const The top-wards (Z+) direction vector constant `[0,0,1]`.
- [`up()`](transforms.scad#functionmodule-up) Func/Mod Translates children upwards (Z+). <sup title="Can transform children.">[<abbr>Trans</abbr>]</sup> <sup title="Can return a Path.">[<abbr>Path</abbr>]</sup> <sup title="Can return a VNF.">[<abbr>VNF</abbr>]</sup> <sup title="Can return a transformation matrix.">[<abbr>Mat</abbr>]</sup>
- [`upcase()`](strings.scad#function-upcase) Func Uppercases all characters in a string.
## V
- [`v_abs()`](vectors.scad#function-v_abs) Func Returns the absolute values of the given vector.
- [`v_ceil()`](vectors.scad#function-v_ceil) Func Returns the values of the given vector, rounded up.
- [`v_div()`](vectors.scad#function-v_div) Func Returns the element-wise division of two equal-length vectors.
- [`v_floor()`](vectors.scad#function-v_floor) Func Returns the values of the given vector, rounded down.
- [`v_lookup()`](vectors.scad#function-v_lookup) Func Like `lookup()`, but it can interpolate between vector results.
- [`v_mul()`](vectors.scad#function-v_mul) Func Returns the element-wise multiplication of two equal-length vectors.
- [`v_theta()`](vectors.scad#function-v_theta) Func Returns the angle counter-clockwise from X+ on the XY plane.
- [`valid_range()`](utility.scad#function-valid_range) Func Returns true if the argument is a valid range.
- [`vector_angle()`](vectors.scad#function-vector_angle) Func Returns the minor angle between two vectors.
- [`vector_axis()`](vectors.scad#function-vector_axis) Func Returns the perpendicular axis between two vectors.
- [`vector_bisect()`](vectors.scad#function-vector_bisect) Func Returns the vector that bisects two vectors.
- [`vector_nearest()`](vectors.scad#function-vector_nearest) Func Finds the `k` nearest points in a list to a given point.
- [`vector_perp()`](vectors.scad#function-vector_perp) Func Returns component of a vector perpendicular to a second vector
- [`vector_search()`](vectors.scad#function-vector_search) Func Finds points in a list that are close to a given point.
- [`vector_search_tree()`](vectors.scad#function-vector_search_tree) Func Makes a distance search tree for a list of points.
- [`version_cmp()`](version.scad#function-version_cmp) Func Compares two versions.
- [`version_to_list()`](version.scad#function-version_to_list) Func Splits a version into a list of integer version parts.
- [`version_to_num()`](version.scad#function-version_to_num) Func Coerces a version into a standard version float.
- [`version_to_str()`](version.scad#function-version_to_str) Func Coerces a version into a standard version string.
- [`vnf_area()`](vnf.scad#function-vnf_area) Func Returns the surface area of a VNF.
- [`vnf_bend()`](vnf.scad#function-vnf_bend) Func Bends a VNF around an axis. <sup title="Can return a VNF.">[<abbr>VNF</abbr>]</sup>
- [`vnf_boundary()`](vnf.scad#function-vnf_boundary) Func Returns the boundary of a VNF as an list of paths <sup title="Can return a VNF.">[<abbr>VNF</abbr>]</sup>
- [`vnf_drop_unused_points()`](vnf.scad#function-vnf_drop_unused_points) Func Removes unreferenced vertices from a VNF. <sup title="Can return a VNF.">[<abbr>VNF</abbr>]</sup>
- [`vnf_faces()`](vnf.scad#function-vnf_faces) Func Returns the list of faces from a VNF.
- [`vnf_from_polygons()`](vnf.scad#function-vnf_from_polygons) Func Returns a VNF from a list of 3D polygons. <sup title="Can return a VNF.">[<abbr>VNF</abbr>]</sup>
- [`vnf_from_region()`](vnf.scad#function-vnf_from_region) Func Returns a 3D VNF given a 2D region. <sup title="Can return a VNF.">[<abbr>VNF</abbr>]</sup>
- [`vnf_halfspace()`](vnf.scad#function-vnf_halfspace) Func Returns the intersection of the vnf with a half space. <sup title="Can return a VNF.">[<abbr>VNF</abbr>]</sup>
- [`vnf_hull()`](vnf.scad#functionmodule-vnf_hull) Func/Mod Compute convex hull of VNF or 3d path
- [`vnf_join()`](vnf.scad#function-vnf_join) Func Returns a single VNF structure from a list of VNF structures. <sup title="Can return a VNF.">[<abbr>VNF</abbr>]</sup>
- [`vnf_merge_points()`](vnf.scad#function-vnf_merge_points) Func Consolidates duplicate vertices of a VNF. <sup title="Can return a VNF.">[<abbr>VNF</abbr>]</sup>
- [`vnf_polyhedron()`](vnf.scad#module-vnf_polyhedron) Mod Returns a polyhedron from a VNF or list of VNFs. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup>
- [`vnf_quantize()`](vnf.scad#function-vnf_quantize) Func Quantizes the vertex coordinates of a VNF. <sup title="Can return a VNF.">[<abbr>VNF</abbr>]</sup>
- [`vnf_reverse_faces()`](vnf.scad#function-vnf_reverse_faces) Func Reverses the faces of a VNF. <sup title="Can return a VNF.">[<abbr>VNF</abbr>]</sup>
- [`vnf_sheet()`](vnf.scad#function-vnf_sheet) Func Extends a VNF into a thin sheet by extruding normal to the VNF <sup title="Can return a VNF.">[<abbr>VNF</abbr>]</sup>
- [`vnf_slice()`](vnf.scad#function-vnf_slice) Func Slice the faces of a VNF along an axis. <sup title="Can return a VNF.">[<abbr>VNF</abbr>]</sup>
- [`vnf_small_offset()`](vnf.scad#function-vnf_small_offset) Func Computes an offset surface to a VNF for small offset distances <sup title="Can return a VNF.">[<abbr>VNF</abbr>]</sup>
- [`vnf_tri_array()`](vnf.scad#function-vnf_tri_array) Func Returns a VNF from an array of points. The array need not be rectangular. <sup title="Can return a VNF.">[<abbr>VNF</abbr>]</sup>
- [`vnf_triangulate()`](vnf.scad#function-vnf_triangulate) Func Triangulates the faces of a VNF. <sup title="Can return a VNF.">[<abbr>VNF</abbr>]</sup>
- [`vnf_unify_faces()`](vnf.scad#function-vnf_unify_faces) Func Remove triangulation from VNF, returning a copy with full faces <sup title="Can return a VNF.">[<abbr>VNF</abbr>]</sup>
- [`vnf_validate()`](vnf.scad#module-vnf_validate) Mod Echos non-manifold VNF errors to the console. <sup title="Can return a VNF.">[<abbr>VNF</abbr>]</sup>
- [`vnf_vertex_array()`](vnf.scad#function-vnf_vertex_array) Func Returns a VNF structure from a rectangular vertex list. <sup title="Can return a VNF.">[<abbr>VNF</abbr>]</sup>
- [`vnf_vertices()`](vnf.scad#function-vnf_vertices) Func Returns the list of vertex points from a VNF.
- [`vnf_volume()`](vnf.scad#function-vnf_volume) Func Returns the volume of a VNF.
- [`vnf_wireframe()`](vnf.scad#module-vnf_wireframe) Mod Creates a wireframe model from a VNF. <sup title="Can return a VNF.">[<abbr>VNF</abbr>]</sup>
## W
- [`wedge()`](shapes3d.scad#functionmodule-wedge) Func/Mod Creates a 3d triangular wedge. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup> <sup title="Can return a VNF.">[<abbr>VNF</abbr>]</sup>
- [`while()`](fnliterals.scad#function-while) Func While a `cond` function returns true, iteratively calls a work function, returning the final result.
- [`wire_bundle()`](wiring.scad#module-wire_bundle) Mod Creates a wire bundle for a given number of wires. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup>
- [`worm()`](gears.scad#functionmodule-worm) Func/Mod Creates a worm that will mate with a worm gear. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup> <sup title="Can return a VNF.">[<abbr>VNF</abbr>]</sup>
- [`worm_dist()`](gears.scad#function-worm_dist) Func Returns the distance between a worm and a worm gear
- [`worm_gear()`](gears.scad#functionmodule-worm_gear) Func/Mod Creates a worm gear that will mate with a worm. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup> <sup title="Can return a VNF.">[<abbr>VNF</abbr>]</sup>
- [`worm_gear_thickness()`](gears.scad#function-worm_gear_thickness) Func Returns the thickness for a worm gear.
## X
- [`xcopies()`](distributors.scad#functionmodule-xcopies) Func/Mod Places copies of children along the X axis. <sup title="Can return a list of transformation matrices.">[<abbr>MatList</abbr>]</sup> <sup title="Can transform children.">[<abbr>Trans</abbr>]</sup>
- [`xcyl()`](shapes3d.scad#module-xcyl) Mod creates a cylinder oriented along the X axis. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup>
- [`xdistribute()`](distributors.scad#module-xdistribute) Mod Distributes each child, individually, out along the X axis. <sup title="Can transform children.">[<abbr>Trans</abbr>]</sup>
- [`xflip()`](transforms.scad#functionmodule-xflip) Func/Mod Reflects children across the YZ plane. <sup title="Can transform children.">[<abbr>Trans</abbr>]</sup> <sup title="Can return a Path.">[<abbr>Path</abbr>]</sup> <sup title="Can return a VNF.">[<abbr>VNF</abbr>]</sup> <sup title="Can return a transformation matrix.">[<abbr>Mat</abbr>]</sup>
- [`xflip_copy()`](distributors.scad#functionmodule-xflip_copy) Func/Mod Makes a copy of children mirrored across the X axis. <sup title="Can return a list of transformation matrices.">[<abbr>MatList</abbr>]</sup> <sup title="Can transform children.">[<abbr>Trans</abbr>]</sup>
- [`right()`](transforms.scad#functionmodule-right) Func/Mod Translates children rightwards (X+). <sup title="Can transform children.">[<abbr>Trans</abbr>]</sup> <sup title="Can return a Path.">[<abbr>Path</abbr>]</sup> <sup title="Can return a VNF.">[<abbr>VNF</abbr>]</sup> <sup title="Can return a transformation matrix.">[<abbr>Mat</abbr>]</sup>
- [`xrot()`](transforms.scad#functionmodule-xrot) Func/Mod Rotates children around the X axis using the right-hand rule. <sup title="Can transform children.">[<abbr>Trans</abbr>]</sup> <sup title="Can return a Path.">[<abbr>Path</abbr>]</sup> <sup title="Can return a VNF.">[<abbr>VNF</abbr>]</sup> <sup title="Can return a transformation matrix.">[<abbr>Mat</abbr>]</sup>
- [`xrot_copies()`](distributors.scad#functionmodule-xrot_copies) Func/Mod Rotates copies of children around the X axis. <sup title="Can return a list of transformation matrices.">[<abbr>MatList</abbr>]</sup> <sup title="Can transform children.">[<abbr>Trans</abbr>]</sup>
- [`xscale()`](transforms.scad#functionmodule-xscale) Func/Mod Scales children along the X axis. <sup title="Can transform children.">[<abbr>Trans</abbr>]</sup> <sup title="Can return a Path.">[<abbr>Path</abbr>]</sup> <sup title="Can return a VNF.">[<abbr>VNF</abbr>]</sup> <sup title="Can return a transformation matrix.">[<abbr>Mat</abbr>]</sup>
- [`xval()`](fnliterals.scad#function-xval) Func Generates a function with signature `(i,x)` that calls `func(x)`
- [`xy_to_polar()`](coords.scad#function-xy_to_polar) Func Convert 2D cartesian coordinates to polar coordinates (radius and angle)
- [`xyz_to_altaz()`](coords.scad#function-xyz_to_altaz) Func Convert 3D cartesian coordinates to [altitude,azimuth,range].
- [`xyz_to_cylindrical()`](coords.scad#function-xyz_to_cylindrical) Func Convert 3D cartesian coordinates to cylindrical coordinates.
- [`xyz_to_spherical()`](coords.scad#function-xyz_to_spherical) Func Convert 3D cartesian coordinates to spherical coordinates.
## Y
- [`ycopies()`](distributors.scad#functionmodule-ycopies) Func/Mod Places copies of children along the Y axis. <sup title="Can return a list of transformation matrices.">[<abbr>MatList</abbr>]</sup> <sup title="Can transform children.">[<abbr>Trans</abbr>]</sup>
- [`ycyl()`](shapes3d.scad#module-ycyl) Mod Creates a cylinder oriented along the y axis. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup>
- [`ydistribute()`](distributors.scad#module-ydistribute) Mod Distributes each child, individually, out along the Y axis. <sup title="Can transform children.">[<abbr>Trans</abbr>]</sup>
- [`yflip()`](transforms.scad#functionmodule-yflip) Func/Mod Reflects children across the XZ plane. <sup title="Can transform children.">[<abbr>Trans</abbr>]</sup> <sup title="Can return a Path.">[<abbr>Path</abbr>]</sup> <sup title="Can return a VNF.">[<abbr>VNF</abbr>]</sup> <sup title="Can return a transformation matrix.">[<abbr>Mat</abbr>]</sup>
- [`yflip_copy()`](distributors.scad#functionmodule-yflip_copy) Func/Mod Makes a copy of children mirrored across the Y axis. <sup title="Can return a list of transformation matrices.">[<abbr>MatList</abbr>]</sup> <sup title="Can transform children.">[<abbr>Trans</abbr>]</sup>
- [`back()`](transforms.scad#functionmodule-back) Func/Mod Translates children backwards (Y+). <sup title="Can transform children.">[<abbr>Trans</abbr>]</sup> <sup title="Can return a Path.">[<abbr>Path</abbr>]</sup> <sup title="Can return a VNF.">[<abbr>VNF</abbr>]</sup> <sup title="Can return a transformation matrix.">[<abbr>Mat</abbr>]</sup>
- [`yrot()`](transforms.scad#functionmodule-yrot) Func/Mod Rotates children around the Y axis using the right-hand rule. <sup title="Can transform children.">[<abbr>Trans</abbr>]</sup> <sup title="Can return a Path.">[<abbr>Path</abbr>]</sup> <sup title="Can return a VNF.">[<abbr>VNF</abbr>]</sup> <sup title="Can return a transformation matrix.">[<abbr>Mat</abbr>]</sup>
- [`yrot_copies()`](distributors.scad#functionmodule-yrot_copies) Func/Mod Rotates copies of children around the Y axis. <sup title="Can return a list of transformation matrices.">[<abbr>MatList</abbr>]</sup> <sup title="Can transform children.">[<abbr>Trans</abbr>]</sup>
- [`yscale()`](transforms.scad#functionmodule-yscale) Func/Mod Scales children along the Y axis. <sup title="Can transform children.">[<abbr>Trans</abbr>]</sup> <sup title="Can return a Path.">[<abbr>Path</abbr>]</sup> <sup title="Can return a VNF.">[<abbr>VNF</abbr>]</sup> <sup title="Can return a transformation matrix.">[<abbr>Mat</abbr>]</sup>
## Z
- [`zcopies()`](distributors.scad#functionmodule-zcopies) Func/Mod Places copies of children along the Z axis. <sup title="Can return a list of transformation matrices.">[<abbr>MatList</abbr>]</sup> <sup title="Can transform children.">[<abbr>Trans</abbr>]</sup>
- [`zcyl()`](shapes3d.scad#module-zcyl) Mod Creates a cylinder oriented along the Z axis. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup>
- [`zdistribute()`](distributors.scad#module-zdistribute) Mod Distributes each child, individually, out along the Z axis. <sup title="Can transform children.">[<abbr>Trans</abbr>]</sup>
- [`zflip()`](transforms.scad#functionmodule-zflip) Func/Mod Reflects children across the XY plane. <sup title="Can transform children.">[<abbr>Trans</abbr>]</sup> <sup title="Can return a Path.">[<abbr>Path</abbr>]</sup> <sup title="Can return a VNF.">[<abbr>VNF</abbr>]</sup> <sup title="Can return a transformation matrix.">[<abbr>Mat</abbr>]</sup>
- [`zflip_copy()`](distributors.scad#functionmodule-zflip_copy) Func/Mod Makes a copy of children mirrored across the Z axis. <sup title="Can return a list of transformation matrices.">[<abbr>MatList</abbr>]</sup> <sup title="Can transform children.">[<abbr>Trans</abbr>]</sup>
- [`up()`](transforms.scad#functionmodule-up) Func/Mod Translates children upwards (Z+). <sup title="Can transform children.">[<abbr>Trans</abbr>]</sup> <sup title="Can return a Path.">[<abbr>Path</abbr>]</sup> <sup title="Can return a VNF.">[<abbr>VNF</abbr>]</sup> <sup title="Can return a transformation matrix.">[<abbr>Mat</abbr>]</sup>
- [`zrot()`](transforms.scad#functionmodule-zrot) Func/Mod Rotates children around the Z axis using the right-hand rule. <sup title="Can transform children.">[<abbr>Trans</abbr>]</sup> <sup title="Can return a Path.">[<abbr>Path</abbr>]</sup> <sup title="Can return a VNF.">[<abbr>VNF</abbr>]</sup> <sup title="Can return a transformation matrix.">[<abbr>Mat</abbr>]</sup>
- [`zrot_copies()`](distributors.scad#functionmodule-zrot_copies) Func/Mod Rotates copies of children around the Z axis. <sup title="Can return a list of transformation matrices.">[<abbr>MatList</abbr>]</sup> <sup title="Can transform children.">[<abbr>Trans</abbr>]</sup>
- [`zscale()`](transforms.scad#functionmodule-zscale) Func/Mod Scales children along the Z axis. <sup title="Can transform children.">[<abbr>Trans</abbr>]</sup> <sup title="Can return a Path.">[<abbr>Path</abbr>]</sup> <sup title="Can return a VNF.">[<abbr>VNF</abbr>]</sup> <sup title="Can return a transformation matrix.">[<abbr>Mat</abbr>]</sup>

2781
CheatSheet.md Normal file

File diff suppressed because it is too large Load diff

51
Home.md Normal file

@ -0,0 +1,51 @@
![BOSL2 Logo](https://raw.githubusercontent.com/BelfrySCAD/BOSL2/master/images/BOSL2logo.png)
# Belfry OpenSCAD Library v2
## Documentation Indices
- [Index by File (Table of Contents)](TOC)
- [Index by Function/Module Name](AlphaIndex)
- [Index by Topic](Topics)
- [Usage Cheat Sheet](CheatSheet)
- [List of Tutorials](Tutorials)
## Terminology
For purposes of these library files, the following terms apply:
- **Left**: Towards X
- **Right**: Towards X+
- **Front**/**Forward**: Towards Y
- **Back**/**Behind**: Towards Y+
- **Bottom**/**Down**/**Below**: Towards Z
- **Top**/**Up**/**Above**: Towards Z+
- **Vector**: A list of finite numbers.
- **Coordinate** / **Vertex:** A 2 or 3 element vector representing a point in 2D or 3D space.
- **Path:** A list of connected coordinates, either all 2D or all 3D.
- **Polygon:** A closed Path whose last segment is between the last point and the first point.
- **Region:** A list of non-crossing 2D polygons which describes a set of perimeters with possible holes.
- **VNF:** A 2-item list of Vertices 'N' Faces, which provides an easier way to construct a `polyhedron()` in parts.
## Installation
1. Download the .zip or .tar.gz release file for this library. Currently you should be able to find this at https://github.com/BelfrySCAD/BOSL2/archive/refs/heads/master.zip
2. Unpack it. Make sure that you unpack the whole file structure. Some zipfile unpackers call this option "Use folder names". It should create either a `BOSL-v2.0` or `BOSL2-master` directory with the library files within it. You should see "examples", "scripts", "tests", and other subdirectories.
3. Rename the unpacked main directory to `BOSL2`.
4. Move the `BOSL2` directory into the apropriate OpenSCAD library directory. The library directory may be on the list below, but for SNAP or other prepackaged installations, it is probably somewhere else. To find it, run OpenSCAD and select Help&rarr;Library Info, and look for the entry that says "User Library Path". This is your default library directory. You may choose to change it to something more convenient by setting the environment variable OPENSCADPATH. Using this variable also means that all versions of OpenSCAD you install will look for libraries in the same location.
- Windows: `My Documents\OpenSCAD\libraries\`
- Linux: `$HOME/.local/share/OpenSCAD/libraries/`
- Mac OS X: `$HOME/Documents/OpenSCAD/libraries/`
5. Restart OpenSCAD.
## Other Libraries that Synergize with BOSL2
- [Pathbuilder](https://github.com/dinther/pathbuilder) SVG path string parsing.
- [Attachable Text3d](https://github.com/jon-gilbert/openscad_attachable_text3d) - FontMetrics aware attachable text for BOSL2.
- [JL_SCAD](https://github.com/lijon/jl_scad) - A Library to make enclosures for electronics projects, with BOSL2.

1658
TOC.md Normal file

File diff suppressed because it is too large Load diff

2402
Topics.md Normal file

File diff suppressed because it is too large Load diff

2298
Tutorial-Attachments.md Normal file

File diff suppressed because it is too large Load diff

@ -0,0 +1,602 @@
# Béziers for Beginners
Bézier curves are parametric curves defined by polynomial equations. To work with Béziers in OpenSCAD we need to load the Bézier extension BOSL2/beziers.scad in addition to BOSL2/std.scad.
Bézier curves vary by the degree of the polynomial that defines the curve.
Quadratic Béziers, i.e. Bezier's of degree 2, are defined by [quadratic polynomials](https://en.wikipedia.org/wiki/Quadratic_polynomial). A quadratic Bézier has a starting control point, an ending control point, and, one intermediate control point that most often does not lie on the curve. The curve starts toward the intermediate control point and then turns so that it arrives at the endpoint from the direction of the intermediate control point.
![Image courtesy Wikipedia](images/bezier_2_big.gif "Quadratic Bézier Animation courtesy Wikipedia")
To visualize a Bézier curve we can use the module [debug_bezier()](https://github.com/BelfrySCAD/BOSL2/wiki/beziers.scad#module-debug_bezier). The argument N tells debug_bezier the degree of the Bézier curve.
```openscad
include<BOSL2/std.scad>
include<BOSL2/beziers.scad>
bez = [[0,0], [30,60], [0,100]];
debug_bezier(bez, N = 2);
```
![Figure 1](images/tutorials/Beziers_for_Beginners_1.png)
If we move any of the control points, we change the shape of the curve.
```openscad
include<BOSL2/std.scad>
include<BOSL2/beziers.scad>
bez = [[0,0], [100,50], [0,100]];
debug_bezier(bez, N = 2);
```
![Figure 2](images/tutorials/Beziers_for_Beginners_2.png)
Cubic Bézier curves (degree 3) are defined by cubic polynomials. A cubic Bézier has four control points. The first and last control points are the endpoints of the curve. The curve starts toward the second control point and then turns so that it arrives at the endpoint from the direction of the third control point.
![Image courtesy Wikipedia](images/bezier_3_big.gif "Cubic Bézier Animation courtesy Wikipedia")
```openscad
include<BOSL2/std.scad>
include<BOSL2/beziers.scad>
bez = [[20,0], [100,40], [50,90], [25,80]];
debug_bezier(bez, N = 3);
```
![Figure 3](images/tutorials/Beziers_for_Beginners_3.png)
By moving the second and third points on the list we change the shape of the curve.
```openscad
include<BOSL2/std.scad>
include<BOSL2/beziers.scad>
bez = [[20,0], [60,40], [-20,50], [25,80]];
debug_bezier(bez, N = 3);
```
![Figure 4](images/tutorials/Beziers_for_Beginners_4.png)
For a live example of cubic Béziers see the [Desmos Graphing Calculator](https://www.desmos.com/calculator/cahqdxeshd).
Higher order Béziers such as Quartic (degree 4) and Quintic (degree 5) Béziers exist as well. Degree 4 Béziers are used by [round_corners()](https://github.com/BelfrySCAD/BOSL2/wiki/rounding.scad#function-round_corners) and in the continuous rounding operations of [rounded_prism()](https://github.com/BelfrySCAD/BOSL2/wiki/rounding.scad#functionmodule-rounded_prism).
![Image courtesy Wikipedia](images/bezier_4_big.gif "Quartic Bézier Animation courtesy Wikipedia")
Beziers with higher degree, and hence more control points, offer more control over the shape of the bezier curve. You can add more control points to a bezier if you need to refine the shape of the curve.
![Figure 5](images/tutorials/Beziers_for_Beginners_5.png)
### 3d Bézier Curves
Bézier curves are not restricted to the XY plane. We can define a 3d Bézier as easily as a 2d Bézier.
```openscad
include<BOSL2/std.scad>
include<BOSL2/beziers.scad>
bez = [[10,0,10], [30,30,-10], [-30,30,40], [-10,0,30]];
debug_bezier(bez, N = 3);
```
![Figure 6](images/tutorials/Beziers_for_Beginners_6.png)
## Bézier Paths
A Bézier path is when we string together a sequence of Béiers with coincident endpoints.
The point counts arise as a natural consequence of what a bezier path is. If you have k beziers of order N then that's k(N+1) points, except we have k-1 overlaps, so instead it's
```math
k(N+1)-(k-1) = kN +k -k+1 = kN+1.
```
The list of control points for a Bézier is not an OpenSCAD path. If we treat the list bez[] as a path we would get a very different shape. Here the Bézier is in green and the OpenSCAd path through the control points is in red.
```openscad
include<BOSL2/std.scad>
include<BOSL2/beziers.scad>
bez = [[20,0], [60,40], [-20,50], [25,80]];
debug_bezier(bez, N = 3);
color("red") stroke(bez);
```
![Figure 8](images/tutorials/Beziers_for_Beginners_8.png)
To convert the Bézier curve to an OpenSCAD path, use the [bezpath_curve()](https://github.com/BelfrySCAD/BOSL2/wiki/beziers.scad#function-bezpath_curve) function.
```openscad
include<BOSL2/std.scad>
include<BOSL2/beziers.scad>
bez = [[20,0], [60,40], [-20,50], [25,80]];
path = bezpath_curve(bez, N = 3);
stroke(path);
```
![Figure 9](images/tutorials/Beziers_for_Beginners_9.png)
Bézier paths can be made up of more than one Bézier curve. Quadratic Bezier paths have a multiple of 2 points plus 1, and cubic Bézier paths have a multiple of 3 points plus 1
This means that a series of 7 control points can be grouped into three (overlapping) sets of 3 and treated as a sequence of 3 quadratic beziers. The same 7 points can be grouped into two overlapping sets of 4 and treated as a sequence of two cubic beziers. The two paths have significantly different shapes.
```openscad
include<BOSL2/std.scad>
include<BOSL2/beziers.scad>
bez = [[0,0], [10,30], [20,0], [30,-30], [40,0], [50,30],[60,0]];
path = bezpath_curve(bez, N = 2); //make a quadratic Bézier path
stroke(path);
```
![Figure 10](images/tutorials/Beziers_for_Beginners_10.png)
```openscad
include<BOSL2/std.scad>
include<BOSL2/beziers.scad>
bez = [[0,0], [10,30], [20,0], [30,-30], [40,0], [50,30],[60,0]];
path = bezpath_curve(bez, N=3); //make a cubic Bézier path
stroke(path);
```
![Figure 11](images/tutorials/Beziers_for_Beginners_11.png)
By default [bezpath_curve()](https://github.com/BelfrySCAD/BOSL2/wiki/beziers.scad#function-bezpath_curve) takes a Bézier path and converts it to an OpenSCAD path by splitting each Bézier curve into 16 straight-line segments. The segments are not necessarily of equal length. Note that the special variable $fn has no effect on the number of steps. You can control this number using the **splinesteps** argument.
```openscad
include<BOSL2/std.scad>
include<BOSL2/beziers.scad>
bez = [[20,0], [60,40], [-20,50], [25,80]];
path = bezpath_curve(bez, splinesteps = 6);
stroke(path);
```
![Figure 12](images/tutorials/Beziers_for_Beginners_12.png)
To close the path to the y-axis we can use the [bezpath\_close\_to\_axis()](https://github.com/BelfrySCAD/BOSL2/wiki/beziers.scad#function-bezpath_close_to_axis) function.
```openscad
include<BOSL2/std.scad>
include<BOSL2/beziers.scad>
bez = [[20,0], [60,40], [-20,50], [25,80]];
closed = bezpath_close_to_axis(bez, axis = "Y");
path = bezpath_curve(closed);
stroke(path, width = 2);
```
![Figure 13](images/tutorials/Beziers_for_Beginners_13.png)
If we use [rotate_sweep()](https://github.com/BelfrySCAD/BOSL2/wiki/skin.scad#functionmodule-rotate_sweep) to sweep that path around the y-axis we have a solid vase-shaped object. Here we're using both $fn and the splinesteps argument to produce a smoother object.
```openscad
include<BOSL2/std.scad>
include<BOSL2/beziers.scad>
$fn = 72;
bez = [[20,0], [60,40], [-20,50], [25,80]];
closed = bezpath_close_to_axis(bez, axis = "Y");
path = bezpath_curve(closed, splinesteps = 32);
rotate_sweep(path,360);
```
![Figure 14](images/tutorials/Beziers_for_Beginners_14.png)
Instead of closing the path all the way to the y-axis, we can use [bezpath_offset()](https://github.com/BelfrySCAD/BOSL2/wiki/beziers.scad#function-bezpath_offset) to duplicate the path 5 units to the left, and close the two paths at the top and bottom. Note that bezpath_offset takes an x,y pair as an offset value.
```openscad
include<BOSL2/std.scad>
include<BOSL2/beziers.scad>
$fn = 72;
bez = [[20,0], [60,40], [-20,50], [25,80]];
closed = bezpath_offset([-5,0], bez);
debug_bezier(closed);
```
![Figure 15](images/tutorials/Beziers_for_Beginners_15.png)
Note that [bezpath_offset()](https://github.com/BelfrySCAD/BOSL2/wiki/beziers.scad#function-bezpath_offset) does not ensure a uniform wall thickness. For a constant-width wall we need to offset the path along the normals. This we can do using [offset()](https://github.com/BelfrySCAD/BOSL2/wiki/regions.scad#function-offset), but we must first convert the Bézier to an OpenSCAD path, then reverse the offset path to create a closed path.
We could also do this using [offset_stroke()](https://github.com/BelfrySCAD/BOSL2/wiki/rounding.scad#functionmodule-offset_stroke) as a function. The [offset_stroke()](https://github.com/BelfrySCAD/BOSL2/wiki/rounding.scad#functionmodule-offset_stroke) function automates offsetting the path, reversing it and closing the path all in one step. To use [offset_stroke()](https://github.com/BelfrySCAD/BOSL2/wiki/rounding.scad#functionmodule-offset_stroke), we must also include the file [rounding.scad](https://github.com/BelfrySCAD/BOSL2/wiki/rounding.scad).
You can see the differences between the three methods here, with [bezpath_offset()](https://github.com/BelfrySCAD/BOSL2/wiki/beziers.scad#function-bezpath_offset) in blue, [offset()](https://github.com/BelfrySCAD/BOSL2/wiki/regions.scad#function-offset) in red, and [offset_stroke()]() in green.
```openscad
include<BOSL2/std.scad>
include<BOSL2/beziers.scad>
include<BOSL2/rounding.scad>
$fn = 72;
bez = [[40,0], [110,40], [-60,50], [45,80]];
bez2 = bezpath_offset([5,0], bez);
path= bezpath_curve(bez2, splinesteps = 32);
color("blue") stroke(path);
path2 = bezier_curve(bez, splinesteps = 32);
closed2 = concat(path2,reverse(offset(path2,delta=5)),[bez[0]]);
right(30) color("red") stroke(closed2);
path3 = offset_stroke(bezier_curve(bez, splinesteps = 32), [5,0]);
right(60) color("green") stroke(path3, closed= true);
```
![Figure 16](images/tutorials/Beziers_for_Beginners_16.png)
Sweeping a Bézier path offset using any of the three methods around the y-axis gives us a shape with an open interior. However, as this cross section shows, our new path does not close the bottom of the vase.
```openscad
include<BOSL2/std.scad>
include<BOSL2/beziers.scad>
include<BOSL2/rounding.scad>
$fn = 72;
bez = [[15,0], [60,40], [-25,50], [25,80]];
path = offset_stroke(bezier_curve(bez, splinesteps = 32), [2,0]);
back_half(s = 200) rotate_sweep(path,360);
```
![Figure 17](images/tutorials/Beziers_for_Beginners_17.png)
We'll use a cylinder with a height of 2 for the floor of our vase. At the bottom of the vase the radius of the hole is bez[0].x but we need to find the radius at y = 2. The function [bezier_line_intersection()](https://github.com/BelfrySCAD/BOSL2/wiki/beziers.scad#function-bezier_line_intersection) will return a list of u-values where a given line intersects our Bézier curve.
The u-value is a number between 0 and 1 that designates how far along the curve the intersections occur. In our case the line only crosses the Bézier at one point so we get the single-element list [0.0168783].
The function [bezier_points()](https://github.com/BelfrySCAD/BOSL2/wiki/beziers.scad#function-bezpath_points) will convert that list of u-values to a list of x,y coordinates. Drawing a line at y = 2 gives us the single-element list [[17.1687, 2]].
```openscad
include<BOSL2/std.scad>
include<BOSL2/beziers.scad>
bez = [[15,0], [60,40], [-25,50], [25,80]];
debug_bezier(bez, N = 3);
line = [[0,2], [30,2]];
color("red") stroke(line);
u = bezier_line_intersection(bez,line);
echo(bezier_points(bez,u)); // [[17.1687, 2]]
```
![Figure 18](images/tutorials/Beziers_for_Beginners_18.png)
That means a cyl() with a height of 2, a bottom radius of bez[0].x and a top radius of 17.1687 will fit our vase.
```openscad
include<BOSL2/std.scad>
include<BOSL2/beziers.scad>
include<BOSL2/rounding.scad>
$fn = 72;
bez = [[15,0], [60,40], [-25,50], [25,80]];
path = offset_stroke(bezier_curve(bez, splinesteps = 32), [0,2]);
back_half(s = 200) rotate_sweep(path,360);
line = [[0,2], [30,2]];
u = bezier_line_intersection(bez,line).x;
r2 = bezier_points(bez,u).x;
color("red") cyl(h = 2, r1 = bez[0].x, r2 = r2, anchor = BOT);
```
![Figure 19](images/tutorials/Beziers_for_Beginners_19.png)
Keep in mind the fact that **$fn** controls the smoothness of the [rotate_sweep()](https://github.com/BelfrySCAD/BOSL2/wiki/skin.scad#functionmodule-rotate_sweep) operation while the smoothness of the Bézier is controlled by the **splinesteps** argument.
```openscad
include<BOSL2/std.scad>
include<BOSL2/beziers.scad>
$fn = 72;
bez = [[15,0], [40,40], [-20,50], [20,80]];
closed = bezpath_offset([2,0], bez);
path = bezpath_curve(closed, splinesteps = 64);
rotate_sweep(path,360, $fn = 72);
right(60) rotate_sweep(path,360, $fn = 6);
right(120) rotate_sweep(path,360, $fn = 4);
```
![Figure 20](images/tutorials/Beziers_for_Beginners_20.png)
## 2D Cubic Bézier Path Construction
Paths constructed as a series of cubic Bézier curves are familiar to users of Inkscape, Adobe Illustrator, and Affinity Designer. [The Bézier Game](https://bezier.method.ac) illustrates how these drawing programs work.
BOSL2 includes four functions for constructing Cubic Bézier paths:
[bez_begin()](https://github.com/BelfrySCAD/BOSL2/wiki/beziers.scad#function-bez_begin) and [bez_end()](https://github.com/BelfrySCAD/BOSL2/wiki/beziers.scad#function-bez_end) define the endpoints of a simple cubic Bézier curve.
Because each constructor function produces a list of points , we'll use the [flatten()](https://github.com/BelfrySCAD/BOSL2/wiki/lists.scad#function-flatten) function to consolidate them into a single list.
There are three different ways to specify the location of the endpoints and control points.
First, you can specify the endpoints by vectors and the control points by angle, measured from X+ in the XY plane, and distance:
```openscad
include<BOSL2/std.scad>
include<BOSL2/beziers.scad>
bez = flatten([
bez_begin([0,0], 45, 42.43),
bez_end([100,0], 90, 30),
]);
debug_bezier(bez,N=3);
```
![Figure 21](images/tutorials/Beziers_for_Beginners_21.png)
Second, can specify the XY location of the endpoint and that end's control point as a vector from the control point:
```openscad
include<BOSL2/std.scad>
include<BOSL2/beziers.scad>
bez = flatten([
bez_begin([0,0], [30,30]),
bez_end([100,0], [0,30]),
]);
debug_bezier(bez,N=3);
```
![Figure 22](images/tutorials/Beziers_for_Beginners_22.png)
Third, you can specify the endpoints by vectors, and the control points by a direction vector and a distance:
```openscad
include<BOSL2/std.scad>
include<BOSL2/beziers.scad>
bez = flatten([
bez_begin([0,0], BACK+RIGHT, 42.43),
bez_end([100,0], [0,1], 30),
]);
debug_bezier(bez,N=3);
```
![Figure 23](images/tutorials/Beziers_for_Beginners_23.png)
BOSL2 includes the [bez_joint()](https://github.com/BelfrySCAD/BOSL2/wiki/beziers.scad#function-bez_joint) constructor for adding corners to a Bézier path. A corner point has three control points. These are the point on the path where we want the corner, and the approaching and departing control points. We can specify these control points in any of the three ways shown above.
Here's an example using angle and distance to specify a corner. Note that the angles are specified first, and then the distances:
```openscad
include<BOSL2/std.scad>
include<BOSL2/beziers.scad>
bez = flatten([
bez_begin([0,0], 45, 42.43),
bez_joint([40,20], 90,0, 30,30),
bez_end([100,0], 90, 30),
]);
debug_bezier(bez,N=3);
```
![Figure 24](images/tutorials/Beziers_for_Beginners_24.png)
The fourth cubic Bézier path constructor is [bez_tang()](https://github.com/BelfrySCAD/BOSL2/wiki/beziers.scad#function-bez_tang). This constructor makes smooth joint. It also has three control points, one on the path and the approaching and departing control points. Because all three points lie on a single line, we need only specify the angle of the departing control point. As in this example you can specify different distances for the approaching and departing controls points. If you specify only a single distance, it will be used for both.
We can add a smooth joint to the last example:
```openscad
include<BOSL2/std.scad>
include<BOSL2/beziers.scad>
bez = flatten([
bez_begin([0,0], 45, 42.43),
bez_joint([40,20], 90,0, 30,30),
bez_tang([80,50], 0, 20,40),
bez_end([100,0], 90, 30),
]);
debug_bezier(bez,N=3);
```
![Figure 25](images/tutorials/Beziers_for_Beginners_25.png)
It is not necessary to use the same notation to describe the entire Bézier path. We can mix the Angle, Vector and Vector with Distance notations within a single path:
```openscad
include<BOSL2/std.scad>
include<BOSL2/beziers.scad>
bez = flatten([
bez_begin([0,0], [30,30]),
bez_joint([40,20], BACK,RIGHT, 30,30),
bez_tang([80,50], 0, 20,40),
bez_end([100,0], BACK, 30),
]);
debug_bezier(bez,N=3);
```
![Figure 26](images/tutorials/Beziers_for_Beginners_26.png)
When using the cubic Bézier constructors our Bézier path must always begin with the [bez_begin()](https://github.com/BelfrySCAD/BOSL2/wiki/beziers.scad#function-bez_begin) and [bez_end()](https://github.com/BelfrySCAD/BOSL2/wiki/beziers.scad#function-bez_end) constructors.
This might make some of the examples in [The Bézier Game](https://bezier.method.ac) appear puzzling.
Take for example the circle. We can duplicate those results by replacing their starting tangential control point with our beginning and end points.
The correct distance to place the approaching and departing control points to closely approximate a circle is
```math
r * (4/3) * tan(180/2*n)
```
where r is the radius of the circle and n is the number of bez_tang() segments required to make a full circle. Remember that our bez_begin() and bez_end() segments taken together simulate a bez_tang() segment. For our case, where we're closing the circle in 4 segments, the formula evaluates to r * 0.552284.
```openscad
include<BOSL2/std.scad>
include<BOSL2/beziers.scad>
r = 50; // radius of the circle
n = 4; //bezier segments to complete circle
d = r * (4/3) * tan(180/(2*n)); //control point distance
bez = flatten([
bez_begin([-r,0], 90, d),
bez_tang ([0,r], 0, d),
bez_tang ([r,0], -90, d),
bez_tang ([0,-r], 180, d),
bez_end ([-r,0], -90, d)
]);
debug_bezier(bez, N=3);
```
![Figure 27](images/tutorials/Beziers_for_Beginners_27.png)
Similarly, for the heart-shaped path we'll replace a corner point with the start and end points:
```openscad
include<BOSL2/std.scad>
include<BOSL2/beziers.scad>
bez = flatten([
bez_begin([0,25], 40, 40),
bez_joint([0,-25], 30, 150, 60, 60),
bez_end ([0,25], 140, 40)
]);
debug_bezier(bez, N=3);
```
![Figure 28](images/tutorials/Beziers_for_Beginners_28.png)
The first shape in [The Bézier Game](https://bezier.method.ac) past the stages with hints is the outline of the automobile. Here's how we can duplicate that with our cubic Bézier constructors:
```openscad
include<BOSL2/std.scad>
include<BOSL2/beziers.scad>
bez = flatten([
bez_begin([0,0], BACK, 15),
bez_joint([0,9], FWD, RIGHT, 10,10),
bez_joint([5,9], LEFT, 70, 9,20),
bez_tang([80,65], 3, 35, 20),
bez_joint([130,60], 160, -60, 10, 30),
bez_joint([140,42], 120, 0, 20,55),
bez_joint([208,9], BACK, RIGHT, 10,6),
bez_joint([214,9], LEFT, FWD, 10,10),
bez_joint([214,0], BACK, LEFT, 10,10),
bez_joint([189,0], RIGHT, -95, 10,10),
bez_tang([170,-17], LEFT, 10),
bez_joint([152,0], -85, LEFT, 10,10),
bez_joint([52,0], RIGHT, -95, 10,10),
bez_tang([33,-17], LEFT, 10),
bez_joint([16,0], -85,LEFT, 10,10),
bez_end ([0,0], RIGHT,10)
]);
debug_bezier(bez, N = 3);
```
![Figure 29](images/tutorials/Beziers_for_Beginners_29.png)
### A Bézier Dish
We can make a heart shaped dish using a 2D Bézier path to define the shape. When we convert the Bézier curve to a Bézier path with [bezpath_curve()](https://github.com/BelfrySCAD/BOSL2/wiki/beziers.scad#function-bezpath_curve) we can smooth the resulting path by increasing *splinesteps* to 64.
```openscad
include<BOSL2/std.scad>
include<BOSL2/beziers.scad>
include<BOSL2/rounding.scad>
bez = flatten([
bez_begin([0,50], 40, 100),
bez_joint([0,-50], 30, 150, 120, 120),
bez_end ([0,50], 140, 100)
]);
path = bezpath_curve(bez, splinesteps = 64);
linear_sweep(h = 2, path);
region = offset_stroke(path, -3, closed = true);
linear_sweep(h = 20, region);
```
![Figure 30](images/tutorials/Beziers_for_Beginners_30.png)
## 3D Cubic Bézier Path Construction
BOSL2 includes a set of constructor functions for creating cubic Bézier paths. They can create 2d or 3d Béziers. There are constructors for beginning and end points as well as connectors for corner and tangential connections between Bézier curves. Each function gives you the choice of specifying the curve using Angle Notation, Vector Notation, or by Direction Vector and Distance.
### 3D Path by Angle Notation
The path by angle constructors can be used to create 3D Bézier paths by specifying a 3D point on the curve and listing the angle (from the X axis) and distance to the departing and/or departing control point, then adding a p argument that is the angle away from the Z axis for that control point.
```openscad
include<BOSL2/std.scad>
include<BOSL2/beziers.scad>
bez = flatten([
bez_begin ([-50,0,0], 90, 25, p=90),
bez_joint ([0,50,50], 180,0 , 50,50, p1=45, p2=45),
bez_tang ([50,0,0], -90, 25, p=90),
bez_joint ([0,-50,50], 0,180 , 25,25, p1=135,p2=135),
bez_end ([-50,0,0], -90, 25, p=90)
]);
debug_bezier(bez, N=3);
```
![Figure 31](images/tutorials/Beziers_for_Beginners_31.png)
## 3D Path by Vector Notation
The cubic Bézier path constructors can also be used to create 3D Bézier paths by specifying the control points using vectors. The first vector is the location of the control point that lies on the Bézier path, followed by vectors pointing from that control point to the approaching and/or departing control points.
```openscad
include<BOSL2/std.scad>
include<BOSL2/beziers.scad>
bez = flatten([
bez_begin([-50,0,0], [0,25,0]),
bez_joint([0,50,50], [-35,0,35], [35,0,35]),
bez_tang ([50,0,0], [0,-25,0]),
bez_joint([0,-50,50], [18,0,-18], [-18,0,-18]),
bez_end ([-50,0,0], [0,-25,0])
]);
debug_bezier(bez, N=3);
```
![Figure 32](images/tutorials/Beziers_for_Beginners_32.png)
## 3D Path by Direction Vector and Distance
The third method for specifying 3D cubic Bézier Paths is by Direction Vector and distance. For [bez_tang()](https://github.com/BelfrySCAD/BOSL2/wiki/beziers.scad#function-bez_tang) and [bez_joint()](https://github.com/BelfrySCAD/BOSL2/wiki/beziers.scad#function-bez_joint), if r1 is given and r2 is not, the function uses the value of r1 for r2.
```openscad
include<BOSL2/std.scad>
include<BOSL2/beziers.scad>
bez = flatten([
bez_begin([-50,0,0], BACK, 25),
bez_joint([0,50,50], LEFT+UP, RIGHT+UP, 50,50),
bez_tang ([50,0,0], FWD, 25),
bez_joint([0,-50,50], RIGHT+DOWN, LEFT+DOWN, 25,25),
bez_end ([-50,0,0], FWD, 25)
]);
debug_bezier(bez, N=3);
```
![Figure 33](images/tutorials/Beziers_for_Beginners_33.png)
### A Bud Vase Design using both 2D and 3D Bézier Paths
We can use a 2D Bézier path to define the shape of our bud vase as we did in the examples above. Instead of using a [rotate_sweep()](https://github.com/BelfrySCAD/BOSL2/wiki/skin.scad#functionmodule-rotate_sweep) to make a vase with a circular cross section we'll use a 3D Bèzier path that both defines the cross section and makes the top more interesting. This design uses the [skin()](https://github.com/BelfrySCAD/BOSL2/wiki/skin.scad#functionmodule-skin) module to create the final geometry.
```openscad
include<BOSL2/std.scad>
include<BOSL2/beziers.scad>
//Side Bézier Path
side_bez = [[20,0], [40,40], [-10,70], [20,100]];
side = bezpath_curve(side_bez, splinesteps = 32);
h = last(side).y;
steps = len(side)-1;
step = h/steps;
wall = 2;
//Layer Bézier Path
size = side_bez[0].x; // size of the base
d = size * 0.8; // intermediate control point distance
theta = 65; // adjusts layer "wavyness".
bz = 5 * cos(theta); // offset to raise layer curve minima above z = 0;
layer_bez = flatten([
bez_begin ([-size,0,bz], 90, d, p=theta),
bez_tang ([0, size,bz], 0, d, p=theta),
bez_tang ([size, 0,bz], -90, d, p=theta),
bez_tang ([0,-size,bz], 180, d, p=theta),
bez_end ([-size,0,bz], -90, d, p=180 - theta)
]);
layer = bezpath_curve(layer_bez);
function layer_xy_scale(z) =
let (sample_z = side_bez[0].y + z * step) // the sampling height
let (u = bezier_line_intersection(side_bez, [[0, sample_z],[1, sample_z]]))
flatten(bezier_points(side_bez,u)).x / side_bez[0].x;
outside =[for(i=[0:steps]) scale([layer_xy_scale(i),layer_xy_scale(i),1],up(i*step, layer))];
inside = [for (curve = outside) hstack(offset(path2d(curve), delta = -2, same_length = true), column(curve,2))];
base = path3d(path2d(outside[0])); //flatten the base but keep as a 3d path
floor = up(wall, path3d(offset(path2d(outside[0]), -wall)));
skin([ base, each outside, each reverse(inside), floor ], slices=0, refine=1, method="fast_distance");
```
![Figure 34](images/tutorials/Beziers_for_Beginners_34.png)

247
Tutorial-Distributors.md Normal file

@ -0,0 +1,247 @@
# Distributors Tutorial
<!-- TOC -->
## Distributors
Distributors are modules that are useful for placing multiple copies of a
child across a line, area, volume, or ring. Many transforms have one or
more distributive variation.
Transforms | Related Distributors
----------------------- | ---------------------
`left()`, `right()` | `xcopies()`
`fwd()`, `back()` | `ycopies()`
`down()`, `up()` | `zcopies()`
`move()`, `translate()` | `move_copies()`, `line_copies()`, `grid_copies()`
`xrot()` | `xrot_copies()`
`yrot()` | `yrot_copies()`
`zrot()` | `zrot_copies()`
`rot()`, `rotate()` | `rot_copies()`, `arc_copies()`
`xflip()` | `xflip_copy()`
`yflip()` | `yflip_copy()`
`zflip()` | `zflip_copy()`
`mirror()` | `mirror_copy()`
### Transform Distributors
Using `xcopies()`, you can make a line of evenly spaced copies of a shape
centered along the X axis. To make a line of 5 spheres, spaced every 20
units along the X axis, do:
```openscad
include <BOSL2/std.scad>
xcopies(20, n=5) sphere(d=10);
```
![Figure 1](images/tutorials/Distributors_1.png)
Note that the first expected argument to `xcopies()` is the spacing argument,
so you do not need to supply the `spacing=` argument name.
Similarly, `ycopies()` makes a line of evenly spaced copies centered along the
Y axis. To make a line of 5 spheres, spaced every 20 units along the Y
axis, do:
```openscad
include <BOSL2/std.scad>
ycopies(20, n=5) sphere(d=10);
```
![Figure 2](images/tutorials/Distributors_2.png)
And, `zcopies()` makes a line of evenly spaced copies centered along the Z axis.
To make a line of 5 spheres, spaced every 20 units along the Z axis, do:
```openscad
include <BOSL2/std.scad>
zcopies(20, n=5) sphere(d=10);
```
![Figure 3](images/tutorials/Distributors_3.png)
If you don't give the `n=` argument to `xcopies()`, `ycopies()` or `zcopies()`,
then it defaults to 2 (two) copies. This actually is the most common usage:
```openscad
include <BOSL2/std.scad>
xcopies(20) sphere(d=10);
```
![Figure 4](images/tutorials/Distributors_4.png)
```openscad
include <BOSL2/std.scad>
ycopies(20) sphere(d=10);
```
![Figure 5](images/tutorials/Distributors_5.png)
```openscad
include <BOSL2/std.scad>
zcopies(20) sphere(d=10);
```
![Figure 6](images/tutorials/Distributors_6.png)
If you don't know the spacing you want, but instead know how long a line you
want the copies distributed over, you can use the `l=` argument instead of
the `spacing=` argument:
```openscad
include <BOSL2/std.scad>
xcopies(l=100, n=5) sphere(d=10);
```
![Figure 7](images/tutorials/Distributors_7.png)
```openscad
include <BOSL2/std.scad>
ycopies(l=100, n=5) sphere(d=10);
```
![Figure 8](images/tutorials/Distributors_8.png)
```openscad
include <BOSL2/std.scad>
zcopies(l=100, n=5) sphere(d=10);
```
![Figure 9](images/tutorials/Distributors_9.png)
If you don't want the line of copies centered on the origin, you can give a
starting point `sp=`, and the line of copies will start there. For `xcopies()`,
the line of copies will extend to the right of the starting point.
```openscad
include <BOSL2/std.scad>
xcopies(20, n=5, sp=[0,0,0]) sphere(d=10);
```
![Figure 10](images/tutorials/Distributors_10.png)
For `ycopies()`, the line of copies will extend to the back of the starting point.
```openscad
include <BOSL2/std.scad>
ycopies(20, n=5, sp=[0,0,0]) sphere(d=10);
```
![Figure 11](images/tutorials/Distributors_11.png)
For `zcopies()`, the line of copies will extend upwards from the starting point.
```openscad
include <BOSL2/std.scad>
zcopies(20, n=5, sp=[0,0,0]) sphere(d=10);
```
![Figure 12](images/tutorials/Distributors_12.png)
If you need to distribute copies along an arbitrary line, you can use the
`line_copies()` command. You can give both the direction vector and the spacing
of the line of copies with the `spacing=` argument:
```openscad
include <BOSL2/std.scad>
line_copies(spacing=(BACK+RIGHT)*20, n=5) sphere(d=10);
```
![Figure 13](images/tutorials/Distributors_13.png)
With the `p1=` argument, you can specify the starting point of the line:
```openscad
include <BOSL2/std.scad>
line_copies(spacing=(BACK+RIGHT)*20, n=5, p1=[0,0,0]) sphere(d=10);
```
![Figure 14](images/tutorials/Distributors_14.png)
If you give both `p1=` and `p2=`, you can nail down both the start and
endpoints of the line of copies:
```openscad
include <BOSL2/std.scad>
line_copies(p1=[0,100,0], p2=[100,0,0], n=4)
sphere(d=10);
```
![Figure 15](images/tutorials/Distributors_15.png)
The `grid_copies()` command will let you spread copies across both the X and Y
axes at the same time:
```openscad
include <BOSL2/std.scad>
grid_copies(20, n=6) sphere(d=10);
```
![Figure 16](images/tutorials/Distributors_16.png)
The spacing can be separately specified for both the X and Y axes, as can
the count of rows and columns:
```openscad
include <BOSL2/std.scad>
grid_copies([20,30], n=[6,4]) sphere(d=10);
```
![Figure 17](images/tutorials/Distributors_17.png)
Another neat trick of `grid_copies()`, is that you can stagger the output:
```openscad
include <BOSL2/std.scad>
grid_copies(20, n=[12,6], stagger=true) sphere(d=10);
```
![Figure 18](images/tutorials/Distributors_18.png)
You can get the alternate stagger pattern if you set `stagger="alt"`:
```openscad
include <BOSL2/std.scad>
grid_copies(20, n=[12,6], stagger="alt") sphere(d=10);
```
![Figure 19](images/tutorials/Distributors_19.png)
By default, if you give a scalar for the spacing value, staggering will give
you a hexagonal grid, with the spacing being the distance from an item to all
six of the surrounding items. If you give the spacing as a 2-item vector,
then that will force the X and Y spacings between columns and rows instead.
```openscad
include <BOSL2/std.scad>
grid_copies([20,20], n=6, stagger=true) sphere(d=10);
```
![Figure 20](images/tutorials/Distributors_20.png)
You can alternately specify a grid using size and spacing:
```openscad
include <BOSL2/std.scad>
grid_copies(20, size=100) sphere(d=10);
```
![Figure 21](images/tutorials/Distributors_21.png)
```openscad
include <BOSL2/std.scad>
grid_copies(20, size=[100,80]) sphere(d=10);
```
![Figure 22](images/tutorials/Distributors_22.png)
```openscad
include <BOSL2/std.scad>
grid_copies(20, size=[100,80], stagger=true) sphere(d=10);
```
![Figure 23](images/tutorials/Distributors_23.png)
You can also make grids by specifying size and column/row count:
```openscad
include <BOSL2/std.scad>
grid_copies(n=5, size=100) sphere(d=10);
```
![Figure 24](images/tutorials/Distributors_24.png)
```openscad
include <BOSL2/std.scad>
grid_copies(n=[4,5], size=100) sphere(d=10);
```
![Figure 25](images/tutorials/Distributors_25.png)
```openscad
include <BOSL2/std.scad>
grid_copies(n=[4,5], size=[100,80]) sphere(d=10);
```
![Figure 26](images/tutorials/Distributors_26.png)
Finally, the `grid_copies()` command will let you give a polygon or region shape
to fill with items. Only the items in the grid whose center would be inside
the polygon or region will be created. To fill a star shape with items, you
can do something like:
```openscad
include <BOSL2/std.scad>
poly = [for (i=[0:11]) polar_to_xy(50*(i%2+1), i*360/12-90)];
grid_copies(5, stagger=true, inside=poly) {
cylinder(d=4,h=10,spin=90,$fn=6);
}
```
![Figure 27](images/tutorials/Distributors_27.png)
### Rotational Distributors
You can make six copies of a cone, rotated around a center:
```openscad
include <BOSL2/std.scad>
zrot_copies(n=6) yrot(90) cylinder(h=50,d1=0,d2=20);
```
![Figure 28](images/tutorials/Distributors_28.png)
To Be Completed

128
Tutorial-FractalTree.md Normal file

@ -0,0 +1,128 @@
# Fractal Tree Tutorial
<!-- TOC -->
### Start with a Tree Trunk
Firstoff, include the BOSL2 library, then make a starting module that just has a tapered cylinder for the tree trunk.
```openscad
include <BOSL2/std.scad>
module tree(l=1500, sc=0.7)
cylinder(h=l, d1=l/5, d2=l/5*sc);
tree();
```
![Figure 1](images/tutorials/FractalTree_1.png)
### Attaching a Branch
You can attach a branch to the top of the trunk by using `attach()` as a child of the trunk cylinder.
```openscad
include <BOSL2/std.scad>
module tree(l=1500, sc=0.7)
cylinder(h=l, d1=l/5, d2=l/5*sc)
attach(TOP)
yrot(30) cylinder(h=l*sc, d1=l/5*sc, d2=l/5*sc*sc);
tree();
```
![Figure 2](images/tutorials/FractalTree_2.png)
### Replicating the Branch
Instead of attaching each branch individually, you can make multiple copies of one branch, that are rotated relative to each other.
```openscad
include <BOSL2/std.scad>
module tree(l=1500, sc=0.7)
cylinder(h=l, d1=l/5, d2=l/5*sc)
attach(TOP)
zrot_copies(n=2) // Replicate that branch
yrot(30) cylinder(h=l*sc, d1=l/5*sc, d2=l/5*sc*sc);
tree();
```
![Figure 3](images/tutorials/FractalTree_3.png)
### Use Recursion
Since branches look much like the main trunk, we can make the tree recursive. Don't forget the termination clause, or else it'll try to recurse forever!
```openscad
include <BOSL2/std.scad>
module tree(l=1500, sc=0.7, depth=10)
cylinder(h=l, d1=l/5, d2=l/5*sc)
attach(TOP)
if (depth>0) { // Important!
zrot_copies(n=2)
yrot(30) tree(depth=depth-1, l=l*sc, sc=sc);
}
tree();
```
![Figure 4](images/tutorials/FractalTree_4.png)
### Make it Not Flat
A flat planar tree isn't what we want, so lets bush it out a bit by rotating each level 90 degrees.
```openscad
include <BOSL2/std.scad>
module tree(l=1500, sc=0.7, depth=10)
cylinder(h=l, d1=l/5, d2=l/5*sc)
attach(TOP)
if (depth>0) {
zrot(90) // Bush it out
zrot_copies(n=2)
yrot(30) tree(depth=depth-1, l=l*sc, sc=sc);
}
tree();
```
![Figure 5](images/tutorials/FractalTree_5.png)
### Adding Leaves
Let's add leaves. They look much like squashed versions of the standard teardrop() module, so lets use that.
```openscad
include <BOSL2/std.scad>
module tree(l=1500, sc=0.7, depth=10)
cylinder(h=l, d1=l/5, d2=l/5*sc)
attach(TOP)
if (depth>0) {
zrot(90)
zrot_copies(n=2)
yrot(30) tree(depth=depth-1, l=l*sc, sc=sc);
} else {
yscale(0.67)
teardrop(d=l*3, l=1, anchor=BOT, spin=90);
}
tree();
```
![Figure 6](images/tutorials/FractalTree_6.png)
### Adding Color
We can finish this off with some color. The `color()` module will force all it's children and
their descendants to the new color, even if they were colored before. The `recolor()` module,
however, will only color children and decendants that don't already have a color set by a more
nested `recolor()`.
```openscad
include <BOSL2/std.scad>
module tree(l=1500, sc=0.7, depth=10)
recolor("lightgray")
cylinder(h=l, d1=l/5, d2=l/5*sc)
attach(TOP)
if (depth>0) {
zrot(90)
zrot_copies(n=2)
yrot(30) tree(depth=depth-1, l=l*sc, sc=sc);
} else {
recolor("springgreen")
yscale(0.67)
teardrop(d=l*3, l=1, anchor=BOT, spin=90);
}
tree();
```
![Figure 7](images/tutorials/FractalTree_7.png)

392
Tutorial-Mutators.md Normal file

@ -0,0 +1,392 @@
# Mutators Tutorial
<!-- TOC -->
## 3D Space Halving
Sometimes you want to take a 3D shape like a sphere, and cut it in half.
The BOSL2 library provides a number of ways to do this:
```openscad
include <BOSL2/std.scad>
left_half()
sphere(d=100);
```
![Figure 1](images/tutorials/Mutators_1.png)
```openscad
include <BOSL2/std.scad>
right_half()
sphere(d=100);
```
![Figure 2](images/tutorials/Mutators_2.png)
```openscad
include <BOSL2/std.scad>
front_half()
sphere(d=100);
```
![Figure 3](images/tutorials/Mutators_3.png)
```openscad
include <BOSL2/std.scad>
back_half()
sphere(d=100);
```
![Figure 4](images/tutorials/Mutators_4.png)
```openscad
include <BOSL2/std.scad>
bottom_half()
sphere(d=100);
```
![Figure 5](images/tutorials/Mutators_5.png)
```openscad
include <BOSL2/std.scad>
top_half()
sphere(d=100);
```
![Figure 6](images/tutorials/Mutators_6.png)
You can use the `half_of()` module if you want to split space in a way not aligned with an axis:
```openscad
include <BOSL2/std.scad>
half_of([-1,0,-1])
sphere(d=100);
```
![Figure 7](images/tutorials/Mutators_7.png)
The plane of dissection can be shifted along the axis of any of these operators:
```openscad
include <BOSL2/std.scad>
left_half(x=20)
sphere(d=100);
```
![Figure 8](images/tutorials/Mutators_8.png)
```openscad
include <BOSL2/std.scad>
back_half(y=-20)
sphere(d=100);
```
![Figure 9](images/tutorials/Mutators_9.png)
```openscad
include <BOSL2/std.scad>
bottom_half(z=20)
sphere(d=100);
```
![Figure 10](images/tutorials/Mutators_10.png)
```openscad
include <BOSL2/std.scad>
half_of([-1,0,-1], cp=[20,0,20])
sphere(d=100);
```
![Figure 11](images/tutorials/Mutators_11.png)
By default, these operators can be applied to objects that fit in a cube 1000 on a side. If you need
to apply these halving operators to objects larger than this, you can give the size in the `s=`
argument:
```openscad
include <BOSL2/std.scad>
bottom_half(s=2000)
sphere(d=1500);
```
![Figure 12](images/tutorials/Mutators_12.png)
## 2D Plane Halving
To cut 2D shapes in half, you will need to add the `planar=true` argument:
```openscad
include <BOSL2/std.scad>
left_half(planar=true)
circle(d=100);
```
![Figure 13](images/tutorials/Mutators_13.png)
```openscad
include <BOSL2/std.scad>
right_half(planar=true)
circle(d=100);
```
![Figure 14](images/tutorials/Mutators_14.png)
```openscad
include <BOSL2/std.scad>
front_half(planar=true)
circle(d=100);
```
![Figure 15](images/tutorials/Mutators_15.png)
```openscad
include <BOSL2/std.scad>
back_half(planar=true)
circle(d=100);
```
![Figure 16](images/tutorials/Mutators_16.png)
## Chained Mutators
If you have a set of shapes that you want to do pair-wise hulling of, you can use `chain_hull()`:
```openscad
include <BOSL2/std.scad>
chain_hull() {
cube(5, center=true);
translate([30, 0, 0]) sphere(d=15);
translate([60, 30, 0]) cylinder(d=10, h=20);
translate([60, 60, 0]) cube([10,1,20], center=false);
}
```
![Figure 17](images/tutorials/Mutators_17.png)
## Extrusion Mutators
The OpenSCAD `linear_extrude()` module can take a 2D shape and extrude it vertically in a line:
```openscad
include <BOSL2/std.scad>
linear_extrude(height=30)
zrot(45)
square(40,center=true);
```
![Figure 18](images/tutorials/Mutators_18.png)
The `rotate_extrude()` module can take a 2D shape and rotate it around the Z axis.
```openscad
include <BOSL2/std.scad>
rotate_extrude()
left(50) zrot(45)
square(40,center=true);
```
![Figure 19](images/tutorials/Mutators_19.png)
In a similar manner, the BOSL2 `cylindrical_extrude()` module can take a 2d shape and extrude it
out radially from the center of a cylinder:
```openscad
include <BOSL2/std.scad>
cylindrical_extrude(or=40, ir=35)
text(text="Hello World!", size=10, halign="center", valign="center");
```
![Figure 20](images/tutorials/Mutators_20.png)
## Offset Mutators
### Minkowski Difference
Openscad provides the `minkowski()` module to trace a shape over the entire surface of another shape:
```openscad
include <BOSL2/std.scad>
minkowski() {
union() {
cube([100,33,33], center=true);
cube([33,100,33], center=true);
cube([33,33,100], center=true);
}
sphere(r=8);
}
```
![Figure 21](images/tutorials/Mutators_21.png)
However, it doesn't provide the inverse of this operation; to remove a shape from the entire surface
of another object. For this, the BOSL2 library provides the `minkowski_difference()` module:
```openscad
include <BOSL2/std.scad>
minkowski_difference() {
union() {
cube([100,33,33], center=true);
cube([33,100,33], center=true);
cube([33,33,100], center=true);
}
sphere(r=8);
}
```
![Figure 22](images/tutorials/Mutators_22.png)
To perform a `minkowski_difference()` on 2D shapes, you need to supply the `planar=true` argument:
```openscad
include <BOSL2/std.scad>
minkowski_difference(planar=true) {
union() {
square([100,33], center=true);
square([33,100], center=true);
}
circle(r=8);
}
```
![Figure 23](images/tutorials/Mutators_23.png)
### Round2d
The `round2d()` module lets you take a 2D shape and round inside and outside corners. The inner concave corners are rounded to the radius `ir=`, while the outer convex corners are rounded to the radius `or=`:
```openscad
include <BOSL2/std.scad>
round2d(or=8)
star(6, step=2, d=100);
```
![Figure 24](images/tutorials/Mutators_24.png)
```openscad
include <BOSL2/std.scad>
round2d(ir=12)
star(6, step=2, d=100);
```
![Figure 25](images/tutorials/Mutators_25.png)
```openscad
include <BOSL2/std.scad>
round2d(or=8,ir=12)
star(6, step=2, d=100);
```
![Figure 26](images/tutorials/Mutators_26.png)
You can use `r=` to effectively set both `ir=` and `or=` to the same value:
```openscad
include <BOSL2/std.scad>
round2d(r=8)
star(6, step=2, d=100);
```
![Figure 27](images/tutorials/Mutators_27.png)
### Shell2d
With the `shell2d()` module, you can take an arbitrary shape, and get the shell outline of it.
With a positive thickness, the shell is offset outwards from the original shape:
```openscad
include <BOSL2/std.scad>
shell2d(thickness=5)
star(5,step=2,d=100);
color("blue")
stroke(star(5,step=2,d=100),closed=true);
```
![Figure 28](images/tutorials/Mutators_28.png)
With a negative thickness, the shell if inset from the original shape:
```openscad
include <BOSL2/std.scad>
shell2d(thickness=-5)
star(5,step=2,d=100);
color("blue")
stroke(star(5,step=2,d=100),closed=true);
```
![Figure 29](images/tutorials/Mutators_29.png)
You can give a pair of thickness values if you want it both inset and outset from the original shape:
```openscad
include <BOSL2/std.scad>
shell2d(thickness=[-5,5])
star(5,step=2,d=100);
color("blue")
stroke(star(5,step=2,d=100),closed=true);
```
![Figure 30](images/tutorials/Mutators_30.png)
You can add rounding to the outside by passing a radius to the `or=` argument.
```openscad
include <BOSL2/std.scad>
shell2d(thickness=-5,or=5)
star(5,step=2,d=100);
```
![Figure 31](images/tutorials/Mutators_31.png)
If you need to pass different radii for the convex and concave corners of the outside, you can pass them as `or=[CONVEX,CONCAVE]`:
```openscad
include <BOSL2/std.scad>
shell2d(thickness=-5,or=[5,10])
star(5,step=2,d=100);
```
![Figure 32](images/tutorials/Mutators_32.png)
A radius of 0 can be used to specify no rounding:
```openscad
include <BOSL2/std.scad>
shell2d(thickness=-5,or=[5,0])
star(5,step=2,d=100);
```
![Figure 33](images/tutorials/Mutators_33.png)
You can add rounding to the inside by passing a radius to the `ir=` argument.
```openscad
include <BOSL2/std.scad>
shell2d(thickness=-5,ir=5)
star(5,step=2,d=100);
```
![Figure 34](images/tutorials/Mutators_34.png)
If you need to pass different radii for the convex and concave corners of the inside, you can pass them as `ir=[CONVEX,CONCAVE]`:
```openscad
include <BOSL2/std.scad>
shell2d(thickness=-5,ir=[8,3])
star(5,step=2,d=100);
```
![Figure 35](images/tutorials/Mutators_35.png)
You can use `or=` and `ir=` together to get nice combined rounding effects:
```openscad
include <BOSL2/std.scad>
shell2d(thickness=-5,or=[7,2],ir=[7,2])
star(5,step=2,d=100);
```
![Figure 36](images/tutorials/Mutators_36.png)
```openscad
include <BOSL2/std.scad>
shell2d(thickness=-5,or=[5,0],ir=[5,0])
star(5,step=2,d=100);
```
![Figure 37](images/tutorials/Mutators_37.png)
### Round3d
### Offset3d
(To be Written)
## Color Manipulators
The built-in OpenSCAD `color()` module can let you set the RGB color of an object, but it's often
easier to select colors using other color schemes. You can use the HSL or Hue-Saturation-Lightness
color scheme with the `hsl()` module:
```openscad
include <BOSL2/std.scad>
n = 10; size = 100/n;
for (a=count(n), b=count(n), c=count(n)) {
let( h=360*a/n, s=1-b/(n-1), l=c/(n-1))
translate(size*[a,b,c]) {
hsl(h,s,l) cube(size);
}
}
```
![Figure 38](images/tutorials/Mutators_38.png)
You can use the HSV or Hue-Saturation-Value color scheme with the `hsv()` module:
```openscad
include <BOSL2/std.scad>
n = 10; size = 100/n;
for (a=count(n), b=count(n), c=count(n)) {
let( h=360*a/n, s=1-b/(n-1), v=c/(n-1))
translate(size*[a,b,c]) {
hsv(h,s,v) cube(size);
}
}
```
![Figure 39](images/tutorials/Mutators_39.png)

630
Tutorial-Paths.md Normal file

@ -0,0 +1,630 @@
# Paths, Polygons and Regions Tutorial
<!-- TOC -->
## Paths
A number of advanced features in BOSL2 rely on paths, which are just ordered lists of points.
First-off, some terminology:
- A 2D point is a vector of X and Y axis position values. ie: `[3,4]` or `[7,-3]`.
- A 3D point is a vector of X, Y and Z axis position values. ie: `[3,4,2]` or `[-7,5,3]`.
- A 2D path is simply a list of two or more 2D points. ie: `[[5,7], [1,-5], [-5,6]]`
- A 3D path is simply a list of two or more 3D points. ie: `[[5,7,-1], [1,-5,3], [-5,6,1]]`
- A polygon is a 2D (or planar 3D) path where the last point is assumed to connect to the first point.
- A region is a list of 2D polygons, where each polygon is XORed against all the others. ie: if one polygon is inside another, it makes a hole in the first polygon.
### Stroke
A path can be hard to visualize, since it's just a bunch of numbers in the source code.
One way to see the path is to pass it to `polygon()`:
```openscad
include <BOSL2/std.scad>
path = [[0,0], [-10,10], [0,20], [10,20], [10,10]];
polygon(path);
```
![Figure 1](images/tutorials/Paths_1.png)
Sometimes, however, it's easier to see just the path itself. For this, you can use the `stroke()` module.
At its most basic, `stroke()` just shows the path's line segments:
```openscad
include <BOSL2/std.scad>
path = [[0,0], [-10,10], [0,20], [10,20], [10,10]];
stroke(path);
```
![Figure 2](images/tutorials/Paths_2.png)
You can vary the width of the drawn path with the `width=` argument:
```openscad
include <BOSL2/std.scad>
path = [[0,0], [-10,10], [0,20], [10,20], [10,10]];
stroke(path, width=3);
```
![Figure 3](images/tutorials/Paths_3.png)
You can vary the line length along the path by giving a list of widths, one per point:
```openscad
include <BOSL2/std.scad>
path = [[0,0], [-10,10], [0,20], [10,20], [10,10]];
stroke(path, width=[3,2,1,2,3]);
```
![Figure 4](images/tutorials/Paths_4.png)
If a path is meant to represent a closed polygon, you can use `closed=true` to show it that way:
```openscad
include <BOSL2/std.scad>
path = [[0,0], [-10,10], [0,20], [10,20], [10,10]];
stroke(path, closed=true);
```
![Figure 5](images/tutorials/Paths_5.png)
The ends of the drawn path are normally capped with a "round" endcap, but there are other options:
```openscad
include <BOSL2/std.scad>
path = [[0,0], [-10,10], [0,20], [10,20], [10,10]];
stroke(path, endcaps="round");
```
![Figure 6](images/tutorials/Paths_6.png)
```openscad
include <BOSL2/std.scad>
path = [[0,0], [-10,10], [0,20], [10,20], [10,10]];
stroke(path, endcaps="butt");
```
![Figure 7](images/tutorials/Paths_7.png)
```openscad
include <BOSL2/std.scad>
path = [[0,0], [-10,10], [0,20], [10,20], [10,10]];
stroke(path, endcaps="line");
```
![Figure 8](images/tutorials/Paths_8.png)
```openscad
include <BOSL2/std.scad>
path = [[0,0], [-10,10], [0,20], [10,20], [10,10]];
stroke(path, endcaps="tail");
```
![Figure 9](images/tutorials/Paths_9.png)
```openscad
include <BOSL2/std.scad>
path = [[0,0], [-10,10], [0,20], [10,20], [10,10]];
stroke(path, endcaps="arrow2");
```
![Figure 10](images/tutorials/Paths_10.png)
For more standard supported endcap options, see the docs for [`stroke()`](shapes2d.scad#stroke).
The start and ending endcaps can be specified individually or separately, using `endcap1=` and `endcap2=`:
```openscad
include <BOSL2/std.scad>
path = [[0,0], [-10,10], [0,20], [10,20], [10,10]];
stroke(path, endcap2="arrow2");
```
![Figure 11](images/tutorials/Paths_11.png)
```openscad
include <BOSL2/std.scad>
path = [[0,0], [-10,10], [0,20], [10,20], [10,10]];
stroke(path, endcap1="butt", endcap2="arrow2");
```
![Figure 12](images/tutorials/Paths_12.png)
```openscad
include <BOSL2/std.scad>
path = [[0,0], [-10,10], [0,20], [10,20], [10,10]];
stroke(path, endcap1="tail", endcap2="arrow");
```
![Figure 13](images/tutorials/Paths_13.png)
The size of the endcaps will be relative to the width of the line where the endcap is to be placed:
```openscad
include <BOSL2/std.scad>
path = [[0,0], [-10,10], [0,20], [10,20], [10,10]];
widths = [1, 1.25, 1.5, 1.75, 2];
stroke(path, width=widths, endcaps="arrow2");
```
![Figure 14](images/tutorials/Paths_14.png)
If none of the standard endcaps are useful to you, it is possible to design your own, simply by
passing a path to the `endcaps=`, `endcap1=`, or `endcap2=` arguments. You may also need to give
`trim=` to tell it how far back to trim the main line, so it renders nicely. The values in the
endcap polygon, and in the `trim=` argument are relative to the line width. A value of 1 is one
line width size.
Untrimmed:
```openscad
include <BOSL2/std.scad>
path = [[0,0], [-10,10], [0,20], [10,20], [10,10]];
dblarrow = [[0,0], [2,-3], [0.5,-2.3], [2,-4], [0.5,-3.5], [-0.5,-3.5], [-2,-4], [-0.5,-2.3], [-2,-3]];
stroke(path, endcaps=dblarrow);
```
![Figure 15](images/tutorials/Paths_15.png)
Trimmed:
```openscad
include <BOSL2/std.scad>
path = [[0,0], [-10,10], [0,20], [10,20], [10,10]];
dblarrow = [[0,0], [2,-3], [0.5,-2.3], [2,-4], [0.5,-3.5], [-0.5,-3.5], [-2,-4], [-0.5,-2.3], [-2,-3]];
stroke(path, trim=3.5, endcaps=dblarrow);
```
![Figure 16](images/tutorials/Paths_16.png)
### Standard 2D Shape Polygons
BOSL2 will let you get the perimeter polygon for almost all of the standard 2D shapes simply by calling them like a function:
```openscad
include <BOSL2/std.scad>
path = square(40, center=true);
stroke(list_wrap(path), endcap2="arrow2");
```
![Figure 17](images/tutorials/Paths_17.png)
```openscad
include <BOSL2/std.scad>
path = rect([40,30], rounding=5);
stroke(list_wrap(path), endcap2="arrow2");
```
![Figure 18](images/tutorials/Paths_18.png)
```openscad
include <BOSL2/std.scad>
path = trapezoid(w1=40, w2=20, h=30);
stroke(list_wrap(path), endcap2="arrow2");
```
![Figure 19](images/tutorials/Paths_19.png)
```openscad
include <BOSL2/std.scad>
path = circle(d=50);
stroke(list_wrap(path), endcap2="arrow2");
```
![Figure 20](images/tutorials/Paths_20.png)
```openscad
include <BOSL2/std.scad>
path = ellipse(d=[50,30]);
stroke(list_wrap(path), endcap2="arrow2");
```
![Figure 21](images/tutorials/Paths_21.png)
```openscad
include <BOSL2/std.scad>
path = pentagon(d=50);
stroke(list_wrap(path), endcap2="arrow2");
```
![Figure 22](images/tutorials/Paths_22.png)
```openscad
include <BOSL2/std.scad>
path = star(n=5, step=2, d=50);
stroke(list_wrap(path), endcap2="arrow2");
```
![Figure 23](images/tutorials/Paths_23.png)
### Arcs
Often, when you are constructing a path, you will want to add an arc. The `arc()` command lets you do that:
```openscad
include <BOSL2/std.scad>
path = arc(r=30, angle=120);
stroke(path, endcap2="arrow2");
```
![Figure 24](images/tutorials/Paths_24.png)
```openscad
include <BOSL2/std.scad>
path = arc(d=60, angle=120);
stroke(path, endcap2="arrow2");
```
![Figure 25](images/tutorials/Paths_25.png)
If you give the `n=` argument, you can control exactly how many points the arc is divided into:
```openscad
include <BOSL2/std.scad>
path = arc(n=5, r=30, angle=120);
stroke(path, endcap2="arrow2");
```
![Figure 26](images/tutorials/Paths_26.png)
With the `start=` argument, you can start the arc somewhere other than the X+ axis:
```openscad
include <BOSL2/std.scad>
path = arc(start=45, r=30, angle=120);
stroke(path, endcap2="arrow2");
```
![Figure 27](images/tutorials/Paths_27.png)
Alternatively, you can give starting and ending angles in a list in the `angle=` argument:
```openscad
include <BOSL2/std.scad>
path = arc(angle=[120,45], r=30);
stroke(path, endcap2="arrow2");
```
![Figure 28](images/tutorials/Paths_28.png)
The `cp=` argument lets you center the arc somewhere other than the origin:
```openscad
include <BOSL2/std.scad>
path = arc(cp=[10,0], r=30, angle=120);
stroke(path, endcap2="arrow2");
```
![Figure 29](images/tutorials/Paths_29.png)
The arc can also be given by three points on the arc:
```openscad
include <BOSL2/std.scad>
pts = [[-15,10],[0,20],[35,-5]];
path = arc(points=pts);
stroke(path, endcap2="arrow2");
```
![Figure 30](images/tutorials/Paths_30.png)
### Turtle Graphics
Another way you can create a path is using the `turtle()` command. It implements a simple path
description language that is similar to LOGO Turtle Graphics. The concept is that you have a virtial
turtle or cursor walking a path. It can "move" forward or backward, or turn "left" or "right" in
place:
```openscad
include <BOSL2/std.scad>
path = turtle([
"move", 10,
"left", 90,
"move", 20,
"left", 135,
"move", 10*sqrt(2),
"right", 90,
"move", 10*sqrt(2),
"left", 135,
"move", 20
]);
stroke(path, endcap2="arrow2");
```
![Figure 31](images/tutorials/Paths_31.png)
The position and the facing of the turtle/cursor updates after each command. The motion and turning
commands can also have default distances or angles given:
```openscad
include <BOSL2/std.scad>
path = turtle([
"angle",360/6,
"length",10,
"move","turn",
"move","turn",
"move","turn",
"move","turn",
"move"
]);
stroke(path, endcap2="arrow2");
```
![Figure 32](images/tutorials/Paths_32.png)
You can use "scale" to relatively scale up the default motion length:
```openscad
include <BOSL2/std.scad>
path = turtle([
"angle",360/6,
"length",10,
"move","turn",
"move","turn",
"scale",2,
"move","turn",
"move","turn",
"scale",0.5,
"move"
]);
stroke(path, endcap2="arrow2");
```
![Figure 33](images/tutorials/Paths_33.png)
Sequences of commands can be repeated using the "repeat" command:
```openscad
include <BOSL2/std.scad>
path=turtle([
"angle",360/5,
"length",10,
"repeat",5,["move","turn"]
]);
stroke(path, endcap2="arrow2");
```
![Figure 34](images/tutorials/Paths_34.png)
More complicated commands also exist, including those that form arcs:
```openscad
include <BOSL2/std.scad>
path = turtle([
"move", 10,
"left", 90,
"move", 20,
"arcleft", 10, 180,
"move", 20
]);
stroke(path, endcap2="arrow2");
```
![Figure 35](images/tutorials/Paths_35.png)
A comprehensive list of supported turtle commands can be found in the docs for [`turtle()`](shapes2d.scad#turtle).
### Transforming Paths and Polygons
To translate a path, you can just pass it to the `move()` (or up/down/left/right/fwd/back) function in the `p=` argument:
```openscad
include <BOSL2/std.scad>
path = move([-15,-30], p=square(50,center=true));
stroke(list_wrap(path), endcap2="arrow2");
```
![Figure 36](images/tutorials/Paths_36.png)
```openscad
include <BOSL2/std.scad>
path = fwd(30, p=square(50,center=true));
stroke(list_wrap(path), endcap2="arrow2");
```
![Figure 37](images/tutorials/Paths_37.png)
```openscad
include <BOSL2/std.scad>
path = left(30, p=square(50,center=true));
stroke(list_wrap(path), endcap2="arrow2");
```
![Figure 38](images/tutorials/Paths_38.png)
To scale a path, you can just pass it to the `scale()` (or [xyz]scale) function in the `p=` argument:
```openscad
include <BOSL2/std.scad>
path = scale([1.5,0.75], p=square(50,center=true));
stroke(list_wrap(path), endcap2="arrow2");
```
![Figure 39](images/tutorials/Paths_39.png)
```openscad
include <BOSL2/std.scad>
path = xscale(1.5, p=square(50,center=true));
stroke(list_wrap(path), endcap2="arrow2");
```
![Figure 40](images/tutorials/Paths_40.png)
```openscad
include <BOSL2/std.scad>
path = yscale(1.5, p=square(50,center=true));
stroke(list_wrap(path), endcap2="arrow2");
```
![Figure 41](images/tutorials/Paths_41.png)
To rotate a path, just can pass it to the `rot()` (or [xyz]rot) function in the `p=` argument:
```openscad
include <BOSL2/std.scad>
path = rot(30, p=square(50,center=true));
stroke(list_wrap(path), endcap2="arrow2");
```
![Figure 42](images/tutorials/Paths_42.png)
```openscad
include <BOSL2/std.scad>
path = zrot(30, p=square(50,center=true));
stroke(list_wrap(path), endcap2="arrow2");
```
![Figure 43](images/tutorials/Paths_43.png)
To mirror a path, just can pass it to the `mirror()` (or [xyz]flip) function in the `p=` argument:
```openscad
include <BOSL2/std.scad>
path = mirror([1,1], p=trapezoid(w1=40, w2=10, h=25));
stroke(list_wrap(path), endcap2="arrow2");
```
![Figure 44](images/tutorials/Paths_44.png)
```openscad
include <BOSL2/std.scad>
path = xflip(p=trapezoid(w1=40, w2=10, h=25));
stroke(list_wrap(path), endcap2="arrow2");
```
![Figure 45](images/tutorials/Paths_45.png)
```openscad
include <BOSL2/std.scad>
path = yflip(p=trapezoid(w1=40, w2=10, h=25));
stroke(list_wrap(path), endcap2="arrow2");
```
![Figure 46](images/tutorials/Paths_46.png)
You can get raw transformation matrices for various transformations by calling them like a function without a `p=` argument:
```openscad
include <BOSL2/std.scad>
mat = move([5,10,0]);
multmatrix(mat) square(50,center=true);
```
![Figure 47](images/tutorials/Paths_47.png)
```openscad
include <BOSL2/std.scad>
mat = scale([1.5,0.75,1]);
multmatrix(mat) square(50,center=true);
```
![Figure 48](images/tutorials/Paths_48.png)
```openscad
include <BOSL2/std.scad>
mat = rot(30);
multmatrix(mat) square(50,center=true);
```
![Figure 49](images/tutorials/Paths_49.png)
Raw transformation matrices can be multiplied together to precalculate a compound transformation. For example, to scale a shape, then rotate it, then translate the result, you can do something like:
```openscad
include <BOSL2/std.scad>
mat = move([5,10,0]) * rot(30) * scale([1.5,0.75,1]);
multmatrix(mat) square(50,center=true);
```
![Figure 50](images/tutorials/Paths_50.png)
To apply a compound transformation matrix to a path, you can use the `apply()` function:
```openscad
include <BOSL2/std.scad>
mat = move([5,10]) * rot(30) * scale([1.5,0.75]);
path = square(50,center=true);
tpath = apply(mat, path);
stroke(tpath, endcap2="arrow2");
```
![Figure 51](images/tutorials/Paths_51.png)
### Regions
A polygon is good to denote a single closed 2D shape with no holes in it. For more complex 2D
shapes, you will need to use regions. A region is a list of 2D polygons, where each polygon is
XORed against all the others. You can display a region using the `region()` module.
If you have a region with one polygon fully inside another, it makes a hole:
```openscad
include <BOSL2/std.scad>
rgn = [square(50,center=true), circle(d=30)];
region(rgn);
```
![Figure 52](images/tutorials/Paths_52.png)
If you have a region with multiple polygons that are not contained by any others, they make multiple discontiguous shapes:
```openscad
include <BOSL2/std.scad>
rgn = [
move([-30, 20], p=square(20,center=true)),
move([ 0,-20], p=trapezoid(w1=20, w2=10, h=20)),
move([ 30, 20], p=square(20,center=true)),
];
region(rgn);
```
![Figure 53](images/tutorials/Paths_53.png)
Region polygons can be nested abitrarily deep, in multiple discontiguous shapes:
```openscad
include <BOSL2/std.scad>
rgn = [
for (d=[50:-10:10]) left(30, p=circle(d=d)),
for (d=[50:-10:10]) right(30, p=circle(d=d))
];
region(rgn);
```
![Figure 54](images/tutorials/Paths_54.png)
A region with crossing polygons is somewhat poorly formed, but the intersection(s) of the polygons become holes:
```openscad
include <BOSL2/std.scad>
rgn = [
left(15, p=circle(d=50)),
right(15, p=circle(d=50))
];
region(rgn);
```
![Figure 55](images/tutorials/Paths_55.png)
### Boolean Region Geometry
Similarly to how OpenSCAD can perform operations like union/difference/intersection/offset on shape geometry,
the BOSL2 library lets you perform those same operations on regions:
```openscad
include <BOSL2/std.scad>
rgn1 = [for (d=[40:-10:10]) circle(d=d)];
rgn2 = [square([60,12], center=true)];
rgn = union(rgn1, rgn2);
region(rgn);
```
![Figure 56](images/tutorials/Paths_56.png)
```openscad
include <BOSL2/std.scad>
rgn1 = [for (d=[40:-10:10]) circle(d=d)];
rgn2 = [square([60,12], center=true)];
rgn = difference(rgn1, rgn2);
region(rgn);
```
![Figure 57](images/tutorials/Paths_57.png)
```openscad
include <BOSL2/std.scad>
rgn1 = [for (d=[40:-10:10]) circle(d=d)];
rgn2 = [square([60,12], center=true)];
rgn = intersection(rgn1, rgn2);
region(rgn);
```
![Figure 58](images/tutorials/Paths_58.png)
```openscad
include <BOSL2/std.scad>
rgn1 = [for (d=[40:-10:10]) circle(d=d)];
rgn2 = [square([60,12], center=true)];
rgn = exclusive_or(rgn1, rgn2);
region(rgn);
```
![Figure 59](images/tutorials/Paths_59.png)
```openscad
include <BOSL2/std.scad>
orig_rgn = [star(n=5, step=2, d=50)];
rgn = offset(orig_rgn, r=-3, closed=true);
color("blue") region(orig_rgn);
region(rgn);
```
![Figure 60](images/tutorials/Paths_60.png)
You can use regions for several useful things. If you wanted a grid of holes in your object that
form the shape given by a region, you can do that with `grid_copies()`:
```openscad
include <BOSL2/std.scad>
rgn = [
circle(d=100),
star(n=5,step=2,d=100,spin=90)
];
difference() {
cyl(h=5, d=120);
grid_copies(size=[120,120], spacing=[4,4], inside=rgn) cyl(h=10,d=2);
}
```
![Figure 61](images/tutorials/Paths_61.png)
You can also sweep a region through 3-space to make a solid:
```openscad
include <BOSL2/std.scad>
$fa=1; $fs=1;
rgn = [ for (d=[50:-10:10]) circle(d=d) ];
tforms = [
for (a=[90:-5:0]) xrot(a, cp=[0,-70]),
for (a=[0:5:90]) xrot(a, cp=[0,70]),
move([0,150,-70]) * xrot(90),
];
sweep(rgn, tforms, closed=false, caps=true);
```
![Figure 62](images/tutorials/Paths_62.png)

@ -0,0 +1,492 @@
# Rounding the Cube
One of the shape primitives you'll use most often in your OpenSCAD designs is the cube. Rounding the edges of cube-like objects impacts both the visual appeal and functional aspects of the final design. The BOSL2 library provides a variety of methods for rounding edges and corners.
There are four different 3d shape primitives that you can use to make cube-like objects:
* [**cuboid()**](https://github.com/BelfrySCAD/BOSL2/wiki/shapes3d.scad#module-cuboid) - Creates a cube with chamfering and roundovers.
* [**cube()**](https://github.com/BelfrySCAD/BOSL2/wiki/shapes3d.scad#functionmodule-cube) - An extended version of OpenSCAD's [cube()](https://en.wikibooks.org/wiki/OpenSCAD_User_Manual/Primitive_Solids#cube) with anchors for attaching children. (See the [Attachments Tutorial](https://github.com/BelfrySCAD/BOSL2/wiki/Tutorial-Attachments)).
* [**prismoid()**](https://github.com/BelfrySCAD/BOSL2/wiki/shapes3d.scad#functionmodule-prismoid) - Creates a rectangular prismoid shape with optional roundovers and chamfering.
* [**rounded_prism()**](https://github.com/BelfrySCAD/BOSL2/wiki/rounding.scad#functionmodule-rounded_prism) - Makes a rounded 3d object by connecting two polygons with the same vertex count. Rounded_prism supports continuous curvature rounding. (See [Types of Roundovers](https://github.com/BelfrySCAD/BOSL2/wiki/rounding.scad#section-types-of-roundovers)).
BOSL2 provides two different methods for rounding the edges of these cube-like primitives.
* **Built-in Rounding** - The [cuboid()](https://github.com/BelfrySCAD/BOSL2/wiki/shapes3d.scad#module-cuboid), [prismoid()](https://github.com/BelfrySCAD/BOSL2/wiki/shapes3d.scad#functionmodule-prismoid), and [rounded_prism()](https://github.com/BelfrySCAD/BOSL2/wiki/rounding.scad#functionmodule-rounded_prism) all have built-in arguments for rounding some or all of their edges.
* **Masking** - BOSL2 includes a number of options for masking the edges and corners of objects. Masking can accomplish rounding tasks that are not possible with the built-in rounding arguments. For example with masking you can have a cube with a different rounding radius on the top edges than the rounding radius on the bottom edges.
Cube-like objects have six named faces: **LEFT, RIGHT, TOP, BOT, FWD, BACK**.
![](https://github.com/BelfrySCAD/BOSL2/wiki/images/attachments/subsection-specifying-edges_fig2.png)
Each of those face names is a vector pointing to the face. e.g. UP is [0,0,1], and FWD is [0,-1,0]. By adding two of those vectors we can specify an edge. For example, TOP + RIGHT is the same as [0,0,1] + [0,1,0] = [0,1,1].
![](https://github.com/BelfrySCAD/BOSL2/wiki/images/attachments/subsection-specifying-edges_fig1.png)
See [Specifying Edges](https://github.com/BelfrySCAD/BOSL2/wiki/attachments.scad#subsection-specifying-edges) for more details.
## Cuboid Rounding
You can round the edges of a [cuboid()](https://github.com/BelfrySCAD/BOSL2/wiki/shapes3d.scad#module-cuboid) with the `rounding` argument by specifying the radius of curvature:
```openscad
include <BOSL2/std.scad>
cuboid(100, rounding=20);
```
![Figure 1](images/tutorials/Rounding_the_Cube_1.png)
We can round the edges aligned with one of the axes, X, Y, or Z:
```openscad
include <BOSL2/std.scad>
cuboid([100,80,60], rounding=20, edges = "Z");
```
![Figure 2](images/tutorials/Rounding_the_Cube_2.png)
You can round all the edges on one of the faces. Here we're rounding only the top edges:
```openscad
include <BOSL2/std.scad>
cuboid([100,80,60], rounding=20, edges = TOP);
```
![Figure 3](images/tutorials/Rounding_the_Cube_3.png)
...or just the bottom edges. Here we're using the `teardrop` argument to limit the overhang angle to enable 3d printing on FDM printers without requiring supports:
```openscad
include <BOSL2/std.scad>
cuboid([100,80,60], rounding=20, teardrop = 45, edges = BOTTOM);
```
![Figure 4](images/tutorials/Rounding_the_Cube_4.png)
It is possible to round one or more of the edges while leaving others unrounded:
```openscad
include <BOSL2/std.scad>
cuboid([100,80,60], rounding=20, edges = TOP+FRONT);
```
![Figure 5](images/tutorials/Rounding_the_Cube_5.png)
...or exclude the rounding of one or more edges while rounding all the others:
```openscad
include <BOSL2/std.scad>
cuboid([100,80,60], rounding=20, except = TOP+FRONT);
```
![Figure 6](images/tutorials/Rounding_the_Cube_6.png)
Multiple edges can be specified in the form of a list:
```openscad
include <BOSL2/std.scad>
cuboid([100,80,60], rounding=20, edges=[FWD,TOP], except=[TOP+LEFT,FWD+RIGHT]);
```
![Figure 7](images/tutorials/Rounding_the_Cube_7.png)
You can also specify which edges to round using a 3x4 array, where each entry corresponds to one of the 12 edges and is set to 1 if that edge is included and 0 if the edge is not. The edge ordering is:
[
[Y-Z-, Y+Z-, Y-Z+, Y+Z+],
[X-Z-, X+Z-, X-Z+, X+Z+],
[X-Y-, X+Y-, X-Y+, X+Y+]
]
```openscad
include <BOSL2/std.scad>
cuboid([100,80,60], rounding=20, edges = [[1,0,1,0],[0,1,0,1],[1,0,0,1]]);
```
![Figure 8](images/tutorials/Rounding_the_Cube_8.png)
Similarly, you can use an array to exclude selected edges from rounding:
```openscad
include <BOSL2/std.scad>
cuboid([100,80,60], rounding=20, except = [[1,0,1,0],[0,1,0,1],[1,0,0,1]]);
```
![Figure 9](images/tutorials/Rounding_the_Cube_9.png)
### Negative Rounding
You can fillet top or bottom edges by using negative rounding values. Note that you cannot use negative rounding values on Z-aligned (side) edges. If you need to add a fillet on a Z-aligned edge, use [fillet()](https://github.com/BelfrySCAD/BOSL2/wiki/shapes3d.scad#module-fillet):
```openscad
include <BOSL2/std.scad>
cuboid([100,80,60], rounding=-20, edges = BOTTOM);
```
![Figure 10](images/tutorials/Rounding_the_Cube_10.png)
### Chamfering
Chamfering the edges of the cuboid() can be done in a manner similar to rounding:
```openscad
include <BOSL2/std.scad>
cuboid([100,80,60], chamfer=20);
```
![Figure 11](images/tutorials/Rounding_the_Cube_11.png)
You can specify edges as with rounding:
```openscad
include <BOSL2/std.scad>
cuboid([100,80,60], chamfer=20, edges = "Z", except = FWD+RIGHT);
```
![Figure 12](images/tutorials/Rounding_the_Cube_12.png)
## Prismoid Rounding
The [prismoid()](https://github.com/BelfrySCAD/BOSL2/wiki/shapes3d.scad#functionmodule-prismoid) differs from the cuboid and cube in that you can only round or chamfer the vertical(ish) edges using the built-in parameters. For those edges, you can specify rounding and/or chamfering for top and bottom separately:
```openscad
include <BOSL2/std.scad>
prismoid(size1=[35,50], size2=[20,30], h=20, rounding1 = 8, rounding2 = 1);
```
![Figure 13](images/tutorials/Rounding_the_Cube_13.png)
You can also specify rounding of the individual vertical(ish) edges on an edge by edge basis by listing the edges in counter-clockwise order starting with the BACK+RIGHT (X+Y+) edge:
```openscad
include <BOSL2/std.scad>
prismoid(100, 80, rounding1=[0,50,0,50], rounding2=[40,0,40,0], h=50);
```
![Figure 14](images/tutorials/Rounding_the_Cube_14.png)
## Masking Edges of the Cuboid, Cube and Prismoid
### 2D Edge Masking with [edge_profile()](https://github.com/BelfrySCAD/BOSL2/wiki/attachments.scad#module-edge_profile) and [edge_profile_asym()](https://github.com/BelfrySCAD/BOSL2/wiki/attachments.scad#module-edge_profile_asym)
One limitation of using rounding arguments in [cuboid()](https://github.com/BelfrySCAD/BOSL2/wiki/shapes3d.scad#module-cuboid) is that all the rounded edges must have the same rounding radius. Using masking we have the flexibility to apply different edge treatments to the same cube. Masking can also be used on the [cube()](https://github.com/BelfrySCAD/BOSL2/wiki/shapes3d.scad#functionmodule-cube) and [prismoid()](https://github.com/BelfrySCAD/BOSL2/wiki/shapes3d.scad#functionmodule-prismoid) shapes.
2D edge masks are attached to edges using [edge_profile()](https://github.com/BelfrySCAD/BOSL2/wiki/attachments.scad#module-edge_profile). They have a default tag of "remove" to enable differencing them away from your cube using [diff()](https://github.com/BelfrySCAD/BOSL2/wiki/attachments.scad#module-diff).
We can use a negative rounding value to fillet the bottom of a cuboid and [edge_profile()](https://github.com/BelfrySCAD/BOSL2/wiki/attachments.scad#module-edge_profile) to round the top. Here [edge_profile()](https://github.com/BelfrySCAD/BOSL2/wiki/attachments.scad#module-edge_profile) applies a 2d roundover mask to the top edges of the cuboid.
```openscad
include <BOSL2/std.scad>
diff()
cuboid([50,60,70], rounding = -10, edges = BOT)
edge_profile(TOP)
mask2d_roundover(r=10);
```
![Figure 15](images/tutorials/Rounding_the_Cube_15.png)
We could also fillet the bottom of the cube using [edge_profile_asym()](https://github.com/BelfrySCAD/BOSL2/wiki/attachments.scad#module-edge_profile_asym) and [xflip()](https://github.com/BelfrySCAD/BOSL2/wiki/transforms.scad#functionmodule-xflip)
```openscad
include<BOSL2/std.scad>
cuboid(50)
edge_profile_asym(BOT, corner_type="round")
xflip() mask2d_roundover(10);
```
![Figure 16](images/tutorials/Rounding_the_Cube_16.png)
The flip argumet in [edge_profile_asym()](https://github.com/BelfrySCAD/BOSL2/wiki/attachments.scad#module-edge_profile_asym) determines whether the fillet flares out or up. The corner_type argument is used to shape the corners of external fillets.
```openscad
include<BOSL2/std.scad>
cuboid(50){
edge_profile_asym(TOP, flip = true)
xflip() mask2d_roundover(10);
edge_profile_asym(BOT, corner_type="round")
xflip() mask2d_roundover(10);
}
```
![Figure 17](images/tutorials/Rounding_the_Cube_17.png)
See [mask2d_roundover()](https://github.com/BelfrySCAD/BOSL2/wiki/masks2d.scad#functionmodule-mask2d_roundover) for additional mask parameters. Here we use the *inset* parameter to produce a bead.
```openscad
include <BOSL2/std.scad>
diff()
cube([50,60,70],center=true)
edge_profile(TOP, except=[BACK,TOP+LEFT])
mask2d_roundover(h=12, inset=4);
```
![Figure 18](images/tutorials/Rounding_the_Cube_18.png)
You can use [edge-profile()](https://github.com/BelfrySCAD/BOSL2/wiki/attachments.scad#module-edge_profile) to round the top or bottom of a [prismoid()](https://github.com/BelfrySCAD/BOSL2/wiki/shapes3d.scad#functionmodule-prismoid). Because the side faces of a [prismoid()](https://github.com/BelfrySCAD/BOSL2/wiki/shapes3d.scad#functionmodule-prismoid) are not strictly vertical, it's is necessary to increase the length of the masks using the *excess* parameter in [edge_profile()](https://github.com/BelfrySCAD/BOSL2/wiki/attachments.scad#module-edge_profile), and to set the mask\_angle to $edge\_angle in [mask2d\_roundover()](https://github.com/BelfrySCAD/BOSL2/wiki/masks2d.scad#functionmodule-mask2d_roundover).
```openscad
include<BOSL2/std.scad>
diff()
prismoid(size1=[35,50], size2=[30,30], h=20, rounding1 = 8, rounding2 = 0)
edge_profile([TOP+LEFT, TOP+RIGHT], excess = 5)
mask2d_roundover(r = 15, mask_angle = $edge_angle, $fn = 64);
```
![Figure 19](images/tutorials/Rounding_the_Cube_19.png)
Instead of specifying the rounding radius, you can specify the height of edge rounding.
```openscad
include<BOSL2/std.scad>
diff()
cube(30)
edge_profile([TOP+LEFT, TOP+RIGHT])
mask2d_roundover(h = 12, $fn = 64);
```
![Figure 20](images/tutorials/Rounding_the_Cube_20.png)
Rounding heights larger than an adjacent edge/2 will produce a ridge line on the top surface.
```openscad
include<BOSL2/std.scad>
diff()
cube(30)
edge_profile([TOP+LEFT, TOP+RIGHT])
mask2d_roundover(h = 20, $fn = 64);
```
![Figure 21](images/tutorials/Rounding_the_Cube_21.png)
The [mask2d_teardrop()](https://github.com/BelfrySCAD/BOSL2/wiki/masks2d.scad#functionmodule-mask2d_teardrop) mask can be used to round the bottom of a cube-like object. It limits the overhang angle to 45° or a value you specify in with the **angle** argument.
```
include<BOSL2/std.scad>
diff()
prismoid([30,20], [40,30], rounding = 2, h = 20, $fn = 64)
edge_profile(BOT, excess = 15)
mask2d_teardrop(h = 5, angle = 50, mask_angle = $edge_angle, $fn = 64);
```
![Figure 22](images/tutorials/Rounding_the_Cube_22.png)
In addition to the simple [roundover](https://github.com/BelfrySCAD/BOSL2/wiki/masks2d.scad#functionmodule-mask2d_roundover) mask, and the [teardrop](https://github.com/BelfrySCAD/BOSL2/wiki/masks2d.scad#functionmodule-mask2d_teardrop) mask, there are masks for [cove](https://github.com/BelfrySCAD/BOSL2/wiki/masks2d.scad#functionmodule-mask2d_cove), [chamfer](https://github.com/BelfrySCAD/BOSL2/wiki/masks2d.scad#functionmodule-mask2d_chamfer), [rabbet](https://github.com/BelfrySCAD/BOSL2/wiki/masks2d.scad#functionmodule-mask2d_rabbet), [dovetail](https://github.com/BelfrySCAD/BOSL2/wiki/masks2d.scad#functionmodule-mask2d_dovetail) and [ogee](https://github.com/BelfrySCAD/BOSL2/wiki/masks2d.scad#functionmodule-mask2d_ogee) edges.
The mask2d_ogee() only works on [cube()](https://github.com/BelfrySCAD/BOSL2/wiki/shapes3d.scad#functionmodule-cube) and [cuboid()](https://github.com/BelfrySCAD/BOSL2/wiki/shapes3d.scad#module-cuboid) shapes, or a [prismoid()](https://github.com/BelfrySCAD/BOSL2/wiki/shapes3d.scad#functionmodule-prismoid) where size2 >= size1 in both the X and Y dimensions.
```openscad
include <BOSL2/std.scad>
diff()
prismoid(size1 = [50,50],size2 = [80,80], rounding1 = 25, height = 80)
edge_profile(TOP)
mask2d_ogee([
"xstep",8, "ystep",5, // Starting shoulder.
"fillet",5, "round",5, // S-curve.
"ystep",3, "xstep",3 // Ending shoulder.
]);
```
![Figure 23](images/tutorials/Rounding_the_Cube_23.png)
Prismoids, espcecially prismoids with substantial shift, require careful selection of mask2d_roundover() arguments. Here we're setting radius = 5 and mask_angle = $edge_angle.
```
include<BOSL2/std.scad>
diff()
prismoid([30,20], [50,60], h=20, shift=[30,40])
edge_profile(TOP, excess=35)
mask2d_roundover(r=5, mask_angle=$edge_angle, $fn=128);
```
![Figure 24](images/tutorials/Rounding_the_Cube_24.png)
Specifying rounding height rather than rounding radius produces a different shape.
![Figure 25](images/tutorials/Rounding_the_Cube_25.png)
```
include<BOSL2/std.scad>
diff()
prismoid([30,20], [50,60], h=20, shift=[30,40])
edge_profile(TOP, excess=35)
mask2d_roundover(h=5, mask_angle=$edge_angle, $fn=128);
```
The quarter_round argument works well for edges with acute angles, but leaves a ledge on the edges with obtuse angles.
![Figure 26](images/tutorials/Rounding_the_Cube_26.png)
```
include<BOSL2/std.scad>
diff()
prismoid([30,20], [50,60], h=20, shift=[30,40])
edge_profile(TOP, excess=35)
mask2d_roundover(r=5, mask_angle=$edge_angle, quarter_round = true, $fn=128);
```
A work-around is to use quarter_round only on the edges with acute angles.
![Figure 27](images/tutorials/Rounding_the_Cube_27.png)
```
include<BOSL2/std.scad>
diff()
prismoid([30,20], [50,60], h=20, shift=[30,40])
edge_profile(TOP, excess=35)
mask2d_roundover(r=5, mask_angle=$edge_angle, quarter_round = $edge_angle<90, $fn=128);
```
### 3D Edge and Corner Masking
BOSL2 contains a number of 3d edge and corner masks in addition to the 2d edge profiles shown above.
The 3d edge masks have the advantage of being able to vary the rounding radius along the edge. 3d edge masks, such as[rounding_edge_mask()](https://github.com/BelfrySCAD/BOSL2/wiki/masks3d.scad#module-rounding_edge_mask), can be attached using [edge_mask()](https://github.com/BelfrySCAD/BOSL2/wiki/attachments.scad#module-edge_mask). The 3D edge masks have a default tag of "remove" to enable differencing them away from your cube using [diff()](https://github.com/BelfrySCAD/BOSL2/wiki/attachments.scad#module-diff).
```openscad
include <BOSL2/std.scad>
diff()
cuboid(80)
edge_mask(TOP+FWD)
rounding_edge_mask(r1 = 40, r2 = 0, l = 80);
```
![Figure 28](images/tutorials/Rounding_the_Cube_28.png)
While you can specify the length of the mask with the l or h argument, [edge_mask()](https://github.com/BelfrySCAD/BOSL2/wiki/attachments.scad#module-edge_mask) sets a special variable, `$parent_size`, to the size of the parent object. In the case where the parent is not a perfect cube, you need to mask each edge individually:
```openscad
include <BOSL2/std.scad>
diff()
cuboid([60,80,40]) {
edge_mask(TOP+FWD)
rounding_edge_mask(r = 10, l = $parent_size.x + 0.1);
edge_mask(TOP+RIGHT)
rounding_edge_mask(r = 10, l = $parent_size.y + 0.1);
edge_mask(RIGHT+FWD)
rounding_edge_mask(r = 10, l = $parent_size.z + 0.1);
}
```
![Figure 29](images/tutorials/Rounding_the_Cube_29.png)
As you can see above, using only [rounding\_edge_mask()](https://github.com/BelfrySCAD/BOSL2/wiki/masks3d.scad#module-rounding_edge_mask) to round the top of the cube leaves the corners unrounded. Use [corner_mask()](https://github.com/BelfrySCAD/BOSL2/wiki/attachments.scad#module-corner_mask) and [rounding\_corner_mask()](https://github.com/BelfrySCAD/BOSL2/wiki/masks3d.scad#module-rounding_corner_mask) for a smoother corner.
```openscad
include <BOSL2/std.scad>
diff()
cuboid([60,80,40]) {
edge_mask(TOP+FWD)
rounding_edge_mask(r = 10, l = $parent_size.x + 0.1);
edge_mask(TOP+RIGHT)
rounding_edge_mask(r = 10, l = $parent_size.y + 0.1);
edge_mask(RIGHT+FWD)
rounding_edge_mask(r = 10, l = $parent_size.z + 0.1);
corner_mask(TOP+RIGHT+FWD)
rounding_corner_mask(r = 10);
}
```
![Figure 30](images/tutorials/Rounding_the_Cube_30.png)
As with the built-in rounding arguments, you can use [edge\_mask()](https://github.com/BelfrySCAD/BOSL2/wiki/attachments.scad#module-edge_mask) and [corner\_mask()](https://github.com/BelfrySCAD/BOSL2/wiki/attachments.scad#module-corner_mask) to apply teardrop roundings using [teardrop\_edge_mask()](https://github.com/BelfrySCAD/BOSL2/wiki/masks3d.scad#module-teardrop_edge_mask) and [teardrop\_corner_mask()](https://github.com/BelfrySCAD/BOSL2/wiki/masks3d.scad#module-teardrop_corner_mask) to limit the overhang angle for better printing on FDM printers. Note that the vertical mask on the RIGHT_FWD edge is a [rounding\_edge\_mask()](https://github.com/BelfrySCAD/BOSL2/wiki/masks3d.scad#module-rounding_edge_mask).
```openscad
include <BOSL2/std.scad>
diff()
cuboid([60,80,40]) {
edge_mask(BOT+FWD)
teardrop_edge_mask(r = 10, l = $parent_size.x + 0.1, angle = 40);
edge_mask(BOT+RIGHT)
teardrop_edge_mask(r = 10, l = $parent_size.y + 0.1, angle = 40);
edge_mask(RIGHT+FWD)
rounding_edge_mask(r = 10, l = $parent_size.z + 0.1);
corner_mask(BOT+RIGHT+FWD)
teardrop_corner_mask(r = 10, angle = 40);
}
```
![Figure 31](images/tutorials/Rounding_the_Cube_31.png)
## Rounded Prism
You can construct cube-like objects, as well as a variety of other prisms using [rounded_prism()](https://github.com/BelfrySCAD/BOSL2/wiki/rounding.scad#functionmodule-rounded_prism). In this tutorial we're concentrating on rounding cubes, but [rounded_prism()](https://github.com/BelfrySCAD/BOSL2/wiki/rounding.scad#functionmodule-rounded_prism) has capabilities that extend well beyond cube-like objects. See the [rounded_prism()](https://github.com/BelfrySCAD/BOSL2/wiki/rounding.scad#functionmodule-rounded_prism) examples to learn more.
A feature unique to [rounded_prism()](https://github.com/BelfrySCAD/BOSL2/wiki/rounding.scad#functionmodule-rounded_prism) is that it uses continuous curvature rounding. Rather than using constant radius arcs, continuous curvature rounding uses 4th-order Bezier curves. For complete details on how this works see [Types of Roundovers](https://github.com/BelfrySCAD/BOSL2/wiki/rounding.scad#section-types-of-roundovers).
Two parameters control the roundover, k and joint. The joint parameter is the distance from where the rounding starts to the unrounded edge. The k parameter ranges from 0 to 1 with a default of 0.5. Larger values give a more abrupt transition and smaller ones a more gradual transition.
A smooth roundover with a joint length of 18 and the value of k set to 0.75.
![](https://github.com/BelfrySCAD/BOSL2/wiki/images/rounding/figure_1_3.png)
A smooth roundover, with the value of k set to 0.15. The transition is so gradual that it appears that the roundover is much smaller than specified. The cut length is much smaller for the same joint length.
![](https://github.com/BelfrySCAD/BOSL2/wiki/images/rounding/figure_1_4.png)
The joint parameter is specified separately for the top, bottom and side edges; joint\_top, joint\_bot, and joint_sides.
If you want a very smooth roundover, set the joint parameter as large as possible and then adjust the k value down low enough to achieve a sufficiently large roundover. Joint parameters usually need to be < side/2.
```openscad
include <BOSL2/std.scad>
include <BOSL2/rounding.scad>
rounded_prism(rect(20), height=20,
joint_top=9.99, joint_bot=9.99, joint_sides=9.99, k = 0.5);
```
![Figure 32](images/tutorials/Rounding_the_Cube_32.png)
Here we're using the same cube size and joint sizes, but varying the k parameter.
![Figure 33](images/tutorials/Rounding_the_Cube_33.png)
Alternatively, we can keep k constant at k=0.5 and vary the joint length:
![Figure 34](images/tutorials/Rounding_the_Cube_34.png)
You can match the cicrular roundover of cuboid() by setting the joint values to the rounding used in cuboid() and setting the k value to 0.93:
```openscad
include <BOSL2/std.scad>
include <BOSL2/rounding.scad>
left(15)
rounded_prism(rect(20), height=20, joint_top=4, joint_bot=4, joint_sides=4, k = 0.93);
right(15)
cuboid(20, rounding = 4, $fn = 72);
```
![Figure 35](images/tutorials/Rounding_the_Cube_35.png)
Unlike other cube-like objects, the rounded prism smoothness is not affected by the special variable $fn, but by the splinesteps argument. Splinesteps defaults to 16.
![Figure 36](images/tutorials/Rounding_the_Cube_36.png)
The joint size can be set to different values for each side of the prism:
```openscad
include <BOSL2/std.scad>
include <BOSL2/rounding.scad>
rounded_prism(rect(20), height=20,
joint_top=4, joint_bot=3, joint_sides=[2, 10, 5, 10], k = 0.5);
```
![Figure 37](images/tutorials/Rounding_the_Cube_37.png)
Likewise, k can be set to different values for each side of the prism:
```openscad
include <BOSL2/std.scad>
include <BOSL2/rounding.scad>
rounded_prism(rect(20), height=20,
joint_top=3, joint_bot=3, joint_sides=8,
k_top=0.5, k_bot=0.1, k_sides=[0,0.7,0.3,0.7]);
```
![Figure 38](images/tutorials/Rounding_the_Cube_38.png)
You can specify a 2-vector for the joint distance to produce asymmetric rounding which is different on the two sides of the edge. This may be useful when one one edge in your polygon is much larger than another.
```openscad
include <BOSL2/std.scad>
include <BOSL2/rounding.scad>
rounded_prism(rect([50.1,20.1]), height=6.1,
joint_top=[15,3], joint_bot=[15,3],
joint_sides=[[10,25],[25,10],[10,25],[25,10]],
k_sides=0.3);
```
![Figure 39](images/tutorials/Rounding_the_Cube_39.png)
For the top and bottom you can specify negative joint distances. If you give a scalar negative value then the roundover will flare outward.
```openscad
include <BOSL2/std.scad>
include <BOSL2/rounding.scad>
rounded_prism(rect(20), height=20,
joint_top=5, joint_bot=-5, joint_sides=8, k=0.5);
```
![Figure 40](images/tutorials/Rounding_the_Cube_40.png)
If you give a 2-vector then if joint\_top[0] is negative the shape will flare outward, but if joint\_top[1] is negative the shape will flare upward. At least one value must be non-negative. The same rules apply for joint\_bot. The joint\_sides parameter must be entirely nonnegative.
Flaring the top upward. The bottom has an asymmetric rounding with a small flare but a large rounding up the side.
```openscad
include <BOSL2/std.scad>
include <BOSL2/rounding.scad>
rounded_prism(rect(20), height=20,
joint_top=[3,-3], joint_bot=[-3,10], joint_sides=8, k=0.5);
```
![Figure 41](images/tutorials/Rounding_the_Cube_41.png)

925
Tutorial-Shapes2d.md Normal file

@ -0,0 +1,925 @@
# 2D Shapes Tutorial
<!-- TOC -->
## Primitives
There are two built-in 2D primitive shapes that OpenSCAD provides: `square()`, and `circle()`.
You can still use them in the familiar ways that OpenSCAD provides:
```openscad
include <BOSL2/std.scad>
square([60,40], center=true);
```
![Figure 1](images/tutorials/Shapes2d_1.png)
```openscad
include <BOSL2/std.scad>
circle(r=50);
```
![Figure 2](images/tutorials/Shapes2d_2.png)
```openscad
include <BOSL2/std.scad>
circle(d=100, $fn=8);
```
![Figure 3](images/tutorials/Shapes2d_3.png)
These modules have also been enhanced in the BOSL2 library in three ways: Anchoring, spin, and
attachability.
#### Anchoring:
When you create a `square()`, you can specify what corner or side will be anchored at the
origin. This is used in place of the `center=` argument, and is more flexible. The `anchor=`
argument takes a vector as a value, pointing roughly towards the side or corner you
want to align to the origin. For example, to align the center of the back edge to the
origin, set the anchor to `[0,1]`:
```openscad
include <BOSL2/std.scad>
square([60,40], anchor=[0,1]);
```
![Figure 4](images/tutorials/Shapes2d_4.png)
To align the front right corner to the origin:
```openscad
include <BOSL2/std.scad>
square([60,40], anchor=[1,-1]);
```
![Figure 5](images/tutorials/Shapes2d_5.png)
To center:
```openscad
include <BOSL2/std.scad>
square([60,40], anchor=[0,0]);
```
![Figure 6](images/tutorials/Shapes2d_6.png)
To make it clearer when giving vectors, there are several standard vector constants defined:
Constant | Direction | Value
-------- | --------- | -----------
`LEFT` | X- | `[-1, 0, 0]`
`RIGHT` | X+ | `[ 1, 0, 0]`
`FRONT`/`FORWARD`/`FWD` | Y- | `[ 0,-1, 0]`
`BACK` | Y+ | `[ 0, 1, 0]`
`BOTTOM`/`BOT`/`BTM`/`DOWN` | Z- | `[ 0, 0,-1]` (3D only.)
`TOP`/`UP` | Z+ | `[ 0, 0, 1]` (3D only.)
`CENTER`/`CTR` | Centered | `[ 0, 0, 0]`
Note that even though these are 3D vectors, you can use most of them,
(except `UP`/`DOWN`, of course) for anchors in 2D shapes:
```openscad
include <BOSL2/std.scad>
square([60,40], anchor=BACK);
```
![Figure 7](images/tutorials/Shapes2d_7.png)
```openscad
include <BOSL2/std.scad>
square([60,40], anchor=CENTER);
```
![Figure 8](images/tutorials/Shapes2d_8.png)
You can add vectors together to point to corners:
```openscad
include <BOSL2/std.scad>
square([60,40], anchor=FRONT+RIGHT);
```
![Figure 9](images/tutorials/Shapes2d_9.png)
For `circle()`, the anchor vector can point at any part of the circle perimeter:
```openscad
include <BOSL2/std.scad>
circle(d=50, anchor=polar_to_xy(1,150));
```
![Figure 10](images/tutorials/Shapes2d_10.png)
Note that the radius does not matter for the anchor because only the
anchor's direction affects the result. You can see the typical anchor
points by giving `show_anchors()` as a child of the shape:
```openscad
include <BOSL2/std.scad>
square([60,40], center=true)
show_anchors();
```
![Figure 11](images/tutorials/Shapes2d_11.png)
```openscad
include <BOSL2/std.scad>
circle(d=50)
show_anchors();
```
![Figure 12](images/tutorials/Shapes2d_12.png)
#### Spin:
The second way that `square()` and `circle()` have been enhanced is with spin. When you create
the shape, you can spin it in place with the `spin=` argument. You just pass it a number of
degrees to rotate clockwise:
```openscad
include <BOSL2/std.scad>
square([60,40], anchor=CENTER, spin=30);
```
![Figure 13](images/tutorials/Shapes2d_13.png)
Anchoring or centering is performed before the spin:
```openscad
include <BOSL2/std.scad>
square([60,40], anchor=BACK, spin=30);
```
![Figure 14](images/tutorials/Shapes2d_14.png)
For circles, spin can be useful when `$fn=` is also given:
```openscad
include <BOSL2/std.scad>
circle(d=50, $fn=6, spin=15);
```
![Figure 15](images/tutorials/Shapes2d_15.png)
Since anchoring is performed before spin, you can use them together to spin around the anchor:
```openscad
include <BOSL2/std.scad>
circle(d=50, $fn=6, anchor=LEFT, spin=15);
```
![Figure 16](images/tutorials/Shapes2d_16.png)
#### Attachability:
The third way `square()` and `circle()` have been enhanced is that you can attach them together
at anchoring points in various ways. This is done by making one shape a child of the shape
you want to attach to. By default, just making one shape a child of the other will position
the child shape at the center of the parent shape.
```openscad
include <BOSL2/std.scad>
square(50, center=true)
#square(50, spin=45, center=true);
```
![Figure 17](images/tutorials/Shapes2d_17.png)
```openscad
include <BOSL2/std.scad>
square(50, center=true)
#square([20,40], anchor=FWD);
```
![Figure 18](images/tutorials/Shapes2d_18.png)
By adding the `position()` module, you can position the child at any anchorpoint on the parent:
```openscad
include <BOSL2/std.scad>
square(50, center=true)
position(BACK)
#square(25, spin=45, center=true);
```
![Figure 19](images/tutorials/Shapes2d_19.png)
```openscad
include <BOSL2/std.scad>
square(50, center=true)
position(FWD+RIGHT)
#square(25, spin=45, center=true);
```
![Figure 20](images/tutorials/Shapes2d_20.png)
```openscad
include <BOSL2/std.scad>
circle(d=50)
position(polar_to_xy(1,60))
#circle(d=10);
```
![Figure 21](images/tutorials/Shapes2d_21.png)
Anchorpoints aren't just positions on the parent, though. They also have an orientation. In most
cases, the orientation of an anchorpoint is outward away from the face of the wall, generally away
from the center of the shape. You can see this with the `show_anchors()` module:
```openscad
include <BOSL2/std.scad>
square(50, center=true)
show_anchors();
```
![Figure 22](images/tutorials/Shapes2d_22.png)
```openscad
include <BOSL2/std.scad>
circle(d=50)
show_anchors();
```
![Figure 23](images/tutorials/Shapes2d_23.png)
If you want to orient the child to match the orientation of an anchorpoint, you can use the `orient()`
module. It does not position the child. It only rotates it:
```openscad
include <BOSL2/std.scad>
square(50, center=true)
orient(anchor=LEFT)
#square([10,40], anchor=FWD);
```
![Figure 24](images/tutorials/Shapes2d_24.png)
```openscad
include <BOSL2/std.scad>
square(50, center=true)
orient(anchor=FWD)
#square([10,40], anchor=FWD);
```
![Figure 25](images/tutorials/Shapes2d_25.png)
```openscad
include <BOSL2/std.scad>
square(50, center=true)
orient(anchor=RIGHT)
#square([10,40], anchor=FWD);
```
![Figure 26](images/tutorials/Shapes2d_26.png)
```openscad
include <BOSL2/std.scad>
circle(d=50)
orient(polar_to_xy(1,30))
#square([10,40], anchor=FWD);
```
![Figure 27](images/tutorials/Shapes2d_27.png)
You can use `position()` and `orient()` together to both position and orient to an anchorpoint:
```openscad
include <BOSL2/std.scad>
square(50, center=true)
position(RIGHT+BACK)
orient(anchor=RIGHT+BACK)
#square([10,40], anchor=FWD);
```
![Figure 28](images/tutorials/Shapes2d_28.png)
```openscad
include <BOSL2/std.scad>
circle(d=50)
position(polar_to_xy(1,30))
orient(polar_to_xy(1,30))
#square([10,40], anchor=FWD);
```
![Figure 29](images/tutorials/Shapes2d_29.png)
But it's simpler to just use the `attach()` module to do both at once:
```openscad
include <BOSL2/std.scad>
square(50, center=true)
attach(LEFT+BACK)
#square([10,40], anchor=FWD);
```
![Figure 30](images/tutorials/Shapes2d_30.png)
```openscad
include <BOSL2/std.scad>
circle(d=50)
attach(polar_to_xy(1,30))
#square([10,40], center=true);
```
![Figure 31](images/tutorials/Shapes2d_31.png)
Instead of specifying the `anchor=` in the child, you can pass a second argument to `attach()`
that tells it which side of the child to attach to the parent:
```openscad
include <BOSL2/std.scad>
square([10,50], center=true)
attach(BACK, LEFT)
#square([10,40], center=true);
```
![Figure 32](images/tutorials/Shapes2d_32.png)
```openscad
include <BOSL2/std.scad>
circle(d=50)
attach(polar_to_xy(1,30), LEFT)
#square([10,40], center=true);
```
![Figure 33](images/tutorials/Shapes2d_33.png)
#### Rectangles
The BOSL2 library provides an alternative to `square()`, that support more features. It is
called `rect()`. You can use it in the same way you use `square()`, but it also provides
extended functionality. For example, it allows you to round the corners:
```openscad
include <BOSL2/std.scad>
rect([60,40], rounding=10);
```
![Figure 34](images/tutorials/Shapes2d_34.png)
Or chamfer them:
```openscad
include <BOSL2/std.scad>
rect([60,40], chamfer=10);
```
![Figure 35](images/tutorials/Shapes2d_35.png)
You can even specify *which* corners get rounded or chamfered. If you pass a
list of four size numbers to the `rounding=` or `chamfer=` arguments, it will
give each corner its own size. In order, it goes from the back-right (quadrant I)
corner, counter-clockwise around to the back-left (quadrant II) corner, to the
forward-left (quadrant III) corner, to the forward-right (quadrant IV) corner:
![Figure 36](images/tutorials/Shapes2d_36.png)
If a size is given as `0`, then there is no rounding and/or chamfering for
that quadrant's corner:
```openscad
include <BOSL2/std.scad>
rect([60,40], rounding=[0,5,10,15]);
```
![Figure 37](images/tutorials/Shapes2d_37.png)
```openscad
include <BOSL2/std.scad>
rect([60,40], chamfer=[0,5,10,15]);
```
![Figure 38](images/tutorials/Shapes2d_38.png)
You can give both `rounding=` and `chamfer=` arguments to mix rounding and
chamfering, but only if you specify per corner. If you want a rounding in
a corner, specify a 0 chamfer for that corner, and vice versa:
```openscad
include <BOSL2/std.scad>
rect([60,40], rounding=[5,0,10,0], chamfer=[0,5,0,15]);
```
![Figure 39](images/tutorials/Shapes2d_39.png)
#### Ellipses
The BOSL2 library also provides an enhanced equivalent of `circle()` called `ellipse()`.
You can use it in the same way you use `circle()`, but it also provides extended
functionality. For example, it allows more control over its size.
Since a circle in OpenSCAD can only be approximated by a regular polygon with a number
of straight sides, this can lead to size and shape inaccuracies. To counter this, the
`realign=` and `circum=` arguments are also provided.
The `realign=` argument, if set `true`, rotates the `ellipse()` by half the angle
between the polygon sides:
```openscad
include <BOSL2/std.scad>
ellipse(d=100, $fn=8);
#ellipse(d=100, $fn=8, realign=true);
```
![Figure 40](images/tutorials/Shapes2d_40.png)
The `circum=` argument, if true, makes it so that the polygon forming the
`ellipse()` circumscribes the ideal circle instead of inscribing it.
Inscribing the ideal circle:
```openscad
include <BOSL2/std.scad>
color("green") ellipse(d=100, $fn=360);
ellipse(d=100, $fn=6);
```
![Figure 41](images/tutorials/Shapes2d_41.png)
Circumscribing the ideal circle:
```openscad
include <BOSL2/std.scad>
ellipse(d=100, $fn=6, circum=true);
color("green") ellipse(d=100, $fn=360);
```
![Figure 42](images/tutorials/Shapes2d_42.png)
The `ellipse()` module, as its name suggests, can be given separate X and Y radii
or diameters. To do this, just give `r=` or `d=` with a list of two radii or
diameters:
```openscad
include <BOSL2/std.scad>
ellipse(r=[30,20]);
```
![Figure 43](images/tutorials/Shapes2d_43.png)
```openscad
include <BOSL2/std.scad>
ellipse(d=[60,40]);
```
![Figure 44](images/tutorials/Shapes2d_44.png)
Like `circle()`, you can anchor, spin and attach `ellipse()` shapes:
```openscad
include <BOSL2/std.scad>
ellipse(d=50, anchor=BACK);
```
![Figure 45](images/tutorials/Shapes2d_45.png)
```openscad
include <BOSL2/std.scad>
ellipse(d=50, anchor=FRONT+RIGHT);
```
![Figure 46](images/tutorials/Shapes2d_46.png)
```openscad
include <BOSL2/std.scad>
ellipse(d=50)
attach(BACK+RIGHT, FRONT+LEFT)
ellipse(d=30);
```
![Figure 47](images/tutorials/Shapes2d_47.png)
#### Right Triangles
The BOSL2 library provides a simple way to make a 2D right triangle by using the `right_triangle()` module:
```openscad
include <BOSL2/std.scad>
right_triangle([40,30]);
```
![Figure 48](images/tutorials/Shapes2d_48.png)
You can use `xflip()` and `yflip()` to change which quadrant the triangle is formed in:
```openscad
include <BOSL2/std.scad>
xflip() right_triangle([40,30]);
```
![Figure 49](images/tutorials/Shapes2d_49.png)
```openscad
include <BOSL2/std.scad>
yflip() right_triangle([40,30]);
```
![Figure 50](images/tutorials/Shapes2d_50.png)
```openscad
include <BOSL2/std.scad>
xflip() yflip() right_triangle([40,30]);
```
![Figure 51](images/tutorials/Shapes2d_51.png)
Or, alternatively, just rotate it into the correct quadrant with `spin=`:
```openscad
include <BOSL2/std.scad>
right_triangle([40,30], spin=90);
```
![Figure 52](images/tutorials/Shapes2d_52.png)
```openscad
include <BOSL2/std.scad>
right_triangle([40,30], spin=-90);
```
![Figure 53](images/tutorials/Shapes2d_53.png)
You can also use anchoring with right triangles:
```openscad
include <BOSL2/std.scad>
right_triangle([40,30], anchor=FWD+RIGHT);
```
![Figure 54](images/tutorials/Shapes2d_54.png)
#### Trapezoids
OpenSCAD doesn't provide a simple way to make general 2D triangles, trapezoids, or parallelograms.
The BOSL2 library can provide all of these shapes with the `trapezoid()` module.
To make a simple triangle, just make one of the widths zero:
```openscad
include <BOSL2/std.scad>
trapezoid(w1=50, w2=0, h=40);
```
![Figure 55](images/tutorials/Shapes2d_55.png)
To make a right triangle, you need to use the `shift=` argument, to shift the back of the trapezoid along the X axis:
```openscad
include <BOSL2/std.scad>
trapezoid(w1=50, w2=0, h=50, shift=-25);
```
![Figure 56](images/tutorials/Shapes2d_56.png)
```openscad
include <BOSL2/std.scad>
trapezoid(w1=50, w2=0, h=50, shift=25);
```
![Figure 57](images/tutorials/Shapes2d_57.png)
```openscad
include <BOSL2/std.scad>
trapezoid(w1=0, w2=50, h=50, shift=-25);
```
![Figure 58](images/tutorials/Shapes2d_58.png)
```openscad
include <BOSL2/std.scad>
trapezoid(w1=0, w2=50, h=50, shift=25);
```
![Figure 59](images/tutorials/Shapes2d_59.png)
You can make a trapezoid by specifying non-zero widths for both the front (`w1=`) and back (`w2=`):
```openscad
include <BOSL2/std.scad>
trapezoid(w1=30, w2=50, h=50);
```
![Figure 60](images/tutorials/Shapes2d_60.png)
A parallelogram is just a matter of using the same width for front and back, with a shift along the X axis:
```openscad
include <BOSL2/std.scad>
trapezoid(w1=50, w2=50, shift=20, h=50);
```
![Figure 61](images/tutorials/Shapes2d_61.png)
A quadrilateral can be made by having unequal, non-zero front (`w1=`) and back (`w2=`) widths, with the back shifted along the X axis:
```openscad
include <BOSL2/std.scad>
trapezoid(w1=50, w2=30, shift=20, h=50);
```
![Figure 62](images/tutorials/Shapes2d_62.png)
You can use `anchor=` and `spin=`, just like with other attachable shapes. However, the anchor
point orientations are based on the side angles of the faces, and may not be what you expect:
```openscad
include <BOSL2/std.scad>
trapezoid(w1=30, w2=50, h=50)
show_anchors();
```
![Figure 63](images/tutorials/Shapes2d_63.png)
#### Regular N-Gons
OpenSCAD lets you make regular N-gons (pentagon, hexagon, etc) by using `circle()` with `$fn`.
While this is concise, it may be less than obvious at first glance:
```openscad
include <BOSL2/std.scad>
circle(d=50, $fn=5);
```
![Figure 64](images/tutorials/Shapes2d_64.png)
The BOSL2 library has modules that are named more clearly, for common N-gons:
```openscad
include <BOSL2/std.scad>
pentagon(d=50);
```
![Figure 65](images/tutorials/Shapes2d_65.png)
```openscad
include <BOSL2/std.scad>
hexagon(d=50);
```
![Figure 66](images/tutorials/Shapes2d_66.png)
```openscad
include <BOSL2/std.scad>
octagon(d=50);
```
![Figure 67](images/tutorials/Shapes2d_67.png)
```openscad
include <BOSL2/std.scad>
regular_ngon(n=7, d=50);
```
![Figure 68](images/tutorials/Shapes2d_68.png)
These modules also provide you with extra functionality. They can be sized by side length:
```openscad
include <BOSL2/std.scad>
pentagon(side=20);
```
![Figure 69](images/tutorials/Shapes2d_69.png)
They can be sized by circumscribed circle radius/diameter:
```openscad
include <BOSL2/std.scad>
pentagon(ir=25);
pentagon(id=50);
```
![Figure 70](images/tutorials/Shapes2d_70.png)
They can be rotated by half a side:
```openscad
include <BOSL2/std.scad>
left(30) pentagon(d=50, realign=true);
right(30) pentagon(d=50, realign=false);
```
![Figure 71](images/tutorials/Shapes2d_71.png)
They can be rounded:
```openscad
include <BOSL2/std.scad>
pentagon(d=50, rounding=10);
```
![Figure 72](images/tutorials/Shapes2d_72.png)
```openscad
include <BOSL2/std.scad>
hexagon(d=50, rounding=10);
```
![Figure 73](images/tutorials/Shapes2d_73.png)
They also have somewhat different attachment behavior. A circle with a small `$fn=` will
attach things at the ideal circle, not along the created polygon:
```openscad
include <BOSL2/std.scad>
color("green") stroke(circle(d=50), closed=true);
circle(d=50,$fn=6)
show_anchors();
```
![Figure 74](images/tutorials/Shapes2d_74.png)
While an N-gon will attach along the polygon itself:
```openscad
include <BOSL2/std.scad>
hexagon(d=50)
show_anchors(custom=false);
```
![Figure 75](images/tutorials/Shapes2d_75.png)
You can use `anchor=` and `spin=`, just like with other attachable shapes. However, the anchor
points are based on where the anchor vector would intersect the side of the N-gon, and may not
be where you expect them:
```openscad
include <BOSL2/std.scad>
pentagon(d=50)
show_anchors(custom=false);
```
![Figure 76](images/tutorials/Shapes2d_76.png)
N-gons also have named anchor points for their sides and tips:
```openscad
include <BOSL2/std.scad>
pentagon(d=30)
show_anchors(std=false);
```
![Figure 77](images/tutorials/Shapes2d_77.png)
#### Stars
The BOSL2 library has stars as a basic supported shape. They can have any number of points.
You can specify a star's shape by point count, inner and outer vertex radius/diameters:
```openscad
include <BOSL2/std.scad>
star(n=3, id=10, d=50);
```
![Figure 78](images/tutorials/Shapes2d_78.png)
```openscad
include <BOSL2/std.scad>
star(n=5, id=15, r=25);
```
![Figure 79](images/tutorials/Shapes2d_79.png)
```openscad
include <BOSL2/std.scad>
star(n=10, id=30, d=50);
```
![Figure 80](images/tutorials/Shapes2d_80.png)
Or you can specify the star shape by point count and number of points to step:
```openscad
include <BOSL2/std.scad>
star(n=7, step=2, d=50);
```
![Figure 81](images/tutorials/Shapes2d_81.png)
```openscad
include <BOSL2/std.scad>
star(n=7, step=3, d=50);
```
![Figure 82](images/tutorials/Shapes2d_82.png)
If the `realign=` argument is given a true value, then the star will be rotated by half a point angle:
```openscad
include <BOSL2/std.scad>
left(30) star(n=5, step=2, d=50);
right(30) star(n=5, step=2, d=50, realign=true);
```
![Figure 83](images/tutorials/Shapes2d_83.png)
The `align_tip=` argument can be given a vector so that you can align the first point in a specific direction:
```openscad
include <BOSL2/std.scad>
star(n=5, ir=15, or=30, align_tip=BACK)
attach("tip0") color("blue") anchor_arrow2d();
```
![Figure 84](images/tutorials/Shapes2d_84.png)
```openscad
include <BOSL2/std.scad>
star(n=5, ir=15, or=30, align_tip=BACK+RIGHT)
attach("tip0") color("blue") anchor_arrow2d();
```
![Figure 85](images/tutorials/Shapes2d_85.png)
Similarly, the first indentation or pit can be oriented towards a specific vector with `align_pit=`:
```openscad
include <BOSL2/std.scad>
star(n=5, ir=15, or=30, align_pit=BACK)
attach("pit0") color("blue") anchor_arrow2d();
```
![Figure 86](images/tutorials/Shapes2d_86.png)
```openscad
include <BOSL2/std.scad>
star(n=5, ir=15, or=30, align_pit=BACK+RIGHT)
attach("pit0") color("blue") anchor_arrow2d();
```
![Figure 87](images/tutorials/Shapes2d_87.png)
You can use `anchor=` and `spin=`, just like with other attachable shapes. However, the anchor
points are based on the furthest extents of the shape, and may not be where you expect them:
```openscad
include <BOSL2/std.scad>
star(n=5, step=2, d=50)
show_anchors(custom=false);
```
![Figure 88](images/tutorials/Shapes2d_88.png)
Stars also have named anchor points for their pits, tips, and midpoints between tips:
```openscad
include <BOSL2/std.scad>
star(n=5, step=2, d=40)
show_anchors(std=false);
```
![Figure 89](images/tutorials/Shapes2d_89.png)
#### Teardrop2D
Often when 3D printing, you may want to make a circular hole in a vertical wall. If the hole is
too big, however, the overhang at the top of the hole can cause problems with printing on an
FDM/FFF printer. If you don't want to use support material, you can just use the teardrop shape.
The `teardrop2d()` module will let you make a 2D version of the teardrop shape, so that you can
extrude it later:
```openscad
include <BOSL2/std.scad>
teardrop2d(r=20);
```
![Figure 90](images/tutorials/Shapes2d_90.png)
```openscad
include <BOSL2/std.scad>
teardrop2d(d=50);
```
![Figure 91](images/tutorials/Shapes2d_91.png)
The default overhang angle is 45 degrees, but you can adjust that with the `ang=` argument:
```openscad
include <BOSL2/std.scad>
teardrop2d(d=50, ang=30);
```
![Figure 92](images/tutorials/Shapes2d_92.png)
If you prefer to flatten the top of the teardrop, to encourage bridging, you can use the `cap_h=`
argument:
```openscad
include <BOSL2/std.scad>
teardrop2d(d=50, cap_h=25);
```
![Figure 93](images/tutorials/Shapes2d_93.png)
```openscad
include <BOSL2/std.scad>
teardrop2d(d=50, ang=30, cap_h=30);
```
![Figure 94](images/tutorials/Shapes2d_94.png)
You can use `anchor=` and `spin=`, just like with other attachable shapes. However, the anchor
points are based on the furthest extents of the shape, and may not be where you expect them:
```openscad
include <BOSL2/std.scad>
teardrop2d(d=50, ang=30, cap_h=30)
show_anchors();
```
![Figure 95](images/tutorials/Shapes2d_95.png)
#### Glued Circles
A more unusal shape that BOSL2 provides is Glued Circles. It's basically a pair of circles,
connected by what looks like a gloopy glued miniscus:
```openscad
include <BOSL2/std.scad>
glued_circles(d=30, spread=40);
```
![Figure 96](images/tutorials/Shapes2d_96.png)
The `r=`/`d=` arguments can specify the radius or diameter of the two circles:
```openscad
include <BOSL2/std.scad>
glued_circles(r=20, spread=45);
```
![Figure 97](images/tutorials/Shapes2d_97.png)
```openscad
include <BOSL2/std.scad>
glued_circles(d=40, spread=45);
```
![Figure 98](images/tutorials/Shapes2d_98.png)
The `spread=` argument specifies the distance between the centers of the two circles:
```openscad
include <BOSL2/std.scad>
glued_circles(d=30, spread=30);
```
![Figure 99](images/tutorials/Shapes2d_99.png)
```openscad
include <BOSL2/std.scad>
glued_circles(d=30, spread=40);
```
![Figure 100](images/tutorials/Shapes2d_100.png)
The `tangent=` argument gives the angle of the tangent of the meniscus on the two circles:
```openscad
include <BOSL2/std.scad>
glued_circles(d=30, spread=30, tangent=45);
```
![Figure 101](images/tutorials/Shapes2d_101.png)
```openscad
include <BOSL2/std.scad>
glued_circles(d=30, spread=30, tangent=20);
```
![Figure 102](images/tutorials/Shapes2d_102.png)
```openscad
include <BOSL2/std.scad>
glued_circles(d=30, spread=30, tangent=-20);
```
![Figure 103](images/tutorials/Shapes2d_103.png)
One useful thing you can do is to string a few `glued_circle()`s in a line then extrude them to make a ribbed wall:
```openscad
include <BOSL2/std.scad>
$fn=36; s=10;
linear_extrude(height=50,convexity=16,center=true)
xcopies(s*sqrt(2),n=3)
glued_circles(d=s, spread=s*sqrt(2), tangent=45);
```
![Figure 104](images/tutorials/Shapes2d_104.png)
You can use `anchor=` and `spin=`, just like with other attachable shapes. However, the anchor
points are based on the furthest extents of the shape, and may not be where you expect them:
```openscad
include <BOSL2/std.scad>
glued_circles(d=40, spread=40, tangent=45)
show_anchors();
```
![Figure 105](images/tutorials/Shapes2d_105.png)

453
Tutorial-Shapes3d.md Normal file

@ -0,0 +1,453 @@
# Basic Shapes Tutorial
<!-- TOC -->
## Primitives
There are 3 built-in 3D primitive shapes that OpenSCAD provides: `cube()`, `cylinder()`,
and `sphere()`. The BOSL2 library extends and provides alternative to these shapes so
that they support more features, and more ways to simply reorient them.
### 3D Cubes
BOSL2 overrides the built-in `cube()` module. It still can be used as you expect from the built-in:
```openscad
include <BOSL2/std.scad>
cube(100);
```
![Figure 1](images/tutorials/Shapes3d_1.png)
```openscad
include <BOSL2/std.scad>
cube(100, center=true);
```
![Figure 2](images/tutorials/Shapes3d_2.png)
```openscad
include <BOSL2/std.scad>
cube([50,40,20], center=true);
```
![Figure 3](images/tutorials/Shapes3d_3.png)
It is also enhanced to allow you to anchor, spin, orient, and attach it.
You can use `anchor=` similarly to how you use it with `rect()` or `oval()`,
except you can also anchor vertically in 3D, allowing anchoring to faces, edges,
and corners:
```openscad
include <BOSL2/std.scad>
cube([50,40,20], anchor=BOTTOM);
```
![Figure 4](images/tutorials/Shapes3d_4.png)
```openscad
include <BOSL2/std.scad>
cube([50,40,20], anchor=TOP+BACK);
```
![Figure 5](images/tutorials/Shapes3d_5.png)
```openscad
include <BOSL2/std.scad>
cube([50,40,20], anchor=TOP+FRONT+LEFT);
```
![Figure 6](images/tutorials/Shapes3d_6.png)
You can use `spin=` to rotate around the Z axis **after** anchoring:
```openscad
include <BOSL2/std.scad>
cube([50,40,20], anchor=FRONT, spin=30);
```
![Figure 7](images/tutorials/Shapes3d_7.png)
3D objects also can be given an `orient=` argument as a vector, pointing
to where the top of the shape should be rotated towards.
```openscad
include <BOSL2/std.scad>
cube([50,40,20], orient=UP+BACK+RIGHT);
```
![Figure 8](images/tutorials/Shapes3d_8.png)
If you use `anchor=`, `spin=`, and `orient=` together, the anchor is performed
first, then the spin, then the orient:
```openscad
include <BOSL2/std.scad>
cube([50,40,20], anchor=FRONT);
```
![Figure 9](images/tutorials/Shapes3d_9.png)
```openscad
include <BOSL2/std.scad>
cube([50,40,20], anchor=FRONT, spin=45);
```
![Figure 10](images/tutorials/Shapes3d_10.png)
```openscad
include <BOSL2/std.scad>
cube([50,40,20], anchor=FRONT, spin=45, orient=UP+FWD+RIGHT);
```
![Figure 11](images/tutorials/Shapes3d_11.png)
BOSL2 provides a `cuboid()` module that expands on `cube()`, by providing
rounding and chamfering of edges. You can use it similarly to `cube()`,
except that `cuboid()` centers by default.
You can round the edges with the `rounding=` argument:
```openscad
include <BOSL2/std.scad>
cuboid([100,80,60], rounding=20);
```
![Figure 12](images/tutorials/Shapes3d_12.png)
Similarly, you can chamfer the edges with the `chamfer=` argument:
```openscad
include <BOSL2/std.scad>
cuboid([100,80,60], chamfer=10);
```
![Figure 13](images/tutorials/Shapes3d_13.png)
You can round only some edges, by using the `edges=` arguments. It can be
given a few types of arguments. If you gave it a vector pointed at a face,
it will only round the edges surrounding that face:
```openscad
include <BOSL2/std.scad>
cuboid([100,80,60], rounding=20, edges=TOP);
```
![Figure 14](images/tutorials/Shapes3d_14.png)
```openscad
include <BOSL2/std.scad>
cuboid([100,80,60], rounding=20, edges=RIGHT);
```
![Figure 15](images/tutorials/Shapes3d_15.png)
If you give `edges=` a vector pointing at a corner, it will round all edges
that meet at that corner:
```openscad
include <BOSL2/std.scad>
cuboid([100,80,60], rounding=20, edges=RIGHT+FRONT+TOP);
```
![Figure 16](images/tutorials/Shapes3d_16.png)
```openscad
include <BOSL2/std.scad>
cuboid([100,80,60], rounding=20, edges=LEFT+FRONT+TOP);
```
![Figure 17](images/tutorials/Shapes3d_17.png)
If you give `edges=` a vector pointing at an edge, it will round only that edge:
```openscad
include <BOSL2/std.scad>
cuboid([100,80,60], rounding=10, edges=FRONT+TOP);
```
![Figure 18](images/tutorials/Shapes3d_18.png)
```openscad
include <BOSL2/std.scad>
cuboid([100,80,60], rounding=10, edges=RIGHT+FRONT);
```
![Figure 19](images/tutorials/Shapes3d_19.png)
If you give the string "X", "Y", or "Z", then all edges aligned with the specified
axis will be rounded:
```openscad
include <BOSL2/std.scad>
cuboid([100,80,60], rounding=10, edges="X");
```
![Figure 20](images/tutorials/Shapes3d_20.png)
```openscad
include <BOSL2/std.scad>
cuboid([100,80,60], rounding=10, edges="Y");
```
![Figure 21](images/tutorials/Shapes3d_21.png)
```openscad
include <BOSL2/std.scad>
cuboid([100,80,60], rounding=10, edges="Z");
```
![Figure 22](images/tutorials/Shapes3d_22.png)
If you give a list of edge specs, then all edges referenced in the list will
be rounded:
```openscad
include <BOSL2/std.scad>
cuboid([100,80,60], rounding=10, edges=[TOP,"Z",BOTTOM+RIGHT]);
```
![Figure 23](images/tutorials/Shapes3d_23.png)
The default value for `edges=` is `EDGES_ALL`, which is all edges. You can also
give an `except_edges=` argument that specifies edges to NOT round:
```openscad
include <BOSL2/std.scad>
cuboid([100,80,60], rounding=10, except_edges=BOTTOM+RIGHT);
```
![Figure 24](images/tutorials/Shapes3d_24.png)
You can give the `except_edges=` argument any type of argument that you can
give to `edges=`:
```openscad
include <BOSL2/std.scad>
cuboid([100,80,60], rounding=10, except_edges=[BOTTOM,"Z",TOP+RIGHT]);
```
![Figure 25](images/tutorials/Shapes3d_25.png)
You can give both `edges=` and `except_edges=`, to simplify edge specs:
```openscad
include <BOSL2/std.scad>
cuboid([100,80,60], rounding=10, edges=[TOP,FRONT], except_edges=TOP+FRONT);
```
![Figure 26](images/tutorials/Shapes3d_26.png)
You can specify what edges to chamfer similarly:
```openscad
include <BOSL2/std.scad>
cuboid([100,80,60], chamfer=10, edges=[TOP,FRONT], except_edges=TOP+FRONT);
```
![Figure 27](images/tutorials/Shapes3d_27.png)
### 3D Cylinder
BOSL2 overrides the built-in `cylinder()` module. It still can be used as you
expect from the built-in:
```openscad
include <BOSL2/std.scad>
cylinder(r=50,h=50);
```
![Figure 28](images/tutorials/Shapes3d_28.png)
```openscad
include <BOSL2/std.scad>
cylinder(r=50,h=50,center=true);
```
![Figure 29](images/tutorials/Shapes3d_29.png)
```openscad
include <BOSL2/std.scad>
cylinder(d=100,h=50,center=true);
```
![Figure 30](images/tutorials/Shapes3d_30.png)
```openscad
include <BOSL2/std.scad>
cylinder(d1=100,d2=80,h=50,center=true);
```
![Figure 31](images/tutorials/Shapes3d_31.png)
You can also anchor, spin, orient, and attach like the `cuboid()` module:
```openscad
include <BOSL2/std.scad>
cylinder(r=50, h=50, anchor=TOP+FRONT);
```
![Figure 32](images/tutorials/Shapes3d_32.png)
```openscad
include <BOSL2/std.scad>
cylinder(r=50, h=50, anchor=BOTTOM+LEFT);
```
![Figure 33](images/tutorials/Shapes3d_33.png)
```openscad
include <BOSL2/std.scad>
cylinder(r=50, h=50, anchor=BOTTOM+LEFT, spin=30);
```
![Figure 34](images/tutorials/Shapes3d_34.png)
```openscad
include <BOSL2/std.scad>
cylinder(r=50, h=50, anchor=BOTTOM, orient=UP+BACK+RIGHT);
```
![Figure 35](images/tutorials/Shapes3d_35.png)
BOSL2 provides a `cyl()` module that expands on `cylinder()`, by providing
rounding and chamfering of edges. You can use it similarly to `cylinder()`,
except that `cyl()` centers the cylinder by default.
```openscad
include <BOSL2/std.scad>
cyl(r=60, l=100);
```
![Figure 36](images/tutorials/Shapes3d_36.png)
```openscad
include <BOSL2/std.scad>
cyl(d=100, l=100);
```
![Figure 37](images/tutorials/Shapes3d_37.png)
```openscad
include <BOSL2/std.scad>
cyl(d=100, l=100, anchor=TOP);
```
![Figure 38](images/tutorials/Shapes3d_38.png)
You can round the edges with the `rounding=` argument:
```openscad
include <BOSL2/std.scad>
cyl(d=100, l=100, rounding=20);
```
![Figure 39](images/tutorials/Shapes3d_39.png)
Similarly, you can chamfer the edges with the `chamfer=` argument:
```openscad
include <BOSL2/std.scad>
cyl(d=100, l=100, chamfer=10);
```
![Figure 40](images/tutorials/Shapes3d_40.png)
You can specify rounding and chamfering for each end individually:
```openscad
include <BOSL2/std.scad>
cyl(d=100, l=100, rounding1=20);
```
![Figure 41](images/tutorials/Shapes3d_41.png)
```openscad
include <BOSL2/std.scad>
cyl(d=100, l=100, rounding2=20);
```
![Figure 42](images/tutorials/Shapes3d_42.png)
```openscad
include <BOSL2/std.scad>
cyl(d=100, l=100, chamfer1=10);
```
![Figure 43](images/tutorials/Shapes3d_43.png)
```openscad
include <BOSL2/std.scad>
cyl(d=100, l=100, chamfer2=10);
```
![Figure 44](images/tutorials/Shapes3d_44.png)
You can even mix and match rounding and chamfering:
```openscad
include <BOSL2/std.scad>
cyl(d=100, l=100, rounding1=20, chamfer2=10);
```
![Figure 45](images/tutorials/Shapes3d_45.png)
```openscad
include <BOSL2/std.scad>
cyl(d=100, l=100, rounding2=20, chamfer1=10);
```
![Figure 46](images/tutorials/Shapes3d_46.png)
### 3D Spheres
BOSL2 overrides the built-in `sphere()` module. It still can be used as you
expect from the built-in:
```openscad
include <BOSL2/std.scad>
sphere(r=50);
```
![Figure 47](images/tutorials/Shapes3d_47.png)
```openscad
include <BOSL2/std.scad>
sphere(d=100);
```
![Figure 48](images/tutorials/Shapes3d_48.png)
You can anchor, spin, and orient `sphere()`s, much like you can with `cylinder()`
and `cube()`:
```openscad
include <BOSL2/std.scad>
sphere(d=100, anchor=FRONT);
```
![Figure 49](images/tutorials/Shapes3d_49.png)
```openscad
include <BOSL2/std.scad>
sphere(d=100, anchor=FRONT, spin=30);
```
![Figure 50](images/tutorials/Shapes3d_50.png)
```openscad
include <BOSL2/std.scad>
sphere(d=100, anchor=BOTTOM, orient=RIGHT+TOP);
```
![Figure 51](images/tutorials/Shapes3d_51.png)
BOSL2 also provides `spheroid()`, which enhances `sphere()` with a few features
like the `circum=` and `style=` arguments:
You can use the `circum=true` argument to force the sphere to circumscribe the
ideal sphere, as opposed to the default inscribing:
```openscad
include <BOSL2/std.scad>
spheroid(d=100, circum=true);
```
![Figure 52](images/tutorials/Shapes3d_52.png)
The `style=` argument can choose the way that the sphere will be constructed:
The "orig" style matches the `sphere()` built-in's construction.
```openscad
include <BOSL2/std.scad>
spheroid(d=100, style="orig", $fn=20);
```
![Figure 53](images/tutorials/Shapes3d_53.png)
The "aligned" style will ensure that there is a vertex at each axis extrema,
so long as `$fn` is a multiple of 4.
```openscad
include <BOSL2/std.scad>
spheroid(d=100, style="aligned", $fn=20);
```
![Figure 54](images/tutorials/Shapes3d_54.png)
The "stagger" style will stagger the triangulation of the vertical rows:
```openscad
include <BOSL2/std.scad>
spheroid(d=100, style="stagger", $fn=20);
```
![Figure 55](images/tutorials/Shapes3d_55.png)
The "icosa" style will make for roughly equal-sized triangles for the entire
sphere surface, based on subdividing an icosahedron. This style will round the
effective `$fn` to a multiple of 5 when constructing the spheroid:
```openscad
include <BOSL2/std.scad>
spheroid(d=100, style="icosa", $fn=20);
```
![Figure 56](images/tutorials/Shapes3d_56.png)
The "octa" style will also make for roughly equal-sized triangles for the entire
sphere surface, but based on subdividing an octahedron. This is useful in that it
guarantees vertices at the axis extrema. This style will round the effective `$fn`
to a multiple of 4 when constructing the spheroid:
```openscad
include <BOSL2/std.scad>
spheroid(d=100, style="octa", $fn=20);
```
![Figure 57](images/tutorials/Shapes3d_57.png)

299
Tutorial-Transforms.md Normal file

@ -0,0 +1,299 @@
# Transforms Tutorial
<!-- TOC -->
## Translation
The `translate()` command is very simple:
```openscad
include <BOSL2/std.scad>
#sphere(d=20);
translate([0,0,30]) sphere(d=20);
```
![Figure 1](images/tutorials/Transforms_1.png)
But at a glance, or when the formula to calculate the move is complex, it can be difficult to see
just what axis is being moved along, and in which direction. It's also a bit verbose for such a
frequently used command. For these reasons, BOSL2 provides you with shortcuts for each direction.
These shortcuts are `up()`, `down()`, `fwd()`, `back()`, `left()`, and `right()`:
```openscad
include <BOSL2/std.scad>
#sphere(d=20);
up(30) sphere(d=20);
```
![Figure 2](images/tutorials/Transforms_2.png)
```openscad
include <BOSL2/std.scad>
#sphere(d=20);
down(30) sphere(d=20);
```
![Figure 3](images/tutorials/Transforms_3.png)
```openscad
include <BOSL2/std.scad>
#sphere(d=20);
fwd(30) sphere(d=20);
```
![Figure 4](images/tutorials/Transforms_4.png)
```openscad
include <BOSL2/std.scad>
#sphere(d=20);
back(30) sphere(d=20);
```
![Figure 5](images/tutorials/Transforms_5.png)
```openscad
include <BOSL2/std.scad>
#sphere(d=20);
left(30) sphere(d=20);
```
![Figure 6](images/tutorials/Transforms_6.png)
```openscad
include <BOSL2/std.scad>
#sphere(d=20);
right(30) sphere(d=20);
```
![Figure 7](images/tutorials/Transforms_7.png)
There is also a more generic `move()` command that can work just like `translate()`:
```openscad
include <BOSL2/std.scad>
#sphere(d=20);
move([30,-10]) sphere(d=20);
```
![Figure 8](images/tutorials/Transforms_8.png)
## Scaling
The `scale()` command is also fairly simple:
```openscad
include <BOSL2/std.scad>
scale(2) cube(10, center=true);
```
![Figure 9](images/tutorials/Transforms_9.png)
```openscad
include <BOSL2/std.scad>
scale([1,2,3]) cube(10, center=true);
```
![Figure 10](images/tutorials/Transforms_10.png)
If you want to only change the scaling on one axis, though, BOSL2 provides clearer
commands to do just that; `xscale()`, `yscale()`, and `zscale()`:
```openscad
include <BOSL2/std.scad>
xscale(2) cube(10, center=true);
```
![Figure 11](images/tutorials/Transforms_11.png)
```openscad
include <BOSL2/std.scad>
yscale(2) cube(10, center=true);
```
![Figure 12](images/tutorials/Transforms_12.png)
```openscad
include <BOSL2/std.scad>
zscale(2) cube(10, center=true);
```
![Figure 13](images/tutorials/Transforms_13.png)
## Rotation
The `rotate()` command is fairly straightforward:
```openscad
include <BOSL2/std.scad>
rotate([0,30,0]) cube(20, center=true);
```
![Figure 14](images/tutorials/Transforms_14.png)
It is also a bit verbose, and can, at a glance, be difficult to tell just how it is rotating.
BOSL2 provides shortcuts for rotating around each axis, for clarity; `xrot()`, `yrot()`, and `zrot()`:
```openscad
include <BOSL2/std.scad>
xrot(30) cube(20, center=true);
```
![Figure 15](images/tutorials/Transforms_15.png)
```openscad
include <BOSL2/std.scad>
yrot(30) cube(20, center=true);
```
![Figure 16](images/tutorials/Transforms_16.png)
```openscad
include <BOSL2/std.scad>
zrot(30) cube(20, center=true);
```
![Figure 17](images/tutorials/Transforms_17.png)
The `rot()` command is a more generic rotation command, and shorter to type than `rotate()`:
```openscad
include <BOSL2/std.scad>
rot([0,30,15]) cube(20, center=true);
```
![Figure 18](images/tutorials/Transforms_18.png)
All of the rotation shortcuts can take a `cp=` argument, that lets you specify a
centerpoint to rotate around:
```openscad
include <BOSL2/std.scad>
cp = [0,0,40];
color("blue") move(cp) sphere(d=3);
#cube(20, center=true);
xrot(45, cp=cp) cube(20, center=true);
```
![Figure 19](images/tutorials/Transforms_19.png)
```openscad
include <BOSL2/std.scad>
cp = [0,0,40];
color("blue") move(cp) sphere(d=3);
#cube(20, center=true);
yrot(45, cp=cp) cube(20, center=true);
```
![Figure 20](images/tutorials/Transforms_20.png)
```openscad
include <BOSL2/std.scad>
cp = [0,40,0];
color("blue") move(cp) sphere(d=3);
#cube(20, center=true);
zrot(45, cp=cp) cube(20, center=true);
```
![Figure 21](images/tutorials/Transforms_21.png)
You can also do a new trick with it. You can rotate from pointing in one direction, towards another.
You give these directions using vectors:
```openscad
include <BOSL2/std.scad>
#cylinder(d=10, h=50);
rot(from=[0,0,1], to=[1,0,1]) cylinder(d=10, h=50);
```
![Figure 22](images/tutorials/Transforms_22.png)
There are several direction vectors constants and aliases you can use for clarity:
Constant | Value | Direction
------------------------------ | ------------ | --------------
`CENTER`, `CTR` | `[ 0, 0, 0]` | Centered
`LEFT` | `[-1, 0, 0]` | Towards X-
`RIGHT` | `[ 1, 0, 0]` | Towards X+
`FWD`, `FORWARD`, `FRONT` | `[ 0,-1, 0]` | Towards Y-
`BACK` | `[ 0, 1, 0]` | Towards Y+
`DOWN`, `BOTTOM`, `BOT` | `[ 0, 0,-1]` | Towards Z-
`UP`, `TOP` | `[ 0, 0, 1]` | Towards Z+
This lets you rewrite the above vector rotation more clearly as:
```openscad
include <BOSL2/std.scad>
#cylinder(d=10, h=50);
rot(from=UP, to=UP+RIGHT) cylinder(d=10, h=50);
```
![Figure 23](images/tutorials/Transforms_23.png)
## Mirroring
The standard `mirror()` command works like this:
```openscad
include <BOSL2/std.scad>
#yrot(60) cylinder(h=50, d1=20, d2=10);
mirror([1,0,0]) yrot(60) cylinder(h=50, d1=20, d2=10);
```
![Figure 24](images/tutorials/Transforms_24.png)
BOSL2 provides shortcuts for mirroring across the standard axes; `xflip()`, `yflip()`, and `zflip()`:
```openscad
include <BOSL2/std.scad>
#yrot(60) cylinder(h=50, d1=20, d2=10);
xflip() yrot(60) cylinder(h=50, d1=20, d2=10);
```
![Figure 25](images/tutorials/Transforms_25.png)
```openscad
include <BOSL2/std.scad>
#xrot(60) cylinder(h=50, d1=20, d2=10);
yflip() xrot(60) cylinder(h=50, d1=20, d2=10);
```
![Figure 26](images/tutorials/Transforms_26.png)
```openscad
include <BOSL2/std.scad>
#cylinder(h=50, d1=20, d2=10);
zflip() cylinder(h=50, d1=20, d2=10);
```
![Figure 27](images/tutorials/Transforms_27.png)
All of the flip commands can offset where the mirroring is performed:
```openscad
include <BOSL2/std.scad>
#zrot(30) cube(20, center=true);
xflip(x=-20) zrot(30) cube(20, center=true);
color("blue",0.25) left(20) cube([0.1,50,50], center=true);
```
![Figure 28](images/tutorials/Transforms_28.png)
```openscad
include <BOSL2/std.scad>
#zrot(30) cube(20, center=true);
yflip(y=20) zrot(30) cube(20, center=true);
color("blue",0.25) back(20) cube([40,0.1,40], center=true);
```
![Figure 29](images/tutorials/Transforms_29.png)
```openscad
include <BOSL2/std.scad>
#xrot(30) cube(20, center=true);
zflip(z=-20) xrot(30) cube(20, center=true);
color("blue",0.25) down(20) cube([40,40,0.1], center=true);
```
![Figure 30](images/tutorials/Transforms_30.png)
## Skewing / Shearing
One transform that OpenSCAD does not perform natively is skewing, also
known as shearing.
BOSL2 provides the `skew()` command for that. You give it multipliers
for the skews you want to perform. The arguments used all start with `s`,
followed by the axis you want to skew along, followed by the axis that
the skewing will increase along. For example, to skew along the X axis as
you get farther along the Y axis, use the `sxy=` argument. If you give it
a multiplier of `0.5`, then for each unit further along the Y axis you get,
you will add `0.5` units of skew to the X axis. Giving a negative multiplier
reverses the direction it skews:
```openscad
include <BOSL2/std.scad>
skew(sxy=0.5) cube(10,center=false);
```
![Figure 31](images/tutorials/Transforms_31.png)
```openscad
include <BOSL2/std.scad>
skew(sxz=-0.5) cube(10,center=false);
```
![Figure 32](images/tutorials/Transforms_32.png)
```openscad
include <BOSL2/std.scad>
skew(syx=-0.5) cube(10,center=false);
```
![Figure 33](images/tutorials/Transforms_33.png)
```openscad
include <BOSL2/std.scad>
skew(syz=0.5) cube(10,center=false);
```
![Figure 34](images/tutorials/Transforms_34.png)
```openscad
include <BOSL2/std.scad>
skew(szx=-0.5) cube(10,center=false);
```
![Figure 35](images/tutorials/Transforms_35.png)
```openscad
include <BOSL2/std.scad>
skew(szy=0.5) cube(10,center=false);
```
![Figure 36](images/tutorials/Transforms_36.png)

200
Tutorial-VNF.md Normal file

@ -0,0 +1,200 @@
# VNF Tutorial
<!-- TOC -->
## What's a VNF?
The acronym VNF stands for Vertices 'N' Faces. You have probably already come across the concept of vertices and faces when working with the OpenSCAD built-in module `polyhedron()`. A `polyhedron()` in it's simplest form takes two arguments, the first being a list of vertices, and the second a list of faces, where each face is a lists of indices into the list of vertices. For example, to make a cube, you can do:
```openscad
include <BOSL2/std.scad>
verts = [
[-1,-1,-1], [1,-1,-1], [1,1,-1], [-1,1,-1],
[-1,-1, 1], [1,-1, 1], [1,1, 1], [-1,1, 1]
];
faces = [
[0,1,2], [0,2,3], //BOTTOM
[0,4,5], [0,5,1], //FRONT
[1,5,6], [1,6,2], //RIGHT
[2,6,7], [2,7,3], //BACK
[3,7,4], [3,4,0], //LEFT
[6,4,7], [6,5,4] //TOP
];
polyhedron(verts, faces);
```
![Figure 1](images/tutorials/VNF_1.png)
A VNF structure (usually just called a VNF) is just a two item list where the first item is the list of vertices, and the second item is the list of faces. It's easier to pass a VNF to a function than it is to pass both the vertices and faces separately.
The equivalent to the `polyhedron()` module that takes a VNF instead is `vnf_polyhedron()`. To make the same cube as a VNF, you can do it like:
```openscad
include <BOSL2/std.scad>
vnf = [
[
[-1,-1,-1], [1,-1,-1], [1,1,-1], [-1,1,-1],
[-1,-1, 1], [1,-1, 1], [1,1, 1], [-1,1, 1],
],
[
[0,1,2], [0,2,3], //BOTTOM
[0,4,5], [0,5,1], //FRONT
[1,5,6], [1,6,2], //RIGHT
[2,6,7], [2,7,3], //BACK
[3,7,4], [3,4,0], //LEFT
[6,4,7], [6,5,4] //TOP
]
];
vnf_polyhedron(vnf);
```
![Figure 2](images/tutorials/VNF_2.png)
## Assembling a Polyhedron in Parts
A VNF does not have to contain a complete polyhedron, and the vertices contained in it do not have to be unique. This allows the true power of VNFs: You can use the `vnf_join()` function to take multiple partial-polyhedron VNFs and merge them into a more complete VNF. This lets you construct a complex polyhedron in parts, without having to keep track of all the vertices you created in other parts of it.
As an example, consider a roughly spherical polyhedron with vertices at the top and bottom poles. You can break it down into three major parts: The top cap, the bottom cap, and the side wall. The top and bottom caps both have a ring of vertices linked to the top or bottom vertex in triangles, while the sides are multiple rings of vertices linked in squares. Lets create the top cap first:
```openscad
include <BOSL2/std.scad>
cap_vnf = [
[[0,0,1], for (a=[0:30:359.9]) spherical_to_xyz(1,a,30)], // Vertices
[for (i=[1:12]) [0, i%12+1, i]] // Faces
];
vnf_polyhedron(cap_vnf);
```
![Figure 3](images/tutorials/VNF_3.png)
The bottom cap is exactly the same, just mirrored:
```openscad
include <BOSL2/std.scad>
cap_vnf = [
[[0,0,1], for (a=[0:30:359.9]) spherical_to_xyz(1,a,30)], // Vertices
[for (i=[1:12]) [0, i%12+1, i]] // Faces
];
cap_vnf2 = zflip(cap_vnf);
vnf_polyhedron(cap_vnf2);
```
![Figure 4](images/tutorials/VNF_4.png)
To create the sides, we can make use of the `vnf_vertex_array()` function to turn a row-column grid of vertices into a VNF. The `col_wrap=true` argument tells it to connect the vertices of the last column to the vertices of the first column. The `caps=false` argument tells it that we don't want it to create caps for the ends of the first and last rows:
```openscad
include <BOSL2/std.scad>
wall_vnf = vnf_vertex_array(
points=[
for (phi = [30:30:179.9]) [
for (theta = [0:30:359.9])
spherical_to_xyz(1,theta,phi)
]
],
col_wrap=true, caps=false
);
vnf_polyhedron(wall_vnf);
```
![Figure 5](images/tutorials/VNF_5.png)
Putting all the parts together with `vnf_join()`, we get:
```openscad
include <BOSL2/std.scad>
cap_vnf = [
[[0,0,1], for (a=[0:30:359.9]) spherical_to_xyz(1,a,30)], // Vertices
[for (i=[1:12]) [0, i%12+1, i]] // Faces
];
cap_vnf2 = zflip(cap_vnf);
wall_vnf = vnf_vertex_array(
points=[
for (phi = [30:30:179.9]) [
for (theta = [0:30:359.9])
spherical_to_xyz(1,theta,phi)
]
],
col_wrap=true, caps=false
);
vnf = vnf_join([cap_vnf,cap_vnf2,wall_vnf]);
vnf_polyhedron(vnf);
```
![Figure 6](images/tutorials/VNF_6.png)
Which is now a complete manifold polyhedron.
## Debugging a VNF
One of the critical tasks in creating a polyhedron is making sure that all of your faces are facing the correct way. This is also true for VNFs. The best way to find reversed faces is simply to select the View→Thrown Together menu item in OpenSCAD while viewing your polyhedron or VNF. Any purple faces are reversed, and you will need to fix them. For example, one of the two top face triangles on this cube is reversed:
```openscad
include <BOSL2/std.scad>
vnf = [
[
[-1,-1,-1], [1,-1,-1], [1,1,-1], [-1,1,-1],
[-1,-1, 1], [1,-1, 1], [1,1, 1], [-1,1, 1],
],
[
[0,1,2], [0,2,3], //BOTTOM
[0,4,5], [0,5,1], //FRONT
[1,5,6], [1,6,2], //RIGHT
[2,6,7], [2,7,3], //BACK
[3,7,4], [3,4,0], //LEFT
[6,4,7], [6,4,5] //TOP
]
];
vnf_polyhedron(vnf);
```
![Figure 7](images/tutorials/VNF_7.png)
Another way to find problems with your VNF, is to use the `vnf_validate()` module, which will ECHO problems to the console, and will attempt to display where the issue is. This can find a lot more types of non-manifold errors, but can be slow:
```openscad
include <BOSL2/std.scad>
vnf = [
[
[-1,-1,-1], [1,-1,-1], [1,1,-1], [-1,1,-1],
[-1,-1, 1], [1,-1, 1], [1,1, 1], [-1,1, 1],
],
[
[0,1,2], [0,2,3], //BOTTOM
[0,4,5], //FRONT
[1,5,6], [1,6,2], //RIGHT
[2,6,7], [2,7,3], //BACK
[3,7,4], [3,4,0], //LEFT
[6,4,7], [6,4,5] //TOP
]
];
vnf_validate(vnf, size=0.1);
```
![Figure 8](images/tutorials/VNF_8.png)
```text
ECHO: "ERROR REVERSAL (violet): Faces Reverse Across Edge at [[-1, -1, 1], [1, -1, 1]]"
ECHO: "ERROR REVERSAL (violet): Faces Reverse Across Edge at [[1, -1, 1], [1, 1, 1]]"
ECHO: "ERROR REVERSAL (violet): Faces Reverse Across Edge at [[1, 1, 1], [-1, -1, 1]]"
```
The `vnf_validate()` module will stop after displaying the first found problem type, so once you fix those issues, you will want to run it again to display any other remaining issues. For example, the reversed face in the above example is hiding a non-manifold hole in the front face:
```openscad
include <BOSL2/std.scad>
vnf = [
[
[-1,-1,-1], [1,-1,-1], [1,1,-1], [-1,1,-1],
[-1,-1, 1], [1,-1, 1], [1,1, 1], [-1,1, 1],
],
[
[0,1,2], [0,2,3], //BOTTOM
[0,4,5], //FRONT
[1,5,6], [1,6,2], //RIGHT
[2,6,7], [2,7,3], //BACK
[3,7,4], [3,4,0], //LEFT
[6,4,7], [6,5,4] //TOP
]
];
vnf_validate(vnf, size=0.1);
```
![Figure 9](images/tutorials/VNF_9.png)
```text
ECHO: "ERROR HOLE_EDGE (red): Edge bounds Hole at [[-1, -1, -1], [1, -1, -1]]"
ECHO: "ERROR HOLE_EDGE (red): Edge bounds Hole at [[-1, -1, -1], [1, -1, 1]]"
ECHO: "ERROR HOLE_EDGE (red): Edge bounds Hole at [[1, -1, -1], [1, -1, 1]]"
```

19
Tutorials.md Normal file

@ -0,0 +1,19 @@
# Belfry OpenScad Library v2 Tutorials
1. The Basics
1. [2D Shapes Tutorial](Tutorial-Shapes2d)
1. [3D Shapes Tutorial](Tutorial-Shapes3d)
1. [Transforms Tutorial](Tutorial-Transforms)
1. [Distributors Tutorial](Tutorial-Distributors)
1. [Mutators Tutorial](Tutorial-Mutators)
1. [Attachments Tutorial](Tutorial-Attachments)
1. Advanced Tutorials
1. [Paths and Regions Tutorial](Tutorial-Paths)
1. [VNF Tutorial (AKA: How to build a Polyhedron in parts)](Tutorial-VNF)
1. [Rounding the Cube Tutorial](Tutorial-Rounding_the_Cube)
1. [Beziers for Beginners](Tutorial-Beziers_for_Beginners)
1. Ways to Make a Box (To Be Written)
1. Demo Tutorials
1. [Fractal Tree Demo](Tutorial-FractalTree)
1. Bezier Patch Demo (To Be Written)

1
_Footer.md Normal file

@ -0,0 +1 @@
[Home](Home) [Table&nbsp;of&nbsp;Contents](TOC) [Functions&nbsp;Index](AlphaIndex) [Topics](Topics) [Cheat&nbsp;Sheet](CheatSheet) [Tutorials](Tutorials)

82
_Sidebar.md Normal file

@ -0,0 +1,82 @@
## Indices
[Table of Contents](TOC)
[Function Index](AlphaIndex)
[Topics Index](Topics)
[Cheat Sheet](CheatSheet)
[Tutorials](Tutorials)
## List of Files:
**Basic Modeling:**
- [constants.scad](constants.scad) <sup title="Included in std.scad">[STD](#footnotes)</sup>
- [transforms.scad](transforms.scad) <sup title="Included in std.scad">[STD](#footnotes)</sup>
- [attachments.scad](attachments.scad) <sup title="Included in std.scad">[STD](#footnotes)</sup>
- [shapes2d.scad](shapes2d.scad) <sup title="Included in std.scad">[STD](#footnotes)</sup>
- [shapes3d.scad](shapes3d.scad) <sup title="Included in std.scad">[STD](#footnotes)</sup>
- [drawing.scad](drawing.scad) <sup title="Included in std.scad">[STD](#footnotes)</sup>
- [masks2d.scad](masks2d.scad) <sup title="Included in std.scad">[STD](#footnotes)</sup>
- [masks3d.scad](masks3d.scad) <sup title="Included in std.scad">[STD](#footnotes)</sup>
- [distributors.scad](distributors.scad) <sup title="Included in std.scad">[STD](#footnotes)</sup>
- [color.scad](color.scad) <sup title="Included in std.scad">[STD](#footnotes)</sup>
- [partitions.scad](partitions.scad) <sup title="Included in std.scad">[STD](#footnotes)</sup>
- [miscellaneous.scad](miscellaneous.scad) <sup title="Included in std.scad">[STD](#footnotes)</sup>
**Advanced Modeling:**
- [paths.scad](paths.scad) <sup title="Included in std.scad">[STD](#footnotes)</sup>
- [regions.scad](regions.scad) <sup title="Included in std.scad">[STD](#footnotes)</sup>
- [skin.scad](skin.scad) <sup title="Included in std.scad">[STD](#footnotes)</sup>
- [vnf.scad](vnf.scad) <sup title="Included in std.scad">[STD](#footnotes)</sup>
- [beziers.scad](beziers.scad)
- [nurbs.scad](nurbs.scad)
- [rounding.scad](rounding.scad)
- [turtle3d.scad](turtle3d.scad)
**Math:**
- [math.scad](math.scad) <sup title="Included in std.scad">[STD](#footnotes)</sup>
- [linalg.scad](linalg.scad) <sup title="Included in std.scad">[STD](#footnotes)</sup>
- [vectors.scad](vectors.scad) <sup title="Included in std.scad">[STD](#footnotes)</sup>
- [coords.scad](coords.scad) <sup title="Included in std.scad">[STD](#footnotes)</sup>
- [geometry.scad](geometry.scad) <sup title="Included in std.scad">[STD](#footnotes)</sup>
- [trigonometry.scad](trigonometry.scad) <sup title="Included in std.scad">[STD](#footnotes)</sup>
**Data Management:**
- [version.scad](version.scad) <sup title="Included in std.scad">[STD](#footnotes)</sup>
- [comparisons.scad](comparisons.scad) <sup title="Included in std.scad">[STD](#footnotes)</sup>
- [lists.scad](lists.scad) <sup title="Included in std.scad">[STD](#footnotes)</sup>
- [utility.scad](utility.scad) <sup title="Included in std.scad">[STD](#footnotes)</sup>
- [strings.scad](strings.scad) <sup title="Included in std.scad">[STD](#footnotes)</sup>
- [structs.scad](structs.scad) <sup title="Included in std.scad">[STD](#footnotes)</sup>
- [fnliterals.scad](fnliterals.scad)
**Threaded Parts:**
- [threading.scad](threading.scad)
- [screws.scad](screws.scad)
- [screw\_drive.scad](screw_drive.scad)
- [bottlecaps.scad](bottlecaps.scad)
**Parts:**
- [ball\_bearings.scad](ball_bearings.scad)
- [cubetruss.scad](cubetruss.scad)
- [gears.scad](gears.scad)
- [hinges.scad](hinges.scad)
- [joiners.scad](joiners.scad)
- [linear\_bearings.scad](linear_bearings.scad)
- [modular\_hose.scad](modular_hose.scad)
- [nema\_steppers.scad](nema_steppers.scad)
- [polyhedra.scad](polyhedra.scad)
- [sliders.scad](sliders.scad)
- [tripod\_mounts.scad](tripod_mounts.scad)
- [walls.scad](walls.scad)
- [wiring.scad](wiring.scad)
## Footnotes:
STD = Included in std.scad

4111
attachments.scad.md Normal file

File diff suppressed because it is too large Load diff

146
ball_bearings.scad.md Normal file

@ -0,0 +1,146 @@
# LibFile: ball\_bearings.scad
Models for standard ball bearing cartridges.
To use, add the following lines to the beginning of your file:
include <BOSL2/std.scad>
include <BOSL2/ball_bearings.scad>
## File Contents
1. [Section: Ball Bearing Models](#section-ball-bearing-models)
- [`ball_bearing()`](#module-ball_bearing) Creates a standardized ball bearing assembly. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup>
2. [Section: Ball Bearing Info](#section-ball-bearing-info)
- [`ball_bearing_info()`](#function-ball_bearing_info) Returns size info for a standardized ball bearing assembly.
## Section: Ball Bearing Models
### Module: ball\_bearing()
**Synopsis:** Creates a standardized ball bearing assembly. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup>
**Topics:** [Parts](Topics#parts), [Bearings](Topics#bearings)
**See Also:** [linear\_bearing()](linear_bearings.scad#module-linear_bearing), [lmXuu\_bearing()](linear_bearings.scad#module-lmxuu_bearing), [lmXuu\_housing()](linear_bearings.scad#module-lmxuu_housing)
**Description:**
Creates a model of a ball bearing assembly.
**Arguments:**
<abbr title="These args can be used by position or by name.">By&nbsp;Position</abbr> | What it does
-------------------- | ------------
`trade_size` | String name of a standard ball bearing trade size. ie: "608", "6902ZZ", or "R8"
`id` | Inner diameter of ball bearing assembly.
`od` | Outer diameter of ball bearing assembly.
`width` | Width of ball bearing assembly.
`shield` | If true, the ball bearing assembly has a shield.
`flange` | If true, the ball bearing assembly has a flange.
`fd` | Diameter of the flange (required if `flange=true`).
`fw` | Width of the flange (required if `flange=true`).
`rounding` | Edge rounding radius, if any. The outermost top and bottom edges are rounded by this amount. The edges of the inner hole are also rounded. If you set `trade_size` and you want edges rounded, you must set `rounding` yourself. This parameter has no default value because the rounding depends on manufacturer and bearing size.
`anchor` | Translate so anchor point is at origin (0,0,0). See [anchor](attachments.scad#subsection-anchor). Default: `CENTER`
`spin` | Rotate this many degrees around the Z axis after anchor. See [spin](attachments.scad#subsection-spin). Default: `0`
`orient` | Vector to rotate top towards, after spin. See [orient](attachments.scad#subsection-orient). Default: `UP`
**Example 1:**
<img align="left" alt="ball\_bearing() Example 1" src="images/ball_bearings/ball_bearing.png" width="320" height="240">
include <BOSL2/std.scad>
include <BOSL2/ball_bearings.scad>
ball_bearing("608", $fn=72);
<br clear="all" /><br/>
**Example 2:**
<img align="left" alt="ball\_bearing() Example 2" src="images/ball_bearings/ball_bearing_2.png" width="320" height="240">
include <BOSL2/std.scad>
include <BOSL2/ball_bearings.scad>
ball_bearing("608ZZ", $fn=72);
<br clear="all" /><br/>
**Example 3:**
<img align="left" alt="ball\_bearing() Example 3" src="images/ball_bearings/ball_bearing_3.png" width="320" height="240">
include <BOSL2/std.scad>
include <BOSL2/ball_bearings.scad>
ball_bearing("R8", $fn=72);
<br clear="all" /><br/>
**Example 4:**
<img align="left" alt="ball\_bearing() Example 4" src="images/ball_bearings/ball_bearing_4.png" width="320" height="240">
include <BOSL2/std.scad>
include <BOSL2/ball_bearings.scad>
ball_bearing(id=12,od=32,width=10,shield=false, $fn=72);
<br clear="all" /><br/>
**Example 5:**
<img align="left" alt="ball\_bearing() Example 5" src="images/ball_bearings/ball_bearing_5.png" width="320" height="240">
include <BOSL2/std.scad>
include <BOSL2/ball_bearings.scad>
ball_bearing("MF105ZZ", $fn=72);
<br clear="all" /><br/>
**Example 6:**
<img align="left" alt="ball\_bearing() Example 6" src="images/ball_bearings/ball_bearing_6.png" width="320" height="240">
include <BOSL2/std.scad>
include <BOSL2/ball_bearings.scad>
ball_bearing("F688ZZ", $fn=72);
<br clear="all" /><br/>
**Example 7:** With flange, shield, and rounded edges.
<img align="left" alt="ball\_bearing() Example 7" src="images/ball_bearings/ball_bearing_7.png" width="320" height="240">
<br clear="all" />
include <BOSL2/std.scad>
include <BOSL2/ball_bearings.scad>
ball_bearing(id=12,od=24,width=6,shield=true, flange=true, fd=26.5, fw=1.5, rounding=0.6, $fn=72);
---
## Section: Ball Bearing Info
### Function: ball\_bearing\_info()
**Synopsis:** Returns size info for a standardized ball bearing assembly.
**Topics:** [Parts](Topics#parts), [Bearings](Topics#bearings)
**See Also:** [ball\_bearing()](#module-ball_bearing), [linear\_bearing()](linear_bearings.scad#module-linear_bearing), [lmXuu\_info()](linear_bearings.scad#function-lmxuu_info)
**Description:**
Get dimensional info for a standard metric ball bearing cartridge.
Returns `[SHAFT_DIAM, OUTER_DIAM, WIDTH, SHIELDED, FLANGED, FLANGE_DIAM, FLANGE_WIDTH]` for the cylindrical cartridge.
**Arguments:**
<abbr title="These args can be used by position or by name.">By&nbsp;Position</abbr> | What it does
-------------------- | ------------
`size` | Inner diameter of lmXuu bearing, in mm.
---

1766
beziers.scad.md Normal file

File diff suppressed because it is too large Load diff

875
bottlecaps.scad.md Normal file

@ -0,0 +1,875 @@
# LibFile: bottlecaps.scad
Bottle caps and necks for PCO18XX standard plastic beverage bottles, and SPI standard bottle necks.
To use, add the following lines to the beginning of your file:
include <BOSL2/std.scad>
include <BOSL2/bottlecaps.scad>
## File Contents
1. [Section: PCO-1810 Bottle Threading](#section-pco-1810-bottle-threading)
- [`pco1810_neck()`](#module-pco1810_neck) Creates a neck for a PCO1810 standard bottle. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup>
- [`pco1810_cap()`](#module-pco1810_cap) Creates a cap for a PCO1810 standard bottle. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup>
2. [Section: PCO-1881 Bottle Threading](#section-pco-1881-bottle-threading)
- [`pco1881_neck()`](#module-pco1881_neck) Creates a neck for a PCO1881 standard bottle. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup>
- [`pco1881_cap()`](#module-pco1881_cap) Creates a cap for a PCO1881 standard bottle. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup>
3. [Section: Generic Bottle Connectors](#section-generic-bottle-connectors)
- [`generic_bottle_neck()`](#module-generic_bottle_neck) Creates a generic neck for a bottle. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup>
- [`generic_bottle_cap()`](#module-generic_bottle_cap) Creates a generic cap for a bottle. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup>
- [`bottle_adapter_neck_to_cap()`](#module-bottle_adapter_neck_to_cap) Creates a generic adaptor between a neck and a cap. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup>
- [`bottle_adapter_cap_to_cap()`](#module-bottle_adapter_cap_to_cap) Creates a generic adaptor between a cap and a cap. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup>
- [`bottle_adapter_neck_to_neck()`](#module-bottle_adapter_neck_to_neck) Creates a generic adaptor between a neck and a neck. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup>
4. [Section: SPI Bottle Threading](#section-spi-bottle-threading)
- [`sp_neck()`](#module-sp_neck) Creates an SPI threaded bottle neck. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup>
- [`sp_cap()`](#module-sp_cap) Creates an SPI threaded bottle cap. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup>
- [`sp_diameter()`](#function-sp_diameter) Returns the base diameter of an SPI bottle neck from the nominal diameter and type number.
## Section: PCO-1810 Bottle Threading
### Module: pco1810\_neck()
**Synopsis:** Creates a neck for a PCO1810 standard bottle. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup>
**Topics:** [Bottles](Topics#bottles), [Threading](Topics#threading)
**See Also:** [pco1810\_cap()](#module-pco1810_cap)
**Usage:**
- pco1810_neck([wall]) [ATTACHMENTS];
**Description:**
Creates an approximation of a standard PCO-1810 threaded beverage bottle neck.
**Arguments:**
<abbr title="These args can be used by position or by name.">By&nbsp;Position</abbr> | What it does
-------------------- | ------------
`wall` | Wall thickness in mm.
<abbr title="These args must be used by name, ie: name=value">By&nbsp;Name</abbr> | What it does
-------------------- | ------------
`anchor` | Translate so anchor point is at origin (0,0,0). See [anchor](attachments.scad#subsection-anchor). Default: `CENTER`
`spin` | Rotate this many degrees around the Z axis after anchor. See [spin](attachments.scad#subsection-spin). Default: `0`
`orient` | Vector to rotate top towards, after spin. See [orient](attachments.scad#subsection-orient). Default: `UP`
**Named Anchors:**
Anchor Name | Position
----------- | --------
"tamper-ring" | Centered at the top of the anti-tamper ring channel.
"support-ring" | Centered at the bottom of the support ring.
**Example 1:**
<img align="left" alt="pco1810\_neck() Example 1" src="images/bottlecaps/pco1810_neck.png" width="320" height="240">
include <BOSL2/std.scad>
include <BOSL2/bottlecaps.scad>
pco1810_neck();
<br clear="all" /><br/>
**Example 2:** Standard Anchors
<img align="left" alt="pco1810\_neck() Example 2" src="images/bottlecaps/pco1810_neck_2.png" width="320" height="240">
include <BOSL2/std.scad>
include <BOSL2/bottlecaps.scad>
pco1810_neck() show_anchors(custom=false);
<br clear="all" /><br/>
**Example 3:** Custom Named Anchors
<img align="left" alt="pco1810\_neck() Example 3" src="images/bottlecaps/pco1810_neck_3.png" width="320" height="240">
include <BOSL2/std.scad>
include <BOSL2/bottlecaps.scad>
expose_anchors(0.3)
pco1810_neck()
show_anchors(std=false);
<br clear="all" /><br/>
---
### Module: pco1810\_cap()
**Synopsis:** Creates a cap for a PCO1810 standard bottle. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup>
**Topics:** [Bottles](Topics#bottles), [Threading](Topics#threading)
**See Also:** [pco1810\_neck()](#module-pco1810_neck)
**Usage:**
- pco1810_cap([h], [r|d], [wall], [texture]) [ATTACHMENTS];
**Description:**
Creates a basic cap for a PCO1810 threaded beverage bottle.
**Arguments:**
<abbr title="These args can be used by position or by name.">By&nbsp;Position</abbr> | What it does
-------------------- | ------------
`h` | The height of the cap.
`r` | Outer radius of the cap.
`d` | Outer diameter of the cap.
`wall` | Wall thickness in mm.
`texture` | The surface texture of the cap. Valid values are "none", "knurled", or "ribbed". Default: "none"
<abbr title="These args must be used by name, ie: name=value">By&nbsp;Name</abbr> | What it does
-------------------- | ------------
`anchor` | Translate so anchor point is at origin (0,0,0). See [anchor](attachments.scad#subsection-anchor). Default: `CENTER`
`spin` | Rotate this many degrees around the Z axis after anchor. See [spin](attachments.scad#subsection-spin). Default: `0`
`orient` | Vector to rotate top towards, after spin. See [orient](attachments.scad#subsection-orient). Default: `UP`
**Named Anchors:**
Anchor Name | Position
----------- | --------
"inside-top" | Centered on the inside top of the cap.
**Example 1:**
<img align="left" alt="pco1810\_cap() Example 1" src="images/bottlecaps/pco1810_cap.png" width="320" height="240">
include <BOSL2/std.scad>
include <BOSL2/bottlecaps.scad>
pco1810_cap();
<br clear="all" /><br/>
**Example 2:**
<img align="left" alt="pco1810\_cap() Example 2" src="images/bottlecaps/pco1810_cap_2.png" width="320" height="240">
include <BOSL2/std.scad>
include <BOSL2/bottlecaps.scad>
pco1810_cap(texture="knurled");
<br clear="all" /><br/>
**Example 3:**
<img align="left" alt="pco1810\_cap() Example 3" src="images/bottlecaps/pco1810_cap_3.png" width="320" height="240">
include <BOSL2/std.scad>
include <BOSL2/bottlecaps.scad>
pco1810_cap(texture="ribbed");
<br clear="all" /><br/>
**Example 4:** Standard Anchors
<img align="left" alt="pco1810\_cap() Example 4" src="images/bottlecaps/pco1810_cap_4.png" width="320" height="240">
include <BOSL2/std.scad>
include <BOSL2/bottlecaps.scad>
pco1810_cap(texture="ribbed") show_anchors(custom=false);
<br clear="all" /><br/>
**Example 5:** Custom Named Anchors
<img align="left" alt="pco1810\_cap() Example 5" src="images/bottlecaps/pco1810_cap_5.png" width="320" height="240">
include <BOSL2/std.scad>
include <BOSL2/bottlecaps.scad>
expose_anchors(0.3)
pco1810_cap(texture="ribbed")
show_anchors(std=false);
<br clear="all" /><br/>
---
## Section: PCO-1881 Bottle Threading
### Module: pco1881\_neck()
**Synopsis:** Creates a neck for a PCO1881 standard bottle. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup>
**Topics:** [Bottles](Topics#bottles), [Threading](Topics#threading)
**See Also:** [pco1881\_cap()](#module-pco1881_cap)
**Usage:**
- pco1881_neck([wall]) [ATTACHMENTS];
**Description:**
Creates an approximation of a standard PCO-1881 threaded beverage bottle neck.
**Arguments:**
<abbr title="These args can be used by position or by name.">By&nbsp;Position</abbr> | What it does
-------------------- | ------------
`wall` | Wall thickness in mm.
<abbr title="These args must be used by name, ie: name=value">By&nbsp;Name</abbr> | What it does
-------------------- | ------------
`anchor` | Translate so anchor point is at origin (0,0,0). See [anchor](attachments.scad#subsection-anchor). Default: `CENTER`
`spin` | Rotate this many degrees around the Z axis after anchor. See [spin](attachments.scad#subsection-spin). Default: `0`
`orient` | Vector to rotate top towards, after spin. See [orient](attachments.scad#subsection-orient). Default: `UP`
**Named Anchors:**
Anchor Name | Position
----------- | --------
"tamper-ring" | Centered at the top of the anti-tamper ring channel.
"support-ring" | Centered at the bottom of the support ring.
**Example 1:**
<img align="left" alt="pco1881\_neck() Example 1" src="images/bottlecaps/pco1881_neck.png" width="320" height="240">
include <BOSL2/std.scad>
include <BOSL2/bottlecaps.scad>
pco1881_neck();
<br clear="all" /><br/>
**Example 2:**
<img align="left" alt="pco1881\_neck() Example 2" src="images/bottlecaps/pco1881_neck_2.png" width="320" height="240">
include <BOSL2/std.scad>
include <BOSL2/bottlecaps.scad>
pco1881_neck() show_anchors(custom=false);
<br clear="all" /><br/>
**Example 3:**
<img align="left" alt="pco1881\_neck() Example 3" src="images/bottlecaps/pco1881_neck_3.png" width="320" height="240">
include <BOSL2/std.scad>
include <BOSL2/bottlecaps.scad>
expose_anchors(0.3)
pco1881_neck()
show_anchors(std=false);
<br clear="all" /><br/>
---
### Module: pco1881\_cap()
**Synopsis:** Creates a cap for a PCO1881 standard bottle. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup>
**Topics:** [Bottles](Topics#bottles), [Threading](Topics#threading)
**See Also:** [pco1881\_neck()](#module-pco1881_neck)
**Usage:**
- pco1881_cap(wall, [texture]) [ATTACHMENTS];
**Description:**
Creates a basic cap for a PCO1881 threaded beverage bottle.
**Arguments:**
<abbr title="These args can be used by position or by name.">By&nbsp;Position</abbr> | What it does
-------------------- | ------------
`wall` | Wall thickness in mm.
`texture` | The surface texture of the cap. Valid values are "none", "knurled", or "ribbed". Default: "none"
<abbr title="These args must be used by name, ie: name=value">By&nbsp;Name</abbr> | What it does
-------------------- | ------------
`anchor` | Translate so anchor point is at origin (0,0,0). See [anchor](attachments.scad#subsection-anchor). Default: `CENTER`
`spin` | Rotate this many degrees around the Z axis after anchor. See [spin](attachments.scad#subsection-spin). Default: `0`
`orient` | Vector to rotate top towards, after spin. See [orient](attachments.scad#subsection-orient). Default: `UP`
**Named Anchors:**
Anchor Name | Position
----------- | --------
"inside-top" | Centered on the inside top of the cap.
**Example 1:**
<img align="left" alt="pco1881\_cap() Example 1" src="images/bottlecaps/pco1881_cap.png" width="320" height="240">
include <BOSL2/std.scad>
include <BOSL2/bottlecaps.scad>
pco1881_cap();
<br clear="all" /><br/>
**Example 2:**
<img align="left" alt="pco1881\_cap() Example 2" src="images/bottlecaps/pco1881_cap_2.png" width="320" height="240">
include <BOSL2/std.scad>
include <BOSL2/bottlecaps.scad>
pco1881_cap(texture="knurled");
<br clear="all" /><br/>
**Example 3:**
<img align="left" alt="pco1881\_cap() Example 3" src="images/bottlecaps/pco1881_cap_3.png" width="320" height="240">
include <BOSL2/std.scad>
include <BOSL2/bottlecaps.scad>
pco1881_cap(texture="ribbed");
<br clear="all" /><br/>
**Example 4:** Standard Anchors
<img align="left" alt="pco1881\_cap() Example 4" src="images/bottlecaps/pco1881_cap_4.png" width="320" height="240">
include <BOSL2/std.scad>
include <BOSL2/bottlecaps.scad>
pco1881_cap(texture="ribbed") show_anchors(custom=false);
<br clear="all" /><br/>
**Example 5:** Custom Named Anchors
<img align="left" alt="pco1881\_cap() Example 5" src="images/bottlecaps/pco1881_cap_5.png" width="320" height="240">
include <BOSL2/std.scad>
include <BOSL2/bottlecaps.scad>
expose_anchors(0.5)
pco1881_cap(texture="ribbed")
show_anchors(std=false);
<br clear="all" /><br/>
---
## Section: Generic Bottle Connectors
### Module: generic\_bottle\_neck()
**Synopsis:** Creates a generic neck for a bottle. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup>
**Topics:** [Bottles](Topics#bottles), [Threading](Topics#threading)
**See Also:** [generic\_bottle\_cap()](#module-generic_bottle_cap)
**Usage:**
- generic_bottle_neck([wall], ...) [ATTACHMENTS];
**Description:**
Creates a bottle neck given specifications.
**Arguments:**
<abbr title="These args can be used by position or by name.">By&nbsp;Position</abbr> | What it does
-------------------- | ------------
`wall` | distance between ID and any wall that may be below the support
<abbr title="These args must be used by name, ie: name=value">By&nbsp;Name</abbr> | What it does
-------------------- | ------------
`neck_d` | Outer diameter of neck without threads
`id` | Inner diameter of neck
`thread_od` | Outer diameter of thread
`height` | Height of neck above support
`support_d` | Outer diameter of support ring. Set to 0 for no support.
`pitch` | Thread pitch
`round_supp` | True to round the lower edge of the support ring
`anchor` | Translate so anchor point is at origin (0,0,0). See [anchor](attachments.scad#subsection-anchor). Default: `CENTER`
`spin` | Rotate this many degrees around the Z axis after anchor. See [spin](attachments.scad#subsection-spin). Default: `0`
`orient` | Vector to rotate top towards, after spin. See [orient](attachments.scad#subsection-orient). Default: `UP`
**Named Anchors:**
Anchor Name | Position
----------- | --------
"support-ring" | Centered at the bottom of the support ring.
**Example 1:**
<img align="left" alt="generic\_bottle\_neck() Example 1" src="images/bottlecaps/generic_bottle_neck.png" width="320" height="240">
include <BOSL2/std.scad>
include <BOSL2/bottlecaps.scad>
generic_bottle_neck();
<br clear="all" /><br/>
---
### Module: generic\_bottle\_cap()
**Synopsis:** Creates a generic cap for a bottle. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup>
**Topics:** [Bottles](Topics#bottles), [Threading](Topics#threading)
**See Also:** [generic\_bottle\_neck()](#module-generic_bottle_neck), [sp\_cap()](#module-sp_cap)
**Usage:**
- generic_bottle_cap(wall, [texture], ...) [ATTACHMENTS];
**Description:**
Creates a basic threaded cap given specifications. You must give exactly two of `thread_od`, `neck_od` and `thread_depth` to
specify the thread geometry. Note that most glass bottles conform to the SPI standard and caps for them may be more easily produced using [`sp_cap()`](#module-sp_cap).
**Arguments:**
<abbr title="These args can be used by position or by name.">By&nbsp;Position</abbr> | What it does
-------------------- | ------------
`wall` | Wall thickness. Default: 2
`texture` | The surface texture of the cap. Valid values are "none", "knurled", or "ribbed". Default: "none"
<abbr title="These args must be used by name, ie: name=value">By&nbsp;Name</abbr> | What it does
-------------------- | ------------
`height` | Interior height of the cap
`thread_od` | Outer diameter of the threads
`neck_od` | Outer diameter of neck
`thread_depth` | Depth of the threads
`tolerance` | Extra space to add to the outer diameter of threads and neck. Applied to radius. Default: 0.2
`flank_angle` | Angle of taper on threads. Default: 15
`pitch` | Thread pitch. Default: 4
`anchor` | Translate so anchor point is at origin (0,0,0). See [anchor](attachments.scad#subsection-anchor). Default: `CENTER`
`spin` | Rotate this many degrees around the Z axis after anchor. See [spin](attachments.scad#subsection-spin). Default: `0`
`orient` | Vector to rotate top towards, after spin. See [orient](attachments.scad#subsection-orient). Default: `UP`
**Named Anchors:**
Anchor Name | Position
----------- | --------
"inside-top" | Centered on the inside top of the cap.
**Example 1:**
<img align="left" alt="generic\_bottle\_cap() Example 1" src="images/bottlecaps/generic_bottle_cap.png" width="320" height="240">
include <BOSL2/std.scad>
include <BOSL2/bottlecaps.scad>
generic_bottle_cap(thread_depth=2,neck_od=INCH,height=INCH/2);
<br clear="all" /><br/>
**Example 2:**
<img align="left" alt="generic\_bottle\_cap() Example 2" src="images/bottlecaps/generic_bottle_cap_2.png" width="320" height="240">
<br clear="all" />
include <BOSL2/std.scad>
include <BOSL2/bottlecaps.scad>
generic_bottle_cap(texture="knurled",neck_od=25,thread_od=30,height=10);
**Example 3:**
<img align="left" alt="generic\_bottle\_cap() Example 3" src="images/bottlecaps/generic_bottle_cap_3.png" width="320" height="240">
<br clear="all" />
include <BOSL2/std.scad>
include <BOSL2/bottlecaps.scad>
generic_bottle_cap(texture="ribbed",thread_depth=3,thread_od=25,height=13);
---
### Module: bottle\_adapter\_neck\_to\_cap()
**Synopsis:** Creates a generic adaptor between a neck and a cap. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup>
**Topics:** [Bottles](Topics#bottles), [Threading](Topics#threading)
**See Also:** [bottle\_adapter\_neck\_to\_neck()](#module-bottle_adapter_neck_to_neck)
**Usage:**
- bottle_adapter_neck_to_cap(wall, [texture], ...) [ATTACHMENTS];
**Description:**
Creates a threaded neck to cap adapter
**Arguments:**
<abbr title="These args can be used by position or by name.">By&nbsp;Position</abbr> | What it does
-------------------- | ------------
`wall` | Thickness of wall between neck and cap when d=0. Leave undefined to have the outside of the tube go from the OD of the neck support ring to the OD of the cap. Default: undef
`texture` | The surface texture of the cap. Valid values are "none", "knurled", or "ribbed". Default: "none"
`cap_wall` | Wall thickness of the cap in mm.
`cap_h` | Interior height of the cap in mm.
`cap_thread_depth` | Cap thread depth. Default: 2.34
`tolerance` | Extra space to add to the outer diameter of threads and neck in mm. Applied to radius.
`cap_neck_od` | Inner diameter of the cap threads.
`cap_neck_id` | Inner diameter of the hole through the cap.
`cap_thread_taper` | Angle of taper on threads.
`cap_thread_pitch` | Thread pitch in mm
`neck_d` | Outer diameter of neck w/o threads
`neck_id` | Inner diameter of neck
`neck_thread_od` | 27.2
`neck_h` | Height of neck down to support ring
`neck_thread_pitch` | Thread pitch in mm.
`neck_support_od` | Outer diameter of neck support ring. Leave undefined to set equal to OD of cap. Set to 0 for no ring. Default: undef
`d` | Distance between bottom of neck and top of cap
`taper_lead_in` | Length to leave straight before tapering on tube between neck and cap if exists.
`anchor` | Translate so anchor point is at origin (0,0,0). See [anchor](attachments.scad#subsection-anchor). Default: `CENTER`
`spin` | Rotate this many degrees around the Z axis after anchor. See [spin](attachments.scad#subsection-spin). Default: `0`
`orient` | Vector to rotate top towards, after spin. See [orient](attachments.scad#subsection-orient). Default: `UP`
**Example 1:**
<img align="left" alt="bottle\_adapter\_neck\_to\_cap() Example 1" src="images/bottlecaps/bottle_adapter_neck_to_cap.png" width="320" height="240">
include <BOSL2/std.scad>
include <BOSL2/bottlecaps.scad>
bottle_adapter_neck_to_cap();
<br clear="all" /><br/>
---
### Module: bottle\_adapter\_cap\_to\_cap()
**Synopsis:** Creates a generic adaptor between a cap and a cap. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup>
**Topics:** [Bottles](Topics#bottles), [Threading](Topics#threading)
**See Also:** [bottle\_adapter\_neck\_to\_cap()](#module-bottle_adapter_neck_to_cap), [bottle\_adapter\_neck\_to\_neck()](#module-bottle_adapter_neck_to_neck)
**Usage:**
- bottle_adapter_cap_to_cap(wall, [texture]) [ATTACHMENTS];
**Description:**
Creates a threaded cap to cap adapter.
**Arguments:**
<abbr title="These args can be used by position or by name.">By&nbsp;Position</abbr> | What it does
-------------------- | ------------
`wall` | Wall thickness in mm.
`texture` | The surface texture of the cap. Valid values are "none", "knurled", or "ribbed". Default: "none"
`cap_h1` | Interior height of top cap.
`cap_thread_depth1` | Thread depth on top cap. Default: 2.34
`tolerance` | Extra space to add to the outer diameter of threads and neck in mm. Applied to radius.
`cap_neck_od1` | Inner diameter of threads on top cap.
`cap_thread_pitch1` | Thread pitch of top cap in mm.
`cap_h2` | Interior height of bottom cap. Leave undefined to duplicate cap_h1.
`cap_thread_depth2` | Thread depth on bottom cap. Default: same as cap_thread_depth1
`cap_neck_od2` | Inner diameter of threads on top cap. Leave undefined to duplicate cap_neck_od1.
`cap_thread_pitch2` | Thread pitch of bottom cap in mm. Leave undefinced to duplicate cap_thread_pitch1.
`d` | Distance between caps.
`neck_id1` | Inner diameter of cutout in top cap.
`neck_id2` | Inner diameter of cutout in bottom cap.
`taper_lead_in` | Length to leave straight before tapering on tube between caps if exists.
`anchor` | Translate so anchor point is at origin (0,0,0). See [anchor](attachments.scad#subsection-anchor). Default: `CENTER`
`spin` | Rotate this many degrees around the Z axis after anchor. See [spin](attachments.scad#subsection-spin). Default: `0`
`orient` | Vector to rotate top towards, after spin. See [orient](attachments.scad#subsection-orient). Default: `UP`
**Example 1:**
<img align="left" alt="bottle\_adapter\_cap\_to\_cap() Example 1" src="images/bottlecaps/bottle_adapter_cap_to_cap.png" width="320" height="240">
include <BOSL2/std.scad>
include <BOSL2/bottlecaps.scad>
bottle_adapter_cap_to_cap();
<br clear="all" /><br/>
---
### Module: bottle\_adapter\_neck\_to\_neck()
**Synopsis:** Creates a generic adaptor between a neck and a neck. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup>
**Topics:** [Bottles](Topics#bottles), [Threading](Topics#threading)
**See Also:** [bottle\_adapter\_neck\_to\_cap()](#module-bottle_adapter_neck_to_cap), [bottle\_adapter\_cap\_to\_cap()](#module-bottle_adapter_cap_to_cap)
**Usage:**
- bottle_adapter_neck_to_neck(...) [ATTACHMENTS];
**Description:**
Creates a threaded neck to neck adapter.
**Arguments:**
<abbr title="These args can be used by position or by name.">By&nbsp;Position</abbr> | What it does
-------------------- | ------------
`d` | Distance between bottoms of necks
`neck_od1` | Outer diameter of top neck w/o threads
`neck_id1` | Inner diameter of top neck
`thread_od1` | Outer diameter of threads on top neck
`height1` | Height of top neck above support ring.
`support_od1` | Outer diameter of the support ring on the top neck. Set to 0 for no ring.
`thread_pitch1` | Thread pitch of top neck.
`neck_od2` | Outer diameter of bottom neck w/o threads. Leave undefined to duplicate neck_od1
`neck_id2` | Inner diameter of bottom neck. Leave undefined to duplicate neck_id1
`thread_od2` | Outer diameter of threads on bottom neck. Leave undefined to duplicate thread_od1
`height2` | Height of bottom neck above support ring. Leave undefined to duplicate height1
`support_od2` | Outer diameter of the support ring on bottom neck. Set to 0 for no ring. Leave undefined to duplicate support_od1
`pitch2` | Thread pitch of bottom neck. Leave undefined to duplicate thread_pitch1
`taper_lead_in` | Length to leave straight before tapering on tube between necks if exists.
`wall` | Thickness of tube wall between necks. Leave undefined to match outer diameters with the neckODs/supportODs.
`anchor` | Translate so anchor point is at origin (0,0,0). See [anchor](attachments.scad#subsection-anchor). Default: `CENTER`
`spin` | Rotate this many degrees around the Z axis after anchor. See [spin](attachments.scad#subsection-spin). Default: `0`
`orient` | Vector to rotate top towards, after spin. See [orient](attachments.scad#subsection-orient). Default: `UP`
**Example 1:**
<img align="left" alt="bottle\_adapter\_neck\_to\_neck() Example 1" src="images/bottlecaps/bottle_adapter_neck_to_neck.png" width="320" height="240">
include <BOSL2/std.scad>
include <BOSL2/bottlecaps.scad>
bottle_adapter_neck_to_neck();
<br clear="all" /><br/>
---
## Section: SPI Bottle Threading
### Module: sp\_neck()
**Synopsis:** Creates an SPI threaded bottle neck. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup>
**Topics:** [Bottles](Topics#bottles), [Threading](Topics#threading)
**See Also:** [sp\_cap()](#module-sp_cap)
**Usage:**
- sp_neck(diam, type, wall|id=, [style=], [bead=]) [ATTACHMENTS];
**Description:**
Make a SPI (Society of Plastics Industry) threaded bottle neck. You must
supply the nominal outer diameter of the threads and the thread type, one of
400, 410 and 415. The 400 type neck has 360 degrees of thread, the 410
neck has 540 degrees of thread, and the 415 neck has 720 degrees of thread.
You can also choose between the L style thread, which is symmetric and
the M style thread, which is an asymmetric buttress thread. The M style
may be good for 3d printing if printed with the flat face up.
You can specify the wall thickness (measured from the base of the threads) or
the inner diameter, and you can specify an optional bead at the base of the threads.
**Arguments:**
<abbr title="These args can be used by position or by name.">By&nbsp;Position</abbr> | What it does
-------------------- | ------------
`diam` | nominal outer diameter of threads
`type` | thread type, one of 400, 410 and 415
`wall` | wall thickness
<abbr title="These args must be used by name, ie: name=value">By&nbsp;Name</abbr> | What it does
-------------------- | ------------
`id` | inner diameter
`style` | Either "L" or "M" to specify the thread style. Default: "L"
`bead` | if true apply a bad to the neck. Default: false
`anchor` | Translate so anchor point is at origin (0,0,0). See [anchor](attachments.scad#subsection-anchor). Default: `CENTER`
`spin` | Rotate this many degrees around the Z axis after anchor. See [spin](attachments.scad#subsection-spin). Default: `0`
`orient` | Vector to rotate top towards, after spin. See [orient](attachments.scad#subsection-orient). Default: `UP`
**Example 1:**
<img align="left" alt="sp\_neck() Example 1" src="images/bottlecaps/sp_neck.png" width="320" height="240">
include <BOSL2/std.scad>
include <BOSL2/bottlecaps.scad>
sp_neck(48,400,2);
<br clear="all" /><br/>
**Example 2:**
<img align="left" alt="sp\_neck() Example 2" src="images/bottlecaps/sp_neck_2.png" width="320" height="240">
include <BOSL2/std.scad>
include <BOSL2/bottlecaps.scad>
sp_neck(48,400,2,bead=true);
<br clear="all" /><br/>
**Example 3:**
<img align="left" alt="sp\_neck() Example 3" src="images/bottlecaps/sp_neck_3.png" width="320" height="240">
include <BOSL2/std.scad>
include <BOSL2/bottlecaps.scad>
sp_neck(22,410,2);
<br clear="all" /><br/>
**Example 4:**
<img align="left" alt="sp\_neck() Example 4" src="images/bottlecaps/sp_neck_4.png" width="320" height="240">
include <BOSL2/std.scad>
include <BOSL2/bottlecaps.scad>
sp_neck(22,410,2,bead=true);
<br clear="all" /><br/>
**Example 5:**
<img align="left" alt="sp\_neck() Example 5" src="images/bottlecaps/sp_neck_5.png" width="320" height="240">
include <BOSL2/std.scad>
include <BOSL2/bottlecaps.scad>
sp_neck(28,415,id=20,style="M");
<br clear="all" /><br/>
**Example 6:**
<img align="left" alt="sp\_neck() Example 6" src="images/bottlecaps/sp_neck_6.png" width="320" height="240">
include <BOSL2/std.scad>
include <BOSL2/bottlecaps.scad>
sp_neck(13,415,wall=1,style="M",bead=true);
<br clear="all" /><br/>
---
### Module: sp\_cap()
**Synopsis:** Creates an SPI threaded bottle cap. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup>
**Topics:** [Bottles](Topics#bottles), [Threading](Topics#threading)
**See Also:** [sp\_neck()](#module-sp_neck)
**Usage:**
- sp_cap(diam, type, wall, [style=], [top_adj=], [bot_adj=], [texture=], [$slop]) [ATTACHMENTS];
**Description:**
Make a SPI (Society of Plastics Industry) threaded bottle neck. You must
supply the nominal outer diameter of the threads and the thread type, one of
400, 410 and 415. The 400 type neck has 360 degrees of thread, the 410
neck has 540 degrees of thread, and the 415 neck has 720 degrees of thread.
You can also choose between the L style thread, which is symmetric and
the M style thread, which is an asymmetric buttress thread. Note that it
is OK to mix styles, so you can put an L-style cap onto an M-style neck.
The 410 and 415 caps have very long unthreaded sections at the bottom.
The bot_adj parameter specifies an amount to reduce that bottom extension, which might be
necessary if the cap bottoms out on the bead. Be careful that you don't shrink past the threads,
especially if making adjustments to 400 caps which have a very small bottom extension.
These caps often contain a cardboard or foam sealer disk, which can be as much as 1mm thick, and
would cause the cap to stop in a higher position.
You can also adjust the space between the top of the cap and the threads using top_adj. This
will change how the threads engage when the cap is fully seated.
The inner diameter of the cap is set to allow 10% of the thread depth in clearance. The diameter
is further increased by `2 * $slop` so you can increase clearance if necessary.
Note: there is a published SPI standard for necks, but absolutely nothing for caps. This
cap module was designed based on the neck standard to mate reasonably well, but if you
find ways that it does the wrong thing, file a report.
**Arguments:**
<abbr title="These args can be used by position or by name.">By&nbsp;Position</abbr> | What it does
-------------------- | ------------
`diam` | nominal outer diameter of threads
`type` | thread type, one of 400, 410 and 415
`wall` | wall thickness
<abbr title="These args must be used by name, ie: name=value">By&nbsp;Name</abbr> | What it does
-------------------- | ------------
`style` | Either "L" or "M" to specify the thread style. Default: "L"
`top_adj` | Amount to reduce top space in the cap, which means it doesn't screw down as far. Default: 0
`bot_adj` | Amount to reduce extension of cap at the bottom, which also means it doesn't screw down as far. Default: 0
`texture` | texture for outside of cap, one of "knurled", "ribbed" or "none. Default: "none"
`$slop` | Increase inner diameter by `2 * $slop`.
`anchor` | Translate so anchor point is at origin (0,0,0). See [anchor](attachments.scad#subsection-anchor). Default: `CENTER`
`spin` | Rotate this many degrees around the Z axis after anchor. See [spin](attachments.scad#subsection-spin). Default: `0`
`orient` | Vector to rotate top towards, after spin. See [orient](attachments.scad#subsection-orient). Default: `UP`
**Example 1:**
<img align="left" alt="sp\_cap() Example 1" src="images/bottlecaps/sp_cap.png" width="320" height="240">
include <BOSL2/std.scad>
include <BOSL2/bottlecaps.scad>
sp_cap(48,400,2);
<br clear="all" /><br/>
**Example 2:**
<img align="left" alt="sp\_cap() Example 2" src="images/bottlecaps/sp_cap_2.png" width="320" height="240">
include <BOSL2/std.scad>
include <BOSL2/bottlecaps.scad>
sp_cap(22,400,2);
<br clear="all" /><br/>
**Example 3:**
<img align="left" alt="sp\_cap() Example 3" src="images/bottlecaps/sp_cap_3.png" width="320" height="240">
include <BOSL2/std.scad>
include <BOSL2/bottlecaps.scad>
sp_cap(22,410,2);
<br clear="all" /><br/>
**Example 4:**
<img align="left" alt="sp\_cap() Example 4" src="images/bottlecaps/sp_cap_4.png" width="320" height="240">
include <BOSL2/std.scad>
include <BOSL2/bottlecaps.scad>
sp_cap(28,415,1.5,style="M");
<br clear="all" /><br/>
---
### Function: sp\_diameter()
**Synopsis:** Returns the base diameter of an SPI bottle neck from the nominal diameter and type number.
**Topics:** [Bottles](Topics#bottles), [Threading](Topics#threading)
**See Also:** [sp\_neck()](#module-sp_neck), [sp\_cap()](#module-sp_cap)
**Usage:**
- true_diam = sp_diameter(diam,type)
**Description:**
Returns the actual base diameter (root of the threads) for a SPI plastic bottle neck given the nominal diameter and type number (400, 410, 415).
**Arguments:**
<abbr title="These args can be used by position or by name.">By&nbsp;Position</abbr> | What it does
-------------------- | ------------
`diam` | nominal diameter
`type` | closure type number (400, 410 or 415)
---

480
color.scad.md Normal file

@ -0,0 +1,480 @@
# LibFile: color.scad
HSV and HSL conversion, rainbow() module for coloring multiple objects.
The recolor() and color_this() modules allow you to change the color
of previously colored attachable objects.
To use, add the following lines to the beginning of your file:
include <BOSL2/std.scad>
## File Contents
1. [Section: Coloring Objects](#section-coloring-objects)
- [`recolor()`](#module-recolor) Sets the color for attachable children and their descendants. <sup title="Can transform children.">[<abbr>Trans</abbr>]</sup>
- [`color_this()`](#module-color_this) Sets the color for children at the current level only. <sup title="Can transform children.">[<abbr>Trans</abbr>]</sup>
- [`rainbow()`](#module-rainbow) Iterates through a list, displaying children in different colors. <sup title="Can transform children.">[<abbr>Trans</abbr>]</sup>
- [`color_overlaps()`](#module-color_overlaps) Shows ghostly children, with overlaps highlighted in color. <sup title="Can transform children.">[<abbr>Trans</abbr>]</sup>
2. [Section: Setting Object Modifiers](#section-setting-object-modifiers)
- [`highlight()`](#module-highlight) Sets # modifier for attachable children and their descendents. <sup title="Can transform children.">[<abbr>Trans</abbr>]</sup>
- [`highlight_this()`](#module-highlight_this) Apply # modifier to children at a single level. <sup title="Can transform children.">[<abbr>Trans</abbr>]</sup>
- [`ghost()`](#module-ghost) Sets % modifier for attachable children and their descendents. <sup title="Can transform children.">[<abbr>Trans</abbr>]</sup>
- [`ghost_this()`](#module-ghost_this) Apply % modifier to children at a single level. <sup title="Can transform children.">[<abbr>Trans</abbr>]</sup>
3. [Section: Colorspace Conversion](#section-colorspace-conversion)
- [`hsl()`](#functionmodule-hsl) Sets the color of children to a specified hue, saturation, lightness and optional alpha channel value. <sup title="Can transform children.">[<abbr>Trans</abbr>]</sup>
- [`hsv()`](#functionmodule-hsv) Sets the color of children to a hue, saturation, value and optional alpha channel value. <sup title="Can transform children.">[<abbr>Trans</abbr>]</sup>
## Section: Coloring Objects
### Module: recolor()
**Synopsis:** Sets the color for attachable children and their descendants. <sup title="Can transform children.">[<abbr>Trans</abbr>]</sup>
**Topics:** [Attachments](Topics#attachments)
**See Also:** [color\_this()](#module-color_this), [hsl()](#functionmodule-hsl), [hsv()](#functionmodule-hsv)
**Usage:**
- recolor([c]) CHILDREN;
**Description:**
Sets the color for attachable children and their descendants, down until another [`recolor()`](#module-recolor)
or [`color_this()`](#module-color_this). This only works with attachables and you cannot have any color() modules
above it in any parents, only other [`recolor()`](#module-recolor) or [`color_this()`](#module-color_this) modules. This works by
setting the special `$color` variable, which attachable objects make use of to set the color.
**Arguments:**
<abbr title="These args can be used by position or by name.">By&nbsp;Position</abbr> | What it does
-------------------- | ------------
`c` | Color name or RGBA vector. Default: The default color in your color scheme.
**Side Effects:**
- Changes the value of `$color`.
- Sets the color of child attachments.
**Example 1:**
<img align="left" alt="recolor() Example 1" src="images/color/recolor.png" width="320" height="240">
include <BOSL2/std.scad>
cuboid([10,10,5])
recolor("green")attach(TOP,BOT) cuboid([9,9,4.5])
attach(TOP,BOT) cuboid([8,8,4])
recolor("purple") attach(TOP,BOT) cuboid([7,7,3.5])
attach(TOP,BOT) cuboid([6,6,3])
recolor("cyan")attach(TOP,BOT) cuboid([5,5,2.5])
attach(TOP,BOT) cuboid([4,4,2]);
<br clear="all" /><br/>
---
### Module: color\_this()
**Synopsis:** Sets the color for children at the current level only. <sup title="Can transform children.">[<abbr>Trans</abbr>]</sup>
**Topics:** [Attachments](Topics#attachments)
**See Also:** [recolor()](#module-recolor), [hsl()](#functionmodule-hsl), [hsv()](#functionmodule-hsv)
**Usage:**
- color_this([c]) CHILDREN;
**Description:**
Sets the color for children at one level, reverting to the previous color for further descendants.
This works only with attachables and you cannot have any color() modules above it in any parents,
only recolor() or other color_this() modules. This works using the `$color` and `$save_color` variables,
which attachable objects make use of to set the color.
**Arguments:**
<abbr title="These args can be used by position or by name.">By&nbsp;Position</abbr> | What it does
-------------------- | ------------
`c` | Color name or RGBA vector. Default: the default color in your color scheme
**Side Effects:**
- Changes the value of `$color` and `$save_color`.
- Sets the color of child attachments.
**Example 1:**
<img align="left" alt="color\_this() Example 1" src="images/color/color_this.png" width="320" height="240">
include <BOSL2/std.scad>
cuboid([10,10,5])
color_this("green")attach(TOP,BOT) cuboid([9,9,4.5])
attach(TOP,BOT) cuboid([8,8,4])
color_this("purple") attach(TOP,BOT) cuboid([7,7,3.5])
attach(TOP,BOT) cuboid([6,6,3])
color_this("cyan")attach(TOP,BOT) cuboid([5,5,2.5])
attach(TOP,BOT) cuboid([4,4,2]);
<br clear="all" /><br/>
---
### Module: rainbow()
**Synopsis:** Iterates through a list, displaying children in different colors. <sup title="Can transform children.">[<abbr>Trans</abbr>]</sup>
**Topics:** [List Handling](Topics#list-handling)
**See Also:** [hsl()](#functionmodule-hsl), [hsv()](#functionmodule-hsv)
**Usage:**
- rainbow(list,[stride],[maxhues],[shuffle],[seed]) CHILDREN;
**Description:**
Iterates the list, displaying children in different colors for each list item. The color
is set using the color() module, so this module is not compatible with [`recolor()`](#module-recolor) or
[`color_this()`](#module-color_this). This is useful for debugging regions or lists of paths.
**Arguments:**
<abbr title="These args can be used by position or by name.">By&nbsp;Position</abbr> | What it does
-------------------- | ------------
`list` | The list of items to iterate through.
`stride` | Consecutive colors stride around the color wheel divided into this many parts.
`maxhues` | max number of hues to use (to prevent lots of indistinguishable hues)
`shuffle` | if true then shuffle the hues in a random order. Default: false
`seed` | seed to use for shuffle
**Side Effects:**
- Sets the color to progressive values along the ROYGBIV spectrum for each item.
- Sets `$idx` to the index of the current item in `list` that we want to show.
- Sets `$item` to the current item in `list` that we want to show.
**Example 1:**
<img align="left" alt="rainbow() Example 1" src="images/color/rainbow.png" width="320" height="240">
<br clear="all" />
include <BOSL2/std.scad>
rainbow(["Foo","Bar","Baz"]) fwd($idx*10) text(text=$item,size=8,halign="center",valign="center");
**Example 2:**
<img align="left" alt="rainbow() Example 2" src="images/color/rainbow_2.png" width="320" height="240">
include <BOSL2/std.scad>
rgn = [circle(d=45,$fn=3), circle(d=75,$fn=4), circle(d=50)];
rainbow(rgn) stroke($item, closed=true);
<br clear="all" /><br/>
---
### Module: color\_overlaps()
**Synopsis:** Shows ghostly children, with overlaps highlighted in color. <sup title="Can transform children.">[<abbr>Trans</abbr>]</sup>
**Topics:** [Debugging](Topics#debugging)
**See Also:** [rainbow()](#module-rainbow), [debug\_vnf()](vnf.scad#module-debug_vnf)
**Usage:**
- color_overlaps([color]) CHILDREN;
**Description:**
Displays the given children in ghostly transparent gray, while the places where the
they overlap are highlighted with the given color.
**Arguments:**
<abbr title="These args can be used by position or by name.">By&nbsp;Position</abbr> | What it does
-------------------- | ------------
`color` | The color to highlight overlaps with. Default: "red"
**Example 1:** 2D Overlaps
<img align="left" alt="color\_overlaps() Example 1" src="images/color/color_overlaps.png" width="320" height="240">
include <BOSL2/std.scad>
color_overlaps() {
circle(d=50);
left(20) circle(d=50);
right(20) circle(d=50);
}
<br clear="all" /><br/>
**Example 2:** 3D Overlaps
<img align="left" alt="color\_overlaps() Example 2" src="images/color/color_overlaps_2.png" width="320" height="240">
include <BOSL2/std.scad>
color_overlaps() {
cuboid(50);
left(30) sphere(d=50);
right(30) sphere(d=50);
xcyl(d=10,l=120);
}
<br clear="all" /><br/>
---
## Section: Setting Object Modifiers
### Module: highlight()
**Synopsis:** Sets # modifier for attachable children and their descendents. <sup title="Can transform children.">[<abbr>Trans</abbr>]</sup>
**Topics:** [Attachments](Topics#attachments), [Modifiers](Topics#modifiers)
**See Also:** [highlight\_this()](#module-highlight_this), [ghost()](#module-ghost), [ghost\_this()](#module-ghost_this), [recolor()](#module-recolor), [color\_this()](#module-color_this)
**Usage:**
- highlight([highlight]) CHILDREN;
**Description:**
Sets the `#` modifier for the attachable children and their descendents until another [`highlight()`](#module-highlight) or [`highlight_this()`](#module-highlight_this).
By default, turns `#` on, which makes the children transparent pink and displays them even if they are subtracted from the model.
Give the `false` parameter to disable the modifier and restore children to normal.
Do not mix this with user supplied `#` modifiers anywhere in the geometry tree.
**Arguments:**
<abbr title="These args can be used by position or by name.">By&nbsp;Position</abbr> | What it does
-------------------- | ------------
`highlight` | If true set the descendents to use `#`; if false, disable `#` for descendents. Default: true
**Example 1:**
<img align="left" alt="highlight() Example 1" src="images/color/highlight.png" width="320" height="240">
include <BOSL2/std.scad>
highlight() cuboid(10)
highlight(false) attach(RIGHT,BOT)cuboid(5);
<br clear="all" /><br/>
---
### Module: highlight\_this()
**Synopsis:** Apply # modifier to children at a single level. <sup title="Can transform children.">[<abbr>Trans</abbr>]</sup>
**Topics:** [Attachments](Topics#attachments), [Modifiers](Topics#modifiers)
**See Also:** [highlight()](#module-highlight), [ghost()](#module-ghost), [ghost\_this()](#module-ghost_this), [recolor()](#module-recolor), [color\_this()](#module-color_this)
**Usage:**
- highlight_this() CHILDREN;
**Description:**
Applies the `#` modifier to the children at a single level, reverting to the previous highlight state for further descendents.
This works only with attachables and you cannot give the `#` operator anywhere in the geometry tree.
**Example 1:**
<img align="left" alt="highlight\_this() Example 1" src="images/color/highlight_this.png" width="320" height="240">
include <BOSL2/std.scad>
highlight_this()
cuboid(10)
attach(TOP,BOT)cuboid(5);
<br clear="all" /><br/>
---
### Module: ghost()
**Synopsis:** Sets % modifier for attachable children and their descendents. <sup title="Can transform children.">[<abbr>Trans</abbr>]</sup>
**Topics:** [Attachments](Topics#attachments), [Modifiers](Topics#modifiers)
**See Also:** [ghost\_this()](#module-ghost_this), [recolor()](#module-recolor), [color\_this()](#module-color_this)
**Usage:**
- ghost([ghost]) CHILDREN;
**Description:**
Sets the `%` modifier for the attachable children and their descendents until another [`ghost()`](#module-ghost) or [`ghost_this()`](#module-ghost_this).
By default, turns `%` on, which makes the children gray and also removes them from interaction with the model.
Give the `false` parameter to disable the modifier and restore children to normal.
Do not mix this with user supplied `%` modifiers anywhere in the geometry tree.
**Arguments:**
<abbr title="These args can be used by position or by name.">By&nbsp;Position</abbr> | What it does
-------------------- | ------------
`ghost` | If true set the descendents to use `%`; if false, disable `%` for descendents. Default: true
**Example 1:**
<img align="left" alt="ghost() Example 1" src="images/color/ghost.png" width="320" height="240">
include <BOSL2/std.scad>
ghost() cuboid(10)
ghost(false) cuboid(5);
<br clear="all" /><br/>
---
### Module: ghost\_this()
**Synopsis:** Apply % modifier to children at a single level. <sup title="Can transform children.">[<abbr>Trans</abbr>]</sup>
**Topics:** [Attachments](Topics#attachments), [Modifiers](Topics#modifiers)
**See Also:** [ghost()](#module-ghost), [recolor()](#module-recolor), [color\_this()](#module-color_this)
**Usage:**
- ghost_this() CHILDREN;
**Description:**
Applies the `%` modifier to the children at a single level, reverting to the previous ghost state for further descendents.
This works only with attachables and you cannot give the `%` operator anywhere in the geometry tree.
**Example 1:**
<img align="left" alt="ghost\_this() Example 1" src="images/color/ghost_this.png" width="320" height="240">
include <BOSL2/std.scad>
ghost_this() cuboid(10)
cuboid(5);
<br clear="all" /><br/>
---
## Section: Colorspace Conversion
### Function/Module: hsl()
**Synopsis:** Sets the color of children to a specified hue, saturation, lightness and optional alpha channel value. <sup title="Can transform children.">[<abbr>Trans</abbr>]</sup>
**Topics:** [Colors](Topics#colors), [Colorspace](Topics#colorspace)
**See Also:** [hsv()](#functionmodule-hsv), [recolor()](#module-recolor), [color\_this()](#module-color_this)
**Usage:**
- hsl(h,[s],[l],[a]) CHILDREN;
- rgb = hsl(h,[s],[l],[a]);
**Description:**
When called as a function, returns the `[R,G,B]` color for the given hue `h`, saturation `s`, and
lightness `l` from the HSL colorspace. If you supply the `a` value then you'll get a length 4
list `[R,G,B,A]`. When called as a module, sets the color using the color() module to the given
hue `h`, saturation `s`, and lightness `l` from the HSL colorspace.
**Arguments:**
<abbr title="These args can be used by position or by name.">By&nbsp;Position</abbr> | What it does
-------------------- | ------------
`h` | The hue, given as a value between 0 and 360. 0=red, 60=yellow, 120=green, 180=cyan, 240=blue, 300=magenta.
`s` | The saturation, given as a value between 0 and 1. 0 = grayscale, 1 = vivid colors. Default: 1
`l` | The lightness, between 0 and 1. 0 = black, 0.5 = bright colors, 1 = white. Default: 0.5
`a` | Specifies the alpha channel as a value between 0 and 1. 0 = fully transparent, 1=opaque. Default: 1
**Side Effects:**
- When called as a module, sets the color of all children.
**Example 1:**
<img align="left" alt="hsl() Example 1" src="images/color/hsl.png" width="320" height="240">
include <BOSL2/std.scad>
hsl(h=120,s=1,l=0.5) sphere(d=60);
<br clear="all" /><br/>
**Example 2:**
<img align="left" alt="hsl() Example 2" src="images/color/hsl_2.png" width="320" height="240">
include <BOSL2/std.scad>
rgb = hsl(h=270,s=0.75,l=0.6);
color(rgb) cube(60, center=true);
<br clear="all" /><br/>
---
### Function/Module: hsv()
**Synopsis:** Sets the color of children to a hue, saturation, value and optional alpha channel value. <sup title="Can transform children.">[<abbr>Trans</abbr>]</sup>
**Topics:** [Colors](Topics#colors), [Colorspace](Topics#colorspace)
**See Also:** [hsl()](#functionmodule-hsl), [recolor()](#module-recolor), [color\_this()](#module-color_this)
**Usage:**
- hsv(h,[s],[v],[a]) CHILDREN;
- rgb = hsv(h,[s],[v],[a]);
**Description:**
When called as a function, returns the `[R,G,B]` color for the given hue `h`, saturation `s`, and
value `v` from the HSV colorspace. If you supply the `a` value then you'll get a length 4 list
`[R,G,B,A]`. When called as a module, sets the color using the color() module to the given hue
`h`, saturation `s`, and value `v` from the HSV colorspace.
**Arguments:**
<abbr title="These args can be used by position or by name.">By&nbsp;Position</abbr> | What it does
-------------------- | ------------
`h` | The hue, given as a value between 0 and 360. 0=red, 60=yellow, 120=green, 180=cyan, 240=blue, 300=magenta.
`s` | The saturation, given as a value between 0 and 1. 0 = grayscale, 1 = vivid colors. Default: 1
`v` | The value, between 0 and 1. 0 = darkest black, 1 = bright. Default: 1
`a` | Specifies the alpha channel as a value between 0 and 1. 0 = fully transparent, 1=opaque. Default: 1
**Side Effects:**
- When called as a module, sets the color of all children.
**Example 1:**
<img align="left" alt="hsv() Example 1" src="images/color/hsv.png" width="320" height="240">
include <BOSL2/std.scad>
hsv(h=120,s=1,v=1) sphere(d=60);
<br clear="all" /><br/>
**Example 2:**
<img align="left" alt="hsv() Example 2" src="images/color/hsv_2.png" width="320" height="240">
include <BOSL2/std.scad>
rgb = hsv(h=270,s=0.75,v=0.9);
color(rgb) cube(60, center=true);
<br clear="all" /><br/>
---

1041
comparisons.scad.md Normal file

File diff suppressed because it is too large Load diff

500
constants.scad.md Normal file

@ -0,0 +1,500 @@
# LibFile: constants.scad
Constants for directions (used with anchoring), and for specifying line termination for
use with geometry.scad.
To use, add the following lines to the beginning of your file:
include <BOSL2/std.scad>
## File Contents
1. [Section: General Constants](#section-general-constants)
- [`$slop`](#constant-slop) The slop amount to make printed items fit closely. `0.0` by default.
- [`get_slop()`](#function-get_slop) Returns the $slop value.
- [`INCH`](#constant-inch) A constant containing the number of millimeters in an inch. `25.4`
- [`IDENT`](#constant-ident) A constant containing the 3D identity transformation matrix. <sup title="Can return a transformation matrix.">[<abbr>Mat</abbr>]</sup>
2. [Section: Directional Vectors](#section-directional-vectors)
- [`LEFT`](#constant-left) The left-wards (X-) direction vector constant `[-1,0,0]`.
- [`RIGHT`](#constant-right) The right-wards (X+) direction vector constant `[1,0,0]`.
- [`FRONT`](#constant-front) The front-wards (Y-) direction vector constant `[0,-1,0]`.
- [`BACK`](#constant-back) The backwards (Y+) direction vector constant `[0,1,0]`.
- [`BOTTOM`](#constant-bottom) The down-wards (Z-) direction vector constant `[0,0,-1]`.
- [`TOP`](#constant-top) The top-wards (Z+) direction vector constant `[0,0,1]`.
- [`CENTER`](#constant-center) The center vector constant `[0,0,0]`.
- [`EDGE()`](#function-edge) Named edge anchor constants
- [`FACE()`](#function-face) Named face anchor constants
3. [Section: Line specifiers](#section-line-specifiers)
- [`SEGMENT`](#constant-segment) A constant for specifying a line segment in various geometry.scad functions. `[true,true]`
- [`RAY`](#constant-ray) A constant for specifying a ray line in various geometry.scad functions. `[true,false]`
- [`LINE`](#constant-line) A constant for specifying an unbounded line in various geometry.scad functions. `[false,false]`
## Section: General Constants
### Constant: $slop
**Synopsis:** The slop amount to make printed items fit closely. `0.0` by default.
**Topics:** [Constants](Topics#constants)
**Description:**
A number of printers, particularly FDM/FFF printers, tend to be a bit sloppy in their printing.
This has made it so that some parts won't fit together without adding a bit of extra slop space.
That is what the `$slop` value is for. The value for this will vary from printer to printer.
By default, we use a value of 0.00 so that parts should fit exactly for resin and other precision
printers. This value is measured in millimeters. When making your own parts, you should add
`$slop` to both sides of a hole that another part is to fit snugly into. For a loose fit, add
`2*$slop` to each side. This should be done for both X and Y axes. The Z axis will require a
slop that depends on your layer height and bridging settings, and hole sizes. We leave that as
a more complicated exercise for the user.
Note that the slop value is accessed using the [`get_slop()`](#function-get_slop) function. This function provides
the default value of 0 if you have not set `$slop`. This approach makes it possible for you to
set `$slop` in your programs without experiencing peculiar OpenSCAD issues having to do with multiple
definitions of the variable. If you write code that uses `$slop` be sure to reference it using [`get_slop()`](#function-get_slop).
**Calibration:** To calibrate the `$slop` value for your printer, follow this procedure:
1. Print the Slop Calibration part from the example below.
2. Take the long block and orient it so the numbers are upright, facing you.
3. Take the plug and orient it so that the arrow points down, facing you.
4. Starting with the hole with the largest number in front of it, insert the small end of the plug into the hole.
5. If you can insert and remove the small end of the plug from the hole without much force, then try again with the hole with the next smaller number.
6. Repeat step 5 until you have found the hole with the smallest number that the plug fits into without much force.
7. The correct hole should hold the plug when the long block is turned upside-down.
8. The number in front of that hole will indicate the `$slop` value that is ideal for your printer.
9. Remember to set that slop value in your scripts after you include the BOSL2 library: ie: `$slop = 0.15;`
10. .
11. Note that the `$slop` value may be different using different materials even on the same printer.
**Example 1:** Slop Calibration Part.
<img align="left" alt="$slop Example 1" src="images/constants/slop.png" width="480" height="360">
<br clear="all" />
include <BOSL2/std.scad>
min_slop = 0.00;
slop_step = 0.05;
holes = 8;
holesize = [15,15,15];
height = 20;
gap = 5;
l = holes * (holesize.x + gap) + gap;
w = holesize.y + 2*gap;
h = holesize.z + 5;
diff("holes")
cuboid([l, w, h], anchor=BOT) {
for (i=[0:holes-1]) {
right((i-holes/2+0.5)*(holesize.x+gap)) {
s = min_slop + slop_step * i;
tag("holes") {
cuboid([holesize.x + 2*s, holesize.y + 2*s, h+0.2]);
fwd(w/2-1) xrot(90) linear_extrude(1.1) {
text(
text=format_fixed(s,2),
size=0.4*holesize.x,
halign="center",
valign="center"
);
}
}
}
}
}
back(holesize.y*2.5) {
difference() {
union() {
cuboid([holesize.x+10, holesize.y+10, 15], anchor=BOT);
cuboid([holesize.x, holesize.y, 15+holesize.z], anchor=BOT);
}
up(3) fwd((holesize.y+10)/2) {
prismoid([holesize.x/2,1], [0,1], h=holesize.y-6);
}
}
}
**Example 2:** Where to add `$slop` gaps.
<img align="left" alt="$slop Example 2" src="images/constants/slop_2.png" width="320" height="240">
include <BOSL2/std.scad>
$slop = 0.2;
difference() {
square([20,12],center=true);
back(3) square([10+2*$slop,11],center=true);
}
back(8) {
rect([15,5],anchor=FWD);
rect([10,8],anchor=BACK);
}
color("#000") {
arrow_path = [[5.1,6.1], [6.0,7.1], [8,7.1], [10.5,10]];
xflip_copy()
stroke(arrow_path, width=0.3, endcap1="arrow2");
xcopies(21) back(10.5) {
back(1.8) text("$slop", size=1.5, halign="center");
text("gap", size=1.5, halign="center");
}
}
<br clear="all" /><br/>
---
### Function: get\_slop()
**Synopsis:** Returns the $slop value.
**Topics:** [Slop](Topics#slop)
**See Also:** [$slop](#constant-slop)
**Usage:**
- slop = get_slop();
**Description:**
Returns the current $slop value, or the default value if the user did not set $slop.
Always acess the `$slop` variable using this function.
---
### Constant: INCH
**Synopsis:** A constant containing the number of millimeters in an inch. `25.4`
**Topics:** [Constants](Topics#constants)
**Description:**
The number of millimeters in an inch.
**Example 1:**
<img align="left" alt="INCH Example 1" src="images/constants/inch.png" width="320" height="240">
include <BOSL2/std.scad>
square(2*INCH, center=true);
<br clear="all" /><br/>
**Example 2:**
<img align="left" alt="INCH Example 2" src="images/constants/inch_2.png" width="320" height="240">
include <BOSL2/std.scad>
cube([4,3,2.5]*INCH, center=true);
<br clear="all" /><br/>
---
### Constant: IDENT
**Synopsis:** A constant containing the 3D identity transformation matrix. <sup title="Can return a transformation matrix.">[<abbr>Mat</abbr>]</sup>
**Topics:** [Constants](Topics#constants), [Affine](Topics#affine), [Matrices](Topics#matrices), [Transforms](Topics#transforms)
**See Also:** [ident()](linalg.scad#function-ident)
**Description:**
Identity transformation matrix for three-dimensional transforms. Equal to `ident(4)`.
---
## Section: Directional Vectors
Vectors useful for `rotate()`, `mirror()`, and `anchor` arguments for `cuboid()`, `cyl()`, etc.
### Constant: LEFT
**Synopsis:** The left-wards (X-) direction vector constant `[-1,0,0]`.
**Topics:** [Constants](Topics#constants), [Vectors](Topics#vectors)
**See Also:** [RIGHT](#constant-right), [FRONT](#constant-front), [BACK](#constant-back), [TOP](#constant-top), [BOTTOM](#constant-bottom), [CENTER](#constant-center)
**Description:**
Vector pointing left. [-1,0,0]
**Example 1:** Usage with `anchor`
<img align="left" alt="LEFT Example 1" src="images/constants/left.png" width="320" height="240">
include <BOSL2/std.scad>
cuboid(20, anchor=LEFT);
<br clear="all" /><br/>
---
### Constant: RIGHT
**Synopsis:** The right-wards (X+) direction vector constant `[1,0,0]`.
**Topics:** [Constants](Topics#constants), [Vectors](Topics#vectors)
**See Also:** [LEFT](#constant-left), [FRONT](#constant-front), [BACK](#constant-back), [TOP](#constant-top), [BOTTOM](#constant-bottom), [CENTER](#constant-center)
**Description:**
Vector pointing right. [1,0,0]
**Example 1:** Usage with `anchor`
<img align="left" alt="RIGHT Example 1" src="images/constants/right.png" width="320" height="240">
include <BOSL2/std.scad>
cuboid(20, anchor=RIGHT);
<br clear="all" /><br/>
---
### Constant: FRONT
**Aliases:** FWD, FORWARD
**Synopsis:** The front-wards (Y-) direction vector constant `[0,-1,0]`.
**Topics:** [Constants](Topics#constants), [Vectors](Topics#vectors)
**See Also:** [LEFT](#constant-left), [RIGHT](#constant-right), [BACK](#constant-back), [TOP](#constant-top), [BOTTOM](#constant-bottom), [CENTER](#constant-center)
**Description:**
Vector pointing forward. [0,-1,0]
**Example 1:** Usage with `anchor`
<img align="left" alt="FRONT Example 1" src="images/constants/front.png" width="320" height="240">
include <BOSL2/std.scad>
cuboid(20, anchor=FRONT);
<br clear="all" /><br/>
---
### Constant: BACK
**Synopsis:** The backwards (Y+) direction vector constant `[0,1,0]`.
**Topics:** [Constants](Topics#constants), [Vectors](Topics#vectors)
**See Also:** [LEFT](#constant-left), [RIGHT](#constant-right), [FRONT](#constant-front), [TOP](#constant-top), [BOTTOM](#constant-bottom), [CENTER](#constant-center)
**Description:**
Vector pointing back. [0,1,0]
**Example 1:** Usage with `anchor`
<img align="left" alt="BACK Example 1" src="images/constants/back.png" width="320" height="240">
include <BOSL2/std.scad>
cuboid(20, anchor=BACK);
<br clear="all" /><br/>
---
### Constant: BOTTOM
**Aliases:** BOT, DOWN
**Synopsis:** The down-wards (Z-) direction vector constant `[0,0,-1]`.
**Topics:** [Constants](Topics#constants), [Vectors](Topics#vectors)
**See Also:** [LEFT](#constant-left), [RIGHT](#constant-right), [FRONT](#constant-front), [BACK](#constant-back), [TOP](#constant-top), [CENTER](#constant-center)
**Description:**
Vector pointing down. [0,0,-1]
**Example 1:** Usage with `anchor`
<img align="left" alt="BOTTOM Example 1" src="images/constants/bottom.png" width="320" height="240">
include <BOSL2/std.scad>
cuboid(20, anchor=BOTTOM);
<br clear="all" /><br/>
---
### Constant: TOP
**Aliases:** UP
**Synopsis:** The top-wards (Z+) direction vector constant `[0,0,1]`.
**Topics:** [Constants](Topics#constants), [Vectors](Topics#vectors)
**See Also:** [LEFT](#constant-left), [RIGHT](#constant-right), [FRONT](#constant-front), [BACK](#constant-back), [BOTTOM](#constant-bottom), [CENTER](#constant-center)
**Description:**
Vector pointing up. [0,0,1]
**Example 1:** Usage with `anchor`
<img align="left" alt="TOP Example 1" src="images/constants/top.png" width="320" height="240">
include <BOSL2/std.scad>
cuboid(20, anchor=TOP);
<br clear="all" /><br/>
---
### Constant: CENTER
**Aliases:** CTR, CENTRE
**Synopsis:** The center vector constant `[0,0,0]`.
**Topics:** [Constants](Topics#constants), [Vectors](Topics#vectors)
**See Also:** [LEFT](#constant-left), [RIGHT](#constant-right), [FRONT](#constant-front), [BACK](#constant-back), [TOP](#constant-top), [BOTTOM](#constant-bottom)
**Description:**
Zero vector. Centered. [0,0,0]
**Example 1:** Usage with `anchor`
<img align="left" alt="CENTER Example 1" src="images/constants/center.png" width="320" height="240">
include <BOSL2/std.scad>
cuboid(20, anchor=CENTER);
<br clear="all" /><br/>
---
### Function: EDGE()
**Synopsis:** Named edge anchor constants
**Topics:** [Constants](Topics#constants), [Attachment](Topics#attachment)
**Usage:**
- EDGE(i)
- EDGE(direction,i)
**Description:**
A shorthand for the named anchors "edge0", "top_edge0", "bot_edge0", etc.
Use `EDGE(i)` to get "edge<i>". Use `EDGE(TOP,i)` to get "top_edge<i>" and
use `EDGE(BOT,i)` to get "bot_edge(i)". You can also use
`EDGE(CTR,i)` to get "edge<i>" and you can replace TOP or BOT with simply 1 or -1.
---
### Function: FACE()
**Synopsis:** Named face anchor constants
**Topics:** [Constants](Topics#constants), [Attachment](Topics#attachment)
**Usage:**
- FACE(i)
**Description:**
A shorthand for the named anchors "face0", "face1", etc.
---
## Section: Line specifiers
Used by functions in geometry.scad for specifying whether two points
are treated as an unbounded line, a ray with one endpoint, or a segment
with two endpoints.
### Constant: SEGMENT
**Synopsis:** A constant for specifying a line segment in various geometry.scad functions. `[true,true]`
**Topics:** [Constants](Topics#constants), [Lines](Topics#lines)
**See Also:** [RAY](#constant-ray), [LINE](#constant-line)
**Description:**
Treat a line as a segment. [true, true]
**Example 1:** Usage with line\_intersection:
include <BOSL2/std.scad>
line1 = 10*[[9, 4], [5, 7]];
line2 = 10*[[2, 3], [6, 5]];
isect = line_intersection(line1, line2, SEGMENT, SEGMENT);
<br clear="all" /><br/>
---
### Constant: RAY
**Synopsis:** A constant for specifying a ray line in various geometry.scad functions. `[true,false]`
**Topics:** [Constants](Topics#constants), [Lines](Topics#lines)
**See Also:** [SEGMENT](#constant-segment), [LINE](#constant-line)
**Description:**
Treat a line as a ray, based at the first point. [true, false]
**Example 1:** Usage with line\_intersection:
include <BOSL2/std.scad>
line = [[-30,0],[30,30]];
pt = [40,25];
closest = line_closest_point(line,pt,RAY);
<br clear="all" /><br/>
---
### Constant: LINE
**Synopsis:** A constant for specifying an unbounded line in various geometry.scad functions. `[false,false]`
**Topics:** [Constants](Topics#constants), [Lines](Topics#lines)
**See Also:** [RAY](#constant-ray), [SEGMENT](#constant-segment)
**Description:**
Treat a line as an unbounded line. [false, false]
**Example 1:** Usage with line\_intersection:
include <BOSL2/std.scad>
line1 = 10*[[9, 4], [5, 7]];
line2 = 10*[[2, 3], [6, 5]];
isect = line_intersection(line1, line2, LINE, SEGMENT);
<br clear="all" /><br/>
---

644
coords.scad.md Normal file

@ -0,0 +1,644 @@
# LibFile: coords.scad
Coordinate transformations and coordinate system conversions.
To use, add the following lines to the beginning of your file:
include <BOSL2/std.scad>
## File Contents
1. [Section: Coordinate Manipulation](#section-coordinate-manipulation)
- [`point2d()`](#function-point2d) Convert a vector to 2D.
- [`path2d()`](#function-path2d) Convert a path to 2D. <sup title="Can return a Path.">[<abbr>Path</abbr>]</sup>
- [`point3d()`](#function-point3d) Convert a vector to 3D.
- [`path3d()`](#function-path3d) Convert a path to 3D. <sup title="Can return a Path.">[<abbr>Path</abbr>]</sup>
- [`point4d()`](#function-point4d) Convert a vector to 4d.
- [`path4d()`](#function-path4d) Convert a path to 4d. <sup title="Can return a Path.">[<abbr>Path</abbr>]</sup>
2. [Section: Coordinate Systems](#section-coordinate-systems)
- [`polar_to_xy()`](#function-polar_to_xy) Convert 2D polar coordinates to cartesian coordinates. <sup title="Can return a Path.">[<abbr>Path</abbr>]</sup>
- [`xy_to_polar()`](#function-xy_to_polar) Convert 2D cartesian coordinates to polar coordinates (radius and angle)
- [`project_plane()`](#function-project_plane) Project a set of points onto a specified plane, returning 2D points. <sup title="Can return a Path.">[<abbr>Path</abbr>]</sup>
- [`lift_plane()`](#function-lift_plane) Map a list of 2D points onto a plane in 3D. <sup title="Can return a Path.">[<abbr>Path</abbr>]</sup>
- [`cylindrical_to_xyz()`](#function-cylindrical_to_xyz) Convert cylindrical coordinates to cartesian coordinates. <sup title="Can return a Path.">[<abbr>Path</abbr>]</sup>
- [`xyz_to_cylindrical()`](#function-xyz_to_cylindrical) Convert 3D cartesian coordinates to cylindrical coordinates.
- [`spherical_to_xyz()`](#function-spherical_to_xyz) Convert spherical coordinates to 3D cartesian coordinates. <sup title="Can return a Path.">[<abbr>Path</abbr>]</sup>
- [`xyz_to_spherical()`](#function-xyz_to_spherical) Convert 3D cartesian coordinates to spherical coordinates.
- [`altaz_to_xyz()`](#function-altaz_to_xyz) Convert altitude/azimuth/range to 3D cartesian coordinates. <sup title="Can return a Path.">[<abbr>Path</abbr>]</sup>
- [`xyz_to_altaz()`](#function-xyz_to_altaz) Convert 3D cartesian coordinates to [altitude,azimuth,range].
## Section: Coordinate Manipulation
### Function: point2d()
**Synopsis:** Convert a vector to 2D.
**Topics:** [Coordinates](Topics#coordinates), [Points](Topics#points)
**See Also:** [path2d()](#function-path2d), [point3d()](#function-point3d), [path3d()](#function-path3d)
**Usage:**
- pt = point2d(p, [fill]);
**Description:**
Returns a 2D vector/point from a 2D or 3D vector. If given a 3D point, removes the Z coordinate.
**Arguments:**
<abbr title="These args can be used by position or by name.">By&nbsp;Position</abbr> | What it does
-------------------- | ------------
`p` | The coordinates to force into a 2D vector/point.
`fill` | Value to fill missing values in vector with. Default: 0
---
### Function: path2d()
**Synopsis:** Convert a path to 2D. <sup title="Can return a Path.">[<abbr>Path</abbr>]</sup>
**Topics:** [Coordinates](Topics#coordinates), [Points](Topics#points), [Paths](Topics#paths)
**See Also:** [point2d()](#function-point2d), [point3d()](#function-point3d), [path3d()](#function-path3d)
**Usage:**
- pts = path2d(points);
**Description:**
Returns a list of 2D vectors/points from a list of 2D, 3D or higher dimensional vectors/points.
Removes the extra coordinates from higher dimensional points. The input must be a path, where
every vector has the same length.
**Arguments:**
<abbr title="These args can be used by position or by name.">By&nbsp;Position</abbr> | What it does
-------------------- | ------------
`points` | A list of 2D or 3D points/vectors.
---
### Function: point3d()
**Synopsis:** Convert a vector to 3D.
**Topics:** [Coordinates](Topics#coordinates), [Points](Topics#points)
**See Also:** [path2d()](#function-path2d), [point2d()](#function-point2d), [path3d()](#function-path3d)
**Usage:**
- pt = point3d(p, [fill]);
**Description:**
Returns a 3D vector/point from a 2D or 3D vector.
**Arguments:**
<abbr title="These args can be used by position or by name.">By&nbsp;Position</abbr> | What it does
-------------------- | ------------
`p` | The coordinates to force into a 3D vector/point.
`fill` | Value to fill missing values in vector with. Default: 0
---
### Function: path3d()
**Synopsis:** Convert a path to 3D. <sup title="Can return a Path.">[<abbr>Path</abbr>]</sup>
**Topics:** [Coordinates](Topics#coordinates), [Points](Topics#points), [Paths](Topics#paths)
**See Also:** [point2d()](#function-point2d), [path2d()](#function-path2d), [point3d()](#function-point3d)
**Usage:**
- pts = path3d(points, [fill]);
**Description:**
Returns a list of 3D vectors/points from a list of 2D or higher dimensional vectors/points
by removing extra coordinates or adding the z coordinate.
**Arguments:**
<abbr title="These args can be used by position or by name.">By&nbsp;Position</abbr> | What it does
-------------------- | ------------
`points` | A list of 2D, 3D or higher dimensional points/vectors.
`fill` | Value to fill missing values in vectors with (in the 2D case). Default: 0
---
### Function: point4d()
**Synopsis:** Convert a vector to 4d.
**Topics:** [Coordinates](Topics#coordinates), [Points](Topics#points)
**See Also:** [point2d()](#function-point2d), [path2d()](#function-path2d), [point3d()](#function-point3d), [path3d()](#function-path3d), [path4d()](#function-path4d)
**Usage:**
- pt = point4d(p, [fill]);
**Description:**
Returns a 4D vector/point from a 2D or 3D vector.
**Arguments:**
<abbr title="These args can be used by position or by name.">By&nbsp;Position</abbr> | What it does
-------------------- | ------------
`p` | The coordinates to force into a 4D vector/point.
`fill` | Value to fill missing values in vector with. Default: 0
---
### Function: path4d()
**Synopsis:** Convert a path to 4d. <sup title="Can return a Path.">[<abbr>Path</abbr>]</sup>
**Topics:** [Coordinates](Topics#coordinates), [Points](Topics#points), [Paths](Topics#paths)
**See Also:** [point2d()](#function-point2d), [path2d()](#function-path2d), [point3d()](#function-point3d), [path3d()](#function-path3d), [point4d()](#function-point4d)
**Usage:**
- pt = path4d(points, [fill]);
**Description:**
Returns a list of 4D vectors/points from a list of 2D or 3D vectors/points.
**Arguments:**
<abbr title="These args can be used by position or by name.">By&nbsp;Position</abbr> | What it does
-------------------- | ------------
`points` | A list of 2D or 3D points/vectors.
`fill` | Value to fill missing values in vectors with. Default: 0
---
## Section: Coordinate Systems
### Function: polar\_to\_xy()
**Synopsis:** Convert 2D polar coordinates to cartesian coordinates. <sup title="Can return a Path.">[<abbr>Path</abbr>]</sup>
**Topics:** [Coordinates](Topics#coordinates), [Points](Topics#points), [Paths](Topics#paths)
**See Also:** [xy\_to\_polar()](#function-xy_to_polar), [xyz\_to\_cylindrical()](#function-xyz_to_cylindrical), [cylindrical\_to\_xyz()](#function-cylindrical_to_xyz), [xyz\_to\_spherical()](#function-xyz_to_spherical), [spherical\_to\_xyz()](#function-spherical_to_xyz)
**Usage:**
- pt = polar_to_xy(r, theta);
- pt = polar_to_xy([R, THETA]);
- pts = polar_to_xy([[R,THETA], [R,THETA], ...]);
**Description:**
Called with two arguments, converts the `r` and `theta` 2D polar coordinate into an `[X,Y]` cartesian coordinate.
Called with one `[R,THETA]` vector argument, converts the 2D polar coordinate into an `[X,Y]` cartesian coordinate.
Called with a list of `[R,THETA]` vector arguments, converts each 2D polar coordinate into `[X,Y]` cartesian coordinates.
Theta is the angle counter-clockwise of X+ on the XY plane.
**Arguments:**
<abbr title="These args can be used by position or by name.">By&nbsp;Position</abbr> | What it does
-------------------- | ------------
`r` | distance from the origin.
`theta` | angle in degrees, counter-clockwise of X+.
**Example 1:**
include <BOSL2/std.scad>
xy = polar_to_xy(20,45); // Returns: ~[14.1421365, 14.1421365]
xy = polar_to_xy(40,30); // Returns: ~[34.6410162, 15]
xy = polar_to_xy([40,30]); // Returns: ~[34.6410162, 15]
xy = polar_to_xy([[40,30],[20,120]]); // Returns: ~[[34.6410162, 15], [-10, 17.3205]]
<br clear="all" /><br/>
**Example 2:**
<img align="left" alt="polar\_to\_xy() Example 2" src="images/coords/polar_to_xy_2.png" width="320" height="240">
include <BOSL2/std.scad>
r=40; ang=30; $fn=36;
pt = polar_to_xy(r,ang);
stroke(circle(r=r), closed=true, width=0.5);
color("black") stroke([[r,0], [0,0], pt], width=0.5);
color("black") stroke(arc(r=15, angle=ang), width=0.5);
color("red") move(pt) circle(d=3);
<br clear="all" /><br/>
---
### Function: xy\_to\_polar()
**Synopsis:** Convert 2D cartesian coordinates to polar coordinates (radius and angle)
**Topics:** [Coordinates](Topics#coordinates), [Points](Topics#points), [Paths](Topics#paths)
**See Also:** [polar\_to\_xy()](#function-polar_to_xy), [xyz\_to\_cylindrical()](#function-xyz_to_cylindrical), [cylindrical\_to\_xyz()](#function-cylindrical_to_xyz), [xyz\_to\_spherical()](#function-xyz_to_spherical), [spherical\_to\_xyz()](#function-spherical_to_xyz)
**Usage:**
- r_theta = xy_to_polar(x,y);
- r_theta = xy_to_polar([X,Y]);
- r_thetas = xy_to_polar([[X,Y], [X,Y], ...]);
**Description:**
Called with two arguments, converts the `x` and `y` 2D cartesian coordinate into a `[RADIUS,THETA]` polar coordinate.
Called with one `[X,Y]` vector argument, converts the 2D cartesian coordinate into a `[RADIUS,THETA]` polar coordinate.
Called with a list of `[X,Y]` vector arguments, converts each 2D cartesian coordinate into `[RADIUS,THETA]` polar coordinates.
Theta is the angle counter-clockwise of X+ on the XY plane.
**Arguments:**
<abbr title="These args can be used by position or by name.">By&nbsp;Position</abbr> | What it does
-------------------- | ------------
`x` | X coordinate.
`y` | Y coordinate.
**Example 1:**
include <BOSL2/std.scad>
plr = xy_to_polar(20,30);
plr = xy_to_polar([40,60]);
plrs = xy_to_polar([[40,60],[-10,20]]);
<br clear="all" /><br/>
**Example 2:**
<img align="left" alt="xy\_to\_polar() Example 2" src="images/coords/xy_to_polar_2.png" width="320" height="240">
include <BOSL2/std.scad>
pt = [-20,30]; $fn = 36;
rt = xy_to_polar(pt);
r = rt[0]; ang = rt[1];
stroke(circle(r=r), closed=true, width=0.5);
zrot(ang) stroke([[0,0],[r,0]],width=0.5);
color("red") move(pt) circle(d=3);
<br clear="all" /><br/>
---
### Function: project\_plane()
**Synopsis:** Project a set of points onto a specified plane, returning 2D points. <sup title="Can return a Path.">[<abbr>Path</abbr>]</sup>
**Topics:** [Coordinates](Topics#coordinates), [Points](Topics#points), [Paths](Topics#paths)
**See Also:** [lift\_plane()](#function-lift_plane)
**Usage:**
- xy = project_plane(plane, p);
**Usage:** To get a transform matrix
- M = project_plane(plane)
**Description:**
Maps the provided 3D point(s) from 3D coordinates to a 2D coordinate system defined by `plane`. Points that are not
on the specified plane will be projected orthogonally onto the plane. This coordinate system is useful if you need
to perform 2D operations on a coplanar set of data. After those operations are done you can return the data
to 3D with `lift_plane()`. You could also use this to force approximately coplanar data to be exactly coplanar.
The parameter p can be a point, path, region, bezier patch or VNF.
The plane can be specified as
- A list of three points. The planar coordinate system will have [0,0] at plane[0], and plane[1] will lie on the Y+ axis.
- A list of coplanar points that define a plane (not-collinear)
- A plane definition `[A,B,C,D]` where `Ax+By+CZ=D`. The closest point on that plane to the origin will map to the origin in the new coordinate system.
If you omit the point specification then `project_plane()` returns a rotation matrix that maps the specified plane to the XY plane.
Note that if you apply this transformation to data lying on the plane it will produce 3D points with the Z coordinate of zero.
**Arguments:**
<abbr title="These args can be used by position or by name.">By&nbsp;Position</abbr> | What it does
-------------------- | ------------
`plane` | plane specification or point list defining the plane
`p` | 3D point, path, region, VNF or bezier patch to project
**Example 1:**
include <BOSL2/std.scad>
pt = [5,-5,5];
a=[0,0,0]; b=[10,-10,0]; c=[10,0,10];
xy = project_plane([a,b,c],pt);
<br clear="all" /><br/>
**Example 2:** The yellow points in 3D project onto the red points in 2D
<img align="left" alt="project\_plane() Example 2" src="images/coords/project_plane_2.png" width="320" height="240">
<br clear="all" />
include <BOSL2/std.scad>
M = [[-1, 2, -1, -2], [-1, -3, 2, -1], [2, 3, 4, 53], [0, 0, 0, 1]];
data = apply(M,path3d(circle(r=10, $fn=20)));
move_copies(data) sphere(r=1);
color("red") move_copies(project_plane(data, data)) sphere(r=1);
**Example 3:**
include <BOSL2/std.scad>
xyzpath = move([10,20,30], p=yrot(25, p=path3d(circle(d=100))));
mat = project_plane(xyzpath);
xypath = path2d(apply(mat, xyzpath));
#stroke(xyzpath,closed=true);
stroke(xypath,closed=true);
<br clear="all" /><br/>
---
### Function: lift\_plane()
**Synopsis:** Map a list of 2D points onto a plane in 3D. <sup title="Can return a Path.">[<abbr>Path</abbr>]</sup>
**Topics:** [Coordinates](Topics#coordinates), [Points](Topics#points), [Paths](Topics#paths)
**See Also:** [project\_plane()](#function-project_plane)
**Usage:**
- xyz = lift_plane(plane, p);
**Usage:** to get transform matrix
- M = lift_plane(plane);
**Description:**
Converts the given 2D point on the plane to 3D coordinates of the specified plane.
The parameter p can be a point, path, region, bezier patch or VNF.
The plane can be specified as
- A list of three points. The planar coordinate system will have [0,0] at plane[0], and plane[1] will lie on the Y+ axis.
- A list of coplanar points that define a plane (not-collinear)
- A plane definition `[A,B,C,D]` where `Ax+By+CZ=D`. The closest point on that plane to the origin will map to the origin in the new coordinate system.
If you do not supply `p` then you get a transformation matrix which operates in 3D, assuming that the Z coordinate of the points is zero.
This matrix is a rotation, the inverse of the one produced by project_plane.
**Arguments:**
<abbr title="These args can be used by position or by name.">By&nbsp;Position</abbr> | What it does
-------------------- | ------------
`plane` | Plane specification or list of points to define a plane
`p` | points, path, region, VNF, or bezier patch to transform.
---
### Function: cylindrical\_to\_xyz()
**Synopsis:** Convert cylindrical coordinates to cartesian coordinates. <sup title="Can return a Path.">[<abbr>Path</abbr>]</sup>
**Topics:** [Coordinates](Topics#coordinates), [Points](Topics#points), [Paths](Topics#paths)
**See Also:** [xyz\_to\_cylindrical()](#function-xyz_to_cylindrical), [xy\_to\_polar()](#function-xy_to_polar), [polar\_to\_xy()](#function-polar_to_xy), [xyz\_to\_spherical()](#function-xyz_to_spherical), [spherical\_to\_xyz()](#function-spherical_to_xyz)
**Usage:**
- pt = cylindrical_to_xyz(r, theta, z);
- pt = cylindrical_to_xyz([RADIUS,THETA,Z]);
- pts = cylindrical_to_xyz([[RADIUS,THETA,Z], [RADIUS,THETA,Z], ...]);
**Description:**
Called with three arguments, converts the `r`, `theta`, and 'z' 3D cylindrical coordinate into an `[X,Y,Z]` cartesian coordinate.
Called with one `[RADIUS,THETA,Z]` vector argument, converts the 3D cylindrical coordinate into an `[X,Y,Z]` cartesian coordinate.
Called with a list of `[RADIUS,THETA,Z]` vector arguments, converts each 3D cylindrical coordinate into `[X,Y,Z]` cartesian coordinates.
Theta is the angle counter-clockwise of X+ on the XY plane. Z is height above the XY plane.
**Arguments:**
<abbr title="These args can be used by position or by name.">By&nbsp;Position</abbr> | What it does
-------------------- | ------------
`r` | distance from the Z axis.
`theta` | angle in degrees, counter-clockwise of X+ on the XY plane.
`z` | Height above XY plane.
**Example 1:**
include <BOSL2/std.scad>
xyz = cylindrical_to_xyz(20,30,40);
xyz = cylindrical_to_xyz([40,60,50]);
<br clear="all" /><br/>
---
### Function: xyz\_to\_cylindrical()
**Synopsis:** Convert 3D cartesian coordinates to cylindrical coordinates.
**Topics:** [Coordinates](Topics#coordinates), [Points](Topics#points), [Paths](Topics#paths)
**See Also:** [cylindrical\_to\_xyz()](#function-cylindrical_to_xyz), [xy\_to\_polar()](#function-xy_to_polar), [polar\_to\_xy()](#function-polar_to_xy), [xyz\_to\_spherical()](#function-xyz_to_spherical), [spherical\_to\_xyz()](#function-spherical_to_xyz)
**Usage:**
- rtz = xyz_to_cylindrical(x,y,z);
- rtz = xyz_to_cylindrical([X,Y,Z]);
- rtzs = xyz_to_cylindrical([[X,Y,Z], [X,Y,Z], ...]);
**Description:**
Called with three arguments, converts the `x`, `y`, and `z` 3D cartesian coordinate into a `[RADIUS,THETA,Z]` cylindrical coordinate.
Called with one `[X,Y,Z]` vector argument, converts the 3D cartesian coordinate into a `[RADIUS,THETA,Z]` cylindrical coordinate.
Called with a list of `[X,Y,Z]` vector arguments, converts each 3D cartesian coordinate into `[RADIUS,THETA,Z]` cylindrical coordinates.
Theta is the angle counter-clockwise of X+ on the XY plane. Z is height above the XY plane.
**Arguments:**
<abbr title="These args can be used by position or by name.">By&nbsp;Position</abbr> | What it does
-------------------- | ------------
`x` | X coordinate.
`y` | Y coordinate.
`z` | Z coordinate.
**Example 1:**
include <BOSL2/std.scad>
cyl = xyz_to_cylindrical(20,30,40);
cyl = xyz_to_cylindrical([40,50,70]);
cyls = xyz_to_cylindrical([[40,50,70], [-10,15,-30]]);
<br clear="all" /><br/>
---
### Function: spherical\_to\_xyz()
**Synopsis:** Convert spherical coordinates to 3D cartesian coordinates. <sup title="Can return a Path.">[<abbr>Path</abbr>]</sup>
**Topics:** [Coordinates](Topics#coordinates), [Points](Topics#points), [Paths](Topics#paths)
**See Also:** [cylindrical\_to\_xyz()](#function-cylindrical_to_xyz), [xyz\_to\_spherical()](#function-xyz_to_spherical), [xyz\_to\_cylindrical()](#function-xyz_to_cylindrical), [altaz\_to\_xyz()](#function-altaz_to_xyz), [xyz\_to\_altaz()](#function-xyz_to_altaz)
**Usage:**
- pt = spherical_to_xyz(r, theta, phi);
- pt = spherical_to_xyz([RADIUS,THETA,PHI]);
- pts = spherical_to_xyz([[RADIUS,THETA,PHI], [RADIUS,THETA,PHI], ...]);
**Description:**
Called with three arguments, converts the `r`, `theta`, and 'phi' 3D spherical coordinate into an `[X,Y,Z]` cartesian coordinate.
Called with one `[RADIUS,THETA,PHI]` vector argument, converts the 3D spherical coordinate into an `[X,Y,Z]` cartesian coordinate.
Called with a list of `[RADIUS,THETA,PHI]` vector arguments, converts each 3D spherical coordinate into `[X,Y,Z]` cartesian coordinates.
Theta is the angle counter-clockwise of X+ on the XY plane. Phi is the angle down from the Z+ pole.
**Arguments:**
<abbr title="These args can be used by position or by name.">By&nbsp;Position</abbr> | What it does
-------------------- | ------------
`r` | distance from origin.
`theta` | angle in degrees, counter-clockwise of X+ on the XY plane.
`phi` | angle in degrees from the vertical Z+ axis.
**Example 1:**
include <BOSL2/std.scad>
xyz = spherical_to_xyz(20,30,40);
xyz = spherical_to_xyz([40,60,50]);
xyzs = spherical_to_xyz([[40,60,50], [50,120,100]]);
<br clear="all" /><br/>
---
### Function: xyz\_to\_spherical()
**Synopsis:** Convert 3D cartesian coordinates to spherical coordinates.
**Topics:** [Coordinates](Topics#coordinates), [Points](Topics#points), [Paths](Topics#paths)
**See Also:** [cylindrical\_to\_xyz()](#function-cylindrical_to_xyz), [spherical\_to\_xyz()](#function-spherical_to_xyz), [xyz\_to\_cylindrical()](#function-xyz_to_cylindrical), [altaz\_to\_xyz()](#function-altaz_to_xyz), [xyz\_to\_altaz()](#function-xyz_to_altaz)
**Usage:**
- r_theta_phi = xyz_to_spherical(x,y,z)
- r_theta_phi = xyz_to_spherical([X,Y,Z])
- r_theta_phis = xyz_to_spherical([[X,Y,Z], [X,Y,Z], ...])
**Description:**
Called with three arguments, converts the `x`, `y`, and `z` 3D cartesian coordinate into a `[RADIUS,THETA,PHI]` spherical coordinate.
Called with one `[X,Y,Z]` vector argument, converts the 3D cartesian coordinate into a `[RADIUS,THETA,PHI]` spherical coordinate.
Called with a list of `[X,Y,Z]` vector arguments, converts each 3D cartesian coordinate into `[RADIUS,THETA,PHI]` spherical coordinates.
Theta is the angle counter-clockwise of X+ on the XY plane. Phi is the angle down from the Z+ pole.
**Arguments:**
<abbr title="These args can be used by position or by name.">By&nbsp;Position</abbr> | What it does
-------------------- | ------------
`x` | X coordinate.
`y` | Y coordinate.
`z` | Z coordinate.
**Example 1:**
include <BOSL2/std.scad>
sph = xyz_to_spherical(20,30,40);
sph = xyz_to_spherical([40,50,70]);
sphs = xyz_to_spherical([[40,50,70], [25,-14,27]]);
<br clear="all" /><br/>
---
### Function: altaz\_to\_xyz()
**Synopsis:** Convert altitude/azimuth/range to 3D cartesian coordinates. <sup title="Can return a Path.">[<abbr>Path</abbr>]</sup>
**Topics:** [Coordinates](Topics#coordinates), [Points](Topics#points), [Paths](Topics#paths)
**See Also:** [cylindrical\_to\_xyz()](#function-cylindrical_to_xyz), [xyz\_to\_spherical()](#function-xyz_to_spherical), [spherical\_to\_xyz()](#function-spherical_to_xyz), [xyz\_to\_cylindrical()](#function-xyz_to_cylindrical), [xyz\_to\_altaz()](#function-xyz_to_altaz)
**Usage:**
- pt = altaz_to_xyz(alt, az, r);
- pt = altaz_to_xyz([ALT,AZ,R]);
- pts = altaz_to_xyz([[ALT,AZ,R], [ALT,AZ,R], ...]);
**Description:**
Convert altitude/azimuth/range coordinates to 3D cartesian coordinates.
Called with three arguments, converts the `alt`, `az`, and 'r' 3D altitude-azimuth coordinate into an `[X,Y,Z]` cartesian coordinate.
Called with one `[ALTITUDE,AZIMUTH,RANGE]` vector argument, converts the 3D alt-az coordinate into an `[X,Y,Z]` cartesian coordinate.
Called with a list of `[ALTITUDE,AZIMUTH,RANGE]` vector arguments, converts each 3D alt-az coordinate into `[X,Y,Z]` cartesian coordinates.
Altitude is the angle above the XY plane, Azimuth is degrees clockwise of Y+ on the XY plane, and Range is the distance from the origin.
**Arguments:**
<abbr title="These args can be used by position or by name.">By&nbsp;Position</abbr> | What it does
-------------------- | ------------
`alt` | altitude angle in degrees above the XY plane.
`az` | azimuth angle in degrees clockwise of Y+ on the XY plane.
`r` | distance from origin.
**Example 1:**
include <BOSL2/std.scad>
xyz = altaz_to_xyz(20,30,40);
xyz = altaz_to_xyz([40,60,50]);
<br clear="all" /><br/>
---
### Function: xyz\_to\_altaz()
**Synopsis:** Convert 3D cartesian coordinates to [altitude,azimuth,range].
**Topics:** [Coordinates](Topics#coordinates), [Points](Topics#points), [Paths](Topics#paths)
**See Also:** [cylindrical\_to\_xyz()](#function-cylindrical_to_xyz), [xyz\_to\_spherical()](#function-xyz_to_spherical), [spherical\_to\_xyz()](#function-spherical_to_xyz), [xyz\_to\_cylindrical()](#function-xyz_to_cylindrical), [altaz\_to\_xyz()](#function-altaz_to_xyz)
**Usage:**
- alt_az_r = xyz_to_altaz(x,y,z);
- alt_az_r = xyz_to_altaz([X,Y,Z]);
- alt_az_rs = xyz_to_altaz([[X,Y,Z], [X,Y,Z], ...]);
**Description:**
Converts 3D cartesian coordinates to altitude/azimuth/range coordinates.
Called with three arguments, converts the `x`, `y`, and `z` 3D cartesian coordinate into an `[ALTITUDE,AZIMUTH,RANGE]` coordinate.
Called with one `[X,Y,Z]` vector argument, converts the 3D cartesian coordinate into a `[ALTITUDE,AZIMUTH,RANGE]` coordinate.
Called with a list of `[X,Y,Z]` vector arguments, converts each 3D cartesian coordinate into `[ALTITUDE,AZIMUTH,RANGE]` coordinates.
Altitude is the angle above the XY plane, Azimuth is degrees clockwise of Y+ on the XY plane, and Range is the distance from the origin.
**Arguments:**
<abbr title="These args can be used by position or by name.">By&nbsp;Position</abbr> | What it does
-------------------- | ------------
`x` | X coordinate.
`y` | Y coordinate.
`z` | Z coordinate.
**Example 1:**
include <BOSL2/std.scad>
aa = xyz_to_altaz(20,30,40);
aa = xyz_to_altaz([40,50,70]);
<br clear="all" /><br/>
---

644
cubetruss.scad.md Normal file

@ -0,0 +1,644 @@
# LibFile: cubetruss.scad
Parts for making modular open-frame cross-braced trusses and connectors.
To use, add the following lines to the beginning of your file:
include <BOSL2/std.scad>
include <BOSL2/cubetruss.scad>
## File Contents
1. [Section: Cube Trusses](#section-cube-trusses)
- [`cubetruss()`](#module-cubetruss) Creates a multi-cube straight cubetruss shape. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup>
- [`cubetruss_corner()`](#module-cubetruss_corner) Creates a multi-cube corner cubetruss shape. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup>
- [`cubetruss_support()`](#module-cubetruss_support) Creates a cubetruss support structure shape. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup>
2. [Section: Cubetruss Support](#section-cubetruss-support)
- [`cubetruss_foot()`](#module-cubetruss_foot) Creates a foot that can connect two cubetrusses. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup>
- [`cubetruss_joiner()`](#module-cubetruss_joiner) Creates a joiner that can connect two cubetrusses end-to-end. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup>
- [`cubetruss_uclip()`](#module-cubetruss_uclip) Creates a joiner that can connect two cubetrusses end-to-end. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup>
3. [Section: Cubetruss Primitives](#section-cubetruss-primitives)
- [`cubetruss_segment()`](#module-cubetruss_segment) Creates a single cubetruss cube. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup>
- [`cubetruss_clip()`](#module-cubetruss_clip) Creates a clip for the end of a cubetruss to snap-lock it to another cubetruss. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup>
- [`cubetruss_dist()`](#function-cubetruss_dist) Returns the length of a cubetruss truss.
## Section: Cube Trusses
### Module: cubetruss()
**Synopsis:** Creates a multi-cube straight cubetruss shape. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup>
**Topics:** [Trusses](Topics#trusses), [CubeTruss](Topics#cubetruss), [FDM Optimized](Topics#fdm-optimized), [Parts](Topics#parts)
**See Also:** [cubetruss\_segment()](#module-cubetruss_segment), [cubetruss\_support()](#module-cubetruss_support), [cubetruss\_corner()](#module-cubetruss_corner)
**Usage:**
- cubetruss(extents, [clips=], [bracing=], [size=], [strut=], [clipthick=], ...) [ATTACHMENTS];
**Description:**
Creates a cubetruss truss, assembled out of one or more cubical segments.
**Arguments:**
<abbr title="These args can be used by position or by name.">By&nbsp;Position</abbr> | What it does
-------------------- | ------------
`extents` | The number of cubes in length to make the truss. If given as a [X,Y,Z] vector, specifies the number of cubes in each dimension.
`clips` | List of vectors pointing towards the sides to add clips to.
`bracing` | If true, adds internal cross-braces. Default: `$cubetruss_bracing` (usually true)
`size` | The length of each side of the cubetruss cubes. Default: `$cubetruss_size` (usually 30)
`strut` | The width of the struts on the cubetruss cubes. Default: `$cubetruss_strut_size` (usually 3)
`clipthick` | The thickness of the clips. Default: `$cubetruss_clip_thickness` (usually 1.6)
<abbr title="These args must be used by name, ie: name=value">By&nbsp;Name</abbr> | What it does
-------------------- | ------------
`anchor` | Translate so anchor point is at origin (0,0,0). See [anchor](attachments.scad#subsection-anchor). Default: `CENTER`
`spin` | Rotate this many degrees around the Z axis. See [spin](attachments.scad#subsection-spin). Default: `0`
`orient` | Vector to rotate top towards. See [orient](attachments.scad#subsection-orient). Default: `UP`
**Example 1:**
<img align="left" alt="cubetruss() Example 1" src="images/cubetruss/cubetruss.png" width="320" height="240">
include <BOSL2/std.scad>
include <BOSL2/cubetruss.scad>
cubetruss(extents=3);
<br clear="all" /><br/>
**Example 2:**
<img align="left" alt="cubetruss() Example 2" src="images/cubetruss/cubetruss_2.png" width="320" height="240">
include <BOSL2/std.scad>
include <BOSL2/cubetruss.scad>
cubetruss(extents=3, clips=FRONT);
<br clear="all" /><br/>
**Example 3:**
<img align="left" alt="cubetruss() Example 3" src="images/cubetruss/cubetruss_3.png" width="320" height="240">
include <BOSL2/std.scad>
include <BOSL2/cubetruss.scad>
cubetruss(extents=3, clips=[FRONT,BACK]);
<br clear="all" /><br/>
**Example 4:**
<img align="left" alt="cubetruss() Example 4" src="images/cubetruss/cubetruss_4.png" width="320" height="240">
include <BOSL2/std.scad>
include <BOSL2/cubetruss.scad>
cubetruss(extents=[2,3]);
<br clear="all" /><br/>
**Example 5:**
<img align="left" alt="cubetruss() Example 5" src="images/cubetruss/cubetruss_5.png" width="320" height="240">
include <BOSL2/std.scad>
include <BOSL2/cubetruss.scad>
cubetruss(extents=[1,4,2]);
<br clear="all" /><br/>
**Example 6:**
<img align="left" alt="cubetruss() Example 6" src="images/cubetruss/cubetruss_6.png" width="320" height="240">
include <BOSL2/std.scad>
include <BOSL2/cubetruss.scad>
cubetruss(extents=[1,4,2], bracing=false);
<br clear="all" /><br/>
---
### Module: cubetruss\_corner()
**Synopsis:** Creates a multi-cube corner cubetruss shape. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup>
**Topics:** [Trusses](Topics#trusses), [CubeTruss](Topics#cubetruss), [FDM Optimized](Topics#fdm-optimized), [Parts](Topics#parts)
**See Also:** [cubetruss\_segment()](#module-cubetruss_segment), [cubetruss\_support()](#module-cubetruss_support), [cubetruss()](#module-cubetruss)
**Usage:**
- cubetruss_corner(h, extents, [bracing=], [size=], [strut=], [clipthick=]);
**Description:**
Creates a corner cubetruss with extents jutting out in one or more directions.
**Arguments:**
<abbr title="These args can be used by position or by name.">By&nbsp;Position</abbr> | What it does
-------------------- | ------------
`h` | The number of cubes high to make the base and horizontal extents.
`extents` | The number of cubes to extend beyond the corner. If given as a vector of cube counts, gives the number of cubes to extend right, back, left, front, and up in order. If the vector is shorter than length 5 the extra cube counts are taken to be zero.
`bracing` | If true, adds internal cross-braces. Default: `$cubetruss_bracing` (usually true)
`size` | The length of each side of the cubetruss cubes. Default: `$cubetruss_size` (usually 30)
`strut` | The width of the struts on the cubetruss cubes. Default: `$cubetruss_strut_size` (usually 3)
`clipthick` | The thickness of the clips. Default: `$cubetruss_clip_thickness` (usually 1.6)
<abbr title="These args must be used by name, ie: name=value">By&nbsp;Name</abbr> | What it does
-------------------- | ------------
`anchor` | Translate so anchor point is at origin (0,0,0). See [anchor](attachments.scad#subsection-anchor). Default: `CENTER`
`spin` | Rotate this many degrees around the Z axis. See [spin](attachments.scad#subsection-spin). Default: `0`
`orient` | Vector to rotate top towards. See [orient](attachments.scad#subsection-orient). Default: `UP`
**Example 1:**
<img align="left" alt="cubetruss\_corner() Example 1" src="images/cubetruss/cubetruss_corner.png" width="320" height="240">
include <BOSL2/std.scad>
include <BOSL2/cubetruss.scad>
cubetruss_corner(extents=2);
<br clear="all" /><br/>
**Example 2:**
<img align="left" alt="cubetruss\_corner() Example 2" src="images/cubetruss/cubetruss_corner_2.png" width="320" height="240">
include <BOSL2/std.scad>
include <BOSL2/cubetruss.scad>
cubetruss_corner(extents=2, h=2);
<br clear="all" /><br/>
**Example 3:**
<img align="left" alt="cubetruss\_corner() Example 3" src="images/cubetruss/cubetruss_corner_3.png" width="320" height="240">
include <BOSL2/std.scad>
include <BOSL2/cubetruss.scad>
cubetruss_corner(extents=[3,3,0,0,2]);
<br clear="all" /><br/>
**Example 4:**
<img align="left" alt="cubetruss\_corner() Example 4" src="images/cubetruss/cubetruss_corner_4.png" width="320" height="240">
include <BOSL2/std.scad>
include <BOSL2/cubetruss.scad>
cubetruss_corner(extents=[3,0,3,0,2]);
<br clear="all" /><br/>
**Example 5:**
<img align="left" alt="cubetruss\_corner() Example 5" src="images/cubetruss/cubetruss_corner_5.png" width="320" height="240">
include <BOSL2/std.scad>
include <BOSL2/cubetruss.scad>
cubetruss_corner(extents=[3,3,3,3,2]);
<br clear="all" /><br/>
---
### Module: cubetruss\_support()
**Synopsis:** Creates a cubetruss support structure shape. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup>
**Topics:** [Trusses](Topics#trusses), [CubeTruss](Topics#cubetruss), [FDM Optimized](Topics#fdm-optimized), [Parts](Topics#parts)
**See Also:** [cubetruss\_segment()](#module-cubetruss_segment), [cubetruss()](#module-cubetruss), [cubetruss\_corner()](#module-cubetruss_corner)
**Usage:**
- cubetruss_support([size=], [strut=], [extents=]) [ATTACHMENTS];
**Description:**
Creates a single cubetruss support.
**Arguments:**
<abbr title="These args can be used by position or by name.">By&nbsp;Position</abbr> | What it does
-------------------- | ------------
`size` | The length of each side of the cubetruss cubes. Default: `$cubetruss_size` (usually 30)
`strut` | The width of the struts on the cubetruss cubes. Default: `$cubetruss_strut_size` (usually 3)
`extents` | If given as an integer, specifies the number of vertical segments for the support. If given as a list of 3 integers, specifies the number of segments in the X, Y, and Z directions. Default: 1.
<abbr title="These args must be used by name, ie: name=value">By&nbsp;Name</abbr> | What it does
-------------------- | ------------
`anchor` | Translate so anchor point is at origin (0,0,0). See [anchor](attachments.scad#subsection-anchor). Default: `CENTER`
`spin` | Rotate this many degrees around the Z axis. See [spin](attachments.scad#subsection-spin). Default: `0`
`orient` | Vector to rotate top towards. See [orient](attachments.scad#subsection-orient). Default: `UP`
**Example 1:**
<img align="left" alt="cubetruss\_support() Example 1" src="images/cubetruss/cubetruss_support.png" width="320" height="240">
include <BOSL2/std.scad>
include <BOSL2/cubetruss.scad>
cubetruss_support();
<br clear="all" /><br/>
**Example 2:**
<img align="left" alt="cubetruss\_support() Example 2" src="images/cubetruss/cubetruss_support_2.png" width="320" height="240">
include <BOSL2/std.scad>
include <BOSL2/cubetruss.scad>
cubetruss_support(extents=2);
<br clear="all" /><br/>
**Example 3:**
<img align="left" alt="cubetruss\_support() Example 3" src="images/cubetruss/cubetruss_support_3.png" width="320" height="240">
include <BOSL2/std.scad>
include <BOSL2/cubetruss.scad>
cubetruss_support(extents=3);
<br clear="all" /><br/>
**Example 4:**
<img align="left" alt="cubetruss\_support() Example 4" src="images/cubetruss/cubetruss_support_4.png" width="320" height="240">
include <BOSL2/std.scad>
include <BOSL2/cubetruss.scad>
cubetruss_support(extents=[2,2,3]);
<br clear="all" /><br/>
**Example 5:**
<img align="left" alt="cubetruss\_support() Example 5" src="images/cubetruss/cubetruss_support_5.png" width="320" height="240">
include <BOSL2/std.scad>
include <BOSL2/cubetruss.scad>
cubetruss_support(strut=4);
<br clear="all" /><br/>
**Example 6:**
<img align="left" alt="cubetruss\_support() Example 6" src="images/cubetruss/cubetruss_support_6.png" width="320" height="240">
include <BOSL2/std.scad>
include <BOSL2/cubetruss.scad>
cubetruss_support(extents=2) show_anchors();
<br clear="all" /><br/>
---
## Section: Cubetruss Support
### Module: cubetruss\_foot()
**Synopsis:** Creates a foot that can connect two cubetrusses. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup>
**Topics:** [Trusses](Topics#trusses), [CubeTruss](Topics#cubetruss), [FDM Optimized](Topics#fdm-optimized), [Parts](Topics#parts)
**See Also:** [cubetruss\_segment()](#module-cubetruss_segment), [cubetruss\_support()](#module-cubetruss_support), [cubetruss()](#module-cubetruss), [cubetruss\_corner()](#module-cubetruss_corner)
**Usage:**
- cubetruss_foot(w, [size=], [strut=], [clipthick=]) [ATTACHMENTS];
**Description:**
Creates a foot that can be clipped onto the bottom of a truss for support.
**Arguments:**
<abbr title="These args can be used by position or by name.">By&nbsp;Position</abbr> | What it does
-------------------- | ------------
`w` | The number of cube segments to span between the clips. Default: 1
`size` | The length of each side of the cubetruss cubes. Default: `$cubetruss_size` (usually 30)
`strut` | The width of the struts on the cubetruss cubes. Default: `$cubetruss_strut_size` (usually 3)
`clipthick` | The thickness of the clips. Default: `$cubetruss_clip_thickness` (usually 1.6)
<abbr title="These args must be used by name, ie: name=value">By&nbsp;Name</abbr> | What it does
-------------------- | ------------
`$slop` | make fit looser to allow for printer overextrusion
`anchor` | Translate so anchor point is at origin (0,0,0). See [anchor](attachments.scad#subsection-anchor). Default: `CENTER`
`spin` | Rotate this many degrees around the Z axis. See [spin](attachments.scad#subsection-spin). Default: `0`
`orient` | Vector to rotate top towards. See [orient](attachments.scad#subsection-orient). Default: `UP`
**Example 1:**
<img align="left" alt="cubetruss\_foot() Example 1" src="images/cubetruss/cubetruss_foot.png" width="320" height="240">
include <BOSL2/std.scad>
include <BOSL2/cubetruss.scad>
cubetruss_foot(w=1);
<br clear="all" /><br/>
**Example 2:**
<img align="left" alt="cubetruss\_foot() Example 2" src="images/cubetruss/cubetruss_foot_2.png" width="320" height="240">
include <BOSL2/std.scad>
include <BOSL2/cubetruss.scad>
cubetruss_foot(w=3);
<br clear="all" /><br/>
---
### Module: cubetruss\_joiner()
**Synopsis:** Creates a joiner that can connect two cubetrusses end-to-end. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup>
**Topics:** [Trusses](Topics#trusses), [CubeTruss](Topics#cubetruss), [FDM Optimized](Topics#fdm-optimized), [Parts](Topics#parts)
**See Also:** [cubetruss\_segment()](#module-cubetruss_segment), [cubetruss\_support()](#module-cubetruss_support), [cubetruss()](#module-cubetruss), [cubetruss\_corner()](#module-cubetruss_corner)
**Usage:**
- cubetruss_joiner([w=], [vert=], [size=], [strut=], [clipthick=]) [ATTACHMENTS];
**Description:**
Creates a part to join two cubetruss trusses end-to-end.
**Arguments:**
<abbr title="These args can be used by position or by name.">By&nbsp;Position</abbr> | What it does
-------------------- | ------------
`w` | The number of cube segments to span between the clips. Default: 1
`vert` | If true, add vertical risers to clip to the ends of the cubetruss trusses. Default: true
`size` | The length of each side of the cubetruss cubes. Default: `$cubetruss_size` (usually 30)
`strut` | The width of the struts on the cubetruss cubes. Default: `$cubetruss_strut_size` (usually 3)
`clipthick` | The thickness of the clips. Default: `$cubetruss_clip_thickness` (usually 1.6)
<abbr title="These args must be used by name, ie: name=value">By&nbsp;Name</abbr> | What it does
-------------------- | ------------
`$slop` | Make fit looser by this amount to allow for printer overextrusion
`anchor` | Translate so anchor point is at origin (0,0,0). See [anchor](attachments.scad#subsection-anchor). Default: `CENTER`
`spin` | Rotate this many degrees around the Z axis. See [spin](attachments.scad#subsection-spin). Default: `0`
`orient` | Vector to rotate top towards. See [orient](attachments.scad#subsection-orient). Default: `UP`
**Example 1:**
<img align="left" alt="cubetruss\_joiner() Example 1" src="images/cubetruss/cubetruss_joiner.png" width="320" height="240">
include <BOSL2/std.scad>
include <BOSL2/cubetruss.scad>
cubetruss_joiner(w=1, vert=false);
<br clear="all" /><br/>
**Example 2:**
<img align="left" alt="cubetruss\_joiner() Example 2" src="images/cubetruss/cubetruss_joiner_2.png" width="320" height="240">
include <BOSL2/std.scad>
include <BOSL2/cubetruss.scad>
cubetruss_joiner(w=1, vert=true);
<br clear="all" /><br/>
**Example 3:**
<img align="left" alt="cubetruss\_joiner() Example 3" src="images/cubetruss/cubetruss_joiner_3.png" width="320" height="240">
include <BOSL2/std.scad>
include <BOSL2/cubetruss.scad>
cubetruss_joiner(w=2, vert=true, anchor=BOT);
<br clear="all" /><br/>
---
### Module: cubetruss\_uclip()
**Synopsis:** Creates a joiner that can connect two cubetrusses end-to-end. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup>
**Topics:** [Trusses](Topics#trusses), [CubeTruss](Topics#cubetruss), [FDM Optimized](Topics#fdm-optimized), [Parts](Topics#parts)
**See Also:** [cubetruss\_segment()](#module-cubetruss_segment), [cubetruss\_support()](#module-cubetruss_support), [cubetruss()](#module-cubetruss), [cubetruss\_corner()](#module-cubetruss_corner)
**Usage:**
- cubetruss_uclip(dual, [size=], [strut=], [clipthick=]) [ATTACHMENTS];
**Description:**
Creates a small clip that can snap around one or two adjacent struts.
**Arguments:**
<abbr title="These args can be used by position or by name.">By&nbsp;Position</abbr> | What it does
-------------------- | ------------
`dual` | If true, create a clip to clip around two adjacent struts. If false, just fit around one strut. Default: true
`size` | The length of each side of the cubetruss cubes. Default: `$cubetruss_size` (usually 30)
`strut` | The width of the struts on the cubetruss cubes. Default: `$cubetruss_strut_size` (usually 3)
`clipthick` | The thickness of the clips. Default: `$cubetruss_clip_thickness` (usually 1.6)
<abbr title="These args must be used by name, ie: name=value">By&nbsp;Name</abbr> | What it does
-------------------- | ------------
`$slop` | Make fit looser by this amount
`anchor` | Translate so anchor point is at origin (0,0,0). See [anchor](attachments.scad#subsection-anchor). Default: `CENTER`
`spin` | Rotate this many degrees around the Z axis. See [spin](attachments.scad#subsection-spin). Default: `0`
`orient` | Vector to rotate top towards. See [orient](attachments.scad#subsection-orient). Default: `UP`
**Example 1:**
<img align="left" alt="cubetruss\_uclip() Example 1" src="images/cubetruss/cubetruss_uclip.png" width="320" height="240">
include <BOSL2/std.scad>
include <BOSL2/cubetruss.scad>
cubetruss_uclip(dual=false);
<br clear="all" /><br/>
**Example 2:**
<img align="left" alt="cubetruss\_uclip() Example 2" src="images/cubetruss/cubetruss_uclip_2.png" width="320" height="240">
include <BOSL2/std.scad>
include <BOSL2/cubetruss.scad>
cubetruss_uclip(dual=true);
<br clear="all" /><br/>
---
## Section: Cubetruss Primitives
### Module: cubetruss\_segment()
**Synopsis:** Creates a single cubetruss cube. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup>
**Topics:** [Trusses](Topics#trusses), [CubeTruss](Topics#cubetruss), [FDM Optimized](Topics#fdm-optimized), [Parts](Topics#parts)
**See Also:** [cubetruss\_support()](#module-cubetruss_support), [cubetruss()](#module-cubetruss), [cubetruss\_corner()](#module-cubetruss_corner)
**Usage:**
- cubetruss_segment([size=], [strut=], [bracing=]);
**Description:**
Creates a single cubetruss cube segment.
**Arguments:**
<abbr title="These args can be used by position or by name.">By&nbsp;Position</abbr> | What it does
-------------------- | ------------
`size` | The length of each side of the cubetruss cubes. Default: `$cubetruss_size` (usually 30)
`strut` | The width of the struts on the cubetruss cubes. Default: `$cubetruss_strut_size` (usually 3)
`bracing` | If true, adds internal cross-braces. Default: `$cubetruss_bracing` (usually true)
<abbr title="These args must be used by name, ie: name=value">By&nbsp;Name</abbr> | What it does
-------------------- | ------------
`anchor` | Translate so anchor point is at origin (0,0,0). See [anchor](attachments.scad#subsection-anchor). Default: `CENTER`
`spin` | Rotate this many degrees around the Z axis. See [spin](attachments.scad#subsection-spin). Default: `0`
`orient` | Vector to rotate top towards. See [orient](attachments.scad#subsection-orient). Default: `UP`
**Example 1:**
<img align="left" alt="cubetruss\_segment() Example 1" src="images/cubetruss/cubetruss_segment.png" width="320" height="240">
include <BOSL2/std.scad>
include <BOSL2/cubetruss.scad>
cubetruss_segment(bracing=false);
<br clear="all" /><br/>
**Example 2:**
<img align="left" alt="cubetruss\_segment() Example 2" src="images/cubetruss/cubetruss_segment_2.png" width="320" height="240">
include <BOSL2/std.scad>
include <BOSL2/cubetruss.scad>
cubetruss_segment(bracing=true);
<br clear="all" /><br/>
**Example 3:**
<img align="left" alt="cubetruss\_segment() Example 3" src="images/cubetruss/cubetruss_segment_3.png" width="320" height="240">
include <BOSL2/std.scad>
include <BOSL2/cubetruss.scad>
cubetruss_segment(strut=4);
<br clear="all" /><br/>
**Example 4:**
<img align="left" alt="cubetruss\_segment() Example 4" src="images/cubetruss/cubetruss_segment_4.png" width="320" height="240">
include <BOSL2/std.scad>
include <BOSL2/cubetruss.scad>
cubetruss_segment(size=40);
<br clear="all" /><br/>
---
### Module: cubetruss\_clip()
**Synopsis:** Creates a clip for the end of a cubetruss to snap-lock it to another cubetruss. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup>
**Topics:** [Trusses](Topics#trusses), [CubeTruss](Topics#cubetruss), [FDM Optimized](Topics#fdm-optimized), [Parts](Topics#parts)
**See Also:** [cubetruss\_segment()](#module-cubetruss_segment), [cubetruss\_support()](#module-cubetruss_support), [cubetruss()](#module-cubetruss), [cubetruss\_corner()](#module-cubetruss_corner)
**Usage:**
- cubetruss_clip(extents, [size=], [strut=], [clipthick=]) [ATTACHMENTS];
**Description:**
Creates a pair of clips to add onto the end of a truss.
**Arguments:**
<abbr title="These args can be used by position or by name.">By&nbsp;Position</abbr> | What it does
-------------------- | ------------
`extents` | How many cubes to separate the clips by.
`size` | The length of each side of the cubetruss cubes. Default: `$cubetruss_size` (usually 30)
`strut` | The width of the struts on the cubetruss cubes. Default: `$cubetruss_strut_size` (usually 3)
`clipthick` | The thickness of the clip. Default: `$cubetruss_clip_thickness` (usually 1.6)
<abbr title="These args must be used by name, ie: name=value">By&nbsp;Name</abbr> | What it does
-------------------- | ------------
`$slop` | allowance for printer overextrusion
`anchor` | Translate so anchor point is at origin (0,0,0). See [anchor](attachments.scad#subsection-anchor). Default: `CENTER`
`spin` | Rotate this many degrees around the Z axis. See [spin](attachments.scad#subsection-spin). Default: `0`
`orient` | Vector to rotate top towards. See [orient](attachments.scad#subsection-orient). Default: `UP`
**Example 1:**
<img align="left" alt="cubetruss\_clip() Example 1" src="images/cubetruss/cubetruss_clip.png" width="320" height="240">
include <BOSL2/std.scad>
include <BOSL2/cubetruss.scad>
cubetruss_clip(extents=2);
<br clear="all" /><br/>
**Example 2:**
<img align="left" alt="cubetruss\_clip() Example 2" src="images/cubetruss/cubetruss_clip_2.png" width="320" height="240">
include <BOSL2/std.scad>
include <BOSL2/cubetruss.scad>
cubetruss_clip(extents=1);
<br clear="all" /><br/>
**Example 3:**
<img align="left" alt="cubetruss\_clip() Example 3" src="images/cubetruss/cubetruss_clip_3.png" width="320" height="240">
include <BOSL2/std.scad>
include <BOSL2/cubetruss.scad>
cubetruss_clip(clipthick=2.5);
<br clear="all" /><br/>
---
### Function: cubetruss\_dist()
**Synopsis:** Returns the length of a cubetruss truss.
**Topics:** [Trusses](Topics#trusses), [CubeTruss](Topics#cubetruss), [FDM Optimized](Topics#fdm-optimized), [Parts](Topics#parts)
**See Also:** [cubetruss\_segment()](#module-cubetruss_segment), [cubetruss\_support()](#module-cubetruss_support), [cubetruss()](#module-cubetruss), [cubetruss\_corner()](#module-cubetruss_corner)
**Usage:**
- length = cubetruss_dist(cubes, [gaps], [size=], [strut=]);
**Description:**
Function to calculate the length of a cubetruss truss.
**Arguments:**
<abbr title="These args can be used by position or by name.">By&nbsp;Position</abbr> | What it does
-------------------- | ------------
`cubes` | The number of cubes along the truss's length.
`gaps` | The number of extra strut widths to add in, corresponding to each time a truss butts up against another.
`size` | The length of each side of the cubetruss cubes. Default: `$cubetruss_size` (usually 30)
`strut` | The width of the struts on the cubetruss cubes. Default: `$cubetruss_strut_size` (usually 3)
---

2286
distributors.scad.md Normal file

File diff suppressed because it is too large Load diff

1046
drawing.scad.md Normal file

File diff suppressed because it is too large Load diff

2898
fnliterals.scad.md Normal file

File diff suppressed because it is too large Load diff

3109
gears.scad.md Normal file

File diff suppressed because it is too large Load diff

2629
geometry.scad.md Normal file

File diff suppressed because it is too large Load diff

576
hinges.scad.md Normal file

@ -0,0 +1,576 @@
# LibFile: hinges.scad
Functions and modules for creating hinges and snap-locking hinged parts.
To use, add the following lines to the beginning of your file:
include <BOSL2/std.scad>
include <BOSL2/hinges.scad>
## File Contents
1. [Section: Hinges](#section-hinges)
- [`knuckle_hinge()`](#module-knuckle_hinge) Creates a knuckle-hinge shape. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup>
- [`living_hinge_mask()`](#module-living_hinge_mask) Creates a mask to make a folding "living" hinge. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup>
2. [Section: Snap Locks](#section-snap-locks)
- [`apply_folding_hinges_and_snaps()`](#module-apply_folding_hinges_and_snaps) Adds snap shapes and removes living hinges from a child shape. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup>
- [`snap_lock()`](#module-snap_lock) Creates a snap-lock shape. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup>
- [`snap_socket()`](#module-snap_socket) Creates a snap-lock socket shape. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup>
## Section: Hinges
### Module: knuckle\_hinge()
**Synopsis:** Creates a knuckle-hinge shape. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup>
**Topics:** [Hinges](Topics#hinges), [Parts](Topics#parts)
**See Also:** [living\_hinge\_mask()](#module-living_hinge_mask), [snap\_lock()](#module-snap_lock), [snap\_socket()](#module-snap_socket)
**Usage:**
- knuckle_hinge(length, offset, segs, [inner], [arm_height=], [arm_angle=], [fill=], [clear_top=], [gap=], [round_top=], [round_bot=], [knuckle_diam=], [pin_diam=], [pin_fn=], [anchor=], [spin=], [orient=]) [ATTACHMENTS];
**Description:**
Construct standard knuckle hinge in two parts using a hinge pin that must be separately supplied.
The default is configured to use a piece of 1.75 mm filament as the hinge pin, but you can select
any dimensions you like to use a screw or other available pin material. The BOTTOM of the hinge
is its mount point, which is aligned with the hinge pin centersurface, and the hinge pin hole is
the CENTER of the hinge. The offset is the distance from a vertical mounting point to the center
of the hinge pin. The hinge barrel is held by an angled support and vertical support. The
length of the angled support is determined by its angle and the offset. You specify the length
of the vertical support with the arm_height parameter.
A hinge requires clearance so its parts don't interfere. If the hinge pin is exactly centered on
the top of your part, then the hinge may not close all the way due to interference at the edge.
A small clearance, specified with `clearance=`, raises the hinge up and can ease this
interference. It should probably be equal to a layer thickness or two. If the hinge knuckle is
close to the hinged part then the mating part may interfere. You can create clearance to address
this problem by increasing the offset to move the hinge knuckles farther away. Another method is
to cut out a curved recess on the parts to allow space for the other hinges. This is possible
using the `knuckle_clearance=` parameter, which specifies the extra space to cut away to leave
room for the hinge knuckles. It must be positive for any space to be cut, and to use this option
you must make the hinge a child of some object and specify [`diff()`](attachments.scad#module-diff) for the parent object of
the hinge.
**Figure 1.1.1:** The basic hinge form appears on the left. If fill is set to true the gap between the mount surface and hinge arm is filled as shown on the right.
<img align="left" alt="knuckle\_hinge() Figure 1.1.1" src="images/hinges/figure_1_1_1.png" width="480" height="360">
<br clear="all" />
As shown in the above figure, the fill option fills the gap between the hinge arm and the mount surface to make a stronger connection. When the
arm height is set to zero, only a single segment connects the hinge barrel to the mount surface.
**Figure 1.1.2:** Zero arm height with 45 deg arm
<img align="left" alt="knuckle\_hinge() Figure 1.1.2" src="images/hinges/figure_1_1_2.png" width="480" height="360">
<br clear="all" />
**Figure 1.1.3:** Zero arm height with 90 deg arm. The clear\_top parameter removes the hinge support material that is above the x axis
<img align="left" alt="knuckle\_hinge() Figure 1.1.3" src="images/hinges/figure_1_1_3.png" width="480" height="360">
<br clear="all" />
**Figure 1.1.4:** An excessively large clearance value raises up the hinge center. Note that the hinge mounting remains bounded by the X axis, so when `fill=true` or `clear_top=true` this is different than simply raising up the entire hinge.
<img align="left" alt="knuckle\_hinge() Figure 1.1.4" src="images/hinges/figure_1_1_4.png" width="480" height="360">
<br clear="all" />
For 3D printability, you may prefer a teardrop shaped hole, which you can get with `teardrop=true`;
if necessary you can specify the teardrop direction to be UP, DOWN, FORWARD, or BACK.
(These directions assume that the base of the hinge is mounted on the back of something.)
Another option for printability is to use an octagonal hole, though it does seem more
difficult to size these for robust printability. To get an octagonal hole set `pin_fn=8`.
**Figure 1.1.5:** Alternate hole shapes for improved 3D printabililty
<img align="left" alt="knuckle\_hinge() Figure 1.1.5" src="images/hinges/figure_1_1_5.png" width="480" height="360">
<br clear="all" />
The default pin hole size admits a piece of 1.75 mm filament. If you prefer to use a machine
screw you can set the pin_diam to a screw specification like `"M3"` or "#6". In this case,
a clearance hole is created through most of the hinge with a self-tap hole for the last segment.
If the last segment is very long you may shrink the self-tap portion using the tap_depth parameter.
The pin hole diameter is enlarged by the `2*$slop` for numerically specified holes.
Screw holes are made using [`screw_hole()`](screws.scad#module-screw_hole) which enlarges the hole by `4*$slop`.
To blend hinges better with a model you can round off the joint with the mounting surface using
the `round_top` and `round_bot` parameters, which specify the cut distance, the amount of material to add.
They make a continuous curvature "smooth" roundover with `k=0.8`. See [smooth roundovers](rounding.scad#section-types-of-roundovers) for more
information. If you specify too large of a roundover you will get an error that the rounding doesn't fit.
**Figure 1.1.6:** Top and bottom roundovers for smooth hinge attachment
<img align="left" alt="knuckle\_hinge() Figure 1.1.6" src="images/hinges/figure_1_1_6.png" width="480" height="360">
<br clear="all" />
**Arguments:**
<abbr title="These args can be used by position or by name.">By&nbsp;Position</abbr> | What it does
-------------------- | ------------
`length` | total length of the entire hinge
`offset` | horizontal offset of the hinge pin center from the mount point
`segs` | number of hinge segments
`inner` | set to true for the "inner" hinge. Default: false
<abbr title="These args must be used by name, ie: name=value">By&nbsp;Name</abbr> | What it does
-------------------- | ------------
`arm_height` | vertical height of the arm that holds the hinge barrel. Default: 0
`arm_angle` | angle of the arm down from the vertical. Default: 45
`fill` | if true fill in space between arm and mount surface. Default: true
`clear_top` | if true remove any excess arm geometry that appears above the top of the mount surface. Default: false
`gap` | gap between hinge segments. Default: 0.2
`round_top` | rounding amount to add where top of hinge arm joins the mount surface. Generally only useful when fill=false. Default: 0
`round_bot` | rounding amount to add where bottom of hinge arm joins the mount surface. Default: 0
`knuckle_diam` | diameter of hinge barrel. Default: 4
`pin_diam` | diameter of hinge pin hole as a number of screw specification. Default: 1.75
`pin_fn` | $fn value to use for the pin.
`teardrop` | Set to true or UP/DOWN/FWD/BACK to specify teardrop shape for the pin hole. Default: false
`screw_head` | screw head to use for countersink
`screw_tolerance` | screw hole tolerance. Default: "close"
`tap_depth` | Don't make the tapped part of the screw hole larger than this.
`$slop` | increases pin hole diameter
`clearance` | raises pin hole to create clearance at the edge of the mounted surface. Default: 0.15
`clear_knuckle` | clear space for hinge knuckle of mating part. Must use with [`diff()`](attachments.scad#module-diff). Default: 0
`anchor` | Translate so anchor point is at origin (0,0,0). See [anchor](attachments.scad#subsection-anchor). Default: `BOTTOM`
`spin` | Rotate this many degrees around the Z axis after anchor. See [spin](attachments.scad#subsection-spin). Default: `0`
`orient` | Vector to rotate top towards, after spin. See [orient](attachments.scad#subsection-orient). Default: `UP`
**Example 1:** Basic hinge, inner=false in front and inner=true in the back
<img align="left" alt="knuckle\_hinge() Example 1" src="images/hinges/knuckle_hinge.png" width="320" height="240">
<br clear="all" />
include <BOSL2/std.scad>
include <BOSL2/hinges.scad>
$fn=32;
ydistribute(30){
knuckle_hinge(length=35, segs=5, offset=3, arm_height=1);
knuckle_hinge(length=35, segs=5, offset=3, arm_height=1,inner=true);
}
**Example 2:** Basic hinge, mounted. Odd segment count means the "outside" hinge is on the outside at both ends.
<img align="left" alt="knuckle\_hinge() Example 2" src="images/hinges/knuckle_hinge_2.png" width="320" height="240">
include <BOSL2/std.scad>
include <BOSL2/hinges.scad>
$fn=32;
cuboid([2,40,15])
position(TOP+RIGHT) orient(anchor=RIGHT)
knuckle_hinge(length=35, segs=9, offset=3, arm_height=1);
<br clear="all" /><br/>
**Example 3:** Corresponding inner hinge to go with previous example. Note that the total number of hinge segments adds to the 9 specified.
<img align="left" alt="knuckle\_hinge() Example 3" src="images/hinges/knuckle_hinge_3.png" width="320" height="240">
<br clear="all" />
include <BOSL2/std.scad>
include <BOSL2/hinges.scad>
$fn=32;
cuboid([2,40,15])
position(TOP+RIGHT) orient(anchor=RIGHT)
knuckle_hinge(length=35, segs=9, offset=3, arm_height=1, inner=true);
**Example 4:** This example shows how to position and orient the hinge onto the front of an object instead of the right side.
<img align="left" alt="knuckle\_hinge() Example 4" src="images/hinges/knuckle_hinge_4.png" width="320" height="240">
include <BOSL2/std.scad>
include <BOSL2/hinges.scad>
$fn=32;
cuboid([40,2,15])
position(TOP+FRONT) orient(anchor=FWD)
knuckle_hinge(length=35, segs=9, offset=3, arm_height=1);
<br clear="all" /><br/>
**Example 5:** Hinge with round\_bot set to create a smooth transition, but octagonal hinge pin holes for printing
<img align="left" alt="knuckle\_hinge() Example 5" src="images/hinges/knuckle_hinge_5.png" width="320" height="240">
include <BOSL2/std.scad>
include <BOSL2/hinges.scad>
$fn=32;
cuboid([2,40,15])
position(TOP+RIGHT) orient(anchor=RIGHT)
knuckle_hinge(length=35, segs=9, offset=3, arm_height=1,
round_bot=1, pin_fn=8);
<br clear="all" /><br/>
**Example 6:** Hinge with no vertical arm, just angled arm
<img align="left" alt="knuckle\_hinge() Example 6" src="images/hinges/knuckle_hinge_6.png" width="320" height="240">
include <BOSL2/std.scad>
include <BOSL2/hinges.scad>
$fn=32;
cuboid([2,40,15])
position(TOP+RIGHT) orient(anchor=RIGHT)
knuckle_hinge(length=35, segs=9, offset=3, pin_fn=8);
<br clear="all" /><br/>
**Example 7:** Setting the arm\_angle to a large value like 90 produces a hinge that doesn't look great
<img align="left" alt="knuckle\_hinge() Example 7" src="images/hinges/knuckle_hinge_7.png" width="320" height="240">
include <BOSL2/std.scad>
include <BOSL2/hinges.scad>
$fn=32;
cuboid([2,40,15])
position(TOP+RIGHT) orient(anchor=RIGHT)
knuckle_hinge(length=35, segs=9, offset=3, arm_angle=90,
arm_height=0, pin_fn=8);
<br clear="all" /><br/>
**Example 8:** The above hinge is improved with clear\_top, which allows nice attachment to a shape half the thickness of the hinge barrel
<img align="left" alt="knuckle\_hinge() Example 8" src="images/hinges/knuckle_hinge_8.png" width="320" height="240">
include <BOSL2/std.scad>
include <BOSL2/hinges.scad>
$fn=32;
cuboid([20,40,2])
position(TOP+RIGHT) orient(anchor=RIGHT)
knuckle_hinge(length=35, segs=9, offset=3, arm_height=0,
arm_angle=90, pin_fn=8, clear_top=true);
<br clear="all" /><br/>
**Example 9:** Uneven hinge using seg\_ratio. Here the inner hinge segments are 1/3 the outer, a rather extreme difference. Note also that it's a little simpler to mount the inner hinge on the LEFT side of the top section to interface with the hinge mounted on the RIGHT.
<img align="left" alt="knuckle\_hinge() Example 9" src="images/hinges/knuckle_hinge_9.png" width="320" height="240">
<br clear="all" />
include <BOSL2/std.scad>
include <BOSL2/hinges.scad>
$fn=32;
cuboid([2,40,15]){
position(TOP+RIGHT) orient(anchor=RIGHT)
knuckle_hinge(length=35, segs=9, offset=3, arm_height=1,
seg_ratio=1/3);
attach(TOP,TOP) color("green")
cuboid([2,40,15],anchor=TOP)
position(TOP+LEFT) orient(anchor=LEFT)
knuckle_hinge(length=35, segs=9, offset=3, arm_height=1,
seg_ratio=1/3, inner=true);
}
**Example 10:** A single hinge with an even number of segments will probably look strange, but they work together neatly in a pair. This example also shows that the arm\_height can change between the inner and outer hinge parts and they will still interface properly.
<img align="left" alt="knuckle\_hinge() Example 10" src="images/hinges/knuckle_hinge_10.png" width="320" height="240">
<br clear="all" />
include <BOSL2/std.scad>
include <BOSL2/hinges.scad>
$fn=32;
cuboid([2,40,15]){
yflip_copy()
position(TOP+RIGHT+FRONT) orient(anchor=RIGHT)
knuckle_hinge(length=12, segs=2, offset=2, arm_height=2,
anchor=BOT+LEFT);
attach(TOP,TOP) color("green")
cuboid([2,40,15],anchor=TOP)
yflip_copy()
position(TOP+LEFT+FRONT) orient(anchor=LEFT)
knuckle_hinge(length=12, segs=2, offset=2, arm_height=0,
inner=true, anchor=BOT+RIGHT);
}
**Example 11:** Hinge with self-tapping screw hole. Note that last segment has smaller diameter for screw to bite, whereas other segments have clearance holes.
<img align="left" alt="knuckle\_hinge() Example 11" src="images/hinges/knuckle_hinge_11.png" width="320" height="240">
<br clear="all" />
include <BOSL2/std.scad>
include <BOSL2/hinges.scad>
$fn=32;
bottom_half(z=.01)
cuboid([2,40,15],anchor=TOP)
position(TOP+RIGHT) orient(anchor=RIGHT)
knuckle_hinge(length=35, segs=5, offset=5, knuckle_diam=9, pin_diam="#6", fill=false,inner=false, screw_head="flat");
**Example 12:** If you give a non-flat screw head then a counterbore for that head is generated. If you don't want the counterbore, don't give a head type. In this example, tap\_depth limits the narrower self-tap section of the hole.
<img align="left" alt="knuckle\_hinge() Example 12" src="images/hinges/knuckle_hinge_12.png" width="320" height="240">
<br clear="all" />
include <BOSL2/std.scad>
include <BOSL2/hinges.scad>
$fn=32;
bottom_half(z=.01)
cuboid([2,40,15],anchor=TOP)
position(TOP+RIGHT) orient(anchor=RIGHT)
knuckle_hinge(length=35, segs=3, offset=5, knuckle_diam=9, pin_diam="#6",
fill=false, inner=false, tap_depth=6, screw_head="socket");
**Example 13:** This hinge has a small offset, so the hinged parts may interfere. To prevent this, use `knuckle_clearance`. This example shows an excessive clearance value to make the effect obvious. Note that you **must** use [`diff()`](attachments.scad#module-diff) when you set `knuckle_clearance`, and the hinge must be a child of the object it mounts to. Otherwise the cylinders that are supposed to be subtracted will appear as extra objects. This is an inner hinge, so it has clearance zones for the larger outer hinge that will mate with it.
<img align="left" alt="knuckle\_hinge() Example 13" src="images/hinges/knuckle_hinge_13.png" width="320" height="240">
<br clear="all" />
include <BOSL2/std.scad>
include <BOSL2/hinges.scad>
$fn=32;
diff()
cuboid([4,40,15])
position(TOP+RIGHT) orient(anchor=RIGHT)
knuckle_hinge(length=35, segs=5, offset=2, inner=true, knuckle_clearance=1);
**Example 14:** Oh no! Forgot to use [`diff()`](attachments.scad#module-diff) with knuckle\_clearance!
<img align="left" alt="knuckle\_hinge() Example 14" src="images/hinges/knuckle_hinge_14.png" width="320" height="240">
<br clear="all" />
include <BOSL2/std.scad>
include <BOSL2/hinges.scad>
$fn=32;
cuboid([4,40,15])
position(TOP+RIGHT) orient(anchor=RIGHT)
knuckle_hinge(length=35, segs=5, offset=2, inner=true, knuckle_clearance=1);
---
### Module: living\_hinge\_mask()
**Synopsis:** Creates a mask to make a folding "living" hinge. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup>
**Topics:** [Hinges](Topics#hinges), [Parts](Topics#parts)
**See Also:** [knuckle\_hinge()](#module-knuckle_hinge), [snap\_lock()](#module-snap_lock), [snap\_socket()](#module-snap_socket), [apply\_folding\_hinges\_and\_snaps()](#module-apply_folding_hinges_and_snaps)
**Usage:**
- living_hinge_mask(l, thick, [layerheight=], [foldangle=], [hingegap=], [$slop=], [anchor=], [spin=], [orient=]) [ATTACHMENTS];
**Description:**
Creates a mask to be differenced away from a plate to create a "live" hinge, where a thin layer of plastic holds two parts together.
Center the mask at the bottom of the part you want to make a hinge in.
The mask will leave hinge material `2*layerheight` thick on the bottom of the hinge.
**Arguments:**
<abbr title="These args can be used by position or by name.">By&nbsp;Position</abbr> | What it does
-------------------- | ------------
`l` | Length of the hinge in mm.
`thick` | Thickness in mm of the material to make the hinge in.
<abbr title="These args must be used by name, ie: name=value">By&nbsp;Name</abbr> | What it does
-------------------- | ------------
`layerheight` | The expected printing layer height in mm.
`foldangle` | The interior angle in degrees of the joint to be created with the hinge. Default: 90
`hingegap` | Size in mm of the gap at the bottom of the hinge, to make room for folding.
`$slop` | Increase size of hinge gap by double this amount
`anchor` | Translate so anchor point is at origin (0,0,0). See [anchor](attachments.scad#subsection-anchor). Default: `CENTER`
`spin` | Rotate this many degrees around the Z axis. See [spin](attachments.scad#subsection-spin). Default: `0`
`orient` | Vector to rotate top towards. See [orient](attachments.scad#subsection-orient). Default: `UP`
**Example 1:**
<img align="left" alt="living\_hinge\_mask() Example 1" src="images/hinges/living_hinge_mask.png" width="320" height="240">
include <BOSL2/std.scad>
include <BOSL2/hinges.scad>
living_hinge_mask(l=100, thick=3, foldangle=60);
<br clear="all" /><br/>
---
## Section: Snap Locks
### Module: apply\_folding\_hinges\_and\_snaps()
**Synopsis:** Adds snap shapes and removes living hinges from a child shape. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup>
**Topics:** [Hinges](Topics#hinges), [Parts](Topics#parts)
**See Also:** [knuckle\_hinge()](#module-knuckle_hinge), [living\_hinge\_mask()](#module-living_hinge_mask), [snap\_lock()](#module-snap_lock), [snap\_socket()](#module-snap_socket)
**Usage:**
- apply_folding_hinges_and_snaps(thick, [foldangle=], [hinges=], [snaps=], [sockets=], [snaplen=], [snapdiam=], [hingegap=], [layerheight=], [$slop=]) CHILDREN;
**Description:**
Adds snaplocks and create hinges in children at the given positions.
**Arguments:**
<abbr title="These args can be used by position or by name.">By&nbsp;Position</abbr> | What it does
-------------------- | ------------
`thick` | Thickness in mm of the material to make the hinge in.
`foldangle` | The interior angle in degrees of the joint to be created with the hinge. Default: 90
`hinges` | List of [LENGTH, POSITION, SPIN] for each hinge to difference from the children.
`snaps` | List of [POSITION, SPIN] for each central snaplock to add to the children.
`sockets` | List of [POSITION, SPIN] for each outer snaplock sockets to add to the children.
`snaplen` | Length of locking snaps.
`snapdiam` | Diameter/width of locking snaps.
`hingegap` | Size in mm of the gap at the bottom of the hinge, to make room for folding.
`layerheight` | The expected printing layer height in mm.
<abbr title="These args must be used by name, ie: name=value">By&nbsp;Name</abbr> | What it does
-------------------- | ------------
`$slop` | increase hinge gap by twice this amount
**Example 1:**
<img align="left" alt="apply\_folding\_hinges\_and\_snaps() Example 1" src="images/hinges/apply_folding_hinges_and_snaps.png" width="480" height="360">
<br clear="all" />
include <BOSL2/std.scad>
include <BOSL2/hinges.scad>
size=100;
apply_folding_hinges_and_snaps(
thick=3, foldangle=acos(1/3),
hinges=[
for (a=[0,120,240], b=[-size/2,size/4]) each [
[200, polar_to_xy(b,a), a+90]
]
],
snaps=[
for (a=[0,120,240]) each [
[rot(a,p=[ size/4, 0 ]), a+90],
[rot(a,p=[-size/2,-size/2.33]), a-90]
]
],
sockets=[
for (a=[0,120,240]) each [
[rot(a,p=[ size/4, 0 ]), a+90],
[rot(a,p=[-size/2, size/2.33]), a+90]
]
]
) {
$fn=3;
difference() {
cylinder(r=size-1, h=3);
down(0.01) cylinder(r=size/4.5, h=3.1, spin=180);
down(0.01) for (a=[0:120:359.9]) zrot(a) right(size/2) cylinder(r=size/4.5, h=3.1);
}
}
---
### Module: snap\_lock()
**Synopsis:** Creates a snap-lock shape. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup>
**Topics:** [Hinges](Topics#hinges), [Parts](Topics#parts)
**See Also:** [knuckle\_hinge()](#module-knuckle_hinge), [living\_hinge\_mask()](#module-living_hinge_mask), [snap\_socket()](#module-snap_socket)
**Usage:**
- snap_lock(thick, [snaplen=], [snapdiam=], [layerheight=], [foldangle=], [hingegap=], [$slop=], [anchor=], [spin=], [orient=]) [ATTACHMENTS];
**Description:**
Creates the central snaplock part.
**Arguments:**
<abbr title="These args can be used by position or by name.">By&nbsp;Position</abbr> | What it does
-------------------- | ------------
`thick` | Thickness in mm of the material to make the hinge in.
<abbr title="These args must be used by name, ie: name=value">By&nbsp;Name</abbr> | What it does
-------------------- | ------------
`snaplen` | Length of locking snaps.
`snapdiam` | Diameter/width of locking snaps.
`layerheight` | The expected printing layer height in mm.
`foldangle` | The interior angle in degrees of the joint to be created with the hinge. Default: 90
`hingegap` | Size in mm of the gap at the bottom of the hinge, to make room for folding.
`$slop` | increase size of hinge gap by double this amount
`anchor` | Translate so anchor point is at origin (0,0,0). See [anchor](attachments.scad#subsection-anchor). Default: `CENTER`
`spin` | Rotate this many degrees around the Z axis. See [spin](attachments.scad#subsection-spin). Default: `0`
`orient` | Vector to rotate top towards. See [orient](attachments.scad#subsection-orient). Default: `UP`
**Example 1:**
<img align="left" alt="snap\_lock() Example 1" src="images/hinges/snap_lock.png" width="320" height="240">
include <BOSL2/std.scad>
include <BOSL2/hinges.scad>
snap_lock(thick=3, foldangle=60);
<br clear="all" /><br/>
---
### Module: snap\_socket()
**Synopsis:** Creates a snap-lock socket shape. <sup title="Can return geometry.">[<abbr>Geom</abbr>]</sup>
**Topics:** [Hinges](Topics#hinges), [Parts](Topics#parts)
**See Also:** [knuckle\_hinge()](#module-knuckle_hinge), [living\_hinge\_mask()](#module-living_hinge_mask), [snap\_lock()](#module-snap_lock)
**Usage:**
- snap_socket(thick, [snaplen=], [snapdiam=], [layerheight=], [foldangle=], [hingegap=], [$slop=], [anchor=], [spin=], [orient=]) [ATTACHMENTS];
**Description:**
Creates the outside snaplock socketed part.
**Arguments:**
<abbr title="These args can be used by position or by name.">By&nbsp;Position</abbr> | What it does
-------------------- | ------------
`thick` | Thickness in mm of the material to make the hinge in.
<abbr title="These args must be used by name, ie: name=value">By&nbsp;Name</abbr> | What it does
-------------------- | ------------
`snaplen` | Length of locking snaps.
`snapdiam` | Diameter/width of locking snaps.
`layerheight` | The expected printing layer height in mm.
`foldangle` | The interior angle in degrees of the joint to be created with the hinge. Default: 90
`hingegap` | Size in mm of the gap at the bottom of the hinge, to make room for folding.
`$slop` | Increase size of hinge gap by double this amount
`anchor` | Translate so anchor point is at origin (0,0,0). See [anchor](attachments.scad#subsection-anchor). Default: `CENTER`
`spin` | Rotate this many degrees around the Z axis. See [spin](attachments.scad#subsection-spin). Default: `0`
`orient` | Vector to rotate top towards. See [orient](attachments.scad#subsection-orient). Default: `UP`
**Example 1:**
<img align="left" alt="snap\_socket() Example 1" src="images/hinges/snap_socket.png" width="320" height="240">
include <BOSL2/std.scad>
include <BOSL2/hinges.scad>
snap_socket(thick=3, foldangle=60);
<br clear="all" /><br/>
---

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

BIN
images/attachments/diff.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Some files were not shown because too many files have changed in this diff Show more