doc rewrite for shapes2d

teardrop() add support for bot_corner
This commit is contained in:
Adrian Mariano 2025-05-05 19:47:00 -04:00
parent fbc13d7d63
commit 3859d3ecc6
2 changed files with 43 additions and 25 deletions

View file

@ -1321,23 +1321,29 @@ module jittered_poly(path, dist=1/512) {
// Section: Curved 2D Shapes
// When called as a module, makes a 2D teardrop shape. Useful for extruding into 3D printable holes as it limits overhang to a desired angle.
// Uses "intersect" style anchoring.
// Function&Module: teardrop2d()
// Synopsis: Creates a 2D teardrop shape.
// SynTags: Geom, Path
// Topics: Shapes (2D), Paths (2D), Path Generators, Attachable
// See Also: teardrop(), onion(), keyhole()
// Description:
// When called as a module, makes a 2D teardrop shape. Useful for extruding into 3D printable holes as it limits overhang to a desired angle.
// Uses "intersect" style anchoring.
// The cap_h parameter truncates the top of the teardrop at the specified distance from the center. If cap_h is taller than the untruncated form then
// the result will be the full, untruncated shape. The segments of the round section of the teardrop
// the same as a circle or cylinder when rotated 90 degrees. (Note that this agreement is poor when `$fn=6` or `$fn=7`.)
// The number of facets is only approximately equal to `$fn`, and may also change if you set `realign=true`, which produces a flat base on the teardrop.
// A teardrop shape is a circle that comes to a point at the top. This shape is useful for extruding into 3d printable holes as it
// limits the overhang angle. A bottom point can also help ensure a 3d printable hole. This module can make a teardrop shape
// or produce the path for a teardrop with a point at the top or with the top truncated to create a flat cap. It also provides the option to add a bottom point.
// .
// The default teardrop has a pointed top and round bottom. The `ang` parameter specifies the angle away from vertical of the two flat segments at the
// top of the shape. The cap_h parameter truncates the top of the teardrop at the specified
// distance from the center. If `cap_h` is taller than the untruncated form then
// the result will be the full, untruncated shape. You can set `cap_h` smaller than the radius to produce a truncated circle. The segments of the round section of the teardrop
// are the same as a circle or cylinder with matching `$fn` when rotated 90 degrees. The number of facets in the teardrop is only approximately
// equal to `$fn`, and may also change if you set `realign=true`, which adjusts the facets so the bottom of the teardrop has a flat base.
// If `$fn` is a multiple of four then the teardrop will reach its extremes on all four axes. The circum option
// produces a teardrop that circumscribes the circle; in this case set `realign=true` to get a teardrop that meets its internal extremes
// on the axes. To ensure sufficient room in 3d printing applications a bottom corner may also be desirable. You can add this using
// the `bot_corner` parameter, which specifies the length that the corner protrudes from the ideal circle.
// When called as a function, returns a 2D path for the shape, starting at the top corner or top right corner.
// produces a teardrop that circumscribes the circle; in this, `realign=true` produces a teardrop that meets its internal extremes
// on the axes. You can add a bottom corner using the `bot_corner` parameter, which specifies the length that the corner protrudes from the ideal circle.
// Usage: As Module
// teardrop2d(r/d=, [ang], [cap_h], [circum=], [realign=], [bot_corner=]) [ATTACHMENTS];
// Usage: As Function
@ -1379,7 +1385,7 @@ function teardrop2d(r, ang=45, cap_h, d, circum=false, realign=false, anchor=CEN
r = get_radius(r=r, d=d, dflt=1)
)
bot_corner!=0 ?
assert(all_positive([bot_corner]), "bot_corner must be nonnegative")
assert(all_nonnegative([bot_corner]),"bot_corner must be nonnegative")
let(
path = teardrop2d(r=r,ang=ang, cap_h=cap_h, circum=circum, realign=realign),
corner = -r-bot_corner,

View file

@ -3564,19 +3564,21 @@ function torus(
// Topics: Shapes (3D), Attachable, VNF Generators, FDM Optimized
// See Also: onion(), teardrop2d()
// Description:
// Makes a teardrop shape in the XZ plane. Useful for 3D printable holes.
// Makes a teardrop extrusion along the Y axis, which is useful for 3D printable holes.
// Optional chamfers can be added with positive or negative distances. A positive distance
// specifies the amount to inset the chamfer along the front/back faces of the shape.
// The chamfer will extend the same y distance into the shape. If the radii are the same
// then the chamfer will be a 45 degree chamfer, but in other cases it will not.
// Note that with caps, the chamfer must not be so big that it makes the cap height illegal.
//
// With caps, the chamfer must not be so big that it makes the cap height illegal.
// Similarly the chamfer cannot be larger than `bot_corner` if it is set, and if you do
// set chamfer exactly equal to bottom corner, then `$fn` must be even if `realign` is false
// and odd otherwise.
// Usage: Typical
// teardrop(h|l=|length=|height=, r, [ang], [cap_h], [chamfer=], ...) [ATTACHMENTS];
// teardrop(h|l=|length=|height=, d=, [ang=], [cap_h=], [chamfer=], ...) [ATTACHMENTS];
// teardrop(h|l=|length=|height=, r, [ang], [cap_h], [chamfer=], [bot_corner=], ...) [ATTACHMENTS];
// teardrop(h|l=|length=|height=, d=, [ang=], [cap_h=], [chamfer=], [bot_corner=], ...) [ATTACHMENTS];
// Usage: Psuedo-Conical
// teardrop(h|l=|height=|length=, r1=, r2=, [ang=], [cap_h1=], [cap_h2=], ...) [ATTACHMENTS];
// teardrop(h|l=|height=|length=, d1=, d2=, [ang=], [cap_h1=], [cap_h2=], ...) [ATTACHMENTS];
// teardrop(h|l=|height=|length=, r1=, r2=, [ang=], [cap_h1=], [cap_h2=], [bot_corner1=], [bot_corner2=], ...) [ATTACHMENTS];
// teardrop(h|l=|height=|length=, d1=, d2=, [ang=], [cap_h1=], [cap_h2=], [bot_corner1=], [bot_corner2=], ...) [ATTACHMENTS];
// Usage: As Function
// vnf = teardrop(h|l=|height=|length=, r|d=, [ang=], [cap_h=], ...);
// vnf = teardrop(h|l=|height=|length=, r1=|d1=, r2=|d2=, [ang=], [cap_h=], ...);
@ -3619,6 +3621,8 @@ function torus(
// teardrop(r1=20, r2=30, h=40, cap_h1=25, cap_h2=35);
// Example: Adding chamfers can be useful for a teardrop hole mask
// teardrop(r=10, l=50, chamfer1=2, chamfer2=-1.5);
// Example: This teardrop has a 1 unit clearance at the top and bottom using the cap and the bottom corner:
// teardrop(r=10, l=50, cap_h=11, bot_corner=1);
// Example: Getting a VNF
// vnf = teardrop(r1=25, r2=30, l=20, cap_h1=25, cap_h2=35);
// vnf_polyhedron(vnf);
@ -3630,7 +3634,7 @@ function torus(
// show_anchors(std=false);
module teardrop(h, r, ang=45, cap_h, r1, r2, d, d1, d2, cap_h1, cap_h2, l, length, height, circum=false, realign=false,
chamfer, chamfer1, chamfer2,anchor=CENTER, spin=0, orient=UP)
chamfer, chamfer1, chamfer2,anchor=CENTER, spin=0, orient=UP, bot_corner1, bot_corner2, bot_corner=0)
{
length = one_defined([l, h, length, height],"l,h,length,height");
dummy=assert(is_finite(length) && length>0, "length must be positive");
@ -3649,13 +3653,13 @@ module teardrop(h, r, ang=45, cap_h, r1, r2, d, d1, d2, cap_h1, cap_h2, l, lengt
attachable(anchor,spin,orient, r1=r1, r2=r2, l=length, axis=BACK, anchors=anchors)
{
vnf_polyhedron(teardrop(ang=ang,cap_h=cap_h,r1=r1,r2=r2,cap_h1=cap_h1,cap_h2=cap_h2,circum=circum,realign=realign,
length=length, chamfer1=chamfer1,chamfer2=chamfer2,chamfer=chamfer));
length=length, chamfer1=chamfer1,chamfer2=chamfer2,chamfer=chamfer,bot_corner1=bot_corner1, bot_corner2=bot_corner2,bot_corner=bot_corner));
children();
}
}
function teardrop(h, r, ang=45, cap_h, r1, r2, d, d1, d2, cap_h1, cap_h2, chamfer, chamfer1, chamfer2, circum=false, realign=false,
function teardrop(h, r, ang=45, cap_h, r1, r2, d, d1, d2, cap_h1, cap_h2, chamfer, chamfer1, chamfer2, circum=false, realign=false, bot_corner1, bot_corner2, bot_corner=0,
l, length, height, anchor=CENTER, spin=0, orient=UP) =
let(
r1 = get_radius(r=r, r1=r1, d=d, d1=d1, dflt=1),
@ -3664,11 +3668,13 @@ function teardrop(h, r, ang=45, cap_h, r1, r2, d, d1, d2, cap_h1, cap_h2, chamf
dummy0=assert(is_finite(length) && length>0, "length must be positive"),
cap_h1 = first_defined([cap_h1, cap_h]),
cap_h2 = first_defined([cap_h2, cap_h]),
bot_corner1 = first_defined([bot_corner1, bot_corner]),
bot_corner2 = first_defined([bot_corner2, bot_corner]),
chamfer1 = first_defined([chamfer1,chamfer,0]),
chamfer2 = first_defined([chamfer2,chamfer,0]),
sides = segs(max(r1,r2)),
profile1 = teardrop2d(r=r1, ang=ang, cap_h=cap_h1, $fn=sides, circum=circum, realign=realign,_extrapt=true),
profile2 = teardrop2d(r=r2, ang=ang, cap_h=cap_h2, $fn=sides, circum=circum, realign=realign,_extrapt=true),
profile1 = teardrop2d(r=r1, ang=ang, cap_h=cap_h1, $fn=sides, circum=circum, realign=realign,_extrapt=true, bot_corner=bot_corner1),
profile2 = teardrop2d(r=r2, ang=ang, cap_h=cap_h2, $fn=sides, circum=circum, realign=realign,_extrapt=true, bot_corner=bot_corner2),
tip_y1 = r1/cos(90-ang),
tip_y2 = r2/cos(90-ang),
_cap_h1 = min(default(cap_h1, tip_y1), tip_y1),
@ -3677,12 +3683,18 @@ function teardrop(h, r, ang=45, cap_h, r1, r2, d, d1, d2, cap_h1, cap_h2, chamf
dummy=
assert(abs(chamfer1)+abs(chamfer2) <= length,"chamfers are too big to fit in the length")
assert(chamfer1<=r1 && chamfer2<=r2, "Chamfers cannot be larger than raduis")
assert(bot_corner1==0 || bot_corner1>=chamfer1, "\nchamfer1 doesn't work with bottom corner: must have chamfer1 <= bot_corner1")
assert(bot_corner2==0 || bot_corner2>=chamfer2, "\nchamfer2 doesn't work with bottom corner: must have chamfer2 <= bot_corner2")
assert(bot_corner1==0 || bot_corner1>chamfer1 || sides%2==(realign?1:0),
str("\nWith chamfer1==bot_corner1 and realign=",realign," must have ",realign?"odd":"even"," number of sides, but sides=",sides))
assert(is_undef(cap_h1) || cap_h1-chamfer1 > r1*sin(ang), "chamfer1 is too big to work with the specified cap_h1")
assert(is_undef(cap_h2) || cap_h2-chamfer2 > r2*sin(ang), "chamfer2 is too big to work with the specified cap_h2"),
cprof1 = r1==chamfer1 ? repeat([0,0],len(profile1))
: teardrop2d(r=r1-chamfer1, ang=ang, cap_h=u_add(cap_h1,-chamfer1), $fn=sides, circum=circum, realign=realign,_extrapt=true),
: teardrop2d(r=r1-chamfer1, ang=ang, cap_h=u_add(cap_h1,-chamfer1), bot_corner=bot_corner1==0?0:bot_corner1-chamfer1,
$fn=sides, circum=circum, realign=realign,_extrapt=true),
cprof2 = r2==chamfer2 ? repeat([0,0],len(profile2))
: teardrop2d(r=r2-chamfer2, ang=ang, cap_h=u_add(cap_h2,-chamfer2), $fn=sides, circum=circum, realign=realign,_extrapt=true),
: teardrop2d(r=r2-chamfer2, ang=ang, cap_h=u_add(cap_h2,-chamfer2), bot_corner=bot_corner2==0?0:bot_corner2-chamfer2,
$fn=sides, circum=circum, realign=realign,_extrapt=true),
anchors = [
named_anchor("cap", [0,0,(_cap_h1+_cap_h2)/2], capvec),
named_anchor("cap_fwd", [0,-length/2,_cap_h1], unit((capvec+FWD)/2)),