diff --git a/common.scad b/common.scad index e0b3cab..e624205 100644 --- a/common.scad +++ b/common.scad @@ -306,7 +306,7 @@ function get_radius(r1, r2, r, d1, d2, d, dflt) = // h = h. // height = height. // dflt = Value to return if other values are `undef`. -function get_height(h=undef,l=undef,height=undef,dflt=undef) = +function get_height(h,l,height,dflt) = assert(num_defined([h,l,height])<=1,"You must specify only one of `l`, `h`, and `height`") first_defined([h,l,height,dflt]); @@ -400,6 +400,8 @@ function get_named_args(positional, named,_undef=_undef) = val != _undef ? val : ass != [] ? positional[ass[0]] : deft[idx] ]; + + // Function: scalar_vec3() // Usage: // scalar_vec3(v, ); diff --git a/shapes.scad b/shapes.scad index 655b0b0..8f0b5e5 100644 --- a/shapes.scad +++ b/shapes.scad @@ -11,6 +11,17 @@ // Module: cuboid() // +// Usage: Standard Cubes +// cuboid(size, , , ); +// cuboid(size, p1=, ...); +// cuboid(p1=, p2=, ...); +// Usage: Chamfered Cubes +// cuboid(size, , , , , ...); +// Usage: Rounded Cubes +// cuboid(size, , , , , ...); +// Usage: Attaching children +// cuboid(size, , ...) ; +// // Description: // Creates a cube or cuboid object, with optional chamfering or rounding. // Negative chamfers and roundings can be applied to create external masks, @@ -18,6 +29,7 @@ // // Arguments: // size = The size of the cube. +// --- // chamfer = Size of chamfer, inset from sides. Default: No chamfering. // rounding = Radius of the edge rounding. Default: No rounding. // edges = Edges to chamfer/round. See the docs for [`edges()`](edges.scad#edges) to see acceptable values. Default: All edges. @@ -311,6 +323,19 @@ module cuboid( } } +function cuboid( + size=[1,1,1], + p1, p2, + chamfer, + rounding, + edges=EDGES_ALL, + except_edges=[], + trimcorners=true, + anchor=CENTER, + spin=0, + orient=UP +) = no_function("cuboid"); + // Section: Prismoids @@ -318,12 +343,19 @@ module cuboid( // Function&Module: prismoid() // -// Usage: As Module -// prismoid(size1, size2, h|l, [shift], [rounding], [chamfer]); -// prismoid(size1, size2, h|l, [shift], [rounding1], [rounding2], [chamfer1], [chamfer2]); +// Usage: Typical Prismoids +// prismoid(size1, size2, h|l, , ...); +// Usage: Attaching Children +// prismoid(size1, size2, h|l, , ...) ; +// Usage: Chamfered Prismoids +// prismoid(size1, size2, h|l, , ...); +// prismoid(size1, size2, h|l, , , ...); +// Usage: Rounded Prismoids +// prismoid(size1, size2, h|l, , ...); +// prismoid(size1, size2, h|l, , , ...); // Usage: As Function -// vnf = prismoid(size1, size2, h|l, [shift], [rounding], [chamfer]); -// vnf = prismoid(size1, size2, h|l, [shift], [rounding1], [rounding2], [chamfer1], [chamfer2]); +// vnf = prismoid(size1, size2, h|l, , , ); +// vnf = prismoid(size1, size2, h|l, , , , , ); // // Description: // Creates a rectangular prismoid shape with optional roundovers and chamfering. @@ -335,16 +367,17 @@ module cuboid( // ``` // // Arguments: -// size1 = [width, length] of the axis-negative end of the prism. -// size2 = [width, length] of the axis-positive end of the prism. +// size1 = [width, length] of the bottom end of the prism. +// size2 = [width, length] of the top end of the prism. // h|l = Height of the prism. -// shift = [X,Y] amount to shift the center of the top with respect to the center of the bottom. -// rounding = The roundover radius for the edges of the prismoid. Requires including hull.scad. If given as a list of four numbers, gives individual radii for each corner, in the order [X+Y+,X-Y+,X-Y-,X+Y-]. Default: 0 (no rounding) -// rounding1 = The roundover radius for the bottom corners of the prismoid. Requires including hull.scad. If given as a list of four numbers, gives individual radii for each corner, in the order [X+Y+,X-Y+,X-Y-,X+Y-]. -// rounding2 = The roundover radius for the top corners of the prismoid. Requires including hull.scad. If given as a list of four numbers, gives individual radii for each corner, in the order [X+Y+,X-Y+,X-Y-,X+Y-]. -// chamfer = The chamfer size for the edges of the prismoid. Requires including hull.scad. If given as a list of four numbers, gives individual chamfers for each corner, in the order [X+Y+,X-Y+,X-Y-,X+Y-]. Default: 0 (no chamfer) -// chamfer1 = The chamfer size for the bottom corners of the prismoid. Requires including hull.scad. If given as a list of four numbers, gives individual chamfers for each corner, in the order [X+Y+,X-Y+,X-Y-,X+Y-]. -// chamfer2 = The chamfer size for the top corners of the prismoid. Requires including hull.scad. If given as a list of four numbers, gives individual chamfers for each corner, in the order [X+Y+,X-Y+,X-Y-,X+Y-]. +// shift = [X,Y] amount to shift the center of the top end with respect to the center of the bottom end. +// --- +// rounding = The roundover radius for the vertical-ish edges of the prismoid. Requires including hull.scad. If given as a list of four numbers, gives individual radii for each corner, in the order [X+Y+,X-Y+,X-Y-,X+Y-]. Default: 0 (no rounding) +// rounding1 = The roundover radius for the bottom of the vertical-ish edges of the prismoid. Requires including hull.scad. If given as a list of four numbers, gives individual radii for each corner, in the order [X+Y+,X-Y+,X-Y-,X+Y-]. +// rounding2 = The roundover radius for the top of the vertical-ish edges of the prismoid. Requires including hull.scad. If given as a list of four numbers, gives individual radii for each corner, in the order [X+Y+,X-Y+,X-Y-,X+Y-]. +// chamfer = The chamfer size for the vertical-ish edges of the prismoid. Requires including hull.scad. If given as a list of four numbers, gives individual chamfers for each corner, in the order [X+Y+,X-Y+,X-Y-,X+Y-]. Default: 0 (no chamfer) +// chamfer1 = The chamfer size for the bottom of the vertical-ish edges of the prismoid. Requires including hull.scad. If given as a list of four numbers, gives individual chamfers for each corner, in the order [X+Y+,X-Y+,X-Y-,X+Y-]. +// chamfer2 = The chamfer size for the top of the vertical-ish edges of the prismoid. Requires including hull.scad. If given as a list of four numbers, gives individual chamfers for each corner, in the order [X+Y+,X-Y+,X-Y-,X+Y-]. // anchor = Translate so anchor point is at origin (0,0,0). See [anchor](attachments.scad#anchor). Default: `CENTER` // spin = Rotate this many degrees around the Z axis after anchor. See [spin](attachments.scad#spin). Default: `0` // orient = Vector to rotate top towards, after spin. See [orient](attachments.scad#orient). Default: `UP` @@ -488,13 +521,29 @@ function prismoid( // Module: rect_tube() -// Usage: -// rect_tube(size, wall, h, [center]); -// rect_tube(isize, wall, h, [center]); -// rect_tube(size, isize, h, [center]); -// rect_tube(size1, size2, wall, h, [center]); -// rect_tube(isize1, isize2, wall, h, [center]); -// rect_tube(size1, size2, isize1, isize2, h, [center]); +// Usage: Typical Rectangular Tubes +// rect_tube(h, size, isize,
, ); +// rect_tube(h, size, wall=, ); +// rect_tube(h, isize=, wall=, ); +// Usage: Tapering Rectangular Tubes +// rect_tube(h, size1=, size2=, wall=, ...); +// rect_tube(h, isize1=, isize2=, wall=, ...); +// rect_tube(h, size1=, size2=, isize1=, isize2=, ...); +// Usage: Chamfered +// rect_tube(h, size, isize, chamfer=, ...); +// rect_tube(h, size, isize, chamfer1=, chamfer2= ...); +// rect_tube(h, size, isize, ichamfer=, ...); +// rect_tube(h, size, isize, ichamfer1=, ichamfer2= ...); +// rect_tube(h, size, isize, chamfer=, ichamfer=, ...); +// Usage: Rounded +// rect_tube(h, size, isize, rounding=, ...); +// rect_tube(h, size, isize, rounding1=, rounding2= ...); +// rect_tube(h, size, isize, irounding=, ...); +// rect_tube(h, size, isize, irounding1=, irounding2= ...); +// rect_tube(h, size, isize, rounding=, irounding=, ...); +// Usage: Attaching Children +// rect_tube(h, size, isize, ...) ; +// // Description: // Creates a rectangular or prismoid tube with optional roundovers and/or chamfers. // You can only round or chamfer the vertical(ish) edges. For those edges, you can @@ -505,9 +554,12 @@ function prismoid( // include // ``` // Arguments: +// h|l = The height or length of the rectangular tube. Default: 1 // size = The outer [X,Y] size of the rectangular tube. // isize = The inner [X,Y] size of the rectangular tube. -// h|l = The height or length of the rectangular tube. Default: 1 +// center = If given, overrides `anchor`. A true value sets `anchor=CENTER`, false sets `anchor=UP`. +// shift = [X,Y] amount to shift the center of the top end with respect to the center of the bottom end. +// --- // wall = The thickness of the rectangular tube wall. // size1 = The [X,Y] side of the outside of the bottom of the rectangular tube. // size2 = The [X,Y] side of the outside of the top of the rectangular tube. @@ -570,16 +622,14 @@ function prismoid( // rounding2=[0,5,0,10], irounding2=[0,3,0,8] // ); module rect_tube( - size, isize, - h, shift=[0,0], wall, - size1, size2, - isize1, isize2, + h, size, isize, center, shift=[0,0], + wall, size1, size2, isize1, isize2, rounding=0, rounding1, rounding2, irounding=0, irounding1, irounding2, chamfer=0, chamfer1, chamfer2, ichamfer=0, ichamfer1, ichamfer2, anchor, spin=0, orient=UP, - center, l + l ) { h = first_defined([h,l,1]); assert(is_num(h), "l or h argument required."); @@ -646,17 +696,30 @@ module rect_tube( } } +function rect_tube( + h, size, isize, center, shift=[0,0], + wall, size1, size2, isize1, isize2, + rounding=0, rounding1, rounding2, + irounding=0, irounding1, irounding2, + chamfer=0, chamfer1, chamfer2, + ichamfer=0, ichamfer1, ichamfer2, + anchor, spin=0, orient=UP, + l +) = no_function("rect_tube"); + // Module: right_triangle() // // Usage: -// right_triangle(size, [center]); +// right_triangle(size,
); // // Description: // Creates a 3D right triangular prism with the hypotenuse in the X+Y+ quadrant. // // Arguments: // size = [width, thickness, height] +// center = If given, overrides `anchor`. A true value sets `anchor=CENTER`, false sets `anchor=UP`. +// --- // anchor = Translate so anchor point is at origin (0,0,0). See [anchor](attachments.scad#anchor). Default: `ALLNEG` // spin = Rotate this many degrees around the Z axis after anchor. See [spin](attachments.scad#spin). Default: `0` // orient = Vector to rotate top towards, after spin. See [orient](attachments.scad#orient). Default: `UP` @@ -682,6 +745,9 @@ module right_triangle(size=[1, 1, 1], center, anchor, spin=0, orient=UP) } +function right_triangle(size=[1,1,1], center, anchor, spin=0, orient=UP) = + no_function("right_triangle"); + // Section: Cylindroids @@ -689,32 +755,34 @@ module right_triangle(size=[1, 1, 1], center, anchor, spin=0, orient=UP) // Module: cyl() // // Description: -// Creates cylinders in various anchors and orientations, -// with optional rounding 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`. -// Note that that chamfers and rounding cannot cross the -// midpoint of the cylinder's length. +// Creates cylinders in various anchorings and orientations, with optional rounding and chamfers. +// You can use `h` and `l` interchangably, and all variants allow specifying size by either `r`|`d`, +// or `r1`|`d1` and `r2`|`d2`. Note: the chamfers and rounding cannot be cumulatively longer than +// the cylinder's length. // // Usage: Normal Cylinders -// cyl(l|h, r|d, [circum], [realign], [center]); -// cyl(l|h, r1|d1, r2/d2, [circum], [realign], [center]); +// cyl(l|h, r,
, , ); +// cyl(l|h, d=, ...); +// cyl(l|h, r1=, r2=, ...); +// cyl(l|h, d1=, d2=, ...); // // Usage: Chamferred Cylinders -// cyl(l|h, r|d, chamfer, [chamfang], [from_end], [circum], [realign], [center]); -// cyl(l|h, r|d, chamfer1, [chamfang1], [from_end], [circum], [realign], [center]); -// cyl(l|h, r|d, chamfer2, [chamfang2], [from_end], [circum], [realign], [center]); -// cyl(l|h, r|d, chamfer1, chamfer2, [chamfang1], [chamfang2], [from_end], [circum], [realign], [center]); +// cyl(l|h, r|d, chamfer=, , , ...); +// cyl(l|h, r|d, chamfer1=, , , ...); +// cyl(l|h, r|d, chamfer2=, , , ...); +// cyl(l|h, r|d, chamfer1=, chamfer2=, , , , ...); // // Usage: Rounded End Cylinders -// cyl(l|h, r|d, rounding, [circum], [realign], [center]); -// cyl(l|h, r|d, rounding1, [circum], [realign], [center]); -// cyl(l|h, r|d, rounding2, [circum], [realign], [center]); -// cyl(l|h, r|d, rounding1, rounding2, [circum], [realign], [center]); +// cyl(l|h, r|d, rounding=, ...); +// cyl(l|h, r|d, rounding1=, ...); +// cyl(l|h, r|d, rounding2=, ...); +// cyl(l|h, r|d, rounding1=, rounding2=, ...); // // Arguments: -// l / h = Length of cylinder along oriented axis. (Default: 1.0) -// r = Radius of cylinder. +// l / h = Length of cylinder along oriented axis. Default: 1 +// r = Radius of cylinder. Default: 1 +// center = If given, overrides `anchor`. A true value sets `anchor=CENTER`, false sets `anchor=DOWN`. +// --- // r1 = Radius of the negative (X-, Y-, Z-) end of cylinder. // r2 = Radius of the positive (X+, Y+, Z+) end of cylinder. // d = Diameter of cylinder. @@ -722,20 +790,19 @@ module right_triangle(size=[1, 1, 1], center, anchor, spin=0, orient=UP) // d2 = Diameter of the positive (X+, Y+, Z+) end of cylinder. // circum = If true, cylinder should circumscribe the circle of the given size. Otherwise inscribes. Default: `false` // chamfer = The size of the chamfers on the ends of the cylinder. Default: none. -// chamfer1 = The size of the chamfer on the axis-negative end of the cylinder. Default: none. -// chamfer2 = The size of the chamfer on the axis-positive end of the cylinder. Default: none. +// chamfer1 = The size of the chamfer on the bottom end of the cylinder. Default: none. +// chamfer2 = The size of the chamfer on the top end of the cylinder. Default: none. // chamfang = The angle in degrees of the chamfers on the ends of the cylinder. -// chamfang1 = The angle in degrees of the chamfer on the axis-negative end of the cylinder. -// chamfang2 = The angle in degrees of the chamfer on the axis-positive end of the cylinder. +// chamfang1 = The angle in degrees of the chamfer on the bottom end of the cylinder. +// chamfang2 = The angle in degrees of the chamfer on the top end of the cylinder. // from_end = If true, chamfer is measured from the end of the cylinder, instead of inset from the edge. Default: `false`. // rounding = The radius of the rounding on the ends of the cylinder. Default: none. -// rounding1 = The radius of the rounding on the axis-negative end of the cylinder. -// rounding2 = The radius of the rounding on the axis-positive end of the cylinder. +// rounding1 = The radius of the rounding on the bottom end of the cylinder. +// rounding2 = The radius of the rounding on the top end of the cylinder. // realign = If true, rotate the cylinder by half the angle of one face. // anchor = Translate so anchor point is at origin (0,0,0). See [anchor](attachments.scad#anchor). Default: `CENTER` // spin = Rotate this many degrees around the Z axis after anchor. See [spin](attachments.scad#spin). Default: `0` // orient = Vector to rotate top towards, after spin. See [orient](attachments.scad#orient). Default: `UP` -// center = If given, overrides `anchor`. A true value sets `anchor=CENTER`, false sets `anchor=DOWN`. // // Example: By Radius // xdistribute(30) { @@ -784,14 +851,14 @@ module right_triangle(size=[1, 1, 1], center, anchor, spin=0, orient=UP) // } // module cyl( - l=undef, h=undef, - r=undef, r1=undef, r2=undef, - d=undef, d1=undef, d2=undef, - chamfer=undef, chamfer1=undef, chamfer2=undef, - chamfang=undef, chamfang1=undef, chamfang2=undef, - rounding=undef, rounding1=undef, rounding2=undef, + h, r, center, + l, r1, r2, + d, d1, d2, + chamfer, chamfer1, chamfer2, + chamfang, chamfang1, chamfang2, + rounding, rounding1, rounding2, circum=false, realign=false, from_end=false, - center, anchor, spin=0, orient=UP + anchor, spin=0, orient=UP ) { l = first_defined([l, h, 1]); _r1 = get_radius(r1=r1, r=r, d1=d1, d=d, dflt=1); @@ -889,13 +956,17 @@ module cyl( // Description: // Creates a cylinder oriented along the X axis. // -// Usage: -// xcyl(l|h, r|d, [anchor]); -// xcyl(l|h, r1|d1, r2|d2, [anchor]); +// Usage: Typical +// xcyl(l|h, r, ); +// xcyl(l|h, d=, ); +// xcyl(l|h, r1=|d1=, r2=|d2=, ); +// Usage: Attaching Children +// xcyl(l|h, r, ) ; // // Arguments: -// l / h = Length of cylinder along oriented axis. (Default: `1.0`) -// r = Radius of cylinder. +// l / h = Length of cylinder along oriented axis. Default: 1 +// r = Radius of cylinder. Default: 1 +// --- // r1 = Optional radius of left (X-) end of cylinder. // r2 = Optional radius of right (X+) end of cylinder. // d = Optional diameter of cylinder. (use instead of `r`) @@ -914,7 +985,7 @@ 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, anchor=CENTER) +module xcyl(h, r, d, r1, r2, d1, d2, l, anchor=CENTER) { 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); @@ -932,13 +1003,17 @@ module xcyl(l=undef, r=undef, d=undef, r1=undef, r2=undef, d1=undef, d2=undef, h // Description: // Creates a cylinder oriented along the Y axis. // -// Usage: -// ycyl(l|h, r|d, [anchor]); -// ycyl(l|h, r1|d1, r2|d2, [anchor]); +// Usage: Typical +// ycyl(l|h, r, ); +// ycyl(l|h, d=, ); +// ycyl(l|h, r1=|d1=, r2=|d2=, ); +// Usage: Attaching Children +// ycyl(l|h, r, ) ; // // Arguments: // l / h = Length of cylinder along oriented axis. (Default: `1.0`) // r = Radius of cylinder. +// --- // r1 = Radius of front (Y-) end of cone. // r2 = Radius of back (Y+) end of one. // d = Diameter of cylinder. @@ -957,7 +1032,7 @@ 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, r, d, r1, r2, d1, d2, h, anchor=CENTER) +module ycyl(h, r, d, r1, r2, d1, d2, l, anchor=CENTER) { 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); @@ -975,13 +1050,17 @@ module ycyl(l, r, d, r1, r2, d1, d2, h, anchor=CENTER) // Description: // Creates a cylinder oriented along the Z axis. // -// Usage: -// zcyl(l|h, r|d, [anchor]); -// zcyl(l|h, r1|d1, r2|d2, [anchor]); +// Usage: Typical +// zcyl(l|h, r, ); +// zcyl(l|h, d=, ); +// zcyl(l|h, r1=|d1=, r2=|d2=, ); +// Usage: Attaching Children +// zcyl(l|h, r, ) ; // // Arguments: // l / h = Length of cylinder along oriented axis. (Default: 1.0) // r = Radius of cylinder. +// --- // r1 = Radius of front (Y-) end of cone. // r2 = Radius of back (Y+) end of one. // d = Diameter of cylinder. @@ -1000,7 +1079,7 @@ module ycyl(l, r, d, r1, r2, d1, d2, h, anchor=CENTER) // 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, anchor=CENTER) +module zcyl(h, r, d, r1, r2, d1, d2, l, anchor=CENTER) { cyl(l=l, h=h, r=r, r1=r1, r2=r2, d=d, d1=d1, d2=d2, orient=UP, anchor=anchor) children(); } @@ -1012,27 +1091,32 @@ module zcyl(l=undef, r=undef, d=undef, r1=undef, r2=undef, d1=undef, d2=undef, h // Description: // Makes a hollow tube with the given outer size and wall thickness. // -// Usage: -// tube(h|l, ir|id, wall, [realign]); -// tube(h|l, or|od, wall, [realign]); -// tube(h|l, ir|id, or|od, [realign]); -// tube(h|l, ir1|id1, ir2|id2, wall, [realign]); -// tube(h|l, or1|od1, or2|od2, wall, [realign]); -// tube(h|l, ir1|id1, ir2|id2, or1|od1, or2|od2, [realign]); +// Usage: Typical +// tube(h|l, or, ir,
, ); +// tube(h|l, or=|od=, ir=|id=, ...); +// tube(h|l, ir|id, wall, ...); +// tube(h|l, or|od, wall, ...); +// tube(h|l, ir1|id1, ir2|id2, wall, ...); +// tube(h|l, or1|od1, or2|od2, wall, ...); +// tube(h|l, ir1|id1, ir2|id2, or1|od1, or2|od2, ); +// Usage: Attaching Children +// tube(h|l, or, ir,
) ; // // Arguments: -// h / l = height of tube. (Default: 1) -// or = Outer radius of tube. -// or1 = Outer radius of bottom of tube. (Default: value of r) -// or2 = Outer radius of top of tube. (Default: value of r) +// h / l = height of tube. Default: 1 +// or = Outer radius of tube. Default: 1 +// ir = Inner radius of tube. +// center = If given, overrides `anchor`. A true value sets `anchor=CENTER`, false sets `anchor=DOWN`. +// --- // od = Outer diameter of tube. +// id = Inner diameter of tube. +// wall = horizontal thickness of tube wall. Default 0.5 +// or1 = Outer radius of bottom of tube. Default: value of r) +// or2 = Outer radius of top of tube. Default: value of r) // od1 = Outer diameter of bottom of tube. // od2 = Outer diameter of top of tube. -// wall = horizontal thickness of tube wall. (Default 0.5) -// ir = Inner radius of tube. // ir1 = Inner radius of bottom of tube. // ir2 = Inner radius of top of tube. -// id = Inner diameter of tube. // id1 = Inner diameter of bottom of tube. // id2 = Inner diameter of top of tube. // realign = If true, rotate the tube by half the angle of one face. @@ -1054,34 +1138,22 @@ module zcyl(l=undef, r=undef, d=undef, r1=undef, r2=undef, d1=undef, d2=undef, h // Example: Standard Connectors // tube(h=30, or=40, wall=5) show_anchors(); module tube( - h, wall=undef, - r=undef, r1=undef, r2=undef, - d=undef, d1=undef, d2=undef, - or=undef, or1=undef, or2=undef, - od=undef, od1=undef, od2=undef, - ir=undef, id=undef, ir1=undef, - ir2=undef, id1=undef, id2=undef, - anchor, spin=0, orient=UP, - center, realign=false, l + h, or, ir, center, + od, id, wall, + or1, or2, od1, od2, + ir1, ir2, id1, id2, + realign=false, l, + anchor, spin=0, orient=UP ) { - function safe_add(x,wall) = is_undef(x)? undef : x+wall; h = first_defined([h,l,1]); - orr1 = get_radius( - r=first_defined([or1, r1, or, r]), - d=first_defined([od1, d1, od, d]), - dflt=undef - ); - orr2 = get_radius( - r=first_defined([or2, r2, or, r]), - d=first_defined([od2, d2, od, d]), - dflt=undef - ); + orr1 = get_radius(r1=or1, r=or, d1=od1, d=od, dflt=undef); + orr2 = get_radius(r1=or2, r=or, d1=od2, d=od, dflt=undef); irr1 = get_radius(r1=ir1, r=ir, d1=id1, d=id, dflt=undef); irr2 = get_radius(r1=ir2, r=ir, d1=id2, d=id, dflt=undef); - r1 = is_num(orr1)? orr1 : is_num(irr1)? irr1+wall : undef; - r2 = is_num(orr2)? orr2 : is_num(irr2)? irr2+wall : undef; - ir1 = is_num(irr1)? irr1 : is_num(orr1)? orr1-wall : undef; - ir2 = is_num(irr2)? irr2 : is_num(orr2)? orr2-wall : undef; + r1 = default(orr1, u_add(irr1,wall)); + r2 = default(orr2, u_add(irr2,wall)); + ir1 = default(irr1, u_sub(orr1,wall)); + ir2 = default(irr2, u_sub(orr2,wall)); assert(ir1 <= r1, "Inner radius is larger than outer radius."); assert(ir2 <= r2, "Inner radius is larger than outer radius."); sides = segs(max(r1,r2)); @@ -1100,18 +1172,54 @@ module tube( // Module: torus() // +// Usage: Typical +// torus(r_maj|d_maj, r_min|d_min,
, ...); +// torus(or|od, ir|id, ...); +// torus(r_maj|d_maj, or|od, ...); +// torus(r_maj|d_maj, ir|id, ...); +// torus(r_min|d_min, or|od, ...); +// torus(r_min|d_min, ir|id, ...); +// Usage: Attaching Children +// torus(or|od, ir|id, ...) ;; +// // Description: // Creates a torus shape. // -// Usage: -// torus(r|d, r2|d2); -// torus(or|od, ir|id); +// Figure(2D,Med): +// module text3d(t,size=8) text(text=t,size=size,font="Helvetica", halign="center",valign="center"); +// module dashcirc(r,start=0,angle=359.9,dashlen=5) let(step=360*dashlen/(2*r*PI)) for(a=[start:step:start+angle]) stroke(arc(r=r,start=a,angle=step/2)); +// r = 75; r2 = 30; +// down(r2+0.1) #torus(r_maj=r, r_min=r2, $fn=72); +// color("blue") linear_extrude(height=0.01) { +// dashcirc(r=r,start=15,angle=45); +// dashcirc(r=r-r2, start=90+15, angle=60); +// dashcirc(r=r+r2, start=180+45, angle=30); +// dashcirc(r=r+r2, start=15, angle=30); +// } +// rot(240) color("blue") linear_extrude(height=0.01) { +// stroke([[0,0],[r+r2,0]], endcaps="arrow2",width=2); +// right(r) fwd(9) rot(-240) text3d("or",size=10); +// } +// rot(135) color("blue") linear_extrude(height=0.01) { +// stroke([[0,0],[r-r2,0]], endcaps="arrow2",width=2); +// right((r-r2)/2) back(8) rot(-135) text3d("ir",size=10); +// } +// rot(45) color("blue") linear_extrude(height=0.01) { +// stroke([[0,0],[r,0]], endcaps="arrow2",width=2); +// right(r/2) back(8) text3d("r_maj",size=9); +// } +// rot(30) color("blue") linear_extrude(height=0.01) { +// stroke([[r,0],[r+r2,0]], endcaps="arrow2",width=2); +// right(r+r2/2) fwd(8) text3d("r_min",size=7); +// } // // Arguments: -// r = major radius of torus ring. (use with of 'r2', or 'd2') -// r2 = minor radius of torus ring. (use with of 'r', or 'd') -// d = major diameter of torus ring. (use with of 'r2', or 'd2') -// d2 = minor diameter of torus ring. (use with of 'r', or 'd') +// r_maj = major radius of torus ring. (use with of 'r_min', or 'd_min') +// r_min = minor radius of torus ring. (use with of 'r_maj', or 'd_maj') +// center = If given, overrides `anchor`. A true value sets `anchor=CENTER`, false sets `anchor=DOWN`. +// --- +// d_maj = major diameter of torus ring. (use with of 'r_min', or 'd_min') +// d_min = minor diameter of torus ring. (use with of 'r_maj', or 'd_maj') // or = outer radius of the torus. (use with 'ir', or 'id') // ir = inside radius of the torus. (use with 'or', or 'od') // od = outer diameter of the torus. (use with 'ir' or 'id') @@ -1121,23 +1229,35 @@ module tube( // // Example: // // These all produce the same torus. -// torus(r=22.5, r2=7.5); -// torus(d=45, d2=15); +// torus(r_maj=22.5, r_min=7.5); +// torus(d_maj=45, d_min=15); // torus(or=30, ir=15); // torus(od=60, id=30); +// torus(d_maj=45, id=30); +// torus(d_maj=45, od=60); +// torus(d_min=15, id=30); +// torus(d_min=15, od=60); // Example: Standard 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, - center, anchor, spin=0, orient=UP + r_maj, r_min, center, + d_maj, d_min, + or, od, ir, id, + anchor, spin=0, orient=UP ) { - 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); + _or = get_radius(r=or, d=od, dflt=undef); + _ir = get_radius(r=ir, d=id, dflt=undef); + _r_maj = get_radius(r=r_maj, d=d_maj, dflt=undef); + _r_min = get_radius(r=r_min, d=d_min, dflt=undef); + majrad = is_finite(_r_maj)? _r_maj : + is_finite(_ir) && is_finite(_or)? (_or + _ir)/2 : + is_finite(_ir) && is_finite(_r_min)? (_ir + _r_min) : + is_finite(_or) && is_finite(_r_min)? (_or - _r_min) : + assert(false, "Bad Parameters"); + minrad = is_finite(_r_min)? _r_min : + is_finite(_ir)? (majrad - _ir) : + is_finite(_or)? (_or - majrad) : + assert(false, "Bad Parameters"); anchor = get_anchor(anchor, center, BOT, CENTER); attachable(anchor,spin,orient, r=(majrad+minrad), l=minrad*2) { rotate_extrude(convexity=4) { @@ -1153,10 +1273,12 @@ module torus( // Function&Module: spheroid() -// Usage: As Module -// spheroid(r|d, [circum], [style]) +// Usage: Typical +// spheroid(r|d, ,