Renamed align to anchor.

This commit is contained in:
Revar Desmera 2019-04-22 20:55:03 -07:00
parent 597d74fcc8
commit 5a16152416
29 changed files with 684 additions and 698 deletions

View file

@ -24,7 +24,7 @@ Args | What it is
fillet | Radius of rounding for interior or exterior edges.
chamfer | Size of chamfers/bevels for interior or exterior edges.
orient | Axis a part should be oriented along. Given as an XYZ triplet of rotation angles. It is recommended that you use the `ORIENT_` constants from `constants.scad`. Default is usually `ORIENT_Z` for vertical orientation.
align | Side of the origin that the part should be on. Given as a vector away from the origin. It is recommended that you use the constants from `constants.scad`. Default is usually `CENTER` for centered.
anchor | Side of the object that should be anchored to the origin. Given as a vector towards the side of the part to align with the origin. It is recommended that you use the directional constants from `constants.scad`. Default is usually `CENTER` for centered.
## Examples
@ -58,11 +58,14 @@ The library files are as follows:
### Commonly Used
- [`transforms.scad`](https://github.com/revarbat/BOSL2/wiki/transforms.scad): The most commonly used transformations, manipulations, and shortcuts are in this file.
- [`attachments.scad`](https://github.com/revarbat/BOSL2/wiki/attachments.scad): Modules and functions to enable attaching parts together.
- [`primitives.scad`](https://github.com/revarbat/BOSL2/wiki/primitives.scad): Enhanced replacements for `cube()`, `cylinder()`, and `sphere()`.
- [`shapes.scad`](https://github.com/revarbat/BOSL2/wiki/shapes.scad): Common useful shapes and structured objects.
- [`masks.scad`](https://github.com/revarbat/BOSL2/wiki/masks.scad): Shapes that are useful for masking with `difference()` and `intersect()`.
- [`threading.scad`](https://github.com/revarbat/BOSL2/wiki/threading.scad): Modules to make triangular and trapezoidal threaded rods and nuts.
- [`paths.scad`](https://github.com/revarbat/BOSL2/wiki/paths.scad): Functions and modules to work with arbitrary 3D paths.
- [`beziers.scad`](https://github.com/revarbat/BOSL2/wiki/beziers.scad): Functions and modules to work with bezier curves.
- [`debug.scad`](https://github.com/revarbat/BOSL2/wiki/debug.scad): Modules to help debug beziers, `polygons()`s and `polyhedron()`s, etc.
### Standard Parts
- [`involute_gears.scad`](https://github.com/revarbat/BOSL2/wiki/involute_gears.scad): Modules and functions to make involute gears and racks.
@ -75,11 +78,16 @@ The library files are as follows:
- [`torx_drive.scad`](https://github.com/revarbat/BOSL2/wiki/torx_drive.scad): Functions and Modules to create Torx bit drive holes.
- [`wiring.scad`](https://github.com/revarbat/BOSL2/wiki/wiring.scad): Modules to render routed bundles of wires.
### Miscellaneous
- [`math.scad`](https://github.com/revarbat/BOSL2/wiki/math.scad): Useful helper functions.
### Various Math
- [`constants.scad`](https://github.com/revarbat/BOSL2/wiki/constants.scad): Useful constants for vectors, edges, etc.
- [`math.scad`](https://github.com/revarbat/BOSL2/wiki/math.scad): Useful helper functions.
- [`arrays.scad`](https://github.com/revarbat/BOSL2/wiki/arrays.scad): List and Array helper functions.
- [`vectors.scad`](https://github.com/revarbat/BOSL2/wiki/vectors.scad): Vector math functions.
- [`matrices.scad`](https://github.com/revarbat/BOSL2/wiki/matrices.scad): Matrix math and affine transformation functions.
- [`coords.scad`](https://github.com/revarbat/BOSL2/wiki/coords.scad): Coordinate system conversions and point transformations.
- [`quaternions.scad`](https://github.com/revarbat/BOSL2/wiki/quaternions.scad): Functions to work with quaternion rotations.
- [`debug.scad`](https://github.com/revarbat/BOSL2/wiki/debug.scad): Modules to help debug creation of beziers, `polygons()`s and `polyhedron()`s
- [`convex_hull.scad`](https://github.com/revarbat/BOSL2/wiki/convex_hull.scad): Functions to generate 2D and 3D hulls of points.
- [`triangulation.scad`](https://github.com/revarbat/BOSL2/wiki/triangulation.scad): Functions to triangulate `polyhedron()` faces.
## Documentation
The full library docs can be found at https://github.com/revarbat/BOSL2/wiki

View file

@ -40,73 +40,74 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Section: Functions
// Function: connector()
// Function: anchorpt()
// Usage:
// connector(name, pos, dir, [rot])
// anchor(name, pos, [dir], [rot])
// Description:
// Creates a connector data structure.
// Creates a anchor data structure.
// Arguments:
// name = The string name of the connector. Lowercase. Words separated by single dashes. No spaces.
// pos = The [X,Y,Z] position of the connector.
// dir = A vector pointing in the direction parts should project from the connector position.
// name = The string name of the anchor. Lowercase. Words separated by single dashes. No spaces.
// pos = The [X,Y,Z] position of the anchor.
// dir = A vector pointing in the direction parts should project from the anchor position.
// rot = If needed, the angle to rotate the part around the direction vector.
function connector(name, pos=[0,0,0], dir=UP, rot=0) = [name, pos, dir, rot];
function anchorpt(name, pos=[0,0,0], dir=UP, rot=0) = [name, pos, dir, rot];
// Function: find_connector()
// Function: find_anchor()
// Usage:
// find_connector(align, h, size, [size2], [shift], [edges], [corners]);
// find_anchor(anchor, h, size, [size2], [shift], [edges], [corners]);
// Description:
// Generates a list of typical connectors for a cubical region of the given size.
// Generates a list of typical anchors.
// Arguments:
// align = Named alignment/connector string.
// anchor = Vector or named anchor string.
// h = Height of the region.
// size = The [X,Y] size of the bottom of the cubical region.
// size2 = The [X,Y] size of the top of the cubical region.
// shift = The [X,Y] amount to shift the center of the top with respect to the center of the bottom.
// geometry = One of "cube", "cylinder", or "sphere" to denote the overall geometry of the shape. Cones are "cylinder", and prismoids are "cube" for this purpose. Default: "cube"
// extra_conns = A list of extra named connectors.
function find_connector(align, h, size, size2=undef, shift=[0,0], extra_conns=[], geometry="cube") =
is_string(align)? (
let(found = search([align], extra_conns, num_returns_per_match=1)[0])
assert(found!=[], str("Unknown alignment: ",align))
extra_conns[found]
// extra_anchors = A list of extra non-standard named anchors.
function find_anchor(anchor, h, size, size2=undef, shift=[0,0], extra_anchors=[], geometry="cube") =
is_string(anchor)? (
let(found = search([anchor], extra_anchors, num_returns_per_match=1)[0])
assert(found!=[], str("Unknown anchor: ",anchor))
extra_anchors[found]
) : (
let(
size = point2d(size),
size2 = (size2!=undef)? point2d(size2) : size,
shift = point2d(shift),
oang = (
align == UP? 0 :
align == DOWN? 0 :
(norm([align.x,align.y]) < EPSILON)? 0 :
atan2(align.y, align.x)+90
anchor == UP? 0 :
anchor == DOWN? 0 :
(norm([anchor.x,anchor.y]) < EPSILON)? 0 :
atan2(anchor.y, anchor.x)+90
)
)
geometry=="sphere"? let(
phi = align==UP? 0 : align==DOWN? 180 : 90 + (45 * align.z),
theta = atan2(align.y, align.x),
phi = (anchor==UP||anchor==CENTER)? 0 : anchor==DOWN? 180 : 90 + (45 * anchor.z),
theta = anchor==CENTER? 90 : atan2(anchor.y, anchor.x),
vec = spherical_to_xyz(1, theta, phi),
pos = vmul(vec, (point3d(size)+h*UP)/2)
) [align, pos, vec, oang] : let (
pos = anchor==CENTER? CENTER : vmul(vec, (point3d(size)+h*UP)/2)
) [anchor, pos, vec, oang] : let (
xyal = (
geometry=="cylinder"? (
let(xy = point2d(align))
let(xy = point2d(anchor))
norm(xy)>0? xy/norm(xy) : [0,0]
) : point2d(align)
) : point2d(anchor)
),
botpt = point3d(vmul(size/2,xyal))+DOWN*h/2,
toppt = point3d(vmul(size2/2,xyal)+shift)+UP*h/2,
pos = lerp(botpt, toppt, (align.z+1)/2),
pos = lerp(botpt, toppt, (anchor.z+1)/2),
sidevec = rotate_points3d([point3d(xyal)], from=UP, to=toppt-botpt)[0],
vec = (
norm([align.x,align.y]) < EPSILON? align :
abs(align.z) < EPSILON? sidevec :
align.z>0? (UP+sidevec)/2 :
anchor==CENTER? UP :
norm([anchor.x,anchor.y]) < EPSILON? anchor :
abs(anchor.z) < EPSILON? sidevec :
anchor.z>0? (UP+sidevec)/2 :
(DOWN+sidevec)/2
)
) [align, pos, vec, oang]
) [anchor, pos, vec, oang]
);
@ -122,60 +123,60 @@ function _str_char_split(s,delim,n=0,acc=[],word="") =
// Section: Modules
// Module: orient_and_align()
// Module: orient_and_anchor()
//
// Description:
// Takes a vertically oriented shape, and re-orients and aligns it.
// Takes a vertically oriented shape, and re-orients and anchors it.
// This is useful for making a custom shape available in various
// orientations and alignments without extra translate()s and rotate()s.
// orientations and anchor without extra translate()s and rotate()s.
// Children should be vertically (Z-axis) oriented, and centered.
// Non-extremity alignment points should be named via the `alignments` arg.
// Named alignments are aligned pre-rotation.
// Non-vector anchor points should be named via the `anchors` arg.
// Named anchors are translated pre-rotation.
//
// Usage:
// orient_and_align(size, [orient], [align], [center], [noncentered], [orig_orient], [orig_align], [alignments], [chain]) ...
// orient_and_anchor(size, [orient], [anchor], [center], [noncentered], [orig_orient], [orig_anchor], [anchors], [chain]) ...
//
// Arguments:
// size = The [X,Y,Z] size of the part.
// size2 = The [X,Y] size of the top of the part.
// shift = The [X,Y] offset of the top of the part, compared to the bottom of the part.
// orient = The axis to align to. Use `ORIENT_` constants from `constants.scad`.
// align = The side of the origin the part should be aligned with.
// center = If given, overrides `align`. If true, centers vertically. If false, `align` will be set to the value in `noncentered`.
// noncentered = The value to set `align` to if `center` == `false`. Default: `BOTTOM`.
// orient = The axis to orient to. Use `ORIENT_` constants from `constants.scad`.
// anchor = The side of the part that will be anchored to the origin.
// center = If given, overrides `anchor`. If true, centers vertically. If false, `anchor` will be set to the value in `noncentered`.
// noncentered = The value to set `anchor` to if `center` == `false`. Default: `BOTTOM`.
// orig_orient = The original orientation of the part. Default: `ORIENT_Z`.
// orig_align = The original alignment of the part. Default: `CENTER`.
// orig_anchor = The original anchor of the part. Default: `CENTER`.
// geometry = One of "cube", "cylinder", or "sphere" to denote the overall geometry of the shape. Cones are "cylinder", and prismoids are "cube" for this purpose. Default: "cube"
// alignments = A list of extra, non-standard connectors that can be aligned to.
// anchors = A list of extra, non-standard optional anchors.
// chain = If true, allow attachable children.
//
// Side Effects:
// `$parent_size` is set to the parent object's cubical region size.
// `$parent_size2` is set to the parent object's top [X,Y] size.
// `$parent_shift` is set to the parent object's `shift` value, if any.
// `$parent_orient` is set to the parent object's `orient` value.
// `$parent_align` is set to the parent object's `align` value.
// `$parent_geom` is set to the parent object's `geometry` value.
// `$parent_conns` is set to the parent object's list of non-standard extra connectors.
// `$parent_orient` is set to the parent object's `orient` value.
// `$parent_anchor` is set to the parent object's `anchor` value.
// `$parent_anchors` is set to the parent object's list of non-standard extra anchors.
//
// Example:
// #cylinder(d=5, h=10);
// orient_and_align([5,5,10], orient=ORIENT_Y, align=BACK, orig_align=UP) cylinder(d=5, h=10);
module orient_and_align(
size=undef, orient=ORIENT_Z, align=CENTER,
// orient_and_anchor([5,5,10], orient=ORIENT_Y, anchor=BACK, orig_anchor=UP) cylinder(d=5, h=10);
module orient_and_anchor(
size=undef, orient=ORIENT_Z, anchor=CENTER,
center=undef, noncentered=BOTTOM,
orig_orient=ORIENT_Z, orig_align=CENTER,
orig_orient=ORIENT_Z, orig_anchor=CENTER,
size2=undef, shift=[0,0],
alignments=[], chain=false,
anchors=[], chain=false,
geometry="cube"
) {
size2 = point2d(default(size2, size));
shift = point2d(shift);
align = !is_undef(center)? (center? CENTER : noncentered) : align;
anchor = !is_undef(center)? (center? CENTER : noncentered) : anchor;
m = matrix4_mult(concat(
(orig_align==CENTER)? [] : [
// If original alignment is not centered, center it.
matrix4_translate(vmul(size/2, -orig_align))
(orig_anchor==CENTER)? [] : [
// If original anchor is not centered, center it.
matrix4_translate(vmul(size/2, -orig_anchor))
],
(orig_orient==ORIENT_Z)? [] : [
// If original orientation is not upright, rotate it upright.
@ -185,20 +186,20 @@ module orient_and_align(
],
($attach_to!=undef)? (
let(
conn = find_connector($attach_to, size.z, size, size2=size2, shift=shift, geometry=geometry),
ang = vector_angle(conn[2], DOWN),
axis = vector_axis(conn[2], DOWN),
ang2 = (conn[2]==UP || conn[2]==DOWN)? 0 : 180-conn[3],
anch = find_anchor($attach_to, size.z, size, size2=size2, shift=shift, geometry=geometry),
ang = vector_angle(anch[2], DOWN),
axis = vector_axis(anch[2], DOWN),
ang2 = (anch[2]==UP || anch[2]==DOWN)? 0 : 180-anch[3],
axis2 = rotate_points3d([axis],[0,0,ang2])[0]
) [
matrix4_translate(-conn[1]),
matrix4_translate(-anch[1]),
matrix4_zrot(ang2),
matrix4_rot_by_axis(axis2, ang)
]
) : concat(
(align==CENTER)? [] : [
let(conn = find_connector(align, size.z, size, size2=size2, shift=shift, extra_conns=alignments, geometry=geometry))
matrix4_translate(-conn[1])
(anchor==CENTER)? [] : [
let(anch = find_anchor(anchor, size.z, size, size2=size2, shift=shift, extra_anchors=anchors, geometry=geometry))
matrix4_translate(-anch[1])
],
(orient==ORIENT_Z)? [] : [
matrix4_xrot(orient.x),
@ -211,10 +212,10 @@ module orient_and_align(
$parent_size = size;
$parent_size2 = size2;
$parent_shift = shift;
$parent_orient = orient;
$parent_align = align;
$parent_geom = geometry;
$parent_conns = alignments;
$parent_orient = orient;
$parent_anchor = anchor;
$parent_anchors = anchors;
tags = _str_char_split($tags, " ");
s_tags = $tags_shown;
h_tags = $tags_hidden;
@ -237,28 +238,28 @@ module orient_and_align(
// attach(name, [overlap], [norot]) ...
// attach(name, to, [overlap]) ...
// Description:
// Attaches children to a parent object at an attachment point and orientation.
// Attaches children to a parent object at an anchor point and orientation.
// Arguments:
// name = The name of the parent attachment point to attach to.
// to = The name of the child attachment point.
// name = The name of the parent anchor point to attach to.
// to = The name of the child anchor point.
// overlap = Amount to sink child into the parent.
// norot = If true, don't rotate children when aligning to the attachment point.
// norot = If true, don't rotate children when attaching to the anchor point.
// Example:
// spheroid(d=20) {
// attach(TOP) down(1.5) cyl(l=11.5, d1=10, d2=5, align=BOTTOM);
// attach(TOP) down(1.5) cyl(l=11.5, d1=10, d2=5, anchor=BOTTOM);
// attach(RIGHT, BOTTOM) down(1.5) cyl(l=11.5, d1=10, d2=5);
// attach(FRONT) down(1.5) cyl(l=11.5, d1=10, d2=5, align=BOTTOM);
// attach(FRONT) down(1.5) cyl(l=11.5, d1=10, d2=5, anchor=BOTTOM);
// }
module attach(name, to=undef, overlap=undef, norot=false)
{
assert($parent_size != undef, "No object to attach to!");
overlap = (overlap!=undef)? overlap : $overlap;
conn = find_connector(name, $parent_size.z, point2d($parent_size), size2=$parent_size2, shift=$parent_shift, extra_conns=$parent_conns, geometry=$parent_geom);
pos = conn[1];
vec = conn[2];
ang = conn[3];
anch = find_anchor(name, $parent_size.z, point2d($parent_size), size2=$parent_size2, shift=$parent_shift, extra_anchors=$parent_anchors, geometry=$parent_geom);
pos = anch[1];
vec = anch[2];
ang = anch[3];
$attach_to = to;
$attach_conn = conn;
$attach_anchor = anch;
if (norot || (norm(vec-UP)<1e-9 && ang==0)) {
translate(pos) translate([0,0,-overlap]) children();
} else {

View file

@ -428,7 +428,7 @@ module bezier_polygon(bezier, splinesteps=16, N=3) {
// Module: linear_extrude_bezier()
// Usage:
// linear_extrude_bezier(bezier, height, [splinesteps], [N], [center], [convexity], [twist], [slices], [scale], [orient], [align]);
// linear_extrude_bezier(bezier, height, [splinesteps], [N], [center], [convexity], [twist], [slices], [scale], [orient], [anchor]);
// Description:
// Takes a closed 2D bezier path, centered on the XY plane, and
// extrudes it linearly upwards, forming a solid.
@ -442,7 +442,7 @@ module bezier_polygon(bezier, splinesteps=16, N=3) {
// slices = Number of vertical slices to use for twisted extrusion. default=20
// center = If true, the extruded solid is centered vertically at z=0.
// orient = Orientation of the extrusion. Use the `ORIENT_` constants from `constants.scad`. Default: `ORIENT_Z`.
// align = Alignment of the extrusion. Use the constants from `constants.scad`. Default: `UP`.
// anchor = Alignment of the extrusion. Use the constants from `constants.scad`. Default: `UP`.
// Example:
// bez = [
// [-10, 0], [-15, -5],
@ -452,10 +452,10 @@ module bezier_polygon(bezier, splinesteps=16, N=3) {
// [ 25, -15], [-10, 0]
// ];
// linear_extrude_bezier(bez, height=20, splinesteps=32);
module linear_extrude_bezier(bezier, height=100, splinesteps=16, N=3, center=undef, convexity=undef, twist=undef, slices=undef, scale=undef, orient=ORIENT_Z, align=UP) {
module linear_extrude_bezier(bezier, height=100, splinesteps=16, N=3, center=undef, convexity=undef, twist=undef, slices=undef, scale=undef, orient=ORIENT_Z, anchor=UP) {
maxx = max([for (pt = bezier) abs(pt[0])]);
maxy = max([for (pt = bezier) abs(pt[1])]);
orient_and_align([maxx*2,maxy*2,height], orient, align) {
orient_and_anchor([maxx*2,maxy*2,height], orient, anchor) {
linear_extrude(height=height, center=true, convexity=convexity, twist=twist, slices=slices, scale=scale) {
bezier_polygon(bezier, splinesteps=splinesteps, N=N);
}
@ -465,7 +465,7 @@ module linear_extrude_bezier(bezier, height=100, splinesteps=16, N=3, center=und
// Module: revolve_bezier()
// Usage:
// revolve_bezier(bezier, [splinesteps], [N], [convexity], [angle], [orient], [align])
// revolve_bezier(bezier, [splinesteps], [N], [convexity], [angle], [orient], [anchor])
// Description:
// Takes a closed 2D bezier and rotates it around the X axis, forming a solid.
// Arguments:
@ -475,7 +475,7 @@ module linear_extrude_bezier(bezier, height=100, splinesteps=16, N=3, center=und
// convexity = max number of walls a line could pass through, for preview. default=10
// angle = Degrees of sweep to make. Default: 360
// orient = Orientation of the extrusion. Use the `ORIENT_` constants from `constants.scad`. Default: `ORIENT_X`.
// align = Alignment of the extrusion. Use the constants from `constants.scad`. Default: `CENTER`.
// anchor = Alignment of the extrusion. Use the constants from `constants.scad`. Default: `CENTER`.
// Example(FlatSpin):
// path = [
// [ 0, 10], [ 50, 0], [ 50, 40],
@ -485,11 +485,11 @@ module linear_extrude_bezier(bezier, height=100, splinesteps=16, N=3, center=und
// [ 0, 10]
// ];
// revolve_bezier(path, splinesteps=32, $fn=180);
module revolve_bezier(bezier, splinesteps=16, N=3, convexity=10, angle=360, orient=ORIENT_X, align=CENTER)
module revolve_bezier(bezier, splinesteps=16, N=3, convexity=10, angle=360, orient=ORIENT_X, anchor=CENTER)
{
maxx = max([for (pt = bezier) abs(pt[0])]);
maxy = max([for (pt = bezier) abs(pt[1])]);
orient_and_align([maxx*2,maxx*2,maxy*2], orient, align) {
orient_and_anchor([maxx*2,maxx*2,maxy*2], orient, anchor) {
rotate_extrude(convexity=convexity, angle=angle) {
xrot(180) zrot(-90) bezier_polygon(bezier, splinesteps, N);
}
@ -511,7 +511,7 @@ module revolve_bezier(bezier, splinesteps=16, N=3, convexity=10, angle=360, orie
// convexity = max number of walls a line could pass through, for preview. default=10
// angle = Degrees of sweep to make. Default: 360
// orient = Orientation of the extrusion. Use the `ORIENT_` constants from `constants.scad`. Default: `ORIENT_Z`.
// align = Alignment of the extrusion. Use the constants from `constants.scad`. Default: `CENTER`.
// anchor = Alignment of the extrusion. Use the constants from `constants.scad`. Default: `CENTER`.
// Example(Spin):
// path = [
// [ 0, 10], [ 50, 0], [ 50, 40],
@ -521,11 +521,11 @@ module revolve_bezier(bezier, splinesteps=16, N=3, convexity=10, angle=360, orie
// [ 0, 10]
// ];
// rotate_extrude_bezier(path, splinesteps=32, $fn=180);
module rotate_extrude_bezier(bezier, splinesteps=16, N=3, convexity=10, angle=360, orient=ORIENT_Z, align=CENTER)
module rotate_extrude_bezier(bezier, splinesteps=16, N=3, convexity=10, angle=360, orient=ORIENT_Z, anchor=CENTER)
{
maxx = max([for (pt = bezier) abs(pt[0])]);
maxy = max([for (pt = bezier) abs(pt[1])]);
orient_and_align([maxx*2,maxx*2,0], orient, align) {
orient_and_anchor([maxx*2,maxx*2,0], orient, anchor) {
rotate_extrude(convexity=convexity, angle=angle) {
bezier_polygon(bezier, splinesteps, N);
}
@ -536,7 +536,7 @@ module rotate_extrude_bezier(bezier, splinesteps=16, N=3, convexity=10, angle=36
// Module: revolve_bezier_solid_to_axis()
// Usage:
// revolve_bezier_solid_to_axis(bezier, [splinesteps], [N], [convexity], [angle], [orient], [align]);
// revolve_bezier_solid_to_axis(bezier, [splinesteps], [N], [convexity], [angle], [orient], [anchor]);
// Description:
// Takes a 2D bezier and rotates it around the X axis, forming a solid.
// Arguments:
@ -546,18 +546,18 @@ module rotate_extrude_bezier(bezier, splinesteps=16, N=3, convexity=10, angle=36
// convexity = max number of walls a line could pass through, for preview. default=10
// angle = Degrees of sweep to make. Default: 360
// orient = Orientation of the extrusion. Use the `ORIENT_` constants from `constants.scad`. Default: `ORIENT_X`.
// align = Alignment of the extrusion. Use the constants from `constants.scad`. Default: `CENTER`.
// anchor = Alignment of the extrusion. Use the constants from `constants.scad`. Default: `CENTER`.
// Example(FlatSpin):
// path = [ [0, 10], [33, 10], [66, 40], [100, 40] ];
// revolve_bezier_solid_to_axis(path, splinesteps=32, $fn=72);
module revolve_bezier_solid_to_axis(bezier, splinesteps=16, N=3, convexity=10, angle=360, orient=ORIENT_X, align=CENTER) {
revolve_bezier(bezier=bezier_close_to_axis(bezier), splinesteps=splinesteps, N=N, convexity=convexity, angle=angle, orient=orient, align=align);
module revolve_bezier_solid_to_axis(bezier, splinesteps=16, N=3, convexity=10, angle=360, orient=ORIENT_X, anchor=CENTER) {
revolve_bezier(bezier=bezier_close_to_axis(bezier), splinesteps=splinesteps, N=N, convexity=convexity, angle=angle, orient=orient, anchor=anchor);
}
// Module: revolve_bezier_offset_shell()
// Usage:
// revolve_bezier_offset_shell(bezier, offset, [splinesteps], [N], [convexity], [angle], [orient], [align]);
// revolve_bezier_offset_shell(bezier, offset, [splinesteps], [N], [convexity], [angle], [orient], [anchor]);
// Description:
// Takes a 2D bezier and rotates it around the X axis, into a hollow shell.
// Arguments:
@ -568,12 +568,12 @@ module revolve_bezier_solid_to_axis(bezier, splinesteps=16, N=3, convexity=10, a
// convexity = max number of walls a line could pass through, for preview. default=10
// angle = degrees of sweep to make. Default: 360
// orient = Orientation of the extrusion. Use the `ORIENT_` constants from `constants.scad`. Default: `ORIENT_X`.
// align = Alignment of the extrusion. Use the constants from `constants.scad`. Default: `CENTER`.
// anchor = Alignment of the extrusion. Use the constants from `constants.scad`. Default: `CENTER`.
// Example(FlatSpin):
// path = [ [0, 10], [33, 10], [66, 40], [100, 40] ];
// revolve_bezier_offset_shell(path, offset=1, splinesteps=32, $fn=72);
module revolve_bezier_offset_shell(bezier, offset=1, splinesteps=16, N=3, convexity=10, angle=360, orient=ORIENT_X, align=CENTER) {
revolve_bezier(bezier=bezier_offset(offset, bezier), splinesteps=splinesteps, N=N, orient=orient, align=align);
module revolve_bezier_offset_shell(bezier, offset=1, splinesteps=16, N=3, convexity=10, angle=360, orient=ORIENT_X, anchor=CENTER) {
revolve_bezier(bezier=bezier_offset(offset, bezier), splinesteps=splinesteps, N=N, orient=orient, anchor=anchor);
}

View file

@ -50,6 +50,14 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
function default(v,dflt=undef) = is_undef(v)? dflt : v;
// Function: is_vector()
// Usage:
// is_vector(v)
// Description:
// Returns true if the given value is a list, and at least the first item is a number.
function is_vector(v) = is_list(v) && is_num(v[0]);
// Function: get_radius()
// Description:
// Given various radii and diameters, returns the most specific radius.

View file

@ -43,65 +43,65 @@ PRINTER_SLOP = 0.20; // The printer specific amount of slop in mm to print with
// Section: Directional Vectors
// Vectors useful for `rotate()`, `mirror()`, and `align` arguments for `cuboid()`, `cyl()`, etc.
// Vectors useful for `rotate()`, `mirror()`, and `anchor` arguments for `cuboid()`, `cyl()`, etc.
// Constant: LEFT
// Description: Vector pointing left. [-1,0,0]
// Example(3D): Usage with `align`
// cuboid(20, align=LEFT);
// Example(3D): Usage with `anchor`
// cuboid(20, anchor=LEFT);
LEFT = [-1, 0, 0];
// Constant: RIGHT
// Description: Vector pointing right. [1,0,0]
// Example(3D): Usage with `align`
// cuboid(20, align=RIGHT);
// Example(3D): Usage with `anchor`
// cuboid(20, anchor=RIGHT);
RIGHT = [ 1, 0, 0];
// Constant: FWD
// Description: Vector pointing forward. [0,-1,0]
// Example(3D): Usage with `align`
// cuboid(20, align=FWD);
// Example(3D): Usage with `anchor`
// cuboid(20, anchor=FWD);
FWD = [ 0, -1, 0];
// Constant: BACK
// Description: Vector pointing back. [0,1,0]
// Example(3D): Usage with `align`
// cuboid(20, align=BACK);
// Example(3D): Usage with `anchor`
// cuboid(20, anchor=BACK);
BACK = [ 0, 1, 0];
// Constant: DOWN
// Description: Vector pointing down. [0,0,-1]
// Example(3D): Usage with `align`
// cuboid(20, align=DOWN);
// Example(3D): Usage with `anchor`
// cuboid(20, anchor=DOWN);
DOWN = [ 0, 0, -1];
// Constant: UP
// Description: Vector pointing up. [0,0,1]
// Example(3D): Usage with `align`
// cuboid(20, align=UP);
// Example(3D): Usage with `anchor`
// cuboid(20, anchor=UP);
UP = [ 0, 0, 1];
// Constant: ALLPOS
// Description: Vector pointing right, back, and up. [1,1,1]
// Example(3D): Usage with `align`
// cuboid(20, align=ALLPOS);
// Example(3D): Usage with `anchor`
// cuboid(20, anchor=ALLPOS);
ALLPOS = [ 1, 1, 1]; // Vector pointing X+,Y+,Z+.
// Constant: ALLNEG
// Description: Vector pointing left, forwards, and down. [-1,-1,-1]
// Example(3D): Usage with `align`
// cuboid(20, align=ALLNEG);
// Example(3D): Usage with `anchor`
// cuboid(20, anchor=ALLNEG);
ALLNEG = [-1, -1, -1]; // Vector pointing X-,Y-,Z-.
// Constant: CENTER
// Description: Zero vector. Centered. [0,0,0]
// Example(3D): Usage with `align`
// cuboid(20, align=CENTER);
// Example(3D): Usage with `anchor`
// cuboid(20, anchor=CENTER);
CENTER = [ 0, 0, 0]; // Centered zero vector.
// Section: Vector Aliases
// Useful aliases for use with `align`.
// Useful aliases for use with `anchor`.
ABOVE = UP; // Vector pointing up, alias to `UP`.
BELOW = DOWN; // Vector pointing down, alias to `DOWN`.
@ -307,13 +307,13 @@ function corner_edge_count(edges, v) =
$color = undef;
$overlap = 0.01;
$attach_to = undef;
$attach_conn = ["center", CENTER, UP, 0];
$attach_anchor = [CENTER, CENTER, UP, 0];
$parent_size = undef;
$parent_size2 = undef;
$parent_shift = [0,0];
$parent_orient = ORIENT_Z;
$parent_align = "center";
$parent_conns = [];
$parent_anchor = CENTER;
$parent_anchors = [];
$tags_shown = [];
$tags_hidden = [];
$tags = "";

View file

@ -171,10 +171,10 @@ module debug_polyhedron(points, faces, convexity=10, txtsize=1, disabled=false)
// Function: all_connectors()
// Function: standard_anchors()
// Description:
// Return the vectors for all standard connectors.
function all_connectors() = [
// Return the vectors for all standard anchors.
function standard_anchors() = [
for (
zv = [TOP, CENTER, BOTTOM],
yv = [FRONT, CENTER, BACK],
@ -184,22 +184,22 @@ function all_connectors() = [
// Module: connector_arrow()
// Module: anchor_arrow()
// Usage:
// connector_arrow([s], [color], [flag]);
// anchor_arrow([s], [color], [flag]);
// Description:
// Show a connector orientation arrow.
// Show an anchor orientation arrow.
// Arguments:
// s = Length of the arrows.
// color = Color of the arrow.
// flag = If true, draw the orientation flag on the arrowhead.
module connector_arrow(s=10, color=[0.333,0.333,1], flag=true) {
module anchor_arrow(s=10, color=[0.333,0.333,1], flag=true, $tags="anchor-arrow") {
$fn=12;
recolor("gray") spheroid(d=s/6)
recolor(color) cyl(h=s, d=s/15, align=DOWN)
attach(TOP) cyl(h=s/3, d1=s/5, d2=0, align=DOWN) {
recolor(color) cyl(h=s*2/3, d=s/15, anchor=DOWN)
attach(TOP) cyl(h=s/3, d1=s/5, d2=0, anchor=DOWN) {
if(flag) {
attach(BOTTOM) recolor([1,0.5,0.5]) cuboid([s/50, s/6, s/4], align=FRONT+TOP);
attach(BOTTOM) recolor([1,0.5,0.5]) cuboid([s/50, s/6, s/4], anchor=FRONT+TOP);
}
children();
}
@ -207,12 +207,45 @@ module connector_arrow(s=10, color=[0.333,0.333,1], flag=true) {
// Module: show_connectors()
// Module: transparent()
// Usage:
// transparent() ...
// Description:
// Show all standard connectors for the parent object.
module show_connectors() {
for (conn=all_connectors()) {
attach(conn) connector_arrow();
// Makes the children transparent gray, while showing any
// anchor arrows that may exist.
// Example:
// transparent() cube(50, center=true) show_anchors();
module transparent(opacity=0.2) {
show("anchor-arrow") children() show_anchors();
hide("anchor-arrow") recolor([0,0,0,opacity]) children();
}
// Module: show_anchors()
// Description:
// Show all standard anchors for the parent object.
module show_anchors(s=10, std=true, custom=true) {
if (std) {
for (anchor=standard_anchors()) {
attach(anchor) anchor_arrow(s);
}
}
if (custom) {
for (anchor=$parent_anchors) {
attach(anchor[0]) {
anchor_arrow(s, color="cyan");
recolor("black")
noop($tags="anchor-arrow") {
xrot(90) {
up(s/10) {
linear_extrude(height=0.01, convexity=12, center=true) {
text(text=anchor[0], size=s/4, halign="center", valign="center");
}
}
}
}
}
}
}
children();
}
@ -226,9 +259,9 @@ module show_connectors() {
// s = Length of the arrows.
module frame_ref(s=15) {
noop() {
attach(RIGHT) connector_arrow(s=s, color="red", flag=false);
attach(BACK) connector_arrow(s=s, color="green", flag=false);
attach(TOP) connector_arrow(s=s, color="blue", flag=false);
attach(RIGHT) anchor_arrow(s=s, color="red", flag=false);
attach(BACK) anchor_arrow(s=s, color="green", flag=false);
attach(TOP) anchor_arrow(s=s, color="blue", flag=false);
children();
}
}

View file

@ -1,6 +1,8 @@
include <BOSL2/std.scad>
cuboid([60,40,40], fillet=5, edges=EDGES_Z_ALL, align=BOTTOM) {
$fn=32;
cuboid([60,40,40], fillet=5, edges=EDGES_Z_ALL, anchor=BOTTOM) {
attach(TOP, BOTTOM) rounded_prismoid([60,40],[20,20], h=50, r1=5, r2=10) {
attach(TOP) cylinder(d=20, h=30) {
attach(TOP) cylinder(d1=50, d2=30, h=12);

View file

@ -2,7 +2,7 @@ include <BOSL2/std.scad>
include <BOSL2/debug.scad>
prismoid([60,40], [30,20], h=40) show_connectors();
transparent() cylinder(h=30, d1=50, d2=30) show_anchors();
// vim: noexpandtab tabstop=4 shiftwidth=4 softtabstop=4 nowrap

View file

@ -2,7 +2,7 @@ include <BOSL2/std.scad>
include <BOSL2/debug.scad>
cylinder(h=30, d=30) show_connectors();
transparent() cube(40, center=true) show_anchors();
// vim: noexpandtab tabstop=4 shiftwidth=4 softtabstop=4 nowrap

View file

@ -2,7 +2,7 @@ include <BOSL2/std.scad>
include <BOSL2/debug.scad>
cylinder(h=30, d1=50, d2=30) show_connectors();
transparent() cylinder(h=30, d=30) show_anchors();
// vim: noexpandtab tabstop=4 shiftwidth=4 softtabstop=4 nowrap

View file

@ -0,0 +1,8 @@
include <BOSL2/std.scad>
include <BOSL2/debug.scad>
transparent() prismoid([60,40], [30,20], h=40) show_anchors();
// vim: noexpandtab tabstop=4 shiftwidth=4 softtabstop=4 nowrap

View file

@ -0,0 +1,14 @@
include <BOSL2/std.scad>
include <BOSL2/threading.scad>
include <BOSL2/phillips_drive.scad>
include <BOSL2/torx_drive.scad>
include <BOSL2/metric_screws.scad>
include <BOSL2/debug.scad>
transparent()
metric_bolt(headtype="oval", size=10, l=15, shank=5, details=true, phillips="#2")
show_anchors(5, std=false);
// vim: noexpandtab tabstop=4 shiftwidth=4 softtabstop=4 nowrap

View file

@ -2,7 +2,7 @@ include <BOSL2/std.scad>
include <BOSL2/debug.scad>
cube(40, center=true) show_connectors();
transparent() sphere(d=30) show_anchors();
// vim: noexpandtab tabstop=4 shiftwidth=4 softtabstop=4 nowrap

View file

@ -1,8 +0,0 @@
include <BOSL2/std.scad>
include <BOSL2/debug.scad>
sphere(d=30) show_connectors();
// vim: noexpandtab tabstop=4 shiftwidth=4 softtabstop=4 nowrap

View file

@ -286,7 +286,7 @@ module gear2d(
// scale = Scale of top of gear compared to bottom. Useful for making crown gears.
// interior = If true, create a mask for difference()ing from something else.
// orient = Orientation of the gear. Use the `ORIENT_` constants from `constants.scad`. Default: `ORIENT_Z`.
// align = Alignment of the gear. Use the constants from `constants.scad`. Default: `CENTER`.
// anchor = Alignment of the gear. Use the constants from `constants.scad`. Default: `CENTER`.
// Example: Spur Gear
// gear(mm_per_tooth=5, number_of_teeth=20, thickness=8, hole_diameter=5);
// Example: Beveled Gear
@ -305,13 +305,13 @@ module gear(
slices = undef, //Number of slices to divide gear into. Useful for refining gears with `twist`.
interior = false,
orient = ORIENT_Z,
align = CENTER
anchor = CENTER
) {
p = pitch_radius(mm_per_tooth, number_of_teeth);
c = outer_radius(mm_per_tooth, number_of_teeth, clearance, interior);
r = root_radius(mm_per_tooth, number_of_teeth, clearance, interior);
p2 = p - (thickness*tan(bevelang));
orient_and_align([p, p, thickness], orient, align, chain=true) {
orient_and_anchor([p, p, thickness], orient, anchor, chain=true) {
difference() {
linear_extrude(height=thickness, center=true, convexity=10, twist=twist, scale=p2/p, slices=slices) {
gear2d(
@ -356,7 +356,7 @@ module gear(
// pressure_angle = Controls how straight or bulged the tooth sides are. In degrees.
// backlash = Gap between two meshing teeth, in the direction along the circumference of the pitch circle
// orient = Orientation of the rack. Use the `ORIENT_` constants from `constants.scad`. Default: `ORIENT_X`.
// align = Alignment of the rack. Use the constants from `constants.scad`. Default: `RIGHT`.
// anchor = Alignment of the rack. Use the constants from `constants.scad`. Default: `RIGHT`.
// Example:
// rack(mm_per_tooth=5, number_of_teeth=10, thickness=5, height=5, pressure_angle=20);
module rack(
@ -368,13 +368,13 @@ module rack(
backlash = 0.0, //gap between two meshing teeth, in the direction along the circumference of the pitch circle
clearance = undef,
orient = ORIENT_X,
align = RIGHT
anchor = RIGHT
) {
a = adendum(mm_per_tooth);
d = dedendum(mm_per_tooth, clearance);
xa = a * sin(pressure_angle);
xd = d * sin(pressure_angle);
orient_and_align([(number_of_teeth-1)*mm_per_tooth, height, thickness], orient, align, orig_orient=ORIENT_X, chain=true) {
orient_and_anchor([(number_of_teeth-1)*mm_per_tooth, height, thickness], orient, anchor, orig_orient=ORIENT_X, chain=true) {
left((number_of_teeth-1)*mm_per_tooth/2) {
linear_extrude(height = thickness, center = true, convexity = 10) {
for (i = [0:number_of_teeth-1] ) {

View file

@ -45,7 +45,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Description:
// Creates a mask to clear an area so that a half_joiner can be placed there.
// Usage:
// half_joiner_clear(h, w, [a], [clearance], [overlap], [orient], [align])
// half_joiner_clear(h, w, [a], [clearance], [overlap], [orient], [anchor])
// Arguments:
// h = Height of the joiner to clear space for.
// w = Width of the joiner to clear space for.
@ -53,17 +53,17 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// clearance = Extra width to clear.
// overlap = Extra depth to clear.
// orient = Orientation of the shape. Use the `ORIENT_` constants from `constants.scad`. Default: `ORIENT_Y`.
// align = Alignment of the shape by the axis-negative (size1) end. Use the constants from `constants.scad`. Default: `CENTER`.
// anchor = Alignment of the shape by the axis-negative (size1) end. Use the constants from `constants.scad`. Default: `CENTER`.
// Example:
// half_joiner_clear(orient=ORIENT_X);
module half_joiner_clear(h=20, w=10, a=30, clearance=0, overlap=0.01, orient=ORIENT_Y, align=CENTER)
module half_joiner_clear(h=20, w=10, a=30, clearance=0, overlap=0.01, orient=ORIENT_Y, anchor=CENTER)
{
dmnd_height = h*1.0;
dmnd_width = dmnd_height*tan(a);
guide_size = w/3;
guide_width = 2*(dmnd_height/2-guide_size)*tan(a);
orient_and_align([w, guide_width, h], orient, align, orig_orient=ORIENT_Y, chain=true) {
orient_and_anchor([w, guide_width, h], orient, anchor, orig_orient=ORIENT_Y, chain=true) {
union() {
yspread(overlap, n=overlap>0? 2 : 1) {
difference() {
@ -87,7 +87,7 @@ module half_joiner_clear(h=20, w=10, a=30, clearance=0, overlap=0.01, orient=ORI
// Module: half_joiner()
// Usage:
// half_joiner(h, w, l, [a], [screwsize], [guides], [slop], [orient], [align])
// half_joiner(h, w, l, [a], [screwsize], [guides], [slop], [orient], [anchor])
// Description:
// Creates a half_joiner object that can be attached to half_joiner2 object.
// Arguments:
@ -99,10 +99,10 @@ module half_joiner_clear(h=20, w=10, a=30, clearance=0, overlap=0.01, orient=ORI
// guides = If true, create sliding alignment guides.
// slop = Printer specific slop value to make parts fit more closely.
// orient = Orientation of the shape. Use the `ORIENT_` constants from `constants.scad`. Default: `ORIENT_Y`.
// align = Alignment of the shape by the axis-negative (size1) end. Use the constants from `constants.scad`. Default: `CENTER`.
// anchor = Alignment of the shape by the axis-negative (size1) end. Use the constants from `constants.scad`. Default: `CENTER`.
// Example:
// half_joiner(screwsize=3, orient=ORIENT_X);
module half_joiner(h=20, w=10, l=10, a=30, screwsize=undef, guides=true, slop=PRINTER_SLOP, orient=ORIENT_Y, align=CENTER)
module half_joiner(h=20, w=10, l=10, a=30, screwsize=undef, guides=true, slop=PRINTER_SLOP, orient=ORIENT_Y, anchor=CENTER)
{
dmnd_height = h*1.0;
dmnd_width = dmnd_height*tan(a);
@ -112,11 +112,11 @@ module half_joiner(h=20, w=10, l=10, a=30, screwsize=undef, guides=true, slop=PR
if ($children > 0) {
difference() {
children();
half_joiner_clear(h=h, w=w, a=a, clearance=0.1, overlap=0.01, orient=orient, align=align);
half_joiner_clear(h=h, w=w, a=a, clearance=0.1, overlap=0.01, orient=orient, anchor=anchor);
}
}
render(convexity=12)
orient_and_align([w, 2*l, h], orient, align, orig_orient=ORIENT_Y, chain=true) {
orient_and_anchor([w, 2*l, h], orient, anchor, orig_orient=ORIENT_Y, chain=true) {
difference() {
union() {
// Make base.
@ -165,13 +165,13 @@ module half_joiner(h=20, w=10, l=10, a=30, screwsize=undef, guides=true, slop=PR
children();
}
}
//half_joiner(screwsize=3, orient=ORIENT_Z, align=UP);
//half_joiner(screwsize=3, orient=ORIENT_Z, anchor=UP);
// Module: half_joiner2()
// Usage:
// half_joiner2(h, w, l, [a], [screwsize], [guides], [orient], [align])
// half_joiner2(h, w, l, [a], [screwsize], [guides], [orient], [anchor])
// Description:
// Creates a half_joiner2 object that can be attached to half_joiner object.
// Arguments:
@ -182,10 +182,10 @@ module half_joiner(h=20, w=10, l=10, a=30, screwsize=undef, guides=true, slop=PR
// screwsize = Diameter of screwhole.
// guides = If true, create sliding alignment guides.
// orient = Orientation of the shape. Use the `ORIENT_` constants from `constants.scad`. Default: `ORIENT_Y`.
// align = Alignment of the shape by the axis-negative (size1) end. Use the constants from `constants.scad`. Default: `CENTER`.
// anchor = Alignment of the shape by the axis-negative (size1) end. Use the constants from `constants.scad`. Default: `CENTER`.
// Example:
// half_joiner2(screwsize=3, orient=ORIENT_X);
module half_joiner2(h=20, w=10, l=10, a=30, screwsize=undef, guides=true, orient=ORIENT_Y, align=CENTER)
module half_joiner2(h=20, w=10, l=10, a=30, screwsize=undef, guides=true, orient=ORIENT_Y, anchor=CENTER)
{
dmnd_height = h*1.0;
dmnd_width = dmnd_height*tan(a);
@ -195,12 +195,12 @@ module half_joiner2(h=20, w=10, l=10, a=30, screwsize=undef, guides=true, orient
if ($children > 0) {
difference() {
children();
half_joiner_clear(h=h, w=w, a=a, clearance=0.1, overlap=0.01, orient=orient, align=align);
half_joiner_clear(h=h, w=w, a=a, clearance=0.1, overlap=0.01, orient=orient, anchor=anchor);
}
}
render(convexity=12)
orient_and_align([w, 2*l, h], orient, align, orig_orient=ORIENT_Y, chain=true) {
orient_and_anchor([w, 2*l, h], orient, anchor, orig_orient=ORIENT_Y, chain=true) {
difference() {
union () {
fwd(l/2) cube(size=[w, l, h], center=true);
@ -228,7 +228,7 @@ module half_joiner2(h=20, w=10, l=10, a=30, screwsize=undef, guides=true, orient
// Description:
// Creates a mask to clear an area so that a joiner can be placed there.
// Usage:
// joiner_clear(h, w, [a], [clearance], [overlap], [orient], [align])
// joiner_clear(h, w, [a], [clearance], [overlap], [orient], [anchor])
// Arguments:
// h = Height of the joiner to clear space for.
// w = Width of the joiner to clear space for.
@ -236,17 +236,17 @@ module half_joiner2(h=20, w=10, l=10, a=30, screwsize=undef, guides=true, orient
// clearance = Extra width to clear.
// overlap = Extra depth to clear.
// orient = Orientation of the shape. Use the `ORIENT_` constants from `constants.scad`. Default: `ORIENT_Y`.
// align = Alignment of the shape by the axis-negative (size1) end. Use the constants from `constants.scad`. Default: `CENTER`.
// anchor = Alignment of the shape by the axis-negative (size1) end. Use the constants from `constants.scad`. Default: `CENTER`.
// Example:
// joiner_clear(orient=ORIENT_X);
module joiner_clear(h=40, w=10, a=30, clearance=0, overlap=0.01, orient=ORIENT_Y, align=CENTER)
module joiner_clear(h=40, w=10, a=30, clearance=0, overlap=0.01, orient=ORIENT_Y, anchor=CENTER)
{
dmnd_height = h*0.5;
dmnd_width = dmnd_height*tan(a);
guide_size = w/3;
guide_width = 2*(dmnd_height/2-guide_size)*tan(a);
orient_and_align([w, guide_width, h], orient, align, orig_orient=ORIENT_Y, chain=true) {
orient_and_anchor([w, guide_width, h], orient, anchor, orig_orient=ORIENT_Y, chain=true) {
union() {
up(h/4) half_joiner_clear(h=h/2.0-0.01, w=w, a=a, overlap=overlap, clearance=clearance);
down(h/4) half_joiner_clear(h=h/2.0-0.01, w=w, a=a, overlap=overlap, clearance=-0.01);
@ -259,7 +259,7 @@ module joiner_clear(h=40, w=10, a=30, clearance=0, overlap=0.01, orient=ORIENT_Y
// Module: joiner()
// Usage:
// joiner(h, w, l, [a], [screwsize], [guides], [slop], [orient], [align])
// joiner(h, w, l, [a], [screwsize], [guides], [slop], [orient], [anchor])
// Description:
// Creates a joiner object that can be attached to another joiner object.
// Arguments:
@ -271,19 +271,19 @@ module joiner_clear(h=40, w=10, a=30, clearance=0, overlap=0.01, orient=ORIENT_Y
// guides = If true, create sliding alignment guides.
// slop = Printer specific slop value to make parts fit more closely.
// orient = Orientation of the shape. Use the `ORIENT_` constants from `constants.scad`. Default: `ORIENT_Y`.
// align = Alignment of the shape by the axis-negative (size1) end. Use the constants from `constants.scad`. Default: `CENTER`.
// anchor = Alignment of the shape by the axis-negative (size1) end. Use the constants from `constants.scad`. Default: `CENTER`.
// Examples:
// joiner(screwsize=3, orient=ORIENT_X);
// joiner(w=10, l=10, h=40, orient=ORIENT_X) cuboid([10, 10*2, 40], align=LEFT);
module joiner(h=40, w=10, l=10, a=30, screwsize=undef, guides=true, slop=PRINTER_SLOP, orient=ORIENT_Y, align=CENTER)
// joiner(w=10, l=10, h=40, orient=ORIENT_X) cuboid([10, 10*2, 40], anchor=LEFT);
module joiner(h=40, w=10, l=10, a=30, screwsize=undef, guides=true, slop=PRINTER_SLOP, orient=ORIENT_Y, anchor=CENTER)
{
if ($children > 0) {
difference() {
children();
joiner_clear(h=h, w=w, a=a, clearance=0.1, orient=orient, align=align);
joiner_clear(h=h, w=w, a=a, clearance=0.1, orient=orient, anchor=anchor);
}
}
orient_and_align([w, 2*l, h], orient, align, orig_orient=ORIENT_Y, chain=true) {
orient_and_anchor([w, 2*l, h], orient, anchor, orig_orient=ORIENT_Y, chain=true) {
union() {
up(h/4) half_joiner(h=h/2, w=w, l=l, a=a, screwsize=screwsize, guides=guides, slop=slop);
down(h/4) half_joiner2(h=h/2, w=w, l=l, a=a, screwsize=screwsize, guides=guides);
@ -301,7 +301,7 @@ module joiner(h=40, w=10, l=10, a=30, screwsize=undef, guides=true, slop=PRINTER
// Description:
// Creates a mask to clear an area so that a pair of joiners can be placed there.
// Usage:
// joiner_pair_clear(spacing, [n], [h], [w], [a], [clearance], [overlap], [orient], [align])
// joiner_pair_clear(spacing, [n], [h], [w], [a], [clearance], [overlap], [orient], [anchor])
// Arguments:
// spacing = Spacing between joiner centers.
// h = Height of the joiner to clear space for.
@ -311,18 +311,18 @@ module joiner(h=40, w=10, l=10, a=30, screwsize=undef, guides=true, slop=PRINTER
// clearance = Extra width to clear.
// overlap = Extra depth to clear.
// orient = Orientation of the shape. Use the `ORIENT_` constants from `constants.scad`. Default: `ORIENT_Y`.
// align = Alignment of the shape by the axis-negative (size1) end. Use the constants from `constants.scad`. Default: `CENTER`.
// anchor = Alignment of the shape by the axis-negative (size1) end. Use the constants from `constants.scad`. Default: `CENTER`.
// Examples:
// joiner_pair_clear(spacing=50, n=2);
// joiner_pair_clear(spacing=50, n=3);
module joiner_pair_clear(spacing=100, h=40, w=10, a=30, n=2, clearance=0, overlap=0.01, orient=ORIENT_Y, align=CENTER)
module joiner_pair_clear(spacing=100, h=40, w=10, a=30, n=2, clearance=0, overlap=0.01, orient=ORIENT_Y, anchor=CENTER)
{
dmnd_height = h*0.5;
dmnd_width = dmnd_height*tan(a);
guide_size = w/3;
guide_width = 2*(dmnd_height/2-guide_size)*tan(a);
orient_and_align([spacing+w, guide_width, h], orient, align, orig_orient=ORIENT_Y, chain=true) {
orient_and_anchor([spacing+w, guide_width, h], orient, anchor, orig_orient=ORIENT_Y, chain=true) {
xspread(spacing, n=n) {
joiner_clear(h=h, w=w, a=a, clearance=clearance, overlap=overlap);
}
@ -334,7 +334,7 @@ module joiner_pair_clear(spacing=100, h=40, w=10, a=30, n=2, clearance=0, overla
// Module: joiner_pair()
// Usage:
// joiner_pair(h, w, l, [a], [screwsize], [guides], [slop], [orient], [align])
// joiner_pair(h, w, l, [a], [screwsize], [guides], [slop], [orient], [anchor])
// Description:
// Creates a joiner_pair object that can be attached to other joiner_pairs .
// Arguments:
@ -349,22 +349,22 @@ module joiner_pair_clear(spacing=100, h=40, w=10, a=30, n=2, clearance=0, overla
// guides = If true, create sliding alignment guides.
// slop = Printer specific slop value to make parts fit more closely.
// orient = Orientation of the shape. Use the `ORIENT_` constants from `constants.scad`. Default: `ORIENT_Y`.
// align = Alignment of the shape by the axis-negative (size1) end. Use the constants from `constants.scad`. Default: `CENTER`.
// anchor = Alignment of the shape by the axis-negative (size1) end. Use the constants from `constants.scad`. Default: `CENTER`.
// Examples:
// joiner_pair(spacing=50, l=10, orient=ORIENT_X) cuboid([10, 50+10-0.1, 40], align=LEFT);
// joiner_pair(spacing=50, l=10, orient=ORIENT_X) cuboid([10, 50+10-0.1, 40], anchor=LEFT);
// joiner_pair(spacing=50, l=10, n=2, orient=ORIENT_X);
// joiner_pair(spacing=50, l=10, n=3, alternate=false, orient=ORIENT_X);
// joiner_pair(spacing=50, l=10, n=3, alternate=true, orient=ORIENT_X);
// joiner_pair(spacing=50, l=10, n=3, alternate="alt", orient=ORIENT_X);
module joiner_pair(spacing=100, h=40, w=10, l=10, a=30, n=2, alternate=true, screwsize=undef, guides=true, slop=PRINTER_SLOP, orient=ORIENT_Y, align=CENTER)
module joiner_pair(spacing=100, h=40, w=10, l=10, a=30, n=2, alternate=true, screwsize=undef, guides=true, slop=PRINTER_SLOP, orient=ORIENT_Y, anchor=CENTER)
{
if ($children > 0) {
difference() {
children();
joiner_pair_clear(spacing=spacing, h=h, w=w, a=a, clearance=0.1, orient=orient, align=align);
joiner_pair_clear(spacing=spacing, h=h, w=w, a=a, clearance=0.1, orient=orient, anchor=anchor);
}
}
orient_and_align([spacing+w, 2*l, h], orient, align, orig_orient=ORIENT_Y, chain=true) {
orient_and_anchor([spacing+w, 2*l, h], orient, anchor, orig_orient=ORIENT_Y, chain=true) {
left((n-1)*spacing/2) {
for (i=[0:n-1]) {
right(i*spacing) {
@ -387,7 +387,7 @@ module joiner_pair(spacing=100, h=40, w=10, l=10, a=30, n=2, alternate=true, scr
// Description:
// Creates a mask to clear an area so that a pair of joiners can be placed there.
// Usage:
// joiner_quad_clear(spacing, [n], [h], [w], [a], [clearance], [overlap], [orient], [align])
// joiner_quad_clear(spacing, [n], [h], [w], [a], [clearance], [overlap], [orient], [anchor])
// Arguments:
// spacing1 = Spacing between joiner centers.
// spacing2 = Spacing between back-to-back pairs/sets of joiners.
@ -398,15 +398,15 @@ module joiner_pair(spacing=100, h=40, w=10, l=10, a=30, n=2, alternate=true, scr
// clearance = Extra width to clear.
// overlap = Extra depth to clear.
// orient = Orientation of the shape. Use the `ORIENT_` constants from `constants.scad`. Default: `ORIENT_Y`.
// align = Alignment of the shape by the axis-negative (size1) end. Use the constants from `constants.scad`. Default: `CENTER`.
// anchor = Alignment of the shape by the axis-negative (size1) end. Use the constants from `constants.scad`. Default: `CENTER`.
// Examples:
// joiner_quad_clear(spacing1=50, spacing2=50, n=2);
// joiner_quad_clear(spacing1=50, spacing2=50, n=3);
module joiner_quad_clear(xspacing=undef, yspacing=undef, spacing1=undef, spacing2=undef, n=2, h=40, w=10, a=30, clearance=0, overlap=0.01, orient=ORIENT_Y, align=CENTER)
module joiner_quad_clear(xspacing=undef, yspacing=undef, spacing1=undef, spacing2=undef, n=2, h=40, w=10, a=30, clearance=0, overlap=0.01, orient=ORIENT_Y, anchor=CENTER)
{
spacing1 = first_defined([spacing1, xspacing, 100]);
spacing2 = first_defined([spacing2, yspacing, 50]);
orient_and_align([w+spacing1, spacing2, h], orient, align, orig_orient=ORIENT_Y, chain=true) {
orient_and_anchor([w+spacing1, spacing2, h], orient, anchor, orig_orient=ORIENT_Y, chain=true) {
zrot_copies(n=2) {
back(spacing2/2) {
joiner_pair_clear(spacing=spacing1, n=n, h=h, w=w, a=a, clearance=clearance, overlap=overlap);
@ -420,7 +420,7 @@ module joiner_quad_clear(xspacing=undef, yspacing=undef, spacing1=undef, spacing
// Module: joiner_quad()
// Usage:
// joiner_quad(h, w, l, [a], [screwsize], [guides], [slop], [orient], [align])
// joiner_quad(h, w, l, [a], [screwsize], [guides], [slop], [orient], [anchor])
// Description:
// Creates a joiner_quad object that can be attached to other joiner_pairs .
// Arguments:
@ -435,24 +435,24 @@ module joiner_quad_clear(xspacing=undef, yspacing=undef, spacing1=undef, spacing
// guides = If true, create sliding alignment guides.
// slop = Printer specific slop value to make parts fit more closely.
// orient = Orientation of the shape. Use the `ORIENT_` constants from `constants.scad`. Default: `ORIENT_Y`.
// align = Alignment of the shape by the axis-negative (size1) end. Use the constants from `constants.scad`. Default: `CENTER`.
// anchor = Alignment of the shape by the axis-negative (size1) end. Use the constants from `constants.scad`. Default: `CENTER`.
// Examples:
// joiner_quad(spacing1=50, spacing2=50, l=10, orient=ORIENT_X) cuboid([50, 50+10-0.1, 40]);
// joiner_quad(spacing1=50, spacing2=50, l=10, n=2, orient=ORIENT_X);
// joiner_quad(spacing1=50, spacing2=50, l=10, n=3, alternate=false, orient=ORIENT_X);
// joiner_quad(spacing1=50, spacing2=50, l=10, n=3, alternate=true, orient=ORIENT_X);
// joiner_quad(spacing1=50, spacing2=50, l=10, n=3, alternate="alt", orient=ORIENT_X);
module joiner_quad(spacing1=undef, spacing2=undef, xspacing=undef, yspacing=undef, h=40, w=10, l=10, a=30, n=2, alternate=true, screwsize=undef, guides=true, slop=PRINTER_SLOP, orient=ORIENT_Y, align=CENTER)
module joiner_quad(spacing1=undef, spacing2=undef, xspacing=undef, yspacing=undef, h=40, w=10, l=10, a=30, n=2, alternate=true, screwsize=undef, guides=true, slop=PRINTER_SLOP, orient=ORIENT_Y, anchor=CENTER)
{
spacing1 = first_defined([spacing1, xspacing, 100]);
spacing2 = first_defined([spacing2, yspacing, 50]);
if ($children > 0) {
difference() {
children();
joiner_quad_clear(spacing1=spacing1, spacing2=spacing2, h=h, w=w, a=a, clearance=0.1, orient=orient, align=align);
joiner_quad_clear(spacing1=spacing1, spacing2=spacing2, h=h, w=w, a=a, clearance=0.1, orient=orient, anchor=anchor);
}
}
orient_and_align([w+spacing1, spacing2, h], orient, align, orig_orient=ORIENT_Y, chain=true) {
orient_and_anchor([w+spacing1, spacing2, h], orient, anchor, orig_orient=ORIENT_Y, chain=true) {
zrot_copies(n=2) {
back(spacing2/2) {
joiner_pair(spacing=spacing1, n=n, h=h, w=w, l=l, a=a, screwsize=screwsize, guides=guides, slop=slop);

View file

@ -103,15 +103,15 @@ function get_lmXuu_bearing_length(size) = lookup(size, [
// gap = Gap in clamp. (Default: 5)
// screwsize = Size of screw to use to tighten clamp. (Default: 3)
// orient = Orientation of the housing. Use the `ORIENT_` constants from `constants.scad`. Default: `ORIENT_X`.
// align = Alignment of the housing by the axis-negative (size1) end. Use the constants from `constants.scad`. Default: `UP`
// anchor = Alignment of the housing by the axis-negative (size1) end. Use the constants from `constants.scad`. Default: `UP`
// Example:
// linear_bearing_housing(d=19, l=29, wall=2, tab=6, screwsize=2.5);
module linear_bearing_housing(d=15, l=24, tab=7, gap=5, wall=3, tabwall=5, screwsize=3, orient=ORIENT_X, align=UP)
module linear_bearing_housing(d=15, l=24, tab=7, gap=5, wall=3, tabwall=5, screwsize=3, orient=ORIENT_X, anchor=UP)
{
od = d+2*wall;
ogap = gap+2*tabwall;
tabh = tab/2+od/2*sqrt(2)-ogap/2;
orient_and_align([l, od, od], orient, align, orig_orient=ORIENT_X, chain=true) {
orient_and_anchor([l, od, od], orient, anchor, orig_orient=ORIENT_X, chain=true) {
difference() {
union() {
zrot(90) teardrop(r=od/2,h=l);
@ -144,14 +144,14 @@ module linear_bearing_housing(d=15, l=24, tab=7, gap=5, wall=3, tabwall=5, screw
// gap = Gap in clamp. Default: 5
// screwsize = Size of screw to use to tighten clamp. Default: 3
// orient = Orientation of the housing. Use the `ORIENT_` constants from `constants.scad`. Default: `ORIENT_X`.
// align = Alignment of the housing by the axis-negative (size1) end. Use the constants from `constants.scad`. Default: `UP`
// anchor = Alignment of the housing by the axis-negative (size1) end. Use the constants from `constants.scad`. Default: `UP`
// Example:
// lmXuu_housing(size=10, wall=2, tab=6, screwsize=2.5);
module lmXuu_housing(size=8, tab=7, gap=5, wall=3, tabwall=5, screwsize=3, orient=ORIENT_X, align=UP)
module lmXuu_housing(size=8, tab=7, gap=5, wall=3, tabwall=5, screwsize=3, orient=ORIENT_X, anchor=UP)
{
d = get_lmXuu_bearing_diam(size);
l = get_lmXuu_bearing_length(size);
linear_bearing_housing(d=d,l=l,tab=tab,gap=gap,wall=wall,tabwall=tabwall,screwsize=screwsize, orient=orient, align=align) children();
linear_bearing_housing(d=d,l=l,tab=tab,gap=gap,wall=wall,tabwall=tabwall,screwsize=screwsize, orient=orient, anchor=anchor) children();
}

View file

@ -41,8 +41,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Module: angle_pie_mask()
// Usage:
// angle_pie_mask(r|d, l, ang, [orient], [align]);
// angle_pie_mask(r1|d1, r2|d2, l, ang, [orient], [align]);
// angle_pie_mask(r|d, l, ang, [orient], [anchor]);
// angle_pie_mask(r1|d1, r2|d2, l, ang, [orient], [anchor]);
// Description:
// Creates a pie wedge shape that can be used to mask other shapes.
// Arguments:
@ -55,21 +55,21 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// d1 = Bottom diameter of cone that wedge is created from. (optional)
// d2 = Upper diameter of cone that wedge is created from. (optional)
// orient = Orientation of the pie slice. Use the ORIENT_ constants from constants.h. Default: ORIENT_Z.
// align = Alignment of the pie slice. Use the constants from constants.h. Default: CENTER.
// anchor = Alignment of the pie slice. Use the constants from constants.h. Default: CENTER.
// Example(FR):
// angle_pie_mask(ang=30, d=100, l=20);
module angle_pie_mask(
ang=45, l=undef,
r=undef, r1=undef, r2=undef,
d=undef, d1=undef, d2=undef,
orient=ORIENT_Z, align=CENTER,
orient=ORIENT_Z, anchor=CENTER,
h=undef
) {
l = first_defined([l, h, 1]);
r1 = get_radius(r1, r, d1, d, 10);
r2 = get_radius(r2, r, d2, d, 10);
orient_and_align([2*r1, 2*r1, l], orient, align, chain=true) {
pie_slice(ang=ang, l=l+0.1, r1=r1, r2=r2, align=CENTER);
orient_and_anchor([2*r1, 2*r1, l], orient, anchor, chain=true) {
pie_slice(ang=ang, l=l+0.1, r1=r1, r2=r2, anchor=CENTER);
children();
}
}
@ -77,19 +77,19 @@ module angle_pie_mask(
// Module: cylinder_mask()
// Usage: Mask objects
// cylinder_mask(l, r|d, chamfer, [chamfang], [from_end], [circum], [overage], [ends_only], [orient], [align]);
// cylinder_mask(l, r|d, fillet, [circum], [overage], [ends_only], [orient], [align]);
// cylinder_mask(l, r|d, [chamfer1|fillet1], [chamfer2|fillet2], [chamfang1], [chamfang2], [from_end], [circum], [overage], [ends_only], [orient], [align]);
// cylinder_mask(l, r|d, chamfer, [chamfang], [from_end], [circum], [overage], [ends_only], [orient], [anchor]);
// cylinder_mask(l, r|d, fillet, [circum], [overage], [ends_only], [orient], [anchor]);
// cylinder_mask(l, r|d, [chamfer1|fillet1], [chamfer2|fillet2], [chamfang1], [chamfang2], [from_end], [circum], [overage], [ends_only], [orient], [anchor]);
// Usage: Masking operators
// cylinder_mask(l, r|d, chamfer, [chamfang], [from_end], [circum], [overage], [ends_only], [orient], [align]) ...
// cylinder_mask(l, r|d, fillet, [circum], [overage], [ends_only], [orient], [align]) ...
// cylinder_mask(l, r|d, [chamfer1|fillet1], [chamfer2|fillet2], [chamfang1], [chamfang2], [from_end], [circum], [overage], [ends_only], [orient], [align]) ...
// cylinder_mask(l, r|d, chamfer, [chamfang], [from_end], [circum], [overage], [ends_only], [orient], [anchor]) ...
// cylinder_mask(l, r|d, fillet, [circum], [overage], [ends_only], [orient], [anchor]) ...
// cylinder_mask(l, r|d, [chamfer1|fillet1], [chamfer2|fillet2], [chamfang1], [chamfang2], [from_end], [circum], [overage], [ends_only], [orient], [anchor]) ...
// Description:
// If passed children, bevels/chamfers and/or rounds/fillets one or
// both ends of the origin-centered cylindrical region specified. If
// passed no children, creates a mask to bevel/chamfer and/or round/fillet
// one or both ends of the cylindrical region. Difference the mask
// from the region, making sure the center of the mask object is align
// from the region, making sure the center of the mask object is anchored
// exactly with the center of the cylindrical region to be chamferred.
// Arguments:
// l = Length of the cylindrical/conical region.
@ -113,7 +113,7 @@ module angle_pie_mask(
// overage = The extra thickness of the mask. Default: `10`.
// ends_only = If true, only mask the ends and not around the middle of the cylinder.
// orient = Orientation. Use the `ORIENT_` constants from `constants.scad`. Default: `ORIENT_Z`.
// align = Alignment of the region. Use the constants from `constants.scad`. Default: `CENTER`.
// anchor = Alignment of the region. Use the constants from `constants.scad`. Default: `CENTER`.
// Example:
// difference() {
// cylinder(h=100, r1=60, r2=30, center=true);
@ -132,7 +132,7 @@ module cylinder_mask(
fillet=undef, fillet1=undef, fillet2=undef,
circum=false, from_end=false,
overage=10, ends_only=false,
orient=ORIENT_Z, align=CENTER
orient=ORIENT_Z, anchor=CENTER
) {
r1 = get_radius(r=r, d=d, r1=r1, d1=d1, dflt=1);
r2 = get_radius(r=r, d=d, r1=r2, d1=d2, dflt=1);
@ -152,7 +152,7 @@ module cylinder_mask(
cylinder_mask(l=l, r1=sc*r1, r2=sc*r2, chamfer1=cham1, chamfer2=cham2, chamfang1=ang1, chamfang2=ang2, fillet1=fil1, fillet2=fil2, orient=orient, from_end=from_end);
}
} else {
orient_and_align([2*r1, 2*r1, l], orient, align, chain=true) {
orient_and_anchor([2*r1, 2*r1, l], orient, anchor, chain=true) {
difference() {
union() {
chlen1 = cham1 / (from_end? 1 : tan(ang1));
@ -180,7 +180,7 @@ module cylinder_mask(
// Module: chamfer_mask()
// Usage:
// chamfer_mask(l, chamfer, [orient], [align]);
// chamfer_mask(l, chamfer, [orient], [anchor]);
// Description:
// Creates a shape that can be used to chamfer a 90 degree edge.
// Difference it from the object to be chamfered. The center of
@ -189,14 +189,14 @@ module cylinder_mask(
// l = Length of mask.
// chamfer = Size of chamfer
// orient = Orientation of the mask. Use the `ORIENT_` constants from `constants.h`. Default: vertical.
// align = Alignment of the mask. Use the constants from `constants.h`. Default: centered.
// anchor = Alignment of the mask. Use the constants from `constants.h`. Default: centered.
// Example:
// difference() {
// cube(50);
// #chamfer_mask(l=50, chamfer=10, orient=ORIENT_X, align=RIGHT);
// #chamfer_mask(l=50, chamfer=10, orient=ORIENT_X, anchor=RIGHT);
// }
module chamfer_mask(l=1, chamfer=1, orient=ORIENT_Z, align=CENTER) {
orient_and_align([chamfer, chamfer, l], orient, align, chain=true) {
module chamfer_mask(l=1, chamfer=1, orient=ORIENT_Z, anchor=CENTER) {
orient_and_anchor([chamfer, chamfer, l], orient, anchor, chain=true) {
cylinder(d=chamfer*2, h=l+0.1, center=true, $fn=4);
children();
}
@ -205,7 +205,7 @@ module chamfer_mask(l=1, chamfer=1, orient=ORIENT_Z, align=CENTER) {
// Module: chamfer_mask_x()
// Usage:
// chamfer_mask_x(l, chamfer, [align]);
// chamfer_mask_x(l, chamfer, [anchor]);
// Description:
// Creates a shape that can be used to chamfer a 90 degree edge along the X axis.
// Difference it from the object to be chamfered. The center of the mask
@ -213,20 +213,20 @@ module chamfer_mask(l=1, chamfer=1, orient=ORIENT_Z, align=CENTER) {
// Arguments:
// l = Height of mask
// chamfer = size of chamfer
// align = Alignment of the cylinder. Use the constants from constants.h. Default: centered.
// anchor = Alignment of the cylinder. Use the constants from constants.h. Default: centered.
// Example:
// difference() {
// left(40) cube(80);
// #chamfer_mask_x(l=80, chamfer=20);
// }
module chamfer_mask_x(l=1.0, chamfer=1.0, align=CENTER) {
chamfer_mask(l=l, chamfer=chamfer, orient=ORIENT_X, align=align) children();
module chamfer_mask_x(l=1.0, chamfer=1.0, anchor=CENTER) {
chamfer_mask(l=l, chamfer=chamfer, orient=ORIENT_X, anchor=anchor) children();
}
// Module: chamfer_mask_y()
// Usage:
// chamfer_mask_y(l, chamfer, [align]);
// chamfer_mask_y(l, chamfer, [anchor]);
// Description:
// Creates a shape that can be used to chamfer a 90 degree edge along the Y axis.
// Difference it from the object to be chamfered. The center of the mask
@ -234,20 +234,20 @@ module chamfer_mask_x(l=1.0, chamfer=1.0, align=CENTER) {
// Arguments:
// l = Height of mask
// chamfer = size of chamfer
// align = Alignment of the cylinder. Use the constants from constants.h. Default: centered.
// anchor = Alignment of the cylinder. Use the constants from constants.h. Default: centered.
// Example:
// difference() {
// fwd(40) cube(80);
// right(80) #chamfer_mask_y(l=80, chamfer=20);
// }
module chamfer_mask_y(l=1.0, chamfer=1.0, align=CENTER) {
chamfer_mask(l=l, chamfer=chamfer, orient=ORIENT_Y, align=align) children();
module chamfer_mask_y(l=1.0, chamfer=1.0, anchor=CENTER) {
chamfer_mask(l=l, chamfer=chamfer, orient=ORIENT_Y, anchor=anchor) children();
}
// Module: chamfer_mask_z()
// Usage:
// chamfer_mask_z(l, chamfer, [align]);
// chamfer_mask_z(l, chamfer, [anchor]);
// Description:
// Creates a shape that can be used to chamfer a 90 degree edge along the Z axis.
// Difference it from the object to be chamfered. The center of the mask
@ -255,14 +255,14 @@ module chamfer_mask_y(l=1.0, chamfer=1.0, align=CENTER) {
// Arguments:
// l = Height of mask
// chamfer = size of chamfer
// align = Alignment of the cylinder. Use the constants from constants.h. Default: centered.
// anchor = Alignment of the cylinder. Use the constants from constants.h. Default: centered.
// Example:
// difference() {
// down(40) cube(80);
// #chamfer_mask_z(l=80, chamfer=20);
// }
module chamfer_mask_z(l=1.0, chamfer=1.0, align=CENTER) {
chamfer_mask(l=l, chamfer=chamfer, orient=ORIENT_Z, align=align) children();
module chamfer_mask_z(l=1.0, chamfer=1.0, anchor=CENTER) {
chamfer_mask(l=l, chamfer=chamfer, orient=ORIENT_Z, anchor=anchor) children();
}
@ -326,7 +326,7 @@ module chamfer(chamfer=1, size=[1,1,1], edges=EDGES_ALL)
module chamfer_cylinder_mask(r=1.0, d=undef, chamfer=0.25, ang=45, from_end=false, orient=ORIENT_Z)
{
r = get_radius(r=r, d=d, dflt=1);
rot(orient) cylinder_mask(l=chamfer*3, r=r, chamfer2=chamfer, chamfang2=ang, from_end=from_end, ends_only=true, align=DOWN) children();
rot(orient) cylinder_mask(l=chamfer*3, r=r, chamfer2=chamfer, chamfang2=ang, from_end=from_end, ends_only=true, anchor=DOWN) children();
}
@ -345,7 +345,7 @@ module chamfer_cylinder_mask(r=1.0, d=undef, chamfer=0.25, ang=45, from_end=fals
// from_end = If true, chamfer size is measured from end of hole. If false, chamfer is measured outset from the radius of the hole. (Default: false)
// overage = The extra thickness of the mask. Default: `0.1`.
// orient = Orientation of the mask. Use the `ORIENT_` constants from `constants.h`. Default: `ORIENT_Z`.
// align = Alignment of the mask. Use the constants from `constants.h`. Default: `CENTER`.
// anchor = Alignment of the mask. Use the constants from `constants.h`. Default: `CENTER`.
// Example:
// difference() {
// cube(100, center=true);
@ -354,13 +354,13 @@ module chamfer_cylinder_mask(r=1.0, d=undef, chamfer=0.25, ang=45, from_end=fals
// }
// Example:
// chamfer_hole_mask(d=100, chamfer=25, ang=30, overage=10);
module chamfer_hole_mask(r=undef, d=undef, chamfer=0.25, ang=45, from_end=false, overage=0.1, orient=ORIENT_Z, align=CENTER)
module chamfer_hole_mask(r=undef, d=undef, chamfer=0.25, ang=45, from_end=false, overage=0.1, orient=ORIENT_Z, anchor=CENTER)
{
r = get_radius(r=r, d=d, dflt=1);
h = chamfer * (from_end? 1 : tan(90-ang));
r2 = r + chamfer * (from_end? tan(ang) : 1);
$fn = segs(r);
orient_and_align([2*r, 2*r, h*2], orient, align, size2=[2*r2, 2*r2], chain=true) {
orient_and_anchor([2*r, 2*r, h*2], orient, anchor, size2=[2*r2, 2*r2], chain=true) {
union() {
cylinder(r=r2, h=overage, center=false);
down(h) cylinder(r1=r, r2=r2, h=h, center=false);
@ -375,7 +375,7 @@ module chamfer_hole_mask(r=undef, d=undef, chamfer=0.25, ang=45, from_end=false,
// Module: fillet_mask()
// Usage:
// fillet_mask(l|h, r, [orient], [align])
// fillet_mask(l|h, r, [orient], [anchor])
// Description:
// Creates a shape that can be used to fillet a vertical 90 degree edge.
// Difference it from the object to be filletted. The center of the mask
@ -384,17 +384,17 @@ module chamfer_hole_mask(r=undef, d=undef, chamfer=0.25, ang=45, from_end=false,
// l = Length of mask.
// r = Radius of the fillet.
// orient = Orientation of the mask. Use the `ORIENT_` constants from `constants.h`. Default: vertical.
// align = Alignment of the mask. Use the constants from `constants.h`. Default: centered.
// anchor = Alignment of the mask. Use the constants from `constants.h`. Default: centered.
// Example:
// difference() {
// cube(size=100, center=false);
// #fillet_mask(l=100, r=25, orient=ORIENT_Z, align=UP);
// #fillet_mask(l=100, r=25, orient=ORIENT_Z, anchor=UP);
// }
module fillet_mask(l=undef, r=1.0, orient=ORIENT_Z, align=CENTER, h=undef)
module fillet_mask(l=undef, r=1.0, orient=ORIENT_Z, anchor=CENTER, h=undef)
{
l = first_defined([l, h, 1]);
sides = quantup(segs(r),4);
orient_and_align([2*r, 2*r, l], orient, align, chain=true) {
orient_and_anchor([2*r, 2*r, l], orient, anchor, chain=true) {
linear_extrude(height=l+0.1, convexity=4, center=true) {
difference() {
square(2*r, center=true);
@ -408,7 +408,7 @@ module fillet_mask(l=undef, r=1.0, orient=ORIENT_Z, align=CENTER, h=undef)
// Module: fillet_mask_x()
// Usage:
// fillet_mask_x(l, r, [align])
// fillet_mask_x(l, r, [anchor])
// Description:
// Creates a shape that can be used to fillet a 90 degree edge oriented
// along the X axis. Difference it from the object to be filletted.
@ -417,18 +417,18 @@ module fillet_mask(l=undef, r=1.0, orient=ORIENT_Z, align=CENTER, h=undef)
// Arguments:
// l = Length of mask.
// r = Radius of the fillet.
// align = Alignment of the mask. Use the constants from `constants.h`. Default: centered.
// anchor = Alignment of the mask. Use the constants from `constants.h`. Default: centered.
// Example:
// difference() {
// cube(size=100, center=false);
// #fillet_mask_x(l=100, r=25, align=RIGHT);
// #fillet_mask_x(l=100, r=25, anchor=RIGHT);
// }
module fillet_mask_x(l=1.0, r=1.0, align=CENTER) fillet_mask(l=l, r=r, orient=ORIENT_X, align=align) children();
module fillet_mask_x(l=1.0, r=1.0, anchor=CENTER) fillet_mask(l=l, r=r, orient=ORIENT_X, anchor=anchor) children();
// Module: fillet_mask_y()
// Usage:
// fillet_mask_y(l, r, [align])
// fillet_mask_y(l, r, [anchor])
// Description:
// Creates a shape that can be used to fillet a 90 degree edge oriented
// along the Y axis. Difference it from the object to be filletted.
@ -437,18 +437,18 @@ module fillet_mask_x(l=1.0, r=1.0, align=CENTER) fillet_mask(l=l, r=r, orient=OR
// Arguments:
// l = Length of mask.
// r = Radius of the fillet.
// align = Alignment of the mask. Use the constants from `constants.h`. Default: centered.
// anchor = Alignment of the mask. Use the constants from `constants.h`. Default: centered.
// Example:
// difference() {
// cube(size=100, center=false);
// right(100) #fillet_mask_y(l=100, r=25, align=BACK);
// right(100) #fillet_mask_y(l=100, r=25, anchor=BACK);
// }
module fillet_mask_y(l=1.0, r=1.0, align=CENTER) fillet_mask(l=l, r=r, orient=ORIENT_Y, align=align) children();
module fillet_mask_y(l=1.0, r=1.0, anchor=CENTER) fillet_mask(l=l, r=r, orient=ORIENT_Y, anchor=anchor) children();
// Module: fillet_mask_z()
// Usage:
// fillet_mask_z(l, r, [align])
// fillet_mask_z(l, r, [anchor])
// Description:
// Creates a shape that can be used to fillet a 90 degree edge oriented
// along the Z axis. Difference it from the object to be filletted.
@ -457,13 +457,13 @@ module fillet_mask_y(l=1.0, r=1.0, align=CENTER) fillet_mask(l=l, r=r, orient=OR
// Arguments:
// l = Length of mask.
// r = Radius of the fillet.
// align = Alignment of the mask. Use the constants from `constants.h`. Default: centered.
// anchor = Alignment of the mask. Use the constants from `constants.h`. Default: centered.
// Example:
// difference() {
// cube(size=100, center=false);
// #fillet_mask_z(l=100, r=25, align=UP);
// #fillet_mask_z(l=100, r=25, anchor=UP);
// }
module fillet_mask_z(l=1.0, r=1.0, align=CENTER) fillet_mask(l=l, r=r, orient=ORIENT_Z, align=align) children();
module fillet_mask_z(l=1.0, r=1.0, anchor=CENTER) fillet_mask(l=l, r=r, orient=ORIENT_Z, anchor=anchor) children();
// Module: fillet()
@ -505,7 +505,7 @@ module fillet(fillet=1, size=[1,1,1], edges=EDGES_ALL)
// Module: fillet_angled_edge_mask()
// Usage:
// fillet_angled_edge_mask(h, r, [ang], [orient], [align]);
// fillet_angled_edge_mask(h, r, [ang], [orient], [anchor]);
// Description:
// Creates a vertical mask that can be used to fillet the edge where two
// face meet, at any arbitrary angle. Difference it from the object to
@ -516,18 +516,18 @@ module fillet(fillet=1, size=[1,1,1], edges=EDGES_ALL)
// r = radius of the fillet.
// ang = angle that the planes meet at.
// orient = Orientation of the mask. Use the `ORIENT_` constants from `constants.h`. Default: `ORIENT_Z`.
// align = Alignment of the mask. Use the constants from `constants.h`. Default: `CENTER`.
// anchor = Alignment of the mask. Use the constants from `constants.h`. Default: `CENTER`.
// Example:
// difference() {
// angle_pie_mask(ang=70, h=50, d=100);
// #fillet_angled_edge_mask(h=51, r=20.0, ang=70, $fn=32);
// }
module fillet_angled_edge_mask(h=1.0, r=1.0, ang=90, orient=ORIENT_Z, align=CENTER)
module fillet_angled_edge_mask(h=1.0, r=1.0, ang=90, orient=ORIENT_Z, anchor=CENTER)
{
sweep = 180-ang;
n = ceil(segs(r)*sweep/360);
x = r*sin(90-(ang/2))/sin(ang/2);
orient_and_align([2*x,2*r,h], orient, align, chain=true) {
orient_and_anchor([2*x,2*r,h], orient, anchor, chain=true) {
linear_extrude(height=h, convexity=4, center=true) {
polygon(
points=concat(
@ -547,7 +547,7 @@ module fillet_angled_edge_mask(h=1.0, r=1.0, ang=90, orient=ORIENT_Z, align=CENT
// Module: fillet_angled_corner_mask()
// Usage:
// fillet_angled_corner_mask(fillet, ang, [orient], [align]);
// fillet_angled_corner_mask(fillet, ang, [orient], [anchor]);
// Description:
// Creates a shape that can be used to fillet the corner of an angle.
// Difference it from the object to be filletted. The center of the mask
@ -556,7 +556,7 @@ module fillet_angled_edge_mask(h=1.0, r=1.0, ang=90, orient=ORIENT_Z, align=CENT
// fillet = radius of the fillet.
// ang = angle between planes that you need to fillet the corner of.
// orient = Orientation of the mask. Use the `ORIENT_` constants from `constants.h`. Default: `ORIENT_Z`.
// align = Alignment of the mask. Use the constants from `constants.h`. Default: `CENTER`.
// anchor = Alignment of the mask. Use the constants from `constants.h`. Default: `CENTER`.
// Example:
// ang=60;
// difference() {
@ -567,12 +567,12 @@ module fillet_angled_edge_mask(h=1.0, r=1.0, ang=90, orient=ORIENT_Z, align=CENT
// }
// fillet_angled_edge_mask(h=51, r=20, ang=ang);
// }
module fillet_angled_corner_mask(fillet=1.0, ang=90, orient=ORIENT_Z, align=CENTER)
module fillet_angled_corner_mask(fillet=1.0, ang=90, orient=ORIENT_Z, anchor=CENTER)
{
dx = fillet / tan(ang/2);
dx2 = dx / cos(ang/2) + 1;
fn = quantup(segs(fillet), 4);
orient_and_align([2*dx2, 2*dx2, fillet*2], orient, align, chain=true) {
orient_and_anchor([2*dx2, 2*dx2, fillet*2], orient, anchor, chain=true) {
difference() {
down(fillet) cylinder(r=dx2, h=fillet+1, center=false);
yflip_copy() {
@ -594,14 +594,14 @@ module fillet_angled_corner_mask(fillet=1.0, ang=90, orient=ORIENT_Z, align=CENT
// Module: fillet_corner_mask()
// Usage:
// fillet_corner_mask(r, [align]);
// fillet_corner_mask(r, [anchor]);
// Description:
// Creates a shape that you can use to round 90 degree corners on a fillet.
// Difference it from the object to be filletted. The center of the mask
// object should align exactly with the corner to be filletted.
// Arguments:
// r = radius of corner fillet.
// align = Alignment of the mask. Use the constants from `constants.h`. Default: `CENTER`.
// anchor = Alignment of the mask. Use the constants from `constants.h`. Default: `CENTER`.
// Example:
// fillet_corner_mask(r=20.0);
// Example:
@ -612,9 +612,9 @@ module fillet_angled_corner_mask(fillet=1.0, ang=90, orient=ORIENT_Z, align=CENT
// translate([15, 25, 0]) fillet_mask_z(l=81, r=15);
// translate([15, 25, 40]) #fillet_corner_mask(r=15);
// }
module fillet_corner_mask(r=1.0, align=CENTER)
module fillet_corner_mask(r=1.0, anchor=CENTER)
{
orient_and_align([2*r, 2*r, 2*r], ORIENT_Z, align, chain=true) {
orient_and_anchor([2*r, 2*r, 2*r], ORIENT_Z, anchor, chain=true) {
difference() {
cube(size=r*2, center=true);
grid3d(n=[2,2,2], spacing=r*2-0.05) {
@ -649,7 +649,7 @@ module fillet_corner_mask(r=1.0, align=CENTER)
// }
module fillet_cylinder_mask(r=1.0, fillet=0.25)
{
cylinder_mask(l=fillet*3, r=r, fillet2=fillet, overage=fillet, ends_only=true, align=DOWN) children();
cylinder_mask(l=fillet*3, r=r, fillet2=fillet, overage=fillet, ends_only=true, anchor=DOWN) children();
}
@ -668,7 +668,7 @@ module fillet_cylinder_mask(r=1.0, fillet=0.25)
// fillet = Radius of the filleting. (Default: 0.25)
// overage = The extra thickness of the mask. Default: `0.1`.
// orient = Orientation of the mask. Use the `ORIENT_` constants from `constants.h`. Default: `ORIENT_Z`.
// align = Alignment of the mask. Use the constants from `constants.h`. Default: `CENTER`.
// anchor = Alignment of the mask. Use the constants from `constants.h`. Default: `CENTER`.
// Example:
// difference() {
// cube([150,150,100], center=true);
@ -677,10 +677,10 @@ module fillet_cylinder_mask(r=1.0, fillet=0.25)
// }
// Example:
// fillet_hole_mask(r=40, fillet=20, $fa=2, $fs=2);
module fillet_hole_mask(r=undef, d=undef, fillet=0.25, overage=0.1, orient=ORIENT_Z, align=CENTER)
module fillet_hole_mask(r=undef, d=undef, fillet=0.25, overage=0.1, orient=ORIENT_Z, anchor=CENTER)
{
r = get_radius(r=r, d=d, dflt=1);
orient_and_align([2*(r+fillet), 2*(r+fillet), fillet*2], orient, align, chain=true) {
orient_and_anchor([2*(r+fillet), 2*(r+fillet), fillet*2], orient, anchor, chain=true) {
rotate_extrude(convexity=4) {
difference() {
right(r-overage) fwd(fillet) square(fillet+overage, center=false);

View file

@ -390,7 +390,7 @@ function get_metric_nut_thickness(size) = lookup(size, [
// Description:
// Makes a very simple screw model, useful for making screwholes.
// Usage:
// screw(screwsize, screwlen, headsize, headlen, [countersunk], [orient], [align])
// screw(screwsize, screwlen, headsize, headlen, [countersunk], [orient], [anchor])
// Arguments:
// screwsize = diameter of threaded part of screw.
// screwlen = length of threaded part of screw.
@ -398,10 +398,17 @@ function get_metric_nut_thickness(size) = lookup(size, [
// headlen = length of the screw head.
// countersunk = If true, center from cap's top instead of it's bottom.
// orient = Orientation of the screw. Use the `ORIENT_` constants from `constants.scad`. Default: `ORIENT_Z`.
// align = Alignment of the screw. Use the constants from `constants.scad` or `"sunken"`, or `"base"`. Default: `"base"`.
// anchor = Alignment of the screw. Use the constants from `constants.scad` or `"sunken"`, or `"base"`. Default: `"base"`.
// Examples:
// screw(screwsize=3,screwlen=10,headsize=6,headlen=3,countersunk=true);
// screw(screwsize=3,screwlen=10,headsize=6,headlen=3, align="base");
// screw(screwsize=3,screwlen=10,headsize=6,headlen=3, anchor="base");
// Example(FlatSpin): Standard Anchors
// screw(screwsize=3,screwlen=10,headsize=6,headlen=3)
// show_anchors(5, custom=false);
// Example(FlatSpin): Standard Anchors
// transparent()
// screw(screwsize=3,screwlen=10,headsize=6,headlen=3)
// show_anchors(5, std=false);
module screw(
screwsize=3,
screwlen=10,
@ -410,15 +417,15 @@ module screw(
pitch=undef,
countersunk=false,
orient=ORIENT_Z,
align="base"
anchor="base"
) {
sides = max(12, segs(screwsize/2));
algn = countersunk? DOWN : align;
alignments = [
["base", [0,0,-headlen/2+screwlen/2]],
["sunken", [0,0,(headlen+screwlen)/2-0.01]]
algn = countersunk? DOWN : anchor;
anchors = [
anchorpt("base", [0,0,-headlen/2+screwlen/2]),
anchorpt("sunken", [0,0,(headlen+screwlen)/2-0.01])
];
orient_and_align([headsize, headsize, headlen+screwlen], orient, algn, alignments=alignments, chain=true) {
orient_and_anchor([headsize, headsize, headlen+screwlen], orient, algn, anchors=anchors, chain=true) {
down(headlen/2-screwlen/2) {
down(screwlen/2) {
if (pitch == undef) {
@ -427,7 +434,7 @@ module screw(
threaded_rod(d=screwsize, l=screwlen+0.05, pitch=pitch, $fn=sides);
}
}
up(headlen/2) cylinder(r=headsize/2, h=headlen, center=true, $fn=sides*2);
cylinder(r=headsize/2, h=headlen, center=false, $fn=sides*2);
}
children();
}
@ -449,7 +456,7 @@ module screw(
// phillips = If given, the size of the phillips drive hole to add. (ie: "#1", "#2", or "#3")
// torx = If given, the size of the torx drive hole to add. (ie: 10, 20, 30, etc.)
// orient = Orientation of the bolt. Use the `ORIENT_` constants from `constants.scad`. Default: `ORIENT_Z`.
// align = Alignment of the bolt. Use the constants from `constants.scad` or `"sunken"`, `"base"`, or `"shank"`. Default: `"base"`.
// anchor = Alignment of the bolt. Use the constants from `constants.scad` or `"sunken"`, `"base"`, or `"shank"`. Default: `"base"`.
// Example: Bolt Head Types
// ydistribute(40) {
// xdistribute(30) {
@ -482,6 +489,13 @@ module screw(
// metric_bolt(headtype="hex", size=10, l=15, phillips="#2");
// Example: Hex Head with Torx
// metric_bolt(headtype="hex", size=10, l=15, torx=50);
// Example(FlatSpin): Standard Anchors
// metric_bolt(headtype="oval", size=10, l=15, shank=5, details=true, phillips="#2")
// show_anchors(5, custom=false);
// Example(FlatSpin): Custom Anchors
// transparent(0.125)
// metric_bolt(headtype="oval", size=10, l=15, shank=5, details=true, phillips="#2")
// show_anchors(5, std=false);
module metric_bolt(
headtype="socket",
size=3,
@ -494,7 +508,7 @@ module metric_bolt(
torx=undef,
flange=0,
orient=ORIENT_Z,
align="base"
anchor="base"
) {
D = headtype != "hex"?
get_metric_socket_cap_diam(size) :
@ -524,27 +538,27 @@ module metric_bolt(
headlen-0.001
);
alignments = [
["sunken", [0,0,base+sunklen]],
["base", [0,0,base]],
["shank", [0,0,base-shank]]
anchors = [
anchorpt("sunken", [0,0,base+sunklen]),
anchorpt("base", [0,0,base]),
anchorpt("shank", [0,0,base-shank])
];
color("silver")
orient_and_align([D+flange, D+flange, headlen+l], orient, align, alignments=alignments, chain=true) {
//color("silver")
orient_and_anchor([size, size, headlen+l], orient, anchor, geometry="cylinder", anchors=anchors, chain=true) {
up(base) {
difference() {
union() {
// Head
if (headtype == "hex") {
difference() {
cylinder(d=tcirc, h=H, center=false, $fn=6);
cylinder(d=tcirc, h=H, $fn=6);
// Bevel hex nut top
if (details) {
up(H-bevtop) {
difference() {
upcube([tcirc+1, tcirc+1, bevtop+0.5]);
cube([tcirc+1, tcirc+1, bevtop+0.5], anchor=BOTTOM);
down(0.01) cylinder(d1=tcirc, d2=tcirc-bevtop*2, h=bevtop+0.02, center=false);
}
}
@ -554,25 +568,25 @@ module metric_bolt(
sockw = get_metric_socket_cap_socket_size(size);
sockd = get_metric_socket_cap_socket_depth(size);
difference() {
cylinder(d=D, h=H, center=false);
up(H-sockd) cylinder(h=sockd+0.1, d=sockw/cos(30), center=false, $fn=6);
cylinder(d=D, h=H);
up(H-sockd) cylinder(h=sockd+0.1, d=sockw/cos(30), $fn=6);
if (details) {
kcnt = 36;
zring(n=kcnt, r=D/2) up(H/3) upcube([PI*D/kcnt/2, PI*D/kcnt/2, H]);
zring(n=kcnt, r=D/2) up(H/3) cube([PI*D/kcnt/2, PI*D/kcnt/2, H], anchor=BOTTOM);
}
}
} else if (headtype == "pan") {
cyl(l=H*0.75, d=D, fillet2=H*0.75/2, align=UP);
cyl(l=H*0.75, d=D, fillet2=H*0.75/2, anchor=DOWN);
} else if (headtype == "round") {
top_half() zscale(H*0.75/D*2) sphere(d=D);
top_half(D) zscale(H*0.75/D*2) sphere(d=D);
} else if (headtype == "button") {
up(H*0.75/3) top_half() zscale(H*0.75*2/3/D*2) sphere(d=D);
up(H*0.75/3) top_half(D) zscale(H*0.75*2/3/D*2) sphere(d=D);
cylinder(d=D, h=H*0.75/3+0.01, center=false);
} else if (headtype == "countersunk") {
cylinder(h=(D-size)/2, d1=size, d2=D, center=false);
cylinder(h=(D-size)/2, d1=size, d2=D);
} else if (headtype == "oval") {
up((D-size)/2) top_half() zscale(0.333) sphere(d=D);
cylinder(h=(D-size)/2, d1=size, d2=D, center=false);
up((D-size)/2) top_half(D) zscale(0.333) sphere(d=D);
cylinder(h=(D-size)/2, d1=size, d2=D);
}
// Flange
@ -604,7 +618,7 @@ module metric_bolt(
// Bevel bottom end of threads
if (details) {
difference() {
down(0.5) upcube([size+1, size+1, bevbot+0.5]);
down(0.5) cube([size+1, size+1, bevbot+0.5], anchor=BOTTOM);
cylinder(d1=size-bevbot*2, d2=size, h=bevbot+0.01, center=false);
}
}
@ -640,8 +654,8 @@ module metric_bolt(
// flange = radius of flange beyond the head. Default = 0 (no flange)
// details = true if model should be rendered with extra details. (Default: false)
// orient = Orientation of the nut. Use the `ORIENT_` constants from `constants.scad`. Default: `ORIENT_Z`.
// align = Alignment of the nut. Use the constants from `constants.scad`. Default: `UP`.
// center = If true, centers the nut at the origin. If false, sits on top of XY plane. Overrides `align` if given.
// anchor = Alignment of the nut. Use the constants from `constants.scad`. Default: `UP`.
// center = If true, centers the nut at the origin. If false, sits on top of XY plane. Overrides `anchor` if given.
// Example: No details, No Hole. Useful for a mask.
// metric_nut(size=10, hole=false);
// Example: Hole, with No Threads
@ -662,7 +676,7 @@ module metric_nut(
flange=0,
center=undef,
orient=ORIENT_Z,
align=UP
anchor=UP
) {
H = get_metric_nut_thickness(size);
D = get_metric_nut_size(size);
@ -671,8 +685,8 @@ module metric_nut(
dcirc = D/cos(30);
bevtop = (dcirc - D)/2;
color("silver")
orient_and_align([dcirc+flange, dcirc+flange, H], orient, align, center, chain=true) {
//color("silver")
orient_and_anchor([dcirc+flange, dcirc+flange, H], orient, anchor, center, geometry="cylinder", chain=true) {
difference() {
union() {
difference() {
@ -680,14 +694,14 @@ module metric_nut(
if (details) {
up(H/2-bevtop) {
difference() {
upcube([dcirc+1, dcirc+1, bevtop+0.5]);
cube([dcirc+1, dcirc+1, bevtop+0.5], anchor=BOTTOM);
down(0.01) cylinder(d1=dcirc, d2=dcirc-bevtop*2, h=bevtop+0.02, center=false, $fn=nutfn);
}
}
if (flange == 0) {
down(H/2) {
difference() {
down(0.5) upcube([dcirc+1, dcirc+1, bevtop+0.5]);
down(0.5) cube([dcirc+1, dcirc+1, bevtop+0.5], anchor=BOTTOM);
down(0.01) cylinder(d1=dcirc-bevtop*2, d2=dcirc, h=bevtop+0.02, center=false, $fn=nutfn);
}
}

View file

@ -129,10 +129,10 @@ function nema_motor_screw_depth(size) = lookup(size, [
// shaft = Shaft diameter. Default: 5mm
// shaft_len = Length of shaft protruding out the top of the stepper motor. Default: 20mm
// orient = Orientation of the stepper. Use the `ORIENT_` constants from `constants.scad`. Default: `ORIENT_Z`.
// align = Alignment of the stepper. Use the constants from `constants.scad`. Default: `DOWN`.
// anchor = Alignment of the stepper. Use the constants from `constants.scad`. Default: `DOWN`.
// Example:
// nema11_stepper();
module nema11_stepper(h=24, shaft=5, shaft_len=20, orient=ORIENT_Z, align=DOWN)
module nema11_stepper(h=24, shaft=5, shaft_len=20, orient=ORIENT_Z, anchor=DOWN)
{
size = 11;
motor_width = nema_motor_width(size);
@ -142,11 +142,11 @@ module nema11_stepper(h=24, shaft=5, shaft_len=20, orient=ORIENT_Z, align=DOWN)
screw_size = nema_motor_screw_size(size);
screw_depth = nema_motor_screw_depth(size);
orient_and_align([motor_width, motor_width, h], orient, align, orig_align=DOWN, chain=true) {
orient_and_anchor([motor_width, motor_width, h], orient, anchor, orig_anchor=DOWN, chain=true) {
union() {
difference() {
color([0.4, 0.4, 0.4])
cuboid(size=[motor_width, motor_width, h], chamfer=2, edges=EDGES_Z_ALL, align=DOWN);
cuboid(size=[motor_width, motor_width, h], chamfer=2, edges=EDGES_Z_ALL, anchor=DOWN);
color("silver")
xspread(screw_spacing)
yspread(screw_spacing)
@ -173,10 +173,10 @@ module nema11_stepper(h=24, shaft=5, shaft_len=20, orient=ORIENT_Z, align=DOWN)
// shaft = Shaft diameter. Default: 5mm
// shaft_len = Length of shaft protruding out the top of the stepper motor. Default: 24mm
// orient = Orientation of the stepper. Use the `ORIENT_` constants from `constants.scad`. Default: `ORIENT_Z`.
// align = Alignment of the stepper. Use the constants from `constants.scad`. Default: `DOWN`.
// anchor = Alignment of the stepper. Use the constants from `constants.scad`. Default: `DOWN`.
// Example:
// nema14_stepper();
module nema14_stepper(h=24, shaft=5, shaft_len=24, orient=ORIENT_Z, align=DOWN)
module nema14_stepper(h=24, shaft=5, shaft_len=24, orient=ORIENT_Z, anchor=DOWN)
{
size = 14;
motor_width = nema_motor_width(size);
@ -186,11 +186,11 @@ module nema14_stepper(h=24, shaft=5, shaft_len=24, orient=ORIENT_Z, align=DOWN)
screw_size = nema_motor_screw_size(size);
screw_depth = nema_motor_screw_depth(size);
orient_and_align([motor_width, motor_width, h], orient, align, orig_align=DOWN, chain=true) {
orient_and_anchor([motor_width, motor_width, h], orient, anchor, orig_anchor=DOWN, chain=true) {
union() {
difference() {
color([0.4, 0.4, 0.4])
cuboid(size=[motor_width, motor_width, h], chamfer=2, edges=EDGES_Z_ALL, align=DOWN);
cuboid(size=[motor_width, motor_width, h], chamfer=2, edges=EDGES_Z_ALL, anchor=DOWN);
color("silver")
xspread(screw_spacing)
yspread(screw_spacing)
@ -202,7 +202,7 @@ module nema14_stepper(h=24, shaft=5, shaft_len=24, orient=ORIENT_Z, align=DOWN)
cyl(h=plinth_height*3, d=shaft+0.75);
}
}
color("silver") cyl(h=shaft_len, d=shaft, align=UP, $fn=max(12,segs(shaft/2)));
color("silver") cyl(h=shaft_len, d=shaft, anchor=UP, $fn=max(12,segs(shaft/2)));
}
children();
}
@ -217,10 +217,10 @@ module nema14_stepper(h=24, shaft=5, shaft_len=24, orient=ORIENT_Z, align=DOWN)
// shaft = Shaft diameter. Default: 5mm
// shaft_len = Length of shaft protruding out the top of the stepper motor. Default: 20mm
// orient = Orientation of the stepper. Use the `ORIENT_` constants from `constants.scad`. Default: `ORIENT_Z`.
// align = Alignment of the stepper. Use the constants from `constants.scad`. Default: `DOWN`.
// anchor = Alignment of the stepper. Use the constants from `constants.scad`. Default: `DOWN`.
// Example:
// nema17_stepper();
module nema17_stepper(h=34, shaft=5, shaft_len=20, orient=ORIENT_Z, align=DOWN)
module nema17_stepper(h=34, shaft=5, shaft_len=20, orient=ORIENT_Z, anchor=DOWN)
{
size = 17;
motor_width = nema_motor_width(size);
@ -230,11 +230,11 @@ module nema17_stepper(h=34, shaft=5, shaft_len=20, orient=ORIENT_Z, align=DOWN)
screw_size = nema_motor_screw_size(size);
screw_depth = nema_motor_screw_depth(size);
orient_and_align([motor_width, motor_width, h], orient, align, orig_align=DOWN, chain=true) {
orient_and_anchor([motor_width, motor_width, h], orient, anchor, orig_anchor=DOWN, chain=true) {
union() {
difference() {
color([0.4, 0.4, 0.4])
cuboid([motor_width, motor_width, h], chamfer=2, edges=EDGES_Z_ALL, align=DOWN);
cuboid([motor_width, motor_width, h], chamfer=2, edges=EDGES_Z_ALL, anchor=DOWN);
color("silver")
xspread(screw_spacing)
yspread(screw_spacing)
@ -280,10 +280,10 @@ module nema17_stepper(h=34, shaft=5, shaft_len=20, orient=ORIENT_Z, align=DOWN)
// shaft = Shaft diameter. Default: 6.35mm
// shaft_len = Length of shaft protruding out the top of the stepper motor. Default: 25mm
// orient = Orientation of the stepper. Use the `ORIENT_` constants from `constants.scad`. Default: `ORIENT_Z`.
// align = Alignment of the stepper. Use the constants from `constants.scad`. Default: `DOWN`.
// anchor = Alignment of the stepper. Use the constants from `constants.scad`. Default: `DOWN`.
// Example:
// nema23_stepper();
module nema23_stepper(h=50, shaft=6.35, shaft_len=25, orient=ORIENT_Z, align=DOWN)
module nema23_stepper(h=50, shaft=6.35, shaft_len=25, orient=ORIENT_Z, anchor=DOWN)
{
size = 23;
motor_width = nema_motor_width(size);
@ -294,11 +294,11 @@ module nema23_stepper(h=50, shaft=6.35, shaft_len=25, orient=ORIENT_Z, align=DOW
screw_depth = nema_motor_screw_depth(size);
screw_inset = motor_width - screw_spacing + 1;
orient_and_align([motor_width, motor_width, h], orient, align, orig_align=DOWN, chain=true) {
orient_and_anchor([motor_width, motor_width, h], orient, anchor, orig_anchor=DOWN, chain=true) {
difference() {
union() {
color([0.4, 0.4, 0.4])
cuboid([motor_width, motor_width, h], chamfer=2, edges=EDGES_Z_ALL, align=DOWN);
cuboid([motor_width, motor_width, h], chamfer=2, edges=EDGES_Z_ALL, anchor=DOWN);
color([0.4, 0.4, 0.4])
cylinder(h=plinth_height, d=plinth_diam);
color("silver")
@ -308,7 +308,7 @@ module nema23_stepper(h=50, shaft=6.35, shaft_len=25, orient=ORIENT_Z, align=DOW
xspread(screw_spacing) {
yspread(screw_spacing) {
cyl(d=screw_size, h=screw_depth*3, $fn=max(12,segs(screw_size/2)));
down(screw_depth) cuboid([screw_inset, screw_inset, h], align=DOWN);
down(screw_depth) cuboid([screw_inset, screw_inset, h], anchor=DOWN);
}
}
}
@ -326,10 +326,10 @@ module nema23_stepper(h=50, shaft=6.35, shaft_len=25, orient=ORIENT_Z, align=DOW
// shaft = Shaft diameter. Default: 12.7mm
// shaft_len = Length of shaft protruding out the top of the stepper motor. Default: 32mm
// orient = Orientation of the stepper. Use the `ORIENT_` constants from `constants.scad`. Default: `ORIENT_Z`.
// align = Alignment of the stepper. Use the constants from `constants.scad`. Default: `DOWN`.
// anchor = Alignment of the stepper. Use the constants from `constants.scad`. Default: `DOWN`.
// Example:
// nema34_stepper();
module nema34_stepper(h=75, shaft=12.7, shaft_len=32, orient=ORIENT_Z, align=DOWN)
module nema34_stepper(h=75, shaft=12.7, shaft_len=32, orient=ORIENT_Z, anchor=DOWN)
{
size = 34;
motor_width = nema_motor_width(size);
@ -340,11 +340,11 @@ module nema34_stepper(h=75, shaft=12.7, shaft_len=32, orient=ORIENT_Z, align=DOW
screw_depth = nema_motor_screw_depth(size);
screw_inset = motor_width - screw_spacing + 1;
orient_and_align([motor_width, motor_width, h], orient, align, orig_align=DOWN, chain=true) {
orient_and_anchor([motor_width, motor_width, h], orient, anchor, orig_anchor=DOWN, chain=true) {
difference() {
union() {
color([0.4, 0.4, 0.4])
cuboid(size=[motor_width, motor_width, h], chamfer=2, edges=EDGES_Z_ALL, align=DOWN);
cuboid(size=[motor_width, motor_width, h], chamfer=2, edges=EDGES_Z_ALL, anchor=DOWN);
color([0.4, 0.4, 0.4])
cylinder(h=plinth_height, d=plinth_diam);
color("silver")
@ -377,21 +377,21 @@ module nema34_stepper(h=75, shaft=12.7, shaft_len=32, orient=ORIENT_Z, align=DOW
// l = The length of the slots, for making an adjustable motor mount. Default: 5
// slop = The printer-specific slop value to make parts fit just right. Default: `PRINTER_SLOP`
// orient = Orientation of the stepper. Use the `ORIENT_` constants from `constants.scad`. Default: `ORIENT_Z`.
// align = Alignment of the stepper. Use the constants from `constants.scad`. Default: `CENTER`.
// anchor = Alignment of the stepper. Use the constants from `constants.scad`. Default: `CENTER`.
// Example:
// nema_mount_holes(size=14, depth=5, l=5);
// Example:
// nema_mount_holes(size=17, depth=5, l=5);
// Example:
// nema_mount_holes(size=17, depth=5, l=0);
module nema_mount_holes(size=17, depth=5, l=5, slop=PRINTER_SLOP, orient=ORIENT_Z, align=CENTER)
module nema_mount_holes(size=17, depth=5, l=5, slop=PRINTER_SLOP, orient=ORIENT_Z, anchor=CENTER)
{
motor_width = nema_motor_width(size);
plinth_diam = nema_motor_plinth_diam(size)+slop;
screw_spacing = nema_motor_screw_spacing(size);
screw_size = nema_motor_screw_size(size)+slop;
orient_and_align([motor_width, motor_width, l], orient, align, chain=true) {
orient_and_anchor([motor_width, motor_width, l], orient, anchor, chain=true) {
union() {
xspread(screw_spacing) {
yspread(screw_spacing) {
@ -427,14 +427,14 @@ module nema_mount_holes(size=17, depth=5, l=5, slop=PRINTER_SLOP, orient=ORIENT_
// l = The length of the slots, for making an adjustable motor mount. Default: 5
// slop = The printer-specific slop value to make parts fit just right. Default: `PRINTER_SLOP`
// orient = Orientation of the stepper. Use the `ORIENT_` constants from `constants.scad`. Default: `ORIENT_Z`.
// align = Alignment of the stepper. Use the constants from `constants.scad`. Default: `CENTER`.
// anchor = Alignment of the stepper. Use the constants from `constants.scad`. Default: `CENTER`.
// Example:
// nema11_mount_holes(depth=5, l=5);
// Example:
// nema11_mount_holes(depth=5, l=0);
module nema11_mount_holes(depth=5, l=5, slop=PRINTER_SLOP, orient=ORIENT_Z, align=CENTER)
module nema11_mount_holes(depth=5, l=5, slop=PRINTER_SLOP, orient=ORIENT_Z, anchor=CENTER)
{
nema_mount_holes(size=11, depth=depth, l=l, slop=slop, orient=orient, align=align) children();
nema_mount_holes(size=11, depth=depth, l=l, slop=slop, orient=orient, anchor=anchor) children();
}
@ -446,14 +446,14 @@ module nema11_mount_holes(depth=5, l=5, slop=PRINTER_SLOP, orient=ORIENT_Z, alig
// l = The length of the slots, for making an adjustable motor mount. Default: 5
// slop = The printer-specific slop value to make parts fit just right. Default: `PRINTER_SLOP`
// orient = Orientation of the stepper. Use the `ORIENT_` constants from `constants.scad`. Default: `ORIENT_Z`.
// align = Alignment of the stepper. Use the constants from `constants.scad`. Default: `CENTER`.
// anchor = Alignment of the stepper. Use the constants from `constants.scad`. Default: `CENTER`.
// Example:
// nema14_mount_holes(depth=5, l=5);
// Example:
// nema14_mount_holes(depth=5, l=0);
module nema14_mount_holes(depth=5, l=5, slop=PRINTER_SLOP, orient=ORIENT_Z, align=CENTER)
module nema14_mount_holes(depth=5, l=5, slop=PRINTER_SLOP, orient=ORIENT_Z, anchor=CENTER)
{
nema_mount_holes(size=14, depth=depth, l=l, slop=slop, orient=orient, align=align) children();
nema_mount_holes(size=14, depth=depth, l=l, slop=slop, orient=orient, anchor=anchor) children();
}
@ -465,14 +465,14 @@ module nema14_mount_holes(depth=5, l=5, slop=PRINTER_SLOP, orient=ORIENT_Z, alig
// l = The length of the slots, for making an adjustable motor mount. Default: 5
// slop = The printer-specific slop value to make parts fit just right. Default: `PRINTER_SLOP`
// orient = Orientation of the stepper. Use the `ORIENT_` constants from `constants.scad`. Default: `ORIENT_Z`.
// align = Alignment of the stepper. Use the constants from `constants.scad`. Default: `CENTER`.
// anchor = Alignment of the stepper. Use the constants from `constants.scad`. Default: `CENTER`.
// Example:
// nema17_mount_holes(depth=5, l=5);
// Example:
// nema17_mount_holes(depth=5, l=0);
module nema17_mount_holes(depth=5, l=5, slop=PRINTER_SLOP, orient=ORIENT_Z, align=CENTER)
module nema17_mount_holes(depth=5, l=5, slop=PRINTER_SLOP, orient=ORIENT_Z, anchor=CENTER)
{
nema_mount_holes(size=17, depth=depth, l=l, slop=slop, orient=orient, align=align) children();
nema_mount_holes(size=17, depth=depth, l=l, slop=slop, orient=orient, anchor=anchor) children();
}
@ -484,14 +484,14 @@ module nema17_mount_holes(depth=5, l=5, slop=PRINTER_SLOP, orient=ORIENT_Z, alig
// l = The length of the slots, for making an adjustable motor mount. Default: 5
// slop = The printer-specific slop value to make parts fit just right. Default: `PRINTER_SLOP`
// orient = Orientation of the stepper. Use the `ORIENT_` constants from `constants.scad`. Default: `ORIENT_Z`.
// align = Alignment of the stepper. Use the constants from `constants.scad`. Default: `CENTER`.
// anchor = Alignment of the stepper. Use the constants from `constants.scad`. Default: `CENTER`.
// Example:
// nema23_mount_holes(depth=5, l=5);
// Example:
// nema23_mount_holes(depth=5, l=0);
module nema23_mount_holes(depth=5, l=5, slop=PRINTER_SLOP, orient=ORIENT_Z, align=CENTER)
module nema23_mount_holes(depth=5, l=5, slop=PRINTER_SLOP, orient=ORIENT_Z, anchor=CENTER)
{
nema_mount_holes(size=23, depth=depth, l=l, slop=slop, orient=orient, align=align) children();
nema_mount_holes(size=23, depth=depth, l=l, slop=slop, orient=orient, anchor=anchor) children();
}
@ -503,14 +503,14 @@ module nema23_mount_holes(depth=5, l=5, slop=PRINTER_SLOP, orient=ORIENT_Z, alig
// l = The length of the slots, for making an adjustable motor mount. Default: 5
// slop = The printer-specific slop value to make parts fit just right. Default: `PRINTER_SLOP`
// orient = Orientation of the stepper. Use the `ORIENT_` constants from `constants.scad`. Default: `ORIENT_Z`.
// align = Alignment of the stepper. Use the constants from `constants.scad`. Default: `CENTER`.
// anchor = Alignment of the stepper. Use the constants from `constants.scad`. Default: `CENTER`.
// Example:
// nema34_mount_holes(depth=5, l=5);
// Example:
// nema34_mount_holes(depth=5, l=0);
module nema34_mount_holes(depth=5, l=5, slop=PRINTER_SLOP, orient=ORIENT_Z, align=CENTER)
module nema34_mount_holes(depth=5, l=5, slop=PRINTER_SLOP, orient=ORIENT_Z, anchor=CENTER)
{
nema_mount_holes(size=34, depth=depth, l=l, slop=slop, orient=orient, align=align) children();
nema_mount_holes(size=34, depth=depth, l=l, slop=slop, orient=orient, anchor=anchor) children();
}
@ -522,14 +522,14 @@ module nema34_mount_holes(depth=5, l=5, slop=PRINTER_SLOP, orient=ORIENT_Z, alig
// l = The length of the slots, for making an adjustable motor mount. Default: 5
// slop = The printer-specific slop value to make parts fit just right. Default: `PRINTER_SLOP`
// orient = Orientation of the stepper. Use the `ORIENT_` constants from `constants.scad`. Default: `ORIENT_Z`.
// align = Alignment of the stepper. Use the constants from `constants.scad`. Default: `CENTER`.
// anchor = Alignment of the stepper. Use the constants from `constants.scad`. Default: `CENTER`.
// Example:
// nema34_mount_holes(depth=5, l=5);
// Example:
// nema34_mount_holes(depth=5, l=0);
module nema34_mount_holes(depth=5, l=5, slop=PRINTER_SLOP, orient=ORIENT_Z, align=CENTER)
module nema34_mount_holes(depth=5, l=5, slop=PRINTER_SLOP, orient=ORIENT_Z, anchor=CENTER)
{
nema_mount_holes(size=34, depth=depth, l=l, slop=slop, orient=orient, align=align) children();
nema_mount_holes(size=34, depth=depth, l=l, slop=slop, orient=orient, anchor=anchor) children();
}

View file

@ -231,9 +231,9 @@ module extrude_from_to(pt1, pt2, convexity=undef, twist=undef, scale=undef, slic
// Example:
// extrude_2d_hollow(wall=2, height=100, twist=90, slices=50)
// circle(r=40, $fn=6);
module extrude_2d_hollow(wall=2, height=50, twist=90, slices=60, center=undef, orient=ORIENT_Z, align=UP)
module extrude_2d_hollow(wall=2, height=50, twist=90, slices=60, center=undef, orient=ORIENT_Z, anchor=UP)
{
orient_and_align([0,0,height], orient, align, center, chain=true) {
orient_and_anchor([0,0,height], orient, anchor, center, chain=true) {
linear_extrude(height=height, twist=twist, slices=slices, center=true) {
difference() {
children();
@ -259,7 +259,7 @@ module extrude_2d_hollow(wall=2, height=50, twist=90, slices=60, center=undef, o
// Example:
// poly = [[-10,0], [-3,-5], [3,-5], [10,0], [0,-30]];
// extrude_2dpath_along_spiral(poly, h=200, r=50, twist=1080, $fn=36);
module extrude_2dpath_along_spiral(polyline, h, r, twist=360, center=undef, orient=ORIENT_Z, align=CENTER) {
module extrude_2dpath_along_spiral(polyline, h, r, twist=360, center=undef, orient=ORIENT_Z, anchor=CENTER) {
pline_count = len(polyline);
steps = ceil(segs(r)*(twist/360));
@ -301,7 +301,7 @@ module extrude_2dpath_along_spiral(polyline, h, r, twist=360, center=undef, orie
);
tri_faces = triangulate_faces(poly_points, poly_faces);
orient_and_align([r,r,h], orient, align, center, chain=true) {
orient_and_anchor([r,r,h], orient, anchor, center, chain=true) {
polyhedron(points=poly_points, faces=tri_faces, convexity=10);
children();
}

View file

@ -52,7 +52,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// phillips_drive(size="#2", shaft=6, l=20);
// phillips_drive(size="#3", shaft=6, l=20);
// }
module phillips_drive(size="#2", shaft=6, l=20, orient=ORIENT_Z, align=UP) {
module phillips_drive(size="#2", shaft=6, l=20, orient=ORIENT_Z, anchor=BOTTOM) {
// These are my best guess reverse-engineered measurements of
// the tip diameters of various phillips screwdriver sizes.
ang = 11;
@ -61,7 +61,7 @@ module phillips_drive(size="#2", shaft=6, l=20, orient=ORIENT_Z, align=UP) {
r = radidx == []? 0 : rads[radidx][1];
h = (r/2)/tan(ang);
cr = r/2;
orient_and_align([shaft, shaft, l], orient, align, chain=true) {
orient_and_anchor([shaft, shaft, l], orient, anchor, chain=true) {
down(l/2) {
difference() {
intersection() {
@ -78,12 +78,11 @@ module phillips_drive(size="#2", shaft=6, l=20, orient=ORIENT_Z, align=UP) {
zrot(-45) {
off = (r/2-cr*(sqrt(2)-1))/sqrt(2);
translate([off, off, 0]) {
linear_extrude(height=l*2, convexity=4) {
linear_extrude(height=l, convexity=4) {
difference() {
union() {
square([shaft, shaft], center=false);
back(cr) zrot(1.125) square([shaft, shaft], center=false);
right(cr) zrot(-1.125) square([shaft, shaft], center=false);
square([shaft/2, shaft/2], center=false);
mirror_copy([1,-1]) back(cr) zrot(1.125) square([shaft/2, shaft/2], center=false);
}
difference() {
square([cr*2, cr*2], center=true);

View file

@ -44,24 +44,24 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Module: cube()
//
// Description:
// Creates a cube object, with support for alignment and attachments.
// Creates a cube object, with support for anchoring and attachments.
// This is a drop-in replacement for the built-in `cube()` module.
//
// Arguments:
// size = The size of the cube.
// align = The side of the origin to align to. Use constants from `constants.scad`. Default: `CENTER`
// center = If given, overrides `align`. A true value sets `align=CENTER`, false sets `align=UP+BACK+RIGHT`.
// anchor = The side of the origin to anchor to. Use constants from `constants.scad`. Default: `ALLNEG`
// center = If given, overrides `anchor`. A true value sets `anchor=CENTER`, false sets `anchor=ALLNEG`.
//
// Example: Simple regular cube.
// cube(40);
// Example: Rectangular cube.
// cuboid([20,40,50]);
// Example: Standard Connectors.
// cube(40, center=true) show_connectors();
module cube(size, center=undef, align=ALLNEG)
// cube(40, center=true) show_anchors();
module cube(size, center=undef, anchor=ALLNEG)
{
size = scalar_vec3(size);
orient_and_align(size, ORIENT_Z, align, center, noncentered=ALLPOS, chain=true) {
orient_and_anchor(size, ORIENT_Z, anchor, center, noncentered=ALLPOS, chain=true) {
linear_extrude(height=size.z, convexity=2, center=true) {
square([size.x, size.y], center=true);
}
@ -72,10 +72,10 @@ module cube(size, center=undef, align=ALLNEG)
// Module: cylinder()
// Usage:
// cylinder(h, r|d, [center], [orient], [align]);
// cylinder(h, r1/d1, r2/d2, [center], [orient], [align]);
// cylinder(h, r|d, [center], [orient], [anchor]);
// cylinder(h, r1/d1, r2/d2, [center], [orient], [anchor]);
// Description:
// Creates a cylinder object, with support for alignment and attachments.
// Creates a cylinder object, with support for anchoring and attachments.
// This is a drop-in replacement for the built-in `cylinder()` module.
// Arguments:
// l / h = The height of the cylinder.
@ -86,8 +86,8 @@ module cube(size, center=undef, align=ALLNEG)
// d1 = The bottom diameter of the cylinder. (Before orientation.)
// d2 = The top diameter of the cylinder. (Before orientation.)
// orient = Orientation of the cylinder. Use the `ORIENT_` constants from `constants.scad`. Default: vertical.
// align = The side of the origin to align to. Use constants from `constants.scad`. Default: `UP`
// center = If given, overrides `align`. A true value sets `align=CENTER`, false sets `align=UP+BACK+RIGHT`.
// anchor = The side of the part to anchor to the origin. Use constants from `constants.scad`. Default: `UP`
// center = If given, overrides `anchor`. A true value sets `anchor=CENTER`, false sets `anchor=BOTTOM`.
// Example: By Radius
// xdistribute(30) {
// cylinder(h=40, r=10);
@ -100,17 +100,17 @@ module cube(size, center=undef, align=ALLNEG)
// }
// Example: Standard Connectors
// xdistribute(40) {
// cylinder(h=30, d=25) show_connectors();
// cylinder(h=30, d1=25, d2=10) show_connectors();
// cylinder(h=30, d=25) show_anchors();
// cylinder(h=30, d1=25, d2=10) show_anchors();
// }
module cylinder(r=undef, d=undef, r1=undef, r2=undef, d1=undef, d2=undef, h=undef, l=undef, center=undef, orient=ORIENT_Z, align=BOTTOM)
module cylinder(r=undef, d=undef, r1=undef, r2=undef, d1=undef, d2=undef, h=undef, l=undef, center=undef, orient=ORIENT_Z, anchor=BOTTOM)
{
r1 = get_radius(r1=r1, r=r, d1=d1, d=d, dflt=1);
r2 = get_radius(r1=r2, r=r, d1=d2, d=d, dflt=1);
l = first_defined([h, l]);
sides = segs(max(r1,r2));
size = [r1*2, r1*2, l];
orient_and_align(size, orient, align, center, size2=[r2*2,r2*2], noncentered=UP, geometry="cylinder", chain=true) {
orient_and_anchor(size, orient, anchor, center, size2=[r2*2,r2*2], noncentered=BOTTOM, geometry="cylinder", chain=true) {
linear_extrude(height=l, scale=r2/r1, convexity=2, center=true) {
circle(r=r1, $fn=sides);
}
@ -122,27 +122,27 @@ module cylinder(r=undef, d=undef, r1=undef, r2=undef, d1=undef, d2=undef, h=unde
// Module: sphere()
// Usage:
// sphere(r|d, [orient], [align])
// sphere(r|d, [orient], [anchor])
// Description:
// Creates a sphere object, with support for alignment and attachments.
// Creates a sphere object, with support for anchoring and attachments.
// This is a drop-in replacement for the built-in `sphere()` module.
// Arguments:
// r = Radius of the sphere.
// d = Diameter of the sphere.
// orient = Orientation of the sphere, if you don't like where the vertices lay. Use the `ORIENT_` constants from `constants.scad`. Default: `ORIENT_Z`.
// align = Alignment of the sphere. Use the constants from `constants.scad`. Default: `CENTER`.
// anchor = Alignment of the sphere. Use the constants from `constants.scad`. Default: `CENTER`.
// Example: By Radius
// sphere(r=50);
// Example: By Diameter
// sphere(d=100);
// Example: Standard Connectors
// sphere(d=50) show_connectors();
module sphere(r=undef, d=undef, orient=ORIENT_Z, align=CENTER)
// sphere(d=50) show_anchors();
module sphere(r=undef, d=undef, orient=ORIENT_Z, anchor=CENTER)
{
r = get_radius(r=r, d=d, dflt=1);
sides = segs(r);
size = [r*2, r*2, r*2];
orient_and_align(size, orient, align, geometry="sphere", chain=true) {
orient_and_anchor(size, orient, anchor, geometry="sphere", chain=true) {
rotate_extrude(convexity=2) {
difference() {
circle(r=r, $fn=sides);

View file

@ -51,10 +51,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// fillet = Radius of fillet for edge rounding. Default: No filleting.
// edges = Edges to chamfer/fillet. Use `EDGE` constants from constants.scad. Default: `EDGES_ALL`
// trimcorners = If true, rounds or chamfers corners where three chamferred/filleted edges meet. Default: `true`
// p1 = Align the cuboid's corner at `p1`, if given. Forces `align=UP+BACK+RIGHT`.
// p1 = Align the cuboid's corner at `p1`, if given. Forces `anchor=ALLNEG`.
// p2 = If given with `p1`, defines the cornerpoints of the cuboid.
// align = The side of the origin to align to. Use constants from `constants.scad`. Default: `CENTER`
// center = If given, overrides `align`. A true value sets `align=CENTER`, false sets `align=UP+BACK+RIGHT`.
// anchor = The side of the part to anchor to. Use constants from `constants.scad`. Default: `CENTER`
// center = If given, overrides `anchor`. A true value sets `anchor=CENTER`, false sets `anchor=ALLNEG`.
//
// Example: Simple regular cube.
// cuboid(40);
@ -77,7 +77,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Example: Rectangular cube with only some edges rounded.
// cuboid([30,40,50], fillet=5, edges=EDGE_TOP_FR+EDGE_TOP_RT+EDGE_FR_RT, $fn=24);
// Example: Standard Connectors
// cuboid(40, chamfer=5) show_connectors();
// cuboid(40, chamfer=5) show_anchors();
module cuboid(
size=[1,1,1],
p1=undef, p2=undef,
@ -85,25 +85,25 @@ module cuboid(
fillet=undef,
edges=EDGES_ALL,
trimcorners=true,
align=[0,0,0],
anchor=CENTER,
center=undef
) {
size = scalar_vec3(size);
if (!is_undef(p1)) {
if (!is_undef(p2)) {
translate([for (v=array_zip([p1,p2],0)) min(v)]) {
cuboid(size=vabs(p2-p1), chamfer=chamfer, fillet=fillet, edges=edges, trimcorners=trimcorners, align=ALLNEG) children();
cuboid(size=vabs(p2-p1), chamfer=chamfer, fillet=fillet, edges=edges, trimcorners=trimcorners, anchor=ALLNEG) children();
}
} else {
translate(p1) {
cuboid(size=size, chamfer=chamfer, fillet=fillet, edges=edges, trimcorners=trimcorners, align=ALLNEG) children();
cuboid(size=size, chamfer=chamfer, fillet=fillet, edges=edges, trimcorners=trimcorners, anchor=ALLNEG) children();
}
}
} else {
if (chamfer != undef) assert(chamfer <= min(size)/2, "chamfer must be smaller than half the cube width, length, or height.");
if (fillet != undef) assert(fillet <= min(size)/2, "fillet must be smaller than half the cube width, length, or height.");
majrots = [[0,90,0], [90,0,0], [0,0,0]];
orient_and_align(size, ORIENT_Z, align, center=center, noncentered=ALLPOS, chain=true) {
orient_and_anchor(size, ORIENT_Z, anchor, center=center, noncentered=ALLPOS, chain=true) {
if (chamfer != undef) {
isize = [for (v = size) max(0.001, v-2*chamfer)];
if (edges == EDGES_ALL && trimcorners) {
@ -203,102 +203,6 @@ module cuboid(
// Module: leftcube()
//
// Description:
// Makes a cube that is aligned on the left side of the origin.
//
// Usage:
// leftcube(size);
//
// Arguments:
// size = The size of the cube to make.
//
// Example:
// leftcube([20,30,40]);
module leftcube(size=[1,1,1]) {siz = scalar_vec3(size); left(siz[0]/2) cube(size=size, center=true);}
// Module: rightcube()
//
// Description:
// Makes a cube that is aligned on the right side of the origin.
//
// Usage:
// rightcube(size);
//
// Arguments:
// size = The size of the cube to make.
//
// Example:
// rightcube([20,30,40]);
module rightcube(size=[1,1,1]) {siz = scalar_vec3(size); right(siz[0]/2) cube(size=size, center=true);}
// Module: fwdcube()
//
// Description:
// Makes a cube that is aligned on the front side of the origin.
//
// Usage:
// fwdcube(size);
//
// Arguments:
// size = The size of the cube to make.
//
// Example:
// fwdcube([20,30,40]);
module fwdcube(size=[1,1,1]) {siz = scalar_vec3(size); fwd(siz[1]/2) cube(size=size, center=true);}
// Module: backcube()
//
// Description:
// Makes a cube that is aligned on the front side of the origin.
//
// Usage:
// backcube(size);
//
// Arguments:
// size = The size of the cube to make.
//
// Example:
// backcube([20,30,40]);
module backcube(size=[1,1,1]) {siz = scalar_vec3(size); back(siz[1]/2) cube(size=size, center=true);}
// Module: downcube()
//
// Description:
// Makes a cube that is aligned on the bottom side of the origin.
//
// Usage:
// downcube(size);
//
// Arguments:
// size = The size of the cube to make.
//
// Example:
// downcube([20,30,40]);
module downcube(size=[1,1,1]) {siz = scalar_vec3(size); down(siz[2]/2) cube(size=size, center=true);}
// Module: upcube()
//
// Description:
// Makes a cube that is aligned on the top side of the origin.
//
// Usage:
// upcube(size);
//
// Arguments:
// size = The size of the cube to make.
//
// Example:
// upcube([20,30,40]);
module upcube(size=[1,1,1]) {siz = scalar_vec3(size); up(siz[2]/2) cube(size=size, center=true);}
// Section: Prismoids
@ -308,7 +212,7 @@ module upcube(size=[1,1,1]) {siz = scalar_vec3(size); up(siz[2]/2) cube(size=siz
// Creates a rectangular prismoid shape.
//
// Usage:
// prismoid(size1, size2, h, [shift], [orient], [align|center]);
// prismoid(size1, size2, h, [shift], [orient], [anchor|center]);
//
// Arguments:
// size1 = [width, length] of the axis-negative end of the prism.
@ -316,8 +220,8 @@ module upcube(size=[1,1,1]) {siz = scalar_vec3(size); up(siz[2]/2) cube(size=siz
// h = Height of the prism.
// shift = [x, y] amount to shift the center of the top with respect to the center of the bottom.
// orient = Orientation of the prismoid. Use the `ORIENT_` constants from `constants.scad`. Default: `ORIENT_Z`.
// align = Alignment of the prismoid by the axis-negative (size1) end. Use the constants from `constants.scad`. Default: `UP`.
// center = If given, overrides `align`. A true value sets `align=CENTER`, false sets `align=UP`.
// anchor = Alignment of the prismoid by the axis-negative (size1) end. Use the constants from `constants.scad`. Default: `BOTTOM`.
// center = If given, overrides `anchor`. A true value sets `anchor=CENTER`, false sets `anchor=BOTTOM`.
//
// Example: Rectangular Pyramid
// prismoid(size1=[40,40], size2=[0,0], h=20);
@ -336,16 +240,16 @@ module upcube(size=[1,1,1]) {siz = scalar_vec3(size); up(siz[2]/2) cube(size=siz
// Example(FlatSpin): Shifting/Skewing
// prismoid(size1=[50,30], size2=[20,20], h=20, shift=[15,5]);
// Example(Spin): Standard Connectors
// prismoid(size1=[50,30], size2=[20,20], h=20, shift=[15,5]) show_connectors();
// prismoid(size1=[50,30], size2=[20,20], h=20, shift=[15,5]) show_anchors();
module prismoid(
size1=[1,1], size2=[1,1], h=1, shift=[0,0],
orient=ORIENT_Z, align=DOWN, center=undef
orient=ORIENT_Z, anchor=DOWN, center=undef
) {
eps = 0.001;
shiftby = point3d(point2d(shift));
s1 = [max(size1.x, eps), max(size1.y, eps)];
s2 = [max(size2.x, eps), max(size2.y, eps)];
orient_and_align([s1.x,s1.y,h], orient, align, center, size2=s2, shift=shift, noncentered=DOWN, chain=true) {
orient_and_anchor([s1.x,s1.y,h], orient, anchor, center, size2=s2, shift=shift, noncentered=DOWN, chain=true) {
polyhedron(
points=[
[+s2.x/2, +s2.y/2, +h/2] + shiftby,
@ -392,8 +296,8 @@ module prismoid(
// r2 = radius of vertical edge fillets at top.
// shift = [x, y] amount to shift the center of the top with respect to the center of the bottom.
// orient = Orientation of the prismoid. Use the `ORIENT_` constants from `constants.scad`. Default: `ORIENT_Z`.
// align = Alignment of the prismoid by the axis-negative (`size1`) end. Use the constants from `constants.scad`. Default: `UP`.
// center = vertically center the prism. Overrides `align`.
// anchor = Alignment of the prismoid by the axis-negative (`size1`) end. Use the constants from `constants.scad`. Default: `BOTTOM`.
// center = vertically center the prism. Overrides `anchor`.
//
// Example: Rounded Pyramid
// rounded_prismoid(size1=[40,40], size2=[0,0], h=25, r=5);
@ -404,11 +308,11 @@ module prismoid(
// Example(FlatSpin): Shifting/Skewing
// rounded_prismoid(size1=[50,30], size2=[20,20], h=20, shift=[15,5], r=5);
// Example(Spin): Standard Connectors
// rounded_prismoid(size1=[40,60], size2=[40,60], h=20, r1=3, r2=10, $fn=24) show_connectors();
// rounded_prismoid(size1=[40,60], size2=[40,60], h=20, r1=3, r2=10, $fn=24) show_anchors();
module rounded_prismoid(
size1, size2, h, shift=[0,0],
r=undef, r1=undef, r2=undef,
align=DOWN, orient=ORIENT_Z, center=undef
anchor=BOTTOM, orient=ORIENT_Z, center=undef
) {
eps = 0.001;
maxrad1 = min(size1.x/2, size1.y/2);
@ -416,7 +320,7 @@ module rounded_prismoid(
rr1 = min(maxrad1, (r1!=undef)? r1 : r);
rr2 = min(maxrad2, (r2!=undef)? r2 : r);
shiftby = point3d(shift);
orient_and_align([size1.x, size1.y, h], orient, align, center, size2=size2, shift=shift, noncentered=UP, chain=true) {
orient_and_anchor([size1.x, size1.y, h], orient, anchor, center, size2=size2, shift=shift, noncentered=UP, chain=true) {
down(h/2) {
hull() {
linear_extrude(height=eps, center=false, convexity=2) {
@ -447,24 +351,24 @@ module rounded_prismoid(
// Creates a 3D right triangular prism.
//
// Usage:
// right_triangle(size, [orient], [align|center]);
// right_triangle(size, [orient], [anchor|center]);
//
// Arguments:
// size = [width, thickness, height]
// orient = The axis to place the hypotenuse along. Only accepts `ORIENT_X`, `ORIENT_Y`, or `ORIENT_Z` from `constants.scad`. Default: `ORIENT_Y`.
// align = The side of the origin to align to. Use constants from `constants.scad`. Default: `ALLNEG`.
// center = If given, overrides `align`. A true value sets `align=CENTER`, false sets `align=ALLNEG`.
// anchor = The side of the origin to anchor to. Use constants from `constants.scad`. Default: `ALLNEG`.
// center = If given, overrides `anchor`. A true value sets `anchor=CENTER`, false sets `anchor=ALLNEG`.
//
// Example: Centered
// right_triangle([60, 10, 40], center=true);
// Example: *Non*-Centered
// right_triangle([60, 10, 40]);
// Example: Standard Connectors
// right_triangle([60, 15, 40]) show_connectors();
module right_triangle(size=[1, 1, 1], orient=ORIENT_Y, align=ALLNEG, center=undef)
// right_triangle([60, 15, 40]) show_anchors();
module right_triangle(size=[1, 1, 1], orient=ORIENT_Y, anchor=ALLNEG, center=undef)
{
size = scalar_vec3(size);
orient_and_align(size, align=align, center=center, chain=true) {
orient_and_anchor(size, anchor=anchor, center=center, chain=true) {
if (orient == ORIENT_X) {
ang = atan2(size.y, size.z);
masksize = [size.x, size.y, norm([size.y,size.z])] + [1,1,1];
@ -505,7 +409,7 @@ module right_triangle(size=[1, 1, 1], orient=ORIENT_Y, align=ALLNEG, center=unde
// Module: cyl()
//
// Description:
// Creates cylinders in various alignments and orientations,
// Creates cylinders in various anchors and orientations,
// with optional fillets and chamfers. You can use `r` and `l`
// interchangably, and all variants allow specifying size
// by either `r`|`d`, or `r1`|`d1` and `r2`|`d2`.
@ -513,20 +417,20 @@ module right_triangle(size=[1, 1, 1], orient=ORIENT_Y, align=ALLNEG, center=unde
// midpoint of the cylinder's length.
//
// Usage: Normal Cylinders
// cyl(l|h, r|d, [circum], [realign], [orient], [align], [center]);
// cyl(l|h, r1|d1, r2/d2, [circum], [realign], [orient], [align], [center]);
// cyl(l|h, r|d, [circum], [realign], [orient], [anchor], [center]);
// cyl(l|h, r1|d1, r2/d2, [circum], [realign], [orient], [anchor], [center]);
//
// Usage: Chamferred Cylinders
// cyl(l|h, r|d, chamfer, [chamfang], [from_end], [circum], [realign], [orient], [align], [center]);
// cyl(l|h, r|d, chamfer1, [chamfang1], [from_end], [circum], [realign], [orient], [align], [center]);
// cyl(l|h, r|d, chamfer2, [chamfang2], [from_end], [circum], [realign], [orient], [align], [center]);
// cyl(l|h, r|d, chamfer1, chamfer2, [chamfang1], [chamfang2], [from_end], [circum], [realign], [orient], [align], [center]);
// cyl(l|h, r|d, chamfer, [chamfang], [from_end], [circum], [realign], [orient], [anchor], [center]);
// cyl(l|h, r|d, chamfer1, [chamfang1], [from_end], [circum], [realign], [orient], [anchor], [center]);
// cyl(l|h, r|d, chamfer2, [chamfang2], [from_end], [circum], [realign], [orient], [anchor], [center]);
// cyl(l|h, r|d, chamfer1, chamfer2, [chamfang1], [chamfang2], [from_end], [circum], [realign], [orient], [anchor], [center]);
//
// Usage: Rounded/Filleted Cylinders
// cyl(l|h, r|d, fillet, [circum], [realign], [orient], [align], [center]);
// cyl(l|h, r|d, fillet1, [circum], [realign], [orient], [align], [center]);
// cyl(l|h, r|d, fillet2, [circum], [realign], [orient], [align], [center]);
// cyl(l|h, r|d, fillet1, fillet2, [circum], [realign], [orient], [align], [center]);
// cyl(l|h, r|d, fillet, [circum], [realign], [orient], [anchor], [center]);
// cyl(l|h, r|d, fillet1, [circum], [realign], [orient], [anchor], [center]);
// cyl(l|h, r|d, fillet2, [circum], [realign], [orient], [anchor], [center]);
// cyl(l|h, r|d, fillet1, fillet2, [circum], [realign], [orient], [anchor], [center]);
//
// Arguments:
// l / h = Length of cylinder along oriented axis. (Default: 1.0)
@ -549,8 +453,8 @@ module right_triangle(size=[1, 1, 1], orient=ORIENT_Y, align=ALLNEG, center=unde
// fillet2 = The radius of the fillet on the axis-positive end of the cylinder.
// realign = If true, rotate the cylinder by half the angle of one face.
// orient = Orientation of the cylinder. Use the `ORIENT_` constants from `constants.scad`. Default: vertical.
// align = Alignment of the cylinder. Use the constants from `constants.scad`. Default: centered.
// center = If given, overrides `align`. A true value sets `align=CENTER`, false sets `align=DOWN`.
// anchor = Alignment of the cylinder. Use the constants from `constants.scad`. Default: centered.
// center = If given, overrides `anchor`. A true value sets `anchor=CENTER`, false sets `anchor=DOWN`.
//
// Example: By Radius
// xdistribute(30) {
@ -588,8 +492,8 @@ module right_triangle(size=[1, 1, 1], orient=ORIENT_Y, align=ALLNEG, center=unde
//
// Example: Standard Connectors
// xdistribute(40) {
// cyl(l=30, d=25) show_connectors();
// cyl(l=30, d1=25, d2=10) show_connectors();
// cyl(l=30, d=25) show_anchors();
// cyl(l=30, d1=25, d2=10) show_anchors();
// }
//
module cyl(
@ -600,7 +504,7 @@ module cyl(
chamfang=undef, chamfang1=undef, chamfang2=undef,
fillet=undef, fillet1=undef, fillet2=undef,
circum=false, realign=false, from_end=false,
orient=ORIENT_Z, align=CENTER, center=undef
orient=ORIENT_Z, anchor=CENTER, center=undef
) {
r1 = get_radius(r1, r, d1, d, 1);
r2 = get_radius(r2, r, d2, d, 1);
@ -610,7 +514,7 @@ module cyl(
sides = segs(max(r1,r2));
sc = circum? 1/cos(180/sides) : 1;
phi = atan2(l, r1-r2);
orient_and_align(size1, orient, align, center=center, size2=size2, geometry="cylinder", chain=true) {
orient_and_anchor(size1, orient, anchor, center=center, size2=size2, geometry="cylinder", chain=true) {
zrot(realign? 180/sides : 0) {
if (!any_defined([chamfer, chamfer1, chamfer2, fillet, fillet1, fillet2])) {
cylinder(h=l, r1=r1*sc, r2=r2*sc, center=true, $fn=sides);
@ -743,8 +647,8 @@ module cyl(
// Creates a cylinder oriented along the X axis.
//
// Usage:
// xcyl(l|h, r|d, [align|center]);
// xcyl(l|h, r1|d1, r2|d2, [align|center]);
// xcyl(l|h, r|d, [anchor|center]);
// xcyl(l|h, r1|d1, r2|d2, [anchor|center]);
//
// Arguments:
// l / h = Length of cylinder along oriented axis. (Default: `1.0`)
@ -754,8 +658,8 @@ module cyl(
// d = Optional diameter of cylinder. (use instead of `r`)
// d1 = Optional diameter of left (X-) end of cylinder.
// d2 = Optional diameter of right (X+) end of cylinder.
// align = The side of the origin to align to. Use constants from `constants.scad`. Default: `CENTER`
// center = If given, overrides `align`. A `true` value sets `align=CENTER`, `false` sets `align=BOTTOM`.
// anchor = The side of the origin to anchor to. Use constants from `constants.scad`. Default: `CENTER`
// center = If given, overrides `anchor`. A `true` value sets `anchor=CENTER`, `false` sets `anchor=BOTTOM`.
//
// Example: By Radius
// ydistribute(50) {
@ -768,9 +672,9 @@ module cyl(
// xcyl(l=35, d=20);
// xcyl(l=35, d1=30, d2=10);
// }
module xcyl(l=undef, r=undef, d=undef, r1=undef, r2=undef, d1=undef, d2=undef, h=undef, align=CENTER, center=undef)
module xcyl(l=undef, r=undef, d=undef, r1=undef, r2=undef, d1=undef, d2=undef, h=undef, anchor=CENTER, center=undef)
{
cyl(l=l, h=h, r=r, r1=r1, r2=r2, d=d, d1=d1, d2=d2, orient=ORIENT_X, align=align, center=center) children();
cyl(l=l, h=h, r=r, r1=r1, r2=r2, d=d, d1=d1, d2=d2, orient=ORIENT_X, anchor=anchor, center=center) children();
}
@ -781,8 +685,8 @@ module xcyl(l=undef, r=undef, d=undef, r1=undef, r2=undef, d1=undef, d2=undef, h
// Creates a cylinder oriented along the Y axis.
//
// Usage:
// ycyl(l|h, r|d, [align|center]);
// ycyl(l|h, r1|d1, r2|d2, [align|center]);
// ycyl(l|h, r|d, [anchor|center]);
// ycyl(l|h, r1|d1, r2|d2, [anchor|center]);
//
// Arguments:
// l / h = Length of cylinder along oriented axis. (Default: `1.0`)
@ -792,8 +696,8 @@ module xcyl(l=undef, r=undef, d=undef, r1=undef, r2=undef, d1=undef, d2=undef, h
// d = Diameter of cylinder.
// d1 = Diameter of front (Y-) end of one.
// d2 = Diameter of back (Y+) end of one.
// align = The side of the origin to align to. Use constants from `constants.scad`. Default: `CENTER`
// center = Overrides `align` if given. If true, `align=CENTER`, if false, `align=UP`.
// anchor = The side of the origin to anchor to. Use constants from `constants.scad`. Default: `CENTER`
// center = Overrides `anchor` if given. If true, `anchor=CENTER`, if false, `anchor=UP`.
//
// Example: By Radius
// xdistribute(50) {
@ -806,9 +710,9 @@ module xcyl(l=undef, r=undef, d=undef, r1=undef, r2=undef, d1=undef, d2=undef, h
// ycyl(l=35, d=20);
// ycyl(l=35, d1=30, d2=10);
// }
module ycyl(l=undef, r=undef, d=undef, r1=undef, r2=undef, d1=undef, d2=undef, h=undef, align=CENTER, center=undef)
module ycyl(l=undef, r=undef, d=undef, r1=undef, r2=undef, d1=undef, d2=undef, h=undef, anchor=CENTER, center=undef)
{
cyl(l=l, h=h, r=r, r1=r1, r2=r2, d=d, d1=d1, d2=d2, orient=ORIENT_Y, align=align, center=center) children();
cyl(l=l, h=h, r=r, r1=r1, r2=r2, d=d, d1=d1, d2=d2, orient=ORIENT_Y, anchor=anchor, center=center) children();
}
@ -819,8 +723,8 @@ module ycyl(l=undef, r=undef, d=undef, r1=undef, r2=undef, d1=undef, d2=undef, h
// Creates a cylinder oriented along the Z axis.
//
// Usage:
// zcyl(l|h, r|d, [align|center]);
// zcyl(l|h, r1|d1, r2|d2, [align|center]);
// zcyl(l|h, r|d, [anchor|center]);
// zcyl(l|h, r1|d1, r2|d2, [anchor|center]);
//
// Arguments:
// l / h = Length of cylinder along oriented axis. (Default: 1.0)
@ -830,8 +734,8 @@ module ycyl(l=undef, r=undef, d=undef, r1=undef, r2=undef, d1=undef, d2=undef, h
// d = Diameter of cylinder.
// d1 = Diameter of front (Y-) end of one.
// d2 = Diameter of back (Y+) end of one.
// align = The side of the origin to align to. Use constants from `constants.scad`. Default: `CENTER`
// center = Overrides `align` if given. If true, `align=CENTER`, if false, `align=UP`.
// anchor = The side of the origin to anchor to. Use constants from `constants.scad`. Default: `CENTER`
// center = Overrides `anchor` if given. If true, `anchor=CENTER`, if false, `anchor=UP`.
//
// Example: By Radius
// xdistribute(50) {
@ -844,9 +748,9 @@ module ycyl(l=undef, r=undef, d=undef, r1=undef, r2=undef, d1=undef, d2=undef, h
// zcyl(l=35, d=20);
// zcyl(l=35, d1=30, d2=10);
// }
module zcyl(l=undef, r=undef, d=undef, r1=undef, r2=undef, d1=undef, d2=undef, h=undef, align=CENTER, center=undef)
module zcyl(l=undef, r=undef, d=undef, r1=undef, r2=undef, d1=undef, d2=undef, h=undef, anchor=CENTER, center=undef)
{
cyl(l=l, h=h, r=r, r1=r1, r2=r2, d=d, d1=d1, d2=d2, orient=ORIENT_Z, align=align, center=center) children();
cyl(l=l, h=h, r=r, r1=r1, r2=r2, d=d, d1=d1, d2=d2, orient=ORIENT_Z, anchor=anchor, center=center) children();
}
@ -857,12 +761,12 @@ module zcyl(l=undef, r=undef, d=undef, r1=undef, r2=undef, d1=undef, d2=undef, h
// Makes a hollow tube with the given outer size and wall thickness.
//
// Usage:
// tube(h, ir|id, wall, [realign], [orient], [align]);
// tube(h, or|od, wall, [realign], [orient], [align]);
// tube(h, ir|id, or|od, [realign], [orient], [align]);
// tube(h, ir1|id1, ir2|id2, wall, [realign], [orient], [align]);
// tube(h, or1|od1, or2|od2, wall, [realign], [orient], [align]);
// tube(h, ir1|id1, ir2|id2, or1|od1, or2|od2, [realign], [orient], [align]);
// tube(h, ir|id, wall, [realign], [orient], [anchor]);
// tube(h, or|od, wall, [realign], [orient], [anchor]);
// tube(h, ir|id, or|od, [realign], [orient], [anchor]);
// tube(h, ir1|id1, ir2|id2, wall, [realign], [orient], [anchor]);
// tube(h, or1|od1, or2|od2, wall, [realign], [orient], [anchor]);
// tube(h, ir1|id1, ir2|id2, or1|od1, or2|od2, [realign], [orient], [anchor]);
//
// Arguments:
// h = height of tube. (Default: 1)
@ -881,7 +785,7 @@ module zcyl(l=undef, r=undef, d=undef, r1=undef, r2=undef, d1=undef, d2=undef, h
// id2 = Inner diameter of top of tube.
// realign = If true, rotate the tube by half the angle of one face.
// orient = Orientation of the tube. Use the `ORIENT_` constants from `constants.scad`. Default: vertical.
// align = Alignment of the tube. Use the constants from `constants.scad`. Default: centered.
// anchor = Alignment of the tube. Use the constants from `constants.scad`. Default: centered.
//
// Example: These all Produce the Same Tube
// tube(h=30, or=40, wall=5);
@ -895,7 +799,7 @@ module zcyl(l=undef, r=undef, d=undef, r1=undef, r2=undef, d1=undef, d2=undef, h
// Example: Circular Wedge
// tube(h=30, or1=40, or2=30, ir1=20, ir2=30);
// Example: Standard Connectors
// tube(h=30, or=40, wall=5) show_connectors();
// tube(h=30, or=40, wall=5) show_anchors();
module tube(
h=1, wall=undef,
r=undef, r1=undef, r2=undef,
@ -904,7 +808,7 @@ module tube(
od=undef, od1=undef, od2=undef,
ir=undef, id=undef, ir1=undef,
ir2=undef, id1=undef, id2=undef,
center=undef, orient=ORIENT_Z, align=UP,
center=undef, orient=ORIENT_Z, anchor=UP,
realign=false
) {
r1 = first_defined([or1, od1/2, r1, d1/2, or, od/2, r, d/2, ir1+wall, id1/2+wall, ir+wall, id/2+wall]);
@ -916,7 +820,7 @@ module tube(
sides = segs(max(r1,r2));
size = [r1*2,r1*2,h];
size2 = [r2*2,r2*2,h];
orient_and_align(size, orient, align, center=center, size2=size2, geometry="cylinder", chain=true) {
orient_and_anchor(size, orient, anchor, center=center, size2=size2, geometry="cylinder", chain=true) {
zrot(realign? 180/sides : 0) {
difference() {
cyl(h=h, r1=r1, r2=r2, $fn=sides) children();
@ -934,8 +838,8 @@ module tube(
// Creates a torus shape.
//
// Usage:
// torus(r|d, r2|d2, [orient], [align]);
// torus(or|od, ir|id, [orient], [align]);
// torus(r|d, r2|d2, [orient], [anchor]);
// torus(or|od, ir|id, [orient], [anchor]);
//
// Arguments:
// r = major radius of torus ring. (use with of 'r2', or 'd2')
@ -947,7 +851,7 @@ module tube(
// od = outer diameter of the torus. (use with 'ir' or 'id')
// id = inside diameter of the torus. (use with 'or' or 'od')
// orient = Orientation of the torus. Use the `ORIENT_` constants from `constants.scad`. Default: `ORIENT_Z`.
// align = Alignment of the torus. Use the constants from `constants.scad`. Default: `CENTER`.
// anchor = Alignment of the torus. Use the constants from `constants.scad`. Default: `CENTER`.
//
// Example:
// // These all produce the same torus.
@ -956,20 +860,20 @@ module tube(
// torus(or=30, ir=15);
// torus(od=60, id=30);
// Example: Standard Connectors
// torus(od=60, id=30) show_connectors();
// torus(od=60, id=30) show_anchors();
module torus(
r=undef, d=undef,
r2=undef, d2=undef,
or=undef, od=undef,
ir=undef, id=undef,
orient=ORIENT_Z, align=CENTER, center=undef
orient=ORIENT_Z, anchor=CENTER, center=undef
) {
orr = get_radius(r=or, d=od, dflt=1.0);
irr = get_radius(r=ir, d=id, dflt=0.5);
majrad = get_radius(r=r, d=d, dflt=(orr+irr)/2);
minrad = get_radius(r=r2, d=d2, dflt=(orr-irr)/2);
size = [(majrad+minrad)*2, (majrad+minrad)*2, minrad*2];
orient_and_align(size, orient, align, center=center, geometry="cylinder", chain=true) {
orient_and_anchor(size, orient, anchor, center=center, geometry="cylinder", chain=true) {
rotate_extrude(convexity=4) {
right(majrad) circle(minrad);
}
@ -984,7 +888,7 @@ module torus(
// Module: spheroid()
// Description:
// An version of `sphere()` with connector points, orientation, and alignment.
// An version of `sphere()` with anchors points and orientation.
// Usage:
// spheroid(r|d, [circum])
// Arguments:
@ -992,21 +896,21 @@ module torus(
// d = Diameter of the sphere.
// circum = If true, circumscribes the perfect sphere of the given radius/diameter.
// orient = Orientation of the sphere, if you don't like where the vertices lay. Use the `ORIENT_` constants from `constants.scad`. Default: `ORIENT_Z`.
// align = Alignment of the sphere. Use the constants from `constants.scad`. Default: `CENTER`.
// anchor = Alignment of the sphere. Use the constants from `constants.scad`. Default: `CENTER`.
// Example: By Radius
// spheroid(r=50, circum=true);
// Example: By Diameter
// spheroid(d=100, circum=true);
// Example: Standard Connectors
// spheroid(d=40, circum=true) show_connectors();
module spheroid(r=undef, d=undef, circum=false, orient=UP, align=CENTER)
// spheroid(d=40, circum=true) show_anchors();
module spheroid(r=undef, d=undef, circum=false, orient=UP, anchor=CENTER)
{
r = get_radius(r=r, d=d, dflt=1);
hsides = segs(r);
vsides = ceil(hsides/2);
rr = circum? (r / cos(90/vsides) / cos(180/hsides)) : r;
size = [2*rr, 2*rr, 2*rr];
orient_and_align(size, orient, align, geometry="sphere", chain=true) {
orient_and_anchor(size, orient, anchor, geometry="sphere", chain=true) {
sphere(r=rr);
children();
}
@ -1027,15 +931,15 @@ module spheroid(r=undef, d=undef, circum=false, orient=UP, align=CENTER)
// d = Diameter of the sphere.
// circum = If true, circumscribes the perfect sphere of the given size.
// orient = Orientation of the sphere, if you don't like where the vertices lay. Use the `ORIENT_` constants from `constants.scad`. Default: `ORIENT_Z`.
// align = Alignment of the sphere. Use the constants from `constants.scad`. Default: `CENTER`.
// anchor = Alignment of the sphere. Use the constants from `constants.scad`. Default: `CENTER`.
//
// Example: By Radius
// staggered_sphere(r=50, circum=true);
// Example: By Diameter
// staggered_sphere(d=100, circum=true);
// Example: Standard Connectors
// staggered_sphere(d=40, circum=true) show_connectors();
module staggered_sphere(r=undef, d=undef, circum=false, orient=UP, align=CENTER) {
// staggered_sphere(d=40, circum=true) show_anchors();
module staggered_sphere(r=undef, d=undef, circum=false, orient=UP, anchor=CENTER) {
r = get_radius(r=r, d=d, dflt=1);
sides = segs(r);
vsides = max(3, ceil(sides/2))+1;
@ -1072,7 +976,7 @@ module staggered_sphere(r=undef, d=undef, circum=false, orient=UP, align=CENTER)
]
);
size = [2*rr, 2*rr, 2*rr];
orient_and_align(size, orient, align, geometry="sphere", chain=true) {
orient_and_anchor(size, orient, anchor, geometry="sphere", chain=true) {
polyhedron(points=pts, faces=faces);
children();
}
@ -1128,7 +1032,7 @@ module teardrop2d(r=1, d=undef, ang=45, cap_h=undef)
// Makes a teardrop shape in the XZ plane. Useful for 3D printable holes.
//
// Usage:
// teardrop(r|d, l|h, [ang], [cap_h], [orient], [align])
// teardrop(r|d, l|h, [ang], [cap_h], [orient], [anchor])
//
// Arguments:
// r = Radius of circular part of teardrop. (Default: 1)
@ -1137,7 +1041,7 @@ module teardrop2d(r=1, d=undef, ang=45, cap_h=undef)
// ang = Angle of hat walls from the Z axis. (Default: 45 degrees)
// cap_h = If given, height above center where the shape will be truncated.
// orient = Orientation of the shape. Use the `ORIENT_` constants from `constants.scad`. Default: `ORIENT_Y`.
// align = Alignment of the shape. Use the constants from `constants.scad`. Default: `CENTER`.
// anchor = Alignment of the shape. Use the constants from `constants.scad`. Default: `CENTER`.
//
// Example: Typical Shape
// teardrop(r=30, h=10, ang=30);
@ -1145,12 +1049,12 @@ module teardrop2d(r=1, d=undef, ang=45, cap_h=undef)
// teardrop(r=30, h=10, ang=30, cap_h=40);
// Example: Close Crop
// teardrop(r=30, h=10, ang=30, cap_h=20);
module teardrop(r=undef, d=undef, l=undef, h=undef, ang=45, cap_h=undef, orient=ORIENT_Y, align=CENTER)
module teardrop(r=undef, d=undef, l=undef, h=undef, ang=45, cap_h=undef, orient=ORIENT_Y, anchor=CENTER)
{
r = get_radius(r=r, d=d, dflt=1);
l = first_defined([l, h, 1]);
size = [r*2,r*2,l];
orient_and_align(size, orient, align, geometry="cylinder", chain=true) {
orient_and_anchor(size, orient, anchor, geometry="cylinder", chain=true) {
linear_extrude(height=l, center=true, slices=2) {
teardrop2d(r=r, ang=ang, cap_h=cap_h);
}
@ -1165,7 +1069,7 @@ module teardrop(r=undef, d=undef, l=undef, h=undef, ang=45, cap_h=undef, orient=
// Creates a sphere with a conical hat, to make a 3D teardrop.
//
// Usage:
// onion(r|d, [maxang], [cap_h], [orient], [align]);
// onion(r|d, [maxang], [cap_h], [orient], [anchor]);
//
// Arguments:
// r = radius of spherical portion of the bottom. (Default: 1)
@ -1173,7 +1077,7 @@ module teardrop(r=undef, d=undef, l=undef, h=undef, ang=45, cap_h=undef, orient=
// cap_h = height above sphere center to truncate teardrop shape.
// maxang = angle of cone on top from vertical.
// orient = Orientation of the shape. Use the `ORIENT_` constants from `constants.scad`. Default: `ORIENT_Y`.
// align = Alignment of the shape. Use the constants from `constants.scad`. Default: `CENTER`.
// anchor = Alignment of the shape. Use the constants from `constants.scad`. Default: `CENTER`.
//
// Example: Typical Shape
// onion(r=30, maxang=30);
@ -1182,17 +1086,17 @@ module teardrop(r=undef, d=undef, l=undef, h=undef, ang=45, cap_h=undef, orient=
// Example: Close Crop
// onion(r=30, maxang=30, cap_h=20);
// Example: Standard Connectors
// onion(r=30, maxang=30, cap_h=40) show_connectors();
module onion(cap_h=undef, r=undef, d=undef, maxang=45, h=undef, orient=ORIENT_Z, align=CENTER)
// onion(r=30, maxang=30, cap_h=40) show_anchors();
module onion(cap_h=undef, r=undef, d=undef, maxang=45, h=undef, orient=ORIENT_Z, anchor=CENTER)
{
r = get_radius(r=r, d=d, dflt=1);
h = first_defined([cap_h, h]);
maxd = 3*r/tan(maxang);
size = [r*2,r*2,r*2];
alignments = [
anchors = [
["cap", [0,0,h], UP, 0]
];
orient_and_align(size, orient, align, geometry="sphere", alignments=alignments, chain=true) {
orient_and_anchor(size, orient, anchor, geometry="sphere", anchors=anchors, chain=true) {
rotate_extrude(convexity=2) {
difference() {
teardrop2d(r=r, ang=maxang, cap_h=h);
@ -1213,7 +1117,7 @@ module onion(cap_h=undef, r=undef, d=undef, maxang=45, h=undef, orient=ORIENT_Z,
// overhangs.
//
// Usage:
// narrowing_strut(w, l, wall, [ang], [orient], [align]);
// narrowing_strut(w, l, wall, [ang], [orient], [anchor]);
//
// Arguments:
// w = Width (thickness) of the strut.
@ -1221,15 +1125,15 @@ module onion(cap_h=undef, r=undef, d=undef, maxang=45, h=undef, orient=ORIENT_Z,
// wall = height of rectangular portion of the strut.
// ang = angle that the trianglar side will converge at.
// orient = Orientation of the length axis of the shape. Use the `ORIENT_` constants from `constants.scad`. Default: `ORIENT_Y`.
// align = Alignment of the shape. Use the constants from `constants.scad`. Default: `CENTER`.
// anchor = Alignment of the shape. Use the constants from `constants.scad`. Default: `CENTER`.
//
// Example:
// narrowing_strut(w=10, l=100, wall=5, ang=30);
module narrowing_strut(w=10, l=100, wall=5, ang=30, orient=ORIENT_Y, align=UP)
module narrowing_strut(w=10, l=100, wall=5, ang=30, orient=ORIENT_Y, anchor=UP)
{
h = wall + w/2/tan(ang);
size = [w, h, l];
orient_and_align(size, orient, align, chain=true) {
orient_and_anchor(size, orient, anchor, chain=true) {
fwd(h/2) {
linear_extrude(height=l, center=true, slices=2) {
back(wall/2) square([w, wall], center=true);
@ -1255,7 +1159,7 @@ module narrowing_strut(w=10, l=100, wall=5, ang=30, orient=ORIENT_Y, align=UP)
// with angled supports to prevent critical overhangs.
//
// Usage:
// thinning_wall(h, l, thick, [ang], [strut], [wall], [orient], [align]);
// thinning_wall(h, l, thick, [ang], [strut], [wall], [orient], [anchor]);
//
// Arguments:
// h = height of wall.
@ -1265,13 +1169,13 @@ module narrowing_strut(w=10, l=100, wall=5, ang=30, orient=ORIENT_Y, align=UP)
// strut = the width of the diagonal brace.
// wall = the thickness of the thinned portion of the wall.
// orient = Orientation of the length axis of the wall. Use the `ORIENT_` constants from `constants.scad`. Default: `ORIENT_X`.
// align = Alignment of the shape. Use the constants from `constants.scad`. Default: `CENTER`.
// anchor = Alignment of the shape. Use the constants from `constants.scad`. Default: `CENTER`.
//
// Example: Typical Shape
// thinning_wall(h=50, l=80, thick=4);
// Example: Trapezoidal
// thinning_wall(h=50, l=[80,50], thick=4);
module thinning_wall(h=50, l=100, thick=5, ang=30, strut=5, wall=2, orient=ORIENT_Z, align=CENTER)
module thinning_wall(h=50, l=100, thick=5, ang=30, strut=5, wall=2, orient=ORIENT_Z, anchor=CENTER)
{
l1 = (l[0] == undef)? l : l[0];
l2 = (l[1] == undef)? l : l[1];
@ -1295,7 +1199,7 @@ module thinning_wall(h=50, l=100, thick=5, ang=30, strut=5, wall=2, orient=ORIEN
y2 = y1 - min(z2-z3, x2-x3) * sin(ang);
size = [l1, thick, h];
orient_and_align(size, orient, align, size2=[l2,thick], chain=true) {
orient_and_anchor(size, orient, anchor, size2=[l2,thick], chain=true) {
polyhedron(
points=[
[-x4, -y1, -z1],
@ -1399,7 +1303,7 @@ module thinning_wall(h=50, l=100, thick=5, ang=30, strut=5, wall=2, orient=ORIEN
// with angled supports to prevent critical overhangs.
//
// Usage:
// braced_thinning_wall(h, l, thick, [ang], [strut], [wall], [orient], [align]);
// braced_thinning_wall(h, l, thick, [ang], [strut], [wall], [orient], [anchor]);
//
// Arguments:
// h = height of wall.
@ -1409,16 +1313,16 @@ module thinning_wall(h=50, l=100, thick=5, ang=30, strut=5, wall=2, orient=ORIEN
// strut = the width of the diagonal brace.
// wall = the thickness of the thinned portion of the wall.
// orient = Orientation of the length axis of the wall. Use the `ORIENT_` constants from `constants.scad`. Default: `ORIENT_Y`.
// align = Alignment of the shape. Use the constants from `constants.scad`. Default: `CENTER`.
// anchor = Alignment of the shape. Use the constants from `constants.scad`. Default: `CENTER`.
//
// Example: Typical Shape
// braced_thinning_wall(h=50, l=100, thick=5);
module braced_thinning_wall(h=50, l=100, thick=5, ang=30, strut=5, wall=2, orient=ORIENT_Y, align=CENTER)
module braced_thinning_wall(h=50, l=100, thick=5, ang=30, strut=5, wall=2, orient=ORIENT_Y, anchor=CENTER)
{
dang = atan((h-2*strut)/(l-2*strut));
dlen = (h-2*strut)/sin(dang);
size = [l, thick, h];
orient_and_align(size, orient, align, orig_orient=ORIENT_Y, chain=true) {
orient_and_anchor(size, orient, anchor, orig_orient=ORIENT_Y, chain=true) {
union() {
xrot_copies([0, 180]) {
down(h/2) narrowing_strut(w=thick, l=l, wall=strut, ang=ang);
@ -1450,7 +1354,7 @@ module braced_thinning_wall(h=50, l=100, thick=5, ang=30, strut=5, wall=2, orien
// the center, with angled supports to prevent critical overhangs.
//
// Usage:
// thinning_triangle(h, l, thick, [ang], [strut], [wall], [diagonly], [orient], [align|center]);
// thinning_triangle(h, l, thick, [ang], [strut], [wall], [diagonly], [orient], [anchor|center]);
//
// Arguments:
// h = height of wall.
@ -1461,8 +1365,8 @@ module braced_thinning_wall(h=50, l=100, thick=5, ang=30, strut=5, wall=2, orien
// wall = the thickness of the thinned portion of the wall.
// diagonly = boolean, which denotes only the diagonal side (hypotenuse) should be thick.
// orient = Orientation of the length axis of the shape. Use the `ORIENT_` constants from `constants.scad`. Default: `ORIENT_Y`.
// align = Alignment of the shape. Use the constants from `constants.scad`. Default: `CENTER`.
// center = If true, centers shape. If false, overrides `align` with `UP+BACK`.
// anchor = Alignment of the shape. Use the constants from `constants.scad`. Default: `CENTER`.
// center = If true, centers shape. If false, overrides `anchor` with `UP+BACK`.
//
// Example: Centered
// thinning_triangle(h=50, l=80, thick=4, ang=30, strut=5, wall=2, center=true);
@ -1470,12 +1374,12 @@ module braced_thinning_wall(h=50, l=100, thick=5, ang=30, strut=5, wall=2, orien
// thinning_triangle(h=50, l=80, thick=4, ang=30, strut=5, wall=2, center=false);
// Example: Diagonal Brace Only
// thinning_triangle(h=50, l=80, thick=4, ang=30, strut=5, wall=2, diagonly=true, center=false);
module thinning_triangle(h=50, l=100, thick=5, ang=30, strut=5, wall=3, diagonly=false, center=undef, orient=ORIENT_Y, align=CENTER)
module thinning_triangle(h=50, l=100, thick=5, ang=30, strut=5, wall=3, diagonly=false, center=undef, orient=ORIENT_Y, anchor=CENTER)
{
dang = atan(h/l);
dlen = h/sin(dang);
size = [thick, l, h];
orient_and_align(size, orient, align, center=center, noncentered=UP+BACK, orig_orient=ORIENT_Y, chain=true) {
orient_and_anchor(size, orient, anchor, center=center, noncentered=UP+BACK, orig_orient=ORIENT_Y, chain=true) {
difference() {
union() {
if (!diagonly) {
@ -1510,7 +1414,7 @@ module thinning_triangle(h=50, l=100, thick=5, ang=30, strut=5, wall=3, diagonly
// the need for support material in 3D printing.
//
// Usage:
// sparse_strut(h, l, thick, [strut], [maxang], [max_bridge], [orient], [align])
// sparse_strut(h, l, thick, [strut], [maxang], [max_bridge], [orient], [anchor])
//
// Arguments:
// h = height of strut wall.
@ -1520,7 +1424,7 @@ module thinning_triangle(h=50, l=100, thick=5, ang=30, strut=5, wall=3, diagonly
// max_bridge = maximum bridging distance between cross-braces.
// strut = the width of the cross-braces.
// orient = Orientation of the length axis of the shape. Use the `ORIENT_` constants from `constants.scad`. Default: `ORIENT_Y`.
// align = Alignment of the shape. Use the constants from `constants.scad`. Default: `CENTER`.
// anchor = Alignment of the shape. Use the constants from `constants.scad`. Default: `CENTER`.
//
// Example: Typical Shape
// sparse_strut(h=40, l=100, thick=3);
@ -1530,7 +1434,7 @@ module thinning_triangle(h=50, l=100, thick=5, ang=30, strut=5, wall=3, diagonly
// sparse_strut(h=40, l=100, thick=3, strut=2, maxang=45);
// Example: Longer max_bridge
// sparse_strut(h=40, l=100, thick=3, strut=2, maxang=45, max_bridge=30);
module sparse_strut(h=50, l=100, thick=4, maxang=30, strut=5, max_bridge=20, orient=ORIENT_Y, align=CENTER)
module sparse_strut(h=50, l=100, thick=4, maxang=30, strut=5, max_bridge=20, orient=ORIENT_Y, anchor=CENTER)
{
zoff = h/2 - strut/2;
yoff = l/2 - strut/2;
@ -1551,7 +1455,7 @@ module sparse_strut(h=50, l=100, thick=4, maxang=30, strut=5, max_bridge=20, ori
len = zstep / cos(ang);
size = [thick, l, h];
orient_and_align(size, orient, align, orig_orient=ORIENT_Y, chain=true) {
orient_and_anchor(size, orient, anchor, orig_orient=ORIENT_Y, chain=true) {
union() {
zspread(zoff*2)
cube(size=[thick, l, strut], center=true);
@ -1572,7 +1476,7 @@ module sparse_strut(h=50, l=100, thick=4, maxang=30, strut=5, max_bridge=20, ori
// Module: sparse_strut3d()
//
// Usage:
// sparse_strut3d(h, w, l, [thick], [maxang], [max_bridge], [strut], [orient], [align]);
// sparse_strut3d(h, w, l, [thick], [maxang], [max_bridge], [strut], [orient], [anchor]);
//
// Description:
// Makes an open rectangular strut with X-shaped cross-bracing, designed to reduce the
@ -1587,7 +1491,7 @@ module sparse_strut(h=50, l=100, thick=4, maxang=30, strut=5, max_bridge=20, ori
// max_bridge = maximum bridging distance between cross-braces.
// strut = the width of the cross-braces.
// orient = Orientation of the length axis of the shape. Use the `ORIENT_` constants from `constants.scad`. Default: `ORIENT_Y`.
// align = Alignment of the shape. Use the constants from `constants.scad`. Default: `CENTER`.
// anchor = Alignment of the shape. Use the constants from `constants.scad`. Default: `CENTER`.
//
// Example: Typical Shape
// sparse_strut3d(h=30, w=30, l=100);
@ -1597,7 +1501,7 @@ module sparse_strut(h=50, l=100, thick=4, maxang=30, strut=5, max_bridge=20, ori
// sparse_strut3d(h=30, w=30, l=100, strut=2, maxang=50);
// Example: Smaller max_bridge
// sparse_strut3d(h=30, w=30, l=100, strut=2, maxang=50, max_bridge=20);
module sparse_strut3d(h=50, l=100, w=50, thick=3, maxang=40, strut=3, max_bridge=30, orient=ORIENT_Y, align=CENTER)
module sparse_strut3d(h=50, l=100, w=50, thick=3, maxang=40, strut=3, max_bridge=30, orient=ORIENT_Y, anchor=CENTER)
{
xoff = w - thick;
@ -1620,7 +1524,7 @@ module sparse_strut3d(h=50, l=100, w=50, thick=3, maxang=40, strut=3, max_bridge
supp_step = cross_len/2/supp_reps;
size = [w, l, h];
orient_and_align(size, orient, align, orig_orient=ORIENT_Y, chain=true) {
orient_and_anchor(size, orient, anchor, orig_orient=ORIENT_Y, chain=true) {
intersection() {
union() {
ybridge = (l - (yreps+1) * strut) / yreps;
@ -1674,7 +1578,7 @@ module sparse_strut3d(h=50, l=100, w=50, thick=3, maxang=40, strut=3, max_bridge
// providing support strength. Designed with 3D printing in mind.
//
// Usage:
// corrugated_wall(h, l, thick, [strut], [wall], [orient], [align]);
// corrugated_wall(h, l, thick, [strut], [wall], [orient], [anchor]);
//
// Arguments:
// h = height of strut wall.
@ -1683,7 +1587,7 @@ module sparse_strut3d(h=50, l=100, w=50, thick=3, maxang=40, strut=3, max_bridge
// strut = the width of the cross-braces.
// wall = thickness of corrugations.
// orient = Orientation of the length axis of the shape. Use the `ORIENT_` constants from `constants.scad`. Default: `ORIENT_Y`.
// align = Alignment of the shape. Use the constants from `constants.scad`. Default: `CENTER`.
// anchor = Alignment of the shape. Use the constants from `constants.scad`. Default: `CENTER`.
//
// Example: Typical Shape
// corrugated_wall(h=50, l=100);
@ -1691,7 +1595,7 @@ module sparse_strut3d(h=50, l=100, w=50, thick=3, maxang=40, strut=3, max_bridge
// corrugated_wall(h=50, l=100, strut=8);
// Example: Thicker Wall
// corrugated_wall(h=50, l=100, strut=8, wall=3);
module corrugated_wall(h=50, l=100, thick=5, strut=5, wall=2, orient=ORIENT_Y, align=CENTER)
module corrugated_wall(h=50, l=100, thick=5, strut=5, wall=2, orient=ORIENT_Y, anchor=CENTER)
{
amplitude = (thick - wall) / 2;
period = min(15, thick * 2);
@ -1699,7 +1603,7 @@ module corrugated_wall(h=50, l=100, thick=5, strut=5, wall=2, orient=ORIENT_Y, a
step = period/steps;
il = l - 2*strut + 2*step;
size = [thick, l, h];
orient_and_align(size, orient, align, orig_orient=ORIENT_Y, chain=true) {
orient_and_anchor(size, orient, anchor, orig_orient=ORIENT_Y, chain=true) {
union() {
linear_extrude(height=h-2*strut+0.1, slices=2, convexity=ceil(2*il/period), center=true) {
polygon(
@ -1734,7 +1638,7 @@ module nil() union(){}
// Description:
// Passes through the children passed to it, with no action at all.
// Useful while debugging when you want to replace a command.
module noop(orient=ORIENT_Z) orient_and_align([0,0,0], orient, CENTER, chain=true) {nil(); children();}
module noop(orient=ORIENT_Z) orient_and_anchor([0,0,0], orient, CENTER, chain=true) {nil(); children();}
// Module: pie_slice()
@ -1743,8 +1647,8 @@ module noop(orient=ORIENT_Z) orient_and_align([0,0,0], orient, CENTER, chain=tru
// Creates a pie slice shape.
//
// Usage:
// pie_slice(ang, l|h, r|d, [orient], [align|center]);
// pie_slice(ang, l|h, r1|d1, r2|d2, [orient], [align|center]);
// pie_slice(ang, l|h, r|d, [orient], [anchor|center]);
// pie_slice(ang, l|h, r1|d1, r2|d2, [orient], [anchor|center]);
//
// Arguments:
// ang = pie slice angle in degrees.
@ -1756,8 +1660,8 @@ module noop(orient=ORIENT_Z) orient_and_align([0,0,0], orient, CENTER, chain=tru
// d1 = bottom diameter of pie slice.
// d2 = top diameter of pie slice.
// orient = Orientation of the pie slice. Use the `ORIENT_` constants from `constants.scad`. Default: `ORIENT_Z`.
// align = Alignment of the pie slice. Use the constants from `constants.scad`. Default: `CENTER`.
// center = If given, overrides `align`. A true value sets `align=CENTER`, false sets `align=UP`.
// anchor = Alignment of the pie slice. Use the constants from `constants.scad`. Default: `CENTER`.
// center = If given, overrides `anchor`. A true value sets `anchor=CENTER`, false sets `anchor=UP`.
//
// Example: Cylindrical Pie Slice
// pie_slice(ang=45, l=20, r=30);
@ -1767,7 +1671,7 @@ module pie_slice(
ang=30, l=undef,
r=10, r1=undef, r2=undef,
d=undef, d1=undef, d2=undef,
orient=ORIENT_Z, align=UP,
orient=ORIENT_Z, anchor=UP,
center=undef, h=undef
) {
l = first_defined([l, h, 1]);
@ -1775,7 +1679,7 @@ module pie_slice(
r2 = get_radius(r2, r, d2, d, 10);
maxd = max(r1,r2)+0.1;
size = [2*r1, 2*r1, l];
orient_and_align(size, orient, align, center=center, geometry="cylinder", chain=true) {
orient_and_anchor(size, orient, anchor, center=center, geometry="cylinder", chain=true) {
difference() {
cylinder(r1=r1, r2=r2, h=l, center=true);
if (ang<180) rotate(ang) back(maxd/2) cube([2*maxd, maxd, l+0.1], center=true);
@ -1796,7 +1700,7 @@ module pie_slice(
// Center this part along the concave edge to be chamferred and union it in.
//
// Usage:
// interior_fillet(l, r, [ang], [overlap], [orient], [align]);
// interior_fillet(l, r, [ang], [overlap], [orient], [anchor]);
//
// Arguments:
// l = length of edge to fillet.
@ -1804,7 +1708,7 @@ module pie_slice(
// ang = angle between faces to fillet.
// overlap = overlap size for unioning with faces.
// orient = Orientation of the fillet. Use the `ORIENT_` constants from `constants.scad`. Default: `ORIENT_X`.
// align = Alignment of the fillet. Use the constants from `constants.scad`. Default: `CENTER`.
// anchor = Alignment of the fillet. Use the constants from `constants.scad`. Default: `CENTER`.
//
// Example:
// union() {
@ -1815,10 +1719,10 @@ module pie_slice(
//
// Example:
// interior_fillet(l=40, r=10, orient=ORIENT_Y_90);
module interior_fillet(l=1.0, r=1.0, ang=90, overlap=0.01, orient=ORIENT_X, align=CENTER) {
module interior_fillet(l=1.0, r=1.0, ang=90, overlap=0.01, orient=ORIENT_X, anchor=CENTER) {
dy = r/tan(ang/2);
size = [l,r,r];
orient_and_align(size, orient, align, orig_orient=ORIENT_X, chain=true) {
orient_and_anchor(size, orient, anchor, orig_orient=ORIENT_X, chain=true) {
difference() {
translate([0,-overlap/tan(ang/2),-overlap]) {
if (ang == 90) {
@ -1841,10 +1745,10 @@ module interior_fillet(l=1.0, r=1.0, ang=90, overlap=0.01, orient=ORIENT_X, alig
// Makes a linear slot with rounded ends, appropriate for bolts to slide along.
//
// Usage:
// slot(h, l, r|d, [orient], [align|center]);
// slot(h, p1, p2, r|d, [orient], [align|center]);
// slot(h, l, r1|d1, r2|d2, [orient], [align|center]);
// slot(h, p1, p2, r1|d1, r2|d2, [orient], [align|center]);
// slot(h, l, r|d, [orient], [anchor|center]);
// slot(h, p1, p2, r|d, [orient], [anchor|center]);
// slot(h, l, r1|d1, r2|d2, [orient], [anchor|center]);
// slot(h, p1, p2, r1|d1, r2|d2, [orient], [anchor|center]);
//
// Arguments:
// p1 = center of starting circle of slot.
@ -1870,8 +1774,8 @@ module slot(
r1 = get_radius(r1=r1, r=r, d1=d1, d=d, dflt=5);
r2 = get_radius(r1=r2, r=r, d1=d2, d=d, dflt=5);
sides = quantup(segs(max(r1, r2)), 4);
// TODO: implement orient and align.
// TODO: implement connectors.
// TODO: implement orient and anchor.
// TODO: implement anchors.
hull() spread(p1=p1, p2=p2, l=l, n=2) cyl(l=h, r1=r1, r2=r2, center=true, $fn=sides);
}
@ -1882,8 +1786,8 @@ module slot(
// Makes an arced slot, appropriate for bolts to slide along.
//
// Usage:
// arced_slot(h, r|d, sr|sd, [sa], [ea], [orient], [align|center], [$fn2]);
// arced_slot(h, r|d, sr1|sd1, sr2|sd2, [sa], [ea], [orient], [align|center], [$fn2]);
// arced_slot(h, r|d, sr|sd, [sa], [ea], [orient], [anchor|center], [$fn2]);
// arced_slot(h, r|d, sr1|sd1, sr2|sd2, [sa], [ea], [orient], [anchor|center], [$fn2]);
//
// Arguments:
// cp = centerpoint of slot arc. (default: [0, 0, 0])
@ -1899,8 +1803,8 @@ module slot(
// sa = starting angle. (Default: 0.0)
// ea = ending angle. (Default: 90.0)
// orient = Orientation of the arced slot. Use the `ORIENT_` constants from `constants.scad`. Default: `ORIENT_Z`.
// align = Alignment of the arced slot. Use the constants from `constants.scad`. Default: `CENTER`.
// center = If true, centers vertically. If false, drops flush with XY plane. Overrides `align`.
// anchor = Alignment of the arced slot. Use the constants from `constants.scad`. Default: `CENTER`.
// center = If true, centers vertically. If false, drops flush with XY plane. Overrides `anchor`.
// $fn2 = The $fn value to use on the small round endcaps. The major arcs are still based on $fn. Default: $fn
//
// Example: Typical Arced Slot
@ -1912,7 +1816,7 @@ module arced_slot(
sr=undef, sr1=undef, sr2=undef,
sd=undef, sd1=undef, sd2=undef,
sa=0, ea=90, cp=[0,0,0],
orient=ORIENT_Z, align=CENTER,
orient=ORIENT_Z, anchor=CENTER,
$fn2 = undef
) {
r = get_radius(r=r, d=d, dflt=2);
@ -1921,11 +1825,11 @@ module arced_slot(
fn_minor = first_defined([$fn2, $fn]);
da = ea - sa;
size = [r+sr1, r+sr1, h];
orient_and_align(size, orient, align, geometry="cylinder", chain=true) {
orient_and_anchor(size, orient, anchor, geometry="cylinder", chain=true) {
translate(cp) {
zrot(sa) {
difference() {
pie_slice(ang=da, l=h, r1=r+sr1, r2=r+sr2, orient=ORIENT_Z, align=CENTER);
pie_slice(ang=da, l=h, r1=r+sr1, r2=r+sr2, orient=ORIENT_Z, anchor=CENTER);
cylinder(h=h+0.1, r1=r-sr1, r2=r-sr2, center=true);
}
right(r) cylinder(h=h, r1=sr1, r2=sr2, center=true, $fn=fn_minor);

View file

@ -45,7 +45,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Description:
// Creates a slider to match a V-groove rail.
// Usage:
// slider(l, w, h, [base], [wall], [ang], [slop], [orient], [align])
// slider(l, w, h, [base], [wall], [ang], [slop], [orient], [anchor])
// Arguments:
// l = Length (long axis) of slider.
// w = Width of slider.
@ -55,29 +55,29 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// ang = Overhang angle for slider, to facilitate supportless printig.
// slop = Printer-specific slop value to make parts fit exactly.
// orient = Orientation of the slider. Use the `ORIENT_` constants from `constants.scad`. Default: `ORIENT_Y`.
// align = Alignment of the slider. Use the constants from `constants.scad`. Default: `UP`.
// anchor = Alignment of the slider. Use the constants from `constants.scad`. Default: `UP`.
// Example:
// slider(l=30, base=10, wall=4, slop=0.2, orient=ORIENT_Y);
module slider(l=30, w=10, h=10, base=10, wall=5, ang=30, slop=PRINTER_SLOP, orient=ORIENT_Y, align=UP)
module slider(l=30, w=10, h=10, base=10, wall=5, ang=30, slop=PRINTER_SLOP, orient=ORIENT_Y, anchor=UP)
{
full_width = w + 2*wall;
full_height = h + base;
orient_and_align([full_width, l, h+2*base], orient, align, orig_orient=ORIENT_Y, chain=true) {
orient_and_anchor([full_width, l, h+2*base], orient, anchor, orig_orient=ORIENT_Y, chain=true) {
down(base+h/2) {
// Base
cuboid([full_width, l, base-slop], chamfer=2, edges=EDGE_TOP_FR+EDGE_TOP_BK+EDGES_Z_ALL, align=UP);
cuboid([full_width, l, base-slop], chamfer=2, edges=EDGE_TOP_FR+EDGE_TOP_BK+EDGES_Z_ALL, anchor=UP);
// Wall
xflip_copy(offset=w/2+slop) {
cuboid([wall, l, full_height], chamfer=2, edges=EDGE_TOP_RT+EDGE_FR_RT+EDGE_BK_RT, align=UP+RIGHT);
cuboid([wall, l, full_height], chamfer=2, edges=EDGE_TOP_RT+EDGE_FR_RT+EDGE_BK_RT, anchor=UP+RIGHT);
}
// Sliders
up(base+h/2) {
xflip_copy(offset=w/2+slop+0.02) {
bev_h = h/2*tan(ang);
prismoid([l, h], [l-w, 0], h=bev_h+0.01, orient=ORIENT_XNEG, align=LEFT);
prismoid([l, h], [l-w, 0], h=bev_h+0.01, orient=ORIENT_XNEG, anchor=LEFT);
}
}
}
@ -91,7 +91,7 @@ module slider(l=30, w=10, h=10, base=10, wall=5, ang=30, slop=PRINTER_SLOP, orie
// Description:
// Creates a V-groove rail.
// Usage:
// rail(l, w, h, [chamfer], [ang], [orient], [align])
// rail(l, w, h, [chamfer], [ang], [orient], [anchor])
// Arguments:
// l = Length (long axis) of slider.
// w = Width of slider.
@ -99,10 +99,10 @@ module slider(l=30, w=10, h=10, base=10, wall=5, ang=30, slop=PRINTER_SLOP, orie
// chamfer = Size of chamfer at end of rail.
// ang = Overhang angle for slider, to facilitate supportless printig.
// orient = Orientation of the rail. Use the `ORIENT_` constants from `constants.scad`. Default: `ORIENT_Y`.
// align = Alignment of the rail. Use the constants from `constants.scad`. Default: `UP`.
// anchor = Alignment of the rail. Use the constants from `constants.scad`. Default: `UP`.
// Example:
// rail(l=100, w=10, h=10);
module rail(l=30, w=10, h=10, chamfer=1.0, ang=30, orient=ORIENT_Y, align=UP)
module rail(l=30, w=10, h=10, chamfer=1.0, ang=30, orient=ORIENT_Y, anchor=UP)
{
attack_ang = 30;
attack_len = 2;
@ -128,7 +128,7 @@ module rail(l=30, w=10, h=10, chamfer=1.0, ang=30, orient=ORIENT_Y, align=UP)
y1 = l/2;
y2 = y1 - attack_len * cos(attack_ang);
orient_and_align([w, l, h], orient, align, orig_orient=ORIENT_Y, chain=true) {
orient_and_anchor([w, l, h], orient, anchor, orig_orient=ORIENT_Y, chain=true) {
polyhedron(
convexity=4,
points=[

View file

@ -62,8 +62,8 @@ function _trpzd_thread_pt(thread, threads, start, starts, astep, asteps, part, p
// bevel = if true, bevel the thread ends. Default: true
// starts = The number of lead starts. Default = 1
// orient = Orientation of the rod. Use the `ORIENT_` constants from `constants.scad`. Default: `ORIENT_Z`.
// align = Alignment of the rod. Use the constants from `constants.scad`. Default: `CENTER`.
// center = If given, overrides `align`. A true value sets `align=CENTER`, false sets `align=UP`.
// anchor = Alignment of the rod. Use the constants from `constants.scad`. Default: `CENTER`.
// center = If given, overrides `anchor`. A true value sets `anchor=CENTER`, false sets `anchor=UP`.
// Examples:
// trapezoidal_threaded_rod(d=10, l=100, pitch=2, thread_angle=15, $fn=32);
// trapezoidal_threaded_rod(d=3/8*25.4, l=20, pitch=1/8*25.4, thread_angle=29, $fn=32);
@ -73,7 +73,7 @@ function _trpzd_thread_pt(thread, threads, start, starts, astep, asteps, part, p
// trapezoidal_threaded_rod(d=10, l=40, pitch=3, thread_angle=15, left_handed=true, starts=3, $fn=36);
// trapezoidal_threaded_rod(d=25, l=100, pitch=10, thread_depth=8/3, thread_angle=50, starts=4, center=false, $fa=2, $fs=2);
// trapezoidal_threaded_rod(d=50, l=75, pitch=8, thread_angle=30, starts=3, bevel=true);
// trapezoidal_threaded_rod(l=25, d=10, pitch=2, thread_angle=15, starts=3, $fa=1, $fs=1, orient=ORIENT_X, align=UP);
// trapezoidal_threaded_rod(l=25, d=10, pitch=2, thread_angle=15, starts=3, $fa=1, $fs=1, orient=ORIENT_X, anchor=UP);
module trapezoidal_threaded_rod(
d=10,
l=100,
@ -84,7 +84,7 @@ module trapezoidal_threaded_rod(
bevel=false,
starts=1,
orient=ORIENT_Z,
align=CENTER,
anchor=CENTER,
center=undef
) {
astep = 360 / quantup(segs(d/2), starts);
@ -218,7 +218,7 @@ module trapezoidal_threaded_rod(
) otri
]
);
orient_and_align([d,d,l], orient, align, center, chain=true) {
orient_and_anchor([d,d,l], orient, anchor, center, chain=true) {
difference() {
polyhedron(points=poly_points, faces=poly_faces, convexity=threads*starts*2);
zspread(l+4*pitch*starts) cube([d+1, d+1, 4*pitch*starts], center=true);
@ -250,9 +250,9 @@ module trapezoidal_threaded_rod(
// slop = printer slop calibration to allow for tight fitting of parts. default=0.2
// bevel = if true, bevel the thread ends. Default: true
// orient = Orientation of the nut. Use the `ORIENT_` constants from `constants.scad`. Default: `ORIENT_Z`.
// align = Alignment of the nut. Use the constants from `constants.scad`. Default: `CENTER`.
// anchor = Alignment of the nut. Use the constants from `constants.scad`. Default: `CENTER`.
// Examples:
// trapezoidal_threaded_nut(od=16, id=8, h=8, pitch=2, slop=0.2, align=UP);
// trapezoidal_threaded_nut(od=16, id=8, h=8, pitch=2, slop=0.2, anchor=UP);
// trapezoidal_threaded_nut(od=17.4, id=10, h=10, pitch=2, slop=0.2, left_handed=true);
// trapezoidal_threaded_nut(od=17.4, id=10, h=10, pitch=2, thread_angle=15, starts=3, $fa=1, $fs=1);
module trapezoidal_threaded_nut(
@ -267,10 +267,10 @@ module trapezoidal_threaded_nut(
bevel=true,
slop=PRINTER_SLOP,
orient=ORIENT_Z,
align=CENTER
anchor=CENTER
) {
depth = min((thread_depth==undef? pitch/2 : thread_depth), pitch/2/tan(thread_angle));
orient_and_align([od/cos(30),od,h], orient, align, chain=true) {
orient_and_anchor([od/cos(30),od,h], orient, anchor, chain=true) {
difference() {
cylinder(d=od/cos(30), h=h, center=true, $fn=6);
zspread(slop, n=slop>0?2:1) {
@ -310,10 +310,10 @@ module trapezoidal_threaded_nut(
// left_handed = if true, create left-handed threads. Default = false
// bevel = if true, bevel the thread ends. Default: false
// orient = Orientation of the rod. Use the `ORIENT_` constants from `constants.scad`. Default: `ORIENT_Z`.
// align = Alignment of the rod. Use the constants from `constants.scad`. Default: `CENTER`.
// anchor = Alignment of the rod. Use the constants from `constants.scad`. Default: `CENTER`.
// Examples:
// threaded_rod(d=10, l=30, pitch=1.25, left_handed=true, $fa=1, $fs=1);
module threaded_rod(d=10, l=100, pitch=2, left_handed=false, bevel=false, orient=ORIENT_Z, align=CENTER) {
module threaded_rod(d=10, l=100, pitch=2, left_handed=false, bevel=false, orient=ORIENT_Z, anchor=CENTER) {
trapezoidal_threaded_rod(
d=d, l=l, pitch=pitch,
thread_depth=pitch*3*sqrt(3)/8,
@ -321,7 +321,7 @@ module threaded_rod(d=10, l=100, pitch=2, left_handed=false, bevel=false, orient
left_handed=left_handed,
bevel=bevel,
orient=orient,
align=align
anchor=anchor
) children();
}
@ -340,14 +340,14 @@ module threaded_rod(d=10, l=100, pitch=2, left_handed=false, bevel=false, orient
// bevel = if true, bevel the thread ends. Default: false
// slop = printer slop calibration to allow for tight fitting of parts. default=0.2
// orient = Orientation of the nut. Use the `ORIENT_` constants from `constants.scad`. Default: `ORIENT_Z`.
// align = Alignment of the nut. Use the constants from `constants.scad`. Default: `CENTER`.
// anchor = Alignment of the nut. Use the constants from `constants.scad`. Default: `CENTER`.
// Examples:
// threaded_nut(od=16, id=8, h=8, pitch=1.25, left_handed=true, slop=0.2, $fa=1, $fs=1);
module threaded_nut(
od=16, id=10, h=10,
pitch=2, left_handed=false,
bevel=false, slop=0.2,
orient=ORIENT_Z, align=CENTER
orient=ORIENT_Z, anchor=CENTER
) {
trapezoidal_threaded_nut(
od=od, id=id, h=h,
@ -355,7 +355,7 @@ module threaded_nut(
thread_depth=pitch*3*sqrt(3)/8,
left_handed=left_handed,
bevel=bevel, slop=slop,
orient=orient, align=align
orient=orient, anchor=anchor
) children();
}
@ -374,7 +374,7 @@ module threaded_nut(
// bevel = if true, bevel the thread ends. Default: false
// starts = The number of lead starts. Default = 1
// orient = Orientation of the rod. Use the `ORIENT_` constants from `constants.scad`. Default: `ORIENT_Z`.
// align = Alignment of the rod. Use the constants from `constants.scad`. Default: `CENTER`.
// anchor = Alignment of the rod. Use the constants from `constants.scad`. Default: `CENTER`.
// Examples:
// metric_trapezoidal_threaded_rod(d=10, l=30, pitch=2, left_handed=true, $fa=1, $fs=1);
module metric_trapezoidal_threaded_rod(
@ -383,7 +383,7 @@ module metric_trapezoidal_threaded_rod(
starts=1,
bevel=false,
orient=ORIENT_Z,
align=CENTER
anchor=CENTER
) {
trapezoidal_threaded_rod(
d=d, l=l,
@ -393,7 +393,7 @@ module metric_trapezoidal_threaded_rod(
starts=starts,
bevel=bevel,
orient=orient,
align=align
anchor=anchor
) children();
}
@ -413,7 +413,7 @@ module metric_trapezoidal_threaded_rod(
// starts = The number of lead starts. Default = 1
// slop = printer slop calibration to allow for tight fitting of parts. default=0.2
// orient = Orientation of the nut. Use the `ORIENT_` constants from `constants.scad`. Default: `ORIENT_Z`.
// align = Alignment of the nut. Use the constants from `constants.scad`. Default: `CENTER`.
// anchor = Alignment of the nut. Use the constants from `constants.scad`. Default: `CENTER`.
// Examples:
// metric_trapezoidal_threaded_nut(od=16, id=10, h=10, pitch=2, left_handed=true, bevel=true, $fa=1, $fs=1);
module metric_trapezoidal_threaded_nut(
@ -424,7 +424,7 @@ module metric_trapezoidal_threaded_nut(
bevel=false,
slop=PRINTER_SLOP,
orient=ORIENT_Z,
align=CENTER
anchor=CENTER
) {
trapezoidal_threaded_nut(
od=od, id=id, h=h,
@ -434,7 +434,7 @@ module metric_trapezoidal_threaded_nut(
bevel=bevel,
slop=slop,
orient=orient,
align=align
anchor=anchor
) children();
}
@ -455,7 +455,7 @@ module metric_trapezoidal_threaded_nut(
// left_handed = if true, create left-handed threads. Default = false
// bevel = if true, bevel the thread ends. Default: false
// orient = Orientation of the rod. Use the `ORIENT_` constants from `constants.scad`. Default: `ORIENT_Z`.
// align = Alignment of the rod. Use the constants from `constants.scad`. Default: `CENTER`.
// anchor = Alignment of the rod. Use the constants from `constants.scad`. Default: `CENTER`.
// Examples:
// acme_threaded_rod(d=3/8*25.4, l=20, pitch=1/8*25.4, $fn=32);
// acme_threaded_rod(d=10, l=40, pitch=2, starts=3, $fa=1, $fs=1);
@ -467,7 +467,7 @@ module acme_threaded_rod(
left_handed=false,
bevel=false,
orient=ORIENT_Z,
align=CENTER
anchor=CENTER
) {
trapezoidal_threaded_rod(
d=d, l=l, pitch=pitch,
@ -477,7 +477,7 @@ module acme_threaded_rod(
left_handed=left_handed,
bevel=bevel,
orient=orient,
align=align
anchor=anchor
) children();
}
@ -498,7 +498,7 @@ module acme_threaded_rod(
// bevel = if true, bevel the thread ends. Default: false
// slop = printer slop calibration to allow for tight fitting of parts. default=0.2
// orient = Orientation of the nut. Use the `ORIENT_` constants from `constants.scad`. Default: `ORIENT_Z`.
// align = Alignment of the nut. Use the constants from `constants.scad`. Default: `CENTER`.
// anchor = Alignment of the nut. Use the constants from `constants.scad`. Default: `CENTER`.
// Examples:
// acme_threaded_nut(od=16, id=3/8*25.4, h=8, pitch=1/8*25.4, slop=0.2);
// acme_threaded_nut(od=16, id=10, h=10, pitch=2, starts=3, slop=0.2, $fa=1, $fs=1);
@ -511,7 +511,7 @@ module acme_threaded_nut(
bevel=false,
slop=PRINTER_SLOP,
orient=ORIENT_Z,
align=CENTER
anchor=CENTER
) {
trapezoidal_threaded_nut(
od=od, id=id, h=h, pitch=pitch,
@ -522,7 +522,7 @@ module acme_threaded_nut(
starts=starts,
slop=slop,
orient=orient,
align=align
anchor=anchor
) children();
}
@ -541,7 +541,7 @@ module acme_threaded_nut(
// bevel = if true, bevel the thread ends. Default: false
// starts = The number of lead starts. Default = 1
// orient = Orientation of the rod. Use the `ORIENT_` constants from `constants.scad`. Default: `ORIENT_Z`.
// align = Alignment of the rod. Use the constants from `constants.scad`. Default: `CENTER`.
// anchor = Alignment of the rod. Use the constants from `constants.scad`. Default: `CENTER`.
// Examples:
// square_threaded_rod(d=10, l=30, pitch=2, starts=2, $fn=32);
module square_threaded_rod(
@ -550,7 +550,7 @@ module square_threaded_rod(
bevel=false,
starts=1,
orient=ORIENT_Z,
align=CENTER
anchor=CENTER
) {
trapezoidal_threaded_rod(
d=d, l=l, pitch=pitch,
@ -559,7 +559,7 @@ module square_threaded_rod(
bevel=bevel,
starts=starts,
orient=orient,
align=align
anchor=anchor
) children();
}
@ -579,7 +579,7 @@ module square_threaded_rod(
// starts = The number of lead starts. Default = 1
// slop = printer slop calibration to allow for tight fitting of parts. default=0.2
// orient = Orientation of the nut. Use the `ORIENT_` constants from `constants.scad`. Default: `ORIENT_Z`.
// align = Alignment of the nut. Use the constants from `constants.scad`. Default: `CENTER`.
// anchor = Alignment of the nut. Use the constants from `constants.scad`. Default: `CENTER`.
// Examples:
// square_threaded_nut(od=16, id=10, h=10, pitch=2, starts=2, slop=0.15, $fn=32);
module square_threaded_nut(
@ -590,7 +590,7 @@ module square_threaded_nut(
starts=1,
slop=PRINTER_SLOP,
orient=ORIENT_Z,
align=CENTER
anchor=CENTER
) {
trapezoidal_threaded_nut(
od=od, id=id, h=h, pitch=pitch,
@ -600,7 +600,7 @@ module square_threaded_nut(
starts=starts,
slop=slop,
orient=orient,
align=align
anchor=anchor
) children();
}

View file

@ -210,9 +210,9 @@ module torx_drive2d(size) {
// center = If true, centers bit vertically.
// Examples:
// torx_drive(size=30, l=10, $fa=1, $fs=1);
module torx_drive(size, l=5, center=undef, orient=ORIENT_Z, align=UP) {
module torx_drive(size, l=5, center=undef, orient=ORIENT_Z, anchor=BOTTOM) {
od = torx_outer_diam(size);
orient_and_align([od, od, l], orient, align, center, chain=true) {
orient_and_anchor([od, od, l], orient, anchor, center, chain=true) {
linear_extrude(height=l, convexity=4, center=true) {
torx_drive2d(size);
}

View file

@ -956,11 +956,11 @@ module zdistribute(spacing=10, sizes=undef, l=undef)
// Makes a square or hexagonal grid of copies of children.
//
// Usage:
// grid2d(size, spacing, [stagger], [scale], [in_poly], [orient], [align]) ...
// grid2d(size, cols, rows, [stagger], [scale], [in_poly], [orient], [align]) ...
// grid2d(spacing, cols, rows, [stagger], [scale], [in_poly], [orient], [align]) ...
// grid2d(spacing, in_poly, [stagger], [scale], [orient], [align]) ...
// grid2d(cols, rows, in_poly, [stagger], [scale], [orient], [align]) ...
// grid2d(size, spacing, [stagger], [scale], [in_poly], [orient], [anchor]) ...
// grid2d(size, cols, rows, [stagger], [scale], [in_poly], [orient], [anchor]) ...
// grid2d(spacing, cols, rows, [stagger], [scale], [in_poly], [orient], [anchor]) ...
// grid2d(spacing, in_poly, [stagger], [scale], [orient], [anchor]) ...
// grid2d(cols, rows, in_poly, [stagger], [scale], [orient], [anchor]) ...
//
// Arguments:
// size = The [X,Y] size to spread the copies over.
@ -971,7 +971,7 @@ module zdistribute(spacing=10, sizes=undef, l=undef)
// scale = [X,Y] scaling factors to reshape grid.
// in_poly = If given a list of polygon points, only creates copies whose center would be inside the polygon. Polygon can be concave and/or self crossing.
// orient = Orientation axis for the grid. Orientation is NOT applied to individual children.
// align = Alignment of the grid. Alignment is NOT applies to individual children.
// anchor = Alignment of the grid. Alignment is NOT applies to individual children.
//
// Side Effects:
// `$pos` is set to the relative centerpoint of each child copy, and can be used to modify each child individually.
@ -1002,7 +1002,7 @@ module zdistribute(spacing=10, sizes=undef, l=undef)
// zrot(180/6)
// cylinder(h=20, d=10/cos(180/6)+0.01, $fn=6);
// }
module grid2d(size=undef, spacing=undef, cols=undef, rows=undef, stagger=false, scale=[1,1,1], in_poly=undef, orient=ORIENT_Z, align=CENTER)
module grid2d(size=undef, spacing=undef, cols=undef, rows=undef, stagger=false, scale=[1,1,1], in_poly=undef, orient=ORIENT_Z, anchor=CENTER)
{
assert_in_list("stagger", stagger, [false, true, "alt"]);
scl = vmul(scalar_vec3(scale, 1), (stagger!=false? [0.5, sin(60), 0] : [1,1,0]));
@ -1012,10 +1012,10 @@ module grid2d(size=undef, spacing=undef, cols=undef, rows=undef, stagger=false,
spc = vmul(scalar_vec3(spacing), scl);
maxcols = ceil(siz[0]/spc[0]);
maxrows = ceil(siz[1]/spc[1]);
grid2d(spacing=spacing, cols=maxcols, rows=maxrows, stagger=stagger, scale=scale, in_poly=in_poly, orient=orient, align=align) children();
grid2d(spacing=spacing, cols=maxcols, rows=maxrows, stagger=stagger, scale=scale, in_poly=in_poly, orient=orient, anchor=anchor) children();
} else {
spc = [siz[0]/cols, siz[1]/rows, 0];
grid2d(spacing=spc, cols=cols, rows=rows, stagger=stagger, scale=scale, in_poly=in_poly, orient=orient, align=align) children();
grid2d(spacing=spc, cols=cols, rows=rows, stagger=stagger, scale=scale, in_poly=in_poly, orient=orient, anchor=anchor) children();
}
} else {
spc = is_list(spacing)? spacing : vmul(scalar_vec3(spacing), scl);
@ -1026,7 +1026,7 @@ module grid2d(size=undef, spacing=undef, cols=undef, rows=undef, stagger=false,
siz = vmul(spc, [mcols-1, mrows-1, 0]);
staggermod = (stagger == "alt")? 1 : 0;
if (stagger == false) {
orient_and_align(siz, orient, align) {
orient_and_anchor(siz, orient, anchor) {
for (row = [0:mrows-1]) {
for (col = [0:mcols-1]) {
pos = [col*spc[0], row*spc[1]] - point2d(siz/2);
@ -1041,7 +1041,7 @@ module grid2d(size=undef, spacing=undef, cols=undef, rows=undef, stagger=false,
}
} else {
// stagger == true or stagger == "alt"
orient_and_align(siz, orient, align) {
orient_and_anchor(siz, orient, anchor) {
cols1 = ceil(mcols/2);
cols2 = mcols - cols1;
for (row = [0:mrows-1]) {
@ -2044,7 +2044,7 @@ module chain_hull()
// without the `angle` argument in rotate_extrude.
//
// Usage:
// extrude_arc(arc, r|d, [sa], [caps], [orient], [align], [masksize]) ...
// extrude_arc(arc, r|d, [sa], [caps], [orient], [anchor], [masksize]) ...
//
// Arguments:
// arc = Number of degrees to traverse.
@ -2052,7 +2052,7 @@ module chain_hull()
// r = Radius of arc.
// d = Diameter of arc.
// orient = The axis to align to. Use `ORIENT_` constants from `constants.scad`
// align = The side of the origin the part should be aligned with. Use `` constants from `constants.scad`
// anchor = The side of the origin the part should be anchored with. Use constants from `constants.scad`
// masksize = size of mask used to clear unused part of circle arc. should be larger than height or width of 2D shapes to extrude.
// caps = If true, spin the 2D shapes to make rounded caps the ends of the arc.
// convexity = Max number of times a ray passes through the 2D shape's walls.
@ -2063,11 +2063,11 @@ module chain_hull()
// extrude_arc(arc=270, sa=45, r=40, caps=true, convexity=4, $fa=2, $fs=2) {
// polygon(points=pts);
// }
module extrude_arc(arc=90, sa=0, r=undef, d=undef, orient=ORIENT_Z, align=CENTER, masksize=100, caps=false, convexity=4)
module extrude_arc(arc=90, sa=0, r=undef, d=undef, orient=ORIENT_Z, anchor=CENTER, masksize=100, caps=false, convexity=4)
{
eps = 0.001;
r = get_radius(r=r, d=d, dflt=100);
orient_and_align([2*r, 2*r, 0], orient, align) {
orient_and_anchor([2*r, 2*r, 0], orient, anchor) {
zrot(sa) {
if (caps) {
place_copies([[r,0,0], cylindrical_to_xyz(r, arc, 0)]) {

View file

@ -87,7 +87,10 @@ function normalize(v) = v/norm(v);
// v1 = First vector.
// v2 = Second vector.
// NOTE: constrain() corrects crazy FP rounding errors that exceed acos()'s domain.
function vector_angle(v1,v2) = acos(constrain((v1*v2)/(norm(v1)*norm(v2)), -1, 1));
function vector_angle(v1,v2) =
assert(is_vector(v1))
assert(is_vector(v2))
acos(constrain((v1*v2)/(norm(v1)*norm(v2)), -1, 1));
// Function: vector_axis()