add vnf_hull() and hull_region()

This commit is contained in:
Adrian Mariano 2024-01-13 19:26:15 -05:00
parent d4088bf2a5
commit a26e6950e6
3 changed files with 84 additions and 2 deletions

View file

@ -1396,4 +1396,39 @@ module exclusive_or() {
}
// Function&Module: hull_region()
// Synopsis: Compute convex hull of region or 2d path
// SynTags: Geom, Path
// Topics: Regions, Polygons, Shapes2D
// Usage:
// path = hull_region(region);
// hull_region(region);
// Description:
// Given a path, or a region, compute the convex hull
// and return it as a path. This differs from {{hull()}} and {{hull2d_path()}} which
// return an index list into the point list. As a module invokes the native hull() on
// the specified region.
// Arguments:
// region = region or path listing points to compute the hull from.
// Example(2D, NoAxes):
data = [star(id=10,od=20,n=9),
right(30, star(id=12,od=25, n=7))];
stroke(data);
stroke([hull_region(data)],color="red");
function hull_region(region) =
assert(is_path(region) || is_region(region))
let(
pts = is_region(region) ? flatten(region)
: region,
order = hull2d_path(pts)
)
select(pts,order);
module hull_region(region)
{
hull()region(region);
}
// vim: expandtab tabstop=4 shiftwidth=4 softtabstop=4 nowrap

View file

@ -2958,13 +2958,13 @@ function associate_vertices(polygons, split, curpoly=0) =
// tex_size=[10,10]
// );
// Example(3D): **"dimples"** (VNF) = Round divots. Specify `$fn` to set the number of segments on the cone (will be rounded to a multiple of 4). If you use $fa and $fs then the number of segments is determined for the original VNF scale of 1x1. Giving `border=` specifies the horizontal width of the flat border region between the tile edges and the edge of the dimple. Must be nonnegative and strictly less than 0.5. Default: 0.05.
// tex = texture("dimples");
// tex = texture("dimples", $fn=16);
// linear_sweep(
// rect(30), texture=tex, h=30,
// tex_size=[10,10]
// );
// Example(3D): **"dots"** (VNF) = Raised round bumps. Specify `$fn` to set the number of segments on the cone (will be rounded to a multiple of 4). If you use $fa and $fs then the number of segments is determined for the original VNF scale of 1x1. Giving `border=` specifies the horizontal width of the flat border region between the tile edge and the edge of the dots. Must be nonnegative and strictly less than 0.5. Default: 0.05.
// tex = texture("dots");
// tex = texture("dots", $fn=16);
// linear_sweep(
// rect(30), texture=tex, h=30,
// tex_size=[10,10]

View file

@ -1414,6 +1414,53 @@ function vnf_bend(vnf,r,d,axis="Z") =
) [new_vert,sliced[1]];
// Function&Module: vnf_hull()
// Synopsis: Compute convex hull of VNF or 3d path
// Usage:
// vnf_hull = hull_vnf(vnf);
// hull_vnf(vnf,[fast]);
// Description:
// Given a VNF or a list of 3d points, compute the convex hull
// and return it as a VNF. This differs from {{hull()}} and {{hull3d_faces()}} which
// return just the face list referenced to the input point list. Note that the point
// list that is returned will contain all the points that are actually used in the input
// VNF, which may be many more points than are needed to represent the convex hull.
// This is not usually a problem, but you can run the somewhat slow {{vnf_drop_unused_points()}}
// function to fix this if necessary.
// Arguments:
// region = region or path listing points to compute the hull from.
// fast = (module only) if input is a point list (not a VNF) use a fasterer cheat that may handle more points, but could emit warnings. Ignored if input is a VNF. Default: false.
// Example(3D,Big,NoAxes): Input is a VNF
// ellipse = xscale(2, p=circle($fn=48, r=3));
// pentagon = subdivide_path(pentagon(r=1), 20);
// vnf=path_sweep(pentagon, path3d(ellipse),
// closed=true, twist=360*2);
// vnfhull = vnf_hull(vnf);
// vnf_polyhedron(vnf);
// move([10,10])
// vnf_polyhedron(vnfhull);
// Example(2D, NoAxes): Input is a point list
// h=helix(l=40, turns=1, r=8);
// color("red")move_copies(h)
// sphere(r=0.5,$fn=12);
// vnf_polyhedron(vnf_hull(h));
function vnf_hull(vnf) =
assert(is_vnf(vnf) || is_path(vnf,3),"Input must be a VNF or a 3d path")
let(
pts = is_vnf(vnf) ? select(vnf[0],unique(flatten(vnf[1])))
: vnf,
faces = hull3d_faces(pts)
)
[pts, faces];
module vnf_hull(vnf, fast=false)
{
if (is_vnf(vnf)) hull()vnf_polyhedron(vnf);
else hull_points(vnf, fast);
}
// Section: Debugging Polyhedrons
/// Internal Module: _show_vertices()