From daaff1322f0ec75bd322302cd95ee8747083216d Mon Sep 17 00:00:00 2001 From: Justin Lin Date: Tue, 13 Sep 2022 14:56:36 +0800 Subject: [PATCH] add tri_concave_hull --- src/experimental/tri_concave_hull.scad | 92 ++++++++++++++++++++++++++ 1 file changed, 92 insertions(+) create mode 100644 src/experimental/tri_concave_hull.scad diff --git a/src/experimental/tri_concave_hull.scad b/src/experimental/tri_concave_hull.scad new file mode 100644 index 00000000..0e961871 --- /dev/null +++ b/src/experimental/tri_concave_hull.scad @@ -0,0 +1,92 @@ +use +use +use +use +use +use +use +use + +function circumcircle_rr(shape_pts) = + let( + center = tri_circumcenter(shape_pts), + v = shape_pts[0] - center + ) + v * v; + +function edge(a, b) = a < b ? [a, b] : [b, a]; + +function dist_gt(p1, p2, leng) = let(v = p2 - p1) v * v > leng ^ 2; + +function edge_tri(indices_tris, m, i = 0) = + len(indices_tris) == i ? m : + let( + t_indices = indices_tris[i], + + edge1 = edge(t_indices[0], t_indices[1]), + t_lt1 = hashmap_get(m, edge1), + m1 = hashmap_put(m, edge1, is_undef(t_lt1) ? [t_indices] : [each t_lt1, t_indices]), + + edge2 = edge(t_indices[1], t_indices[2]), + t_lt2 = hashmap_get(m1, edge2), + m2 = hashmap_put(m1, edge2, is_undef(t_lt2) ? [t_indices] : [each t_lt2, t_indices]), + + edge3 = edge(t_indices[2], t_indices[0]), + t_lt3 = hashmap_get(m2, edge3) + ) + edge_tri(indices_tris, hashmap_put(m2, edge3, is_undef(t_lt3) ? [t_indices] : [each t_lt3, t_indices]), i + 1); + +function reduce_tris(indices_tris, dist) = + let( + m = edge_tri(indices_tris, hashmap(number_of_buckets = len(indices_tris) / 4)), + entries = hashmap_entries(m), + edges = [ + for(entry = entries) + if(len(entry[1]) == 1 && dist_gt(points[entry[0][0]], points[entry[0][1]], dist)) + entry[0] + ], + reduce_tris = [ + for(t_indices = indices_tris) + let( + edge1 = edge(t_indices[0], t_indices[1]), + edge2 = edge(t_indices[1], t_indices[2]), + edge3 = edge(t_indices[2], t_indices[0]) + ) + if( + !has(edges, edge1) && !has(edges, edge2) && !has(edges, edge3) + ) + t_indices + ] + ) + len(indices_tris) > len(reduce_tris) ? reduce_tris(reduce_tris, dist) : reduce_tris; + + +function tri_concave_hull(points, dist, d) = + let( + indices_tris = is_undef(d) ? tri_delaunay(points) : tri_delaunay_indices(d) + ) + reduce_tris(indices_tris, dist); + +dist = 30; +seed = 101; +points = [for(i = [0:150]) rands(-100, 100, 2, seed_value = seed + i)]; + +d = tri_delaunay(points, ret = "DELAUNAY"); +convex_hull_tris = tri_delaunay_indices(d); +concave_hull_tris = tri_concave_hull(points, dist, d); + +for(t = concave_hull_tris) { + offset(-.2) + polygon([for(i = t) points[i]]); +} + +%for(t = convex_hull_tris) { + offset(-.2) + polygon([for(i = t) points[i]]); +} + +color("red") +for(p = points) { + translate(p) + circle(2); +}