mirror of
https://github.com/BelfrySCAD/BOSL2.git
synced 2024-12-29 16:29:40 +00:00
fix teardrop for extents to make proper cuboids
This commit is contained in:
parent
9adcf15104
commit
8cd43a6637
2 changed files with 62 additions and 21 deletions
|
@ -1191,12 +1191,16 @@ module jittered_poly(path, dist=1/512) {
|
||||||
// Description:
|
// Description:
|
||||||
// Makes a 2D teardrop shape. Useful for extruding into 3D printable holes. Uses "intersect" style anchoring.
|
// Makes a 2D teardrop shape. Useful for extruding into 3D printable holes. Uses "intersect" style anchoring.
|
||||||
// The cap_h parameter truncates the top of the teardrop. If cap_h is taller than the untruncated form then
|
// The cap_h parameter truncates the top of the teardrop. If cap_h is taller than the untruncated form then
|
||||||
// the result will be the full, untruncated shape.
|
// the result will be the full, untruncated shape. The segments of the bottom section of the teardrop are
|
||||||
|
// calculated to be the same as a circle or cylinder when rotated 90 degrees. (Note that this agreement is poor when `$fn=6` or `$fn=7`.
|
||||||
|
// 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.
|
||||||
//
|
//
|
||||||
// Usage: As Module
|
// Usage: As Module
|
||||||
// teardrop2d(r/d=, [ang], [cap_h]) [ATTACHMENTS];
|
// teardrop2d(r/d=, [ang], [cap_h]) [ATTACHMENTS];
|
||||||
// Usage: As Function
|
// Usage: As Function
|
||||||
// path = teardrop2d(r/d=, [ang], [cap_h]);
|
// path = teardrop2d(r|d=, [ang], [cap_h]);
|
||||||
//
|
//
|
||||||
// Topics: Shapes (2D), Paths (2D), Path Generators, Attachable
|
// Topics: Shapes (2D), Paths (2D), Path Generators, Attachable
|
||||||
//
|
//
|
||||||
|
@ -1208,6 +1212,8 @@ module jittered_poly(path, dist=1/512) {
|
||||||
// cap_h = if given, height above center where the shape will be truncated.
|
// cap_h = if given, height above center where the shape will be truncated.
|
||||||
// ---
|
// ---
|
||||||
// d = diameter of circular portion of bottom. (Use instead of r)
|
// d = diameter of circular portion of bottom. (Use instead of r)
|
||||||
|
// circum = if true, create a circumscribing teardrop. Default: false
|
||||||
|
// realign = if true, change whether bottom of teardrop is a point or a flat. Default: false
|
||||||
// anchor = Translate so anchor point is at origin (0,0,0). See [anchor](attachments.scad#subsection-anchor). Default: `CENTER`
|
// anchor = Translate so anchor point is at origin (0,0,0). See [anchor](attachments.scad#subsection-anchor). Default: `CENTER`
|
||||||
// spin = Rotate this many degrees around the Z axis after anchor. See [spin](attachments.scad#subsection-spin). Default: `0`
|
// spin = Rotate this many degrees around the Z axis after anchor. See [spin](attachments.scad#subsection-spin). Default: `0`
|
||||||
//
|
//
|
||||||
|
@ -1217,9 +1223,9 @@ module jittered_poly(path, dist=1/512) {
|
||||||
// teardrop2d(r=30, ang=30, cap_h=40);
|
// teardrop2d(r=30, ang=30, cap_h=40);
|
||||||
// Example(2D): Close Crop
|
// Example(2D): Close Crop
|
||||||
// teardrop2d(r=30, ang=30, cap_h=20);
|
// teardrop2d(r=30, ang=30, cap_h=20);
|
||||||
module teardrop2d(r, ang=45, cap_h, d, anchor=CENTER, spin=0)
|
module teardrop2d(r, ang=45, cap_h, d, circum=false, realign=false, anchor=CENTER, spin=0)
|
||||||
{
|
{
|
||||||
path = teardrop2d(r=r, d=d, ang=ang, cap_h=cap_h);
|
path = teardrop2d(r=r, d=d, ang=ang, circum=circum, realign=realign, cap_h=cap_h);
|
||||||
attachable(anchor,spin, two_d=true, path=path, extent=false) {
|
attachable(anchor,spin, two_d=true, path=path, extent=false) {
|
||||||
polygon(path);
|
polygon(path);
|
||||||
children();
|
children();
|
||||||
|
@ -1229,20 +1235,54 @@ module teardrop2d(r, ang=45, cap_h, d, anchor=CENTER, spin=0)
|
||||||
// _extrapt = true causes the point to be duplicated so a teardrop with no cap
|
// _extrapt = true causes the point to be duplicated so a teardrop with no cap
|
||||||
// has the same point count as one with a cap.
|
// has the same point count as one with a cap.
|
||||||
|
|
||||||
function teardrop2d(r, ang=45, cap_h, d, anchor=CENTER, spin=0, _extrapt=false) =
|
function teardrop2d(r, ang=45, cap_h, d, circum=false, realign=false, anchor=CENTER, spin=0, _extrapt=false) =
|
||||||
let(
|
let(
|
||||||
r = get_radius(r=r, d=d, dflt=1),
|
r = get_radius(r=r, d=d, dflt=1),
|
||||||
ang2=90-ang,
|
|
||||||
minheight = r*sin(ang),
|
minheight = r*sin(ang),
|
||||||
maxheight = r/cos(ang2)
|
maxheight = r/sin(ang), //cos(90-ang),
|
||||||
|
pointycap = is_undef(cap_h) || cap_h>=maxheight
|
||||||
)
|
)
|
||||||
assert(is_undef(cap_h) || cap_h>=minheight, str("cap_h cannot be less than ",minheight," but it is ",cap_h))
|
assert(is_undef(cap_h) || cap_h>=minheight, str("cap_h cannot be less than ",minheight," but it is ",cap_h))
|
||||||
let(
|
let(
|
||||||
firstpt = is_undef(cap_h) || cap_h>=maxheight ? [[0,maxheight]]
|
cap = [
|
||||||
: [[(maxheight-cap_h)*tan(ang), cap_h]],
|
pointycap? [0,maxheight] : [(maxheight-cap_h)*tan(ang), cap_h],
|
||||||
lastpt = !_extrapt && (is_undef(cap_h) || cap_h>=maxheight) ? [] : [[-firstpt[0].x,firstpt[0].y]],
|
r*[cos(ang),sin(ang)]
|
||||||
path = concat(firstpt, arc(angle=[ang, -180-ang], r=r), lastpt)
|
],
|
||||||
) reorient(anchor,spin, two_d=true, path=path, p=path, extent=false);
|
fullcircle = ellipse(r=r, realign=realign, circum=circum,spin=90),
|
||||||
|
|
||||||
|
// Chose the point on the circle that is lower than the cap but also creates a segment bigger than
|
||||||
|
// seglen/3 so we don't have a teeny tiny segment at the end of the cap
|
||||||
|
path = !circum ?
|
||||||
|
let(seglen = norm(fullcircle[0]-fullcircle[1]))
|
||||||
|
[
|
||||||
|
each cap,
|
||||||
|
for (p=fullcircle)
|
||||||
|
if (
|
||||||
|
p.y<last(cap).y-EPSILON
|
||||||
|
&& norm([abs(p.x)-last(cap).x,p.y-last(cap.y)])>seglen/3
|
||||||
|
) p,
|
||||||
|
xflip(cap[1]),
|
||||||
|
if (_extrapt || !pointycap) xflip(cap[0])
|
||||||
|
]
|
||||||
|
: let(
|
||||||
|
isect = [for(i=[0:1:len(fullcircle)/4])
|
||||||
|
let(p = line_intersection(cap, select(fullcircle,[i,i+1]), bounded1=RAY, bounded2=SEGMENT))
|
||||||
|
if (p) [i,p]
|
||||||
|
],
|
||||||
|
i = last(isect)[0],
|
||||||
|
p = last(isect)[1],
|
||||||
|
ff=echo(isect)
|
||||||
|
)
|
||||||
|
[
|
||||||
|
cap[0],
|
||||||
|
p,
|
||||||
|
each select(fullcircle,i+1,-i-1-(realign?1:0)),
|
||||||
|
xflip(p),
|
||||||
|
if(_extrapt || !pointycap) xflip(cap[0])
|
||||||
|
]
|
||||||
|
)
|
||||||
|
reorient(anchor,spin, two_d=true, path=path, p=path, extent=false);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Function&Module: egg()
|
// Function&Module: egg()
|
||||||
|
|
|
@ -2502,6 +2502,7 @@ function torus(
|
||||||
// ang = Angle of hat walls from the Z axis. Default: 45 degrees
|
// 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. Default: `undef` (no truncation)
|
// cap_h = If given, height above center where the shape will be truncated. Default: `undef` (no truncation)
|
||||||
// ---
|
// ---
|
||||||
|
// circum = produce a circumscribing teardrop shape. Default: false
|
||||||
// r1 = Radius of circular portion of the front end of the teardrop shape.
|
// r1 = Radius of circular portion of the front end of the teardrop shape.
|
||||||
// r2 = Radius of circular portion of the back end of the teardrop shape.
|
// r2 = Radius of circular portion of the back end of the teardrop shape.
|
||||||
// d = Diameter of circular portion of the teardrop shape.
|
// d = Diameter of circular portion of the teardrop shape.
|
||||||
|
@ -2512,6 +2513,7 @@ function torus(
|
||||||
// chamfer = Specifies size of chamfer as distance along the bottom and top faces. Default: 0
|
// chamfer = Specifies size of chamfer as distance along the bottom and top faces. Default: 0
|
||||||
// chamfer1 = Specifies size of chamfer on bottom as distance along bottom face. Default: 0
|
// chamfer1 = Specifies size of chamfer on bottom as distance along bottom face. Default: 0
|
||||||
// chamfer2 = Specifies size of chamfer on top as distance along top face. Default: 0
|
// chamfer2 = Specifies size of chamfer on top as distance along top face. Default: 0
|
||||||
|
// realign = Passes realign option to teardrop2d, which shifts face alignment. Default: false
|
||||||
// anchor = Translate so anchor point is at origin (0,0,0). See [anchor](attachments.scad#subsection-anchor). Default: `CENTER`
|
// anchor = Translate so anchor point is at origin (0,0,0). See [anchor](attachments.scad#subsection-anchor). Default: `CENTER`
|
||||||
// spin = Rotate this many degrees around the Z axis after anchor. See [spin](attachments.scad#subsection-spin). Default: `0`
|
// spin = Rotate this many degrees around the Z axis after anchor. See [spin](attachments.scad#subsection-spin). Default: `0`
|
||||||
// orient = Vector to rotate top towards, after spin. See [orient](attachments.scad#subsection-orient). Default: `UP`
|
// orient = Vector to rotate top towards, after spin. See [orient](attachments.scad#subsection-orient). Default: `UP`
|
||||||
|
@ -2541,7 +2543,8 @@ function torus(
|
||||||
// teardrop(d1=20, d2=30, h=20, cap_h1=11, cap_h2=16)
|
// teardrop(d1=20, d2=30, h=20, cap_h1=11, cap_h2=16)
|
||||||
// show_anchors(std=false);
|
// show_anchors(std=false);
|
||||||
|
|
||||||
module teardrop(h, r, ang=45, cap_h, r1, r2, d, d1, d2, cap_h1, cap_h2, l, length, height, chamfer, chamfer1, chamfer2,anchor=CENTER, spin=0, orient=UP)
|
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)
|
||||||
{
|
{
|
||||||
length = one_defined([l, h, length, height],"l,h,length,height");
|
length = one_defined([l, h, length, height],"l,h,length,height");
|
||||||
r1 = get_radius(r=r, r1=r1, d=d, d1=d1);
|
r1 = get_radius(r=r, r1=r1, d=d, d1=d1);
|
||||||
|
@ -2550,7 +2553,6 @@ module teardrop(h, r, ang=45, cap_h, r1, r2, d, d1, d2, cap_h1, cap_h2, l, lengt
|
||||||
tip_y2 = r2/cos(90-ang);
|
tip_y2 = r2/cos(90-ang);
|
||||||
_cap_h1 = min(default(cap_h1, tip_y1), tip_y1);
|
_cap_h1 = min(default(cap_h1, tip_y1), tip_y1);
|
||||||
_cap_h2 = min(default(cap_h2, tip_y2), tip_y2);
|
_cap_h2 = min(default(cap_h2, tip_y2), tip_y2);
|
||||||
f= echo(fff=_cap_h1,_cap_h2);
|
|
||||||
capvec = unit([0, _cap_h1-_cap_h2, length]);
|
capvec = unit([0, _cap_h1-_cap_h2, length]);
|
||||||
anchors = [
|
anchors = [
|
||||||
named_anchor("cap", [0,0,(_cap_h1+_cap_h2)/2], capvec),
|
named_anchor("cap", [0,0,(_cap_h1+_cap_h2)/2], capvec),
|
||||||
|
@ -2559,14 +2561,14 @@ 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)
|
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,
|
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));
|
||||||
children();
|
children();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function teardrop(h, r, ang=45, cap_h, r1, r2, d, d1, d2, cap_h1, cap_h2, chamfer, chamfer1, chamfer2,
|
function teardrop(h, r, ang=45, cap_h, r1, r2, d, d1, d2, cap_h1, cap_h2, chamfer, chamfer1, chamfer2, circum=false, realign=false,
|
||||||
l, length, height, anchor=CENTER, spin=0, orient=UP) =
|
l, length, height, anchor=CENTER, spin=0, orient=UP) =
|
||||||
let(
|
let(
|
||||||
r1 = get_radius(r=r, r1=r1, d=d, d1=d1, dflt=1),
|
r1 = get_radius(r=r, r1=r1, d=d, d1=d1, dflt=1),
|
||||||
|
@ -2577,8 +2579,8 @@ function teardrop(h, r, ang=45, cap_h, r1, r2, d, d1, d2, cap_h1, cap_h2, chamf
|
||||||
chamfer1 = first_defined([chamfer1,chamfer,0]),
|
chamfer1 = first_defined([chamfer1,chamfer,0]),
|
||||||
chamfer2 = first_defined([chamfer2,chamfer,0]),
|
chamfer2 = first_defined([chamfer2,chamfer,0]),
|
||||||
sides = segs(max(r1,r2)),
|
sides = segs(max(r1,r2)),
|
||||||
profile1 = teardrop2d(r=r1, ang=ang, cap_h=cap_h1, $fn=sides, _extrapt=true),
|
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, _extrapt=true),
|
profile2 = teardrop2d(r=r2, ang=ang, cap_h=cap_h2, $fn=sides, circum=circum, realign=realign,_extrapt=true),
|
||||||
tip_y1 = r1/cos(90-ang),
|
tip_y1 = r1/cos(90-ang),
|
||||||
tip_y2 = r2/cos(90-ang),
|
tip_y2 = r2/cos(90-ang),
|
||||||
_cap_h1 = min(default(cap_h1, tip_y1), tip_y1),
|
_cap_h1 = min(default(cap_h1, tip_y1), tip_y1),
|
||||||
|
@ -2590,10 +2592,9 @@ function teardrop(h, r, ang=45, cap_h, r1, r2, d, d1, d2, cap_h1, cap_h2, chamf
|
||||||
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_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"),
|
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))
|
cprof1 = r1==chamfer1 ? repeat([0,0],len(profile1))
|
||||||
: teardrop2d(r=r1-chamfer1, ang=ang, cap_h=u_add(cap_h1,-chamfer1), $fn=sides, _extrapt=true),
|
: teardrop2d(r=r1-chamfer1, ang=ang, cap_h=u_add(cap_h1,-chamfer1), $fn=sides, circum=circum, realign=realign,_extrapt=true),
|
||||||
cprof2 = r2==chamfer2 ? repeat([0,0],len(profile2))
|
cprof2 = r2==chamfer2 ? repeat([0,0],len(profile2))
|
||||||
: teardrop2d(r=r2-chamfer2, ang=ang, cap_h=u_add(cap_h2,-chamfer2), $fn=sides, _extrapt=true),
|
: teardrop2d(r=r2-chamfer2, ang=ang, cap_h=u_add(cap_h2,-chamfer2), $fn=sides, circum=circum, realign=realign,_extrapt=true),
|
||||||
fefda= echo(lens=len(cprof1),len(cprof2)),
|
|
||||||
anchors = [
|
anchors = [
|
||||||
named_anchor("cap", [0,0,(_cap_h1+_cap_h2)/2], capvec),
|
named_anchor("cap", [0,0,(_cap_h1+_cap_h2)/2], capvec),
|
||||||
named_anchor("cap_fwd", [0,-length/2,_cap_h1], unit((capvec+FWD)/2)),
|
named_anchor("cap_fwd", [0,-length/2,_cap_h1], unit((capvec+FWD)/2)),
|
||||||
|
|
Loading…
Reference in a new issue