more anchoring fixes

This commit is contained in:
Adrian Mariano 2021-11-16 20:46:37 -05:00
parent 45e64f309c
commit 47bf93e6cb
3 changed files with 16 additions and 12 deletions

View file

@ -598,6 +598,8 @@ module dashed_stroke(path, dashpat=[3,3], width=1, closed=false) {
// start = Start angle of arc. // start = Start angle of arc.
// wedge = If true, include centerpoint `cp` in output to form pie slice shape. // wedge = If true, include centerpoint `cp` in output to form pie slice shape.
// endpoint = If false exclude the last point (function only). Default: true // endpoint = If false exclude the last point (function only). Default: true
// anchor = Translate so anchor point is at origin (0,0,0). See [anchor](attachments.scad#anchor). (Module only) Default: `CENTER`
// spin = Rotate this many degrees around the Z axis after anchor. See [spin](attachments.scad#spin). (Module only) Default: `0`
// Examples(2D): // Examples(2D):
// arc(N=4, r=30, angle=30, wedge=true); // arc(N=4, r=30, angle=30, wedge=true);
// arc(r=30, angle=30, wedge=true); // arc(r=30, angle=30, wedge=true);
@ -703,7 +705,7 @@ function arc(N, r, angle, d, cp, points, width, thickness, start, wedge=false, l
module arc(N, r, angle, d, cp, points, width, thickness, start, wedge=false, anchor=CENTER, spin=0) module arc(N, r, angle, d, cp, points, width, thickness, start, wedge=false, anchor=CENTER, spin=0)
{ {
path = arc(N=N, r=r, angle=angle, d=d, cp=cp, points=points, width=width, thickness=thickness, start=start, wedge=wedge); path = arc(N=N, r=r, angle=angle, d=d, cp=cp, points=points, width=width, thickness=thickness, start=start, wedge=wedge);
attachable(anchor,spin, two_d=true, path=path, extent=true) { attachable(anchor,spin, two_d=true, path=path, extent=false) {
polygon(path); polygon(path);
children(); children();
} }

View file

@ -288,6 +288,7 @@ function force_region(poly) = is_path(poly) ? [poly] : poly;
// anchor = Translate so anchor point is at origin (0,0,0). See [anchor](attachments.scad#anchor). Default: `"origin"` // anchor = Translate so anchor point is at origin (0,0,0). See [anchor](attachments.scad#anchor). Default: `"origin"`
// spin = Rotate this many degrees after anchor. See [spin](attachments.scad#spin). Default: `0` // spin = Rotate this many degrees after anchor. See [spin](attachments.scad#spin). Default: `0`
// cp = Centerpoint for determining intersection anchors or centering the shape. Determintes the base of the anchor vector. Can be "centroid", "mean", "box" or a 2D point. Default: "centroid" // cp = Centerpoint for determining intersection anchors or centering the shape. Determintes the base of the anchor vector. Can be "centroid", "mean", "box" or a 2D point. Default: "centroid"
// atype = Set to "hull" or "intersect to select anchor type. Default: "hull"
// Example(2D): Displaying a region // Example(2D): Displaying a region
// region([circle(d=50), square(25,center=true)]); // region([circle(d=50), square(25,center=true)]);
// Example(2D): Displaying a list of polygons that intersect each other, which is not a region // Example(2D): Displaying a list of polygons that intersect each other, which is not a region
@ -298,13 +299,14 @@ function force_region(poly) = is_path(poly) ? [poly] : poly;
// region(rgn); // region(rgn);
module region(r, anchor="origin", spin=0, cp="centroid") module region(r, anchor="origin", spin=0, cp="centroid")
{ {
assert(in_list(atype, _ANCHOR_TYPES), "Anchor type must be \"hull\" or \"intersect\"");
r = force_region(r); r = force_region(r);
dummy=assert(is_region(r), "Input is not a region"); dummy=assert(is_region(r), "Input is not a region");
points = flatten(r); points = flatten(r);
lengths = [for(path=r) len(path)]; lengths = [for(path=r) len(path)];
starts = [0,each cumsum(lengths)]; starts = [0,each cumsum(lengths)];
paths = [for(i=idx(r)) count(s=starts[i], n=lengths[i])]; paths = [for(i=idx(r)) count(s=starts[i], n=lengths[i])];
attachable(anchor, spin, two_d=true, region=r, extent=false, cp=cp){ attachable(anchor, spin, two_d=true, region=r, extent=atype=="hull", cp=cp){
polygon(points=points, paths=paths); polygon(points=points, paths=paths);
children(); children();
} }
@ -646,7 +648,7 @@ module linear_sweep(region, height=1, center, twist=0, scale=1, slices, maxseg,
slices=slices, maxseg=maxseg, slices=slices, maxseg=maxseg,
style=style style=style
); );
attachable(anchor,spin,orient, cp=cp, vnf=vnf, extent=!anchor_isect, anchors=anchors) { attachable(anchor,spin,orient, cp=cp, region=region, h=height, extent=atype=="hull", anchors=anchors) {
vnf_polyhedron(vnf, convexity=convexity); vnf_polyhedron(vnf, convexity=convexity);
children(); children();
} }

View file

@ -16,9 +16,9 @@
// Function&Module: skin() // Function&Module: skin()
// Usage: As module: // Usage: As module:
// skin(profiles, slices, [z=], [refine=], [method=], [sampling=], [caps=], [closed=], [style=], [convexity=], [anchor=],[cp=],[spin=],[orient=],[extent=]) [attachments]; // skin(profiles, slices, [z=], [refine=], [method=], [sampling=], [caps=], [closed=], [style=], [convexity=], [anchor=],[cp=],[spin=],[orient=],[atype=]) {attachments};
// Usage: As function: // Usage: As function:
// vnf = skin(profiles, slices, [z=], [refine=], [method=], [sampling=], [caps=], [closed=], [style=]); // vnf = skin(profiles, slices, [z=], [refine=], [method=], [sampling=], [caps=], [closed=], [style=], [anchor=],[cp=],[spin=],[orient=],[atype=]);
// Description: // Description:
// Given a list of two or more path `profiles` in 3d space, produces faces to skin a surface between // Given a list of two or more path `profiles` in 3d space, produces faces to skin a surface between
// the profiles. Optionally the first and last profiles can have endcaps, or the first and last profiles // the profiles. Optionally the first and last profiles can have endcaps, or the first and last profiles
@ -500,9 +500,9 @@ function skin(profiles, slices, refine=1, method="direct", sampling, caps, close
// Function&Module: path_sweep() // Function&Module: path_sweep()
// Usage: As module // Usage: As module
// path_sweep(shape, path, [method], [normal=], [closed=], [twist=], [twist_by_length=], [symmetry=], [last_normal=], [tangent=], [relaxed=], [caps=], [style=], [convexity=], [transforms=], [anchor=], [cp=], [spin=], [orient=], [extent=]) [attachments]; // path_sweep(shape, path, [method], [normal=], [closed=], [twist=], [twist_by_length=], [symmetry=], [last_normal=], [tangent=], [relaxed=], [caps=], [style=], [convexity=], [anchor=], [cp=], [spin=], [orient=], [atype=]) {attachments};
// Usage: As function // Usage: As function
// vnf = path_sweep(shape, path, [method], [normal=], [closed=], [twist=], [twist_by_length=], [symmetry=], [last_normal=], [tangent=], [relaxed=], [caps=], [style=], [convexity=], [transforms=]); // vnf = path_sweep(shape, path, [method], [normal=], [closed=], [twist=], [twist_by_length=], [symmetry=], [last_normal=], [tangent=], [relaxed=], [caps=], [style=], [transforms=], [anchor=], [cp=], [spin=], [orient=], [atype=]) {attachments};
// Description: // Description:
// Takes as input a 2D polygon path, and a 2d or 3d path and constructs a polyhedron by sweeping the shape along the path. // Takes as input a 2D polygon path, and a 2d or 3d path and constructs a polyhedron by sweeping the shape along the path.
// When run as a module returns the polyhedron geometry. When run as a function returns a VNF by default or if you set `transforms=true` // When run as a module returns the polyhedron geometry. When run as a function returns a VNF by default or if you set `transforms=true`
@ -923,9 +923,9 @@ function path_sweep(shape, path, method="incremental", normal, closed=false, twi
// Function&Module: path_sweep2d() // Function&Module: path_sweep2d()
// Usage: as module // Usage: as module
// path_sweep2d(shape, path, [closed], [caps], [quality], [style], [convexity=], [anchor=], [spin=], [orient=], [extent=], [cp=]) [attachments]; // path_sweep2d(shape, path, [closed], [caps], [quality], [style], [convexity=], [anchor=], [spin=], [orient=], [atype=], [cp=]) {attachments};
// Usage: as function // Usage: as function
// vnf = path_sweep2d(shape, path, [closed], [caps], [quality], [style]); // vnf = path_sweep2d(shape, path, [closed], [caps], [quality], [style], [anchor=], [spin=], [orient=], [atype=], [cp=]);
// Description: // Description:
// Takes an input 2D polygon (the shape) and a 2d path and constructs a polyhedron by sweeping the shape along the path. // Takes an input 2D polygon (the shape) and a 2d path and constructs a polyhedron by sweeping the shape along the path.
// When run as a module returns the polyhedron geometry. When run as a function returns a VNF. // When run as a module returns the polyhedron geometry. When run as a function returns a VNF.
@ -1044,9 +1044,9 @@ function _ofs_face_edge(face,firstlen,second=false) =
// Function&Module: sweep() // Function&Module: sweep()
// Usage: As Module // Usage: As Module
// sweep(shape, transforms, [closed], [caps], [style], [convexity=], [anchor=], [spin=], [orient=], [extent=]) [attachments]; // sweep(shape, transforms, [closed], [caps], [style], [convexity=], [anchor=], [spin=], [orient=], [atype=]) [attachments];
// Usage: As Function // Usage: As Function
// vnf = sweep(shape, transforms, [closed], [caps], [style]); // vnf = sweep(shape, transforms, [closed], [caps], [style], [anchor=], [spin=], [orient=], [atype=]);
// Description: // Description:
// The input `shape` must be a non-self-intersecting 2D polygon or region, and `transforms` // The input `shape` must be a non-self-intersecting 2D polygon or region, and `transforms`
// is a list of 4x4 transformation matrices. The sweep algorithm applies each transformation in sequence // is a list of 4x4 transformation matrices. The sweep algorithm applies each transformation in sequence