From a8ae7c18e49511062911b6645dcf8240c80b9333 Mon Sep 17 00:00:00 2001 From: Justin Lin Date: Thu, 14 Oct 2021 18:22:05 +0800 Subject: [PATCH] rewrite polyhedra --- .../_impl/_geom_platonic_polyhedra.scad | 131 +++++++----------- src/polyhedra/dodecahedron.scad | 4 +- src/polyhedra/geom_dodecahedron.scad | 4 +- src/polyhedra/geom_hexahedron.scad | 4 +- src/polyhedra/geom_icosahedron.scad | 4 +- src/polyhedra/geom_octahedron.scad | 4 +- src/polyhedra/geom_tetrahedron.scad | 4 +- src/polyhedra/hexahedron.scad | 4 +- src/polyhedra/icosahedron.scad | 4 +- src/polyhedra/octahedron.scad | 4 +- src/polyhedra/tetrahedron.scad | 4 +- 11 files changed, 72 insertions(+), 99 deletions(-) diff --git a/src/polyhedra/_impl/_geom_platonic_polyhedra.scad b/src/polyhedra/_impl/_geom_platonic_polyhedra.scad index b7ecc467..498b14d7 100644 --- a/src/polyhedra/_impl/_geom_platonic_polyhedra.scad +++ b/src/polyhedra/_impl/_geom_platonic_polyhedra.scad @@ -1,82 +1,55 @@ -use <../../__comm__/_pt3_hash.scad>; -use <../../util/map/hashmap.scad>; -use <../../util/map/hashmap_put.scad>; -use <../../util/map/hashmap_get.scad>; +use <../../util/sum.scad>; -function _tri_subdivide(points) = - let( - p0 = points[0], - p1 = points[1], - p2 = points[2], - m0 = (p0 + p1) / 2, - m1 = (p1 + p2) / 2, - m2 = (p2 + p0) / 2 - ) - [ - [p0, m0, m2], - [m0, p1, m1], - [m1, p2, m2], - [m0, m1, m2] - ]; +function _tri_subdivide(points, detail) = + let( + rows = detail + 1, + vc = points[2] - points[0], + vr = points[1] - points[0], + dr = vr / (detail + 1), + dc = vc / (detail + 1), + pts = [ + for(ri = [0:rows]) + let(cols = rows - ri) + for(ci = [0:cols]) + points[0] + ci * dc + ri * dr + ], + pre_n = concat([0], [for(ri = [0:rows]) rows - ri + 1]), + idx = function(ci, ri) ci + sum([for(i = [0:ri]) pre_n[i]]), + faces = [ + for(ri = [0:rows - 1]) + let(cols = rows - ri - 1) + for(ci = [0:cols]) + let(pre = 0) + each (ci == cols ? + [ + [idx(ci, ri), idx(ci, ri + 1), idx(ci + 1, ri)] + ] : + [ + [idx(ci, ri), idx(ci, ri + 1), idx(ci + 1, ri)], + [idx(ci + 1, ri), idx(ci, ri + 1), idx(ci + 1, ri + 1)] + ] + ) + ] + ) + [pts, faces]; -function tri_subdivide(points, n = 1) = - n == 1 ? _tri_subdivide(points) : - [for(tri = tri_subdivide(points, n - 1)) each _tri_subdivide(tri)]; - -function _geom_prj2sphere(t, r) = [for(p = t) p / norm(p) * r]; - -function _pimap_pts(radius, points, leng, hash, m, deduped_pts = [], n = -1, i = 0) = - i == leng ? [m, deduped_pts] : - let(v = hashmap_get(m, points[i], hash = hash)) - is_undef(v) ? - _pimap_pts(radius, points, leng, hash, hashmap_put(m, points[i], n + 1, hash = hash), concat(deduped_pts, [points[i] / norm(points[i]) * radius]), n + 1, i + 1) : - _pimap_pts(radius, points, leng, hash, m, deduped_pts, n, i + 1); - -function _geom_pts_faces(points, radius) = +function _subdivide_project(points, faces, radius, detail) = let( - number_of_buckets = ceil(sqrt(len(points)) * 1.5), - hash = function(p) _pt3_hash(p), - leng = len(points), - m_pts = _pimap_pts( - radius, - points, - leng, - hash, - hashmap(number_of_buckets = number_of_buckets) - ), - faces = [ - for(i = [0:3:leng - 3]) - [ - hashmap_get(m_pts[0], points[i], hash = hash), - hashmap_get(m_pts[0], points[i + 1], hash = hash), - hashmap_get(m_pts[0], points[i + 2], hash = hash) - ] - ] - ) - [m_pts[1], faces]; - -function _geom_info(tris, radius, detail) = - _geom_pts_faces([ - for(tri = tris) - each [for(t = tri_subdivide(tri, detail)) each t] - ], radius); - -function _geom_info_quick(tris, radius, detail) = - let( - points = [ - for(tri = tris) - each [for(t = tri_subdivide(tri, detail)) each _geom_prj2sphere(t, radius)] - ], - faces = [for(i = [0:3:len(points) - 3]) [i, i + 1, i + 2]] - ) - [points, faces]; - -function _geom_platonic_polyhedra(points, faces, radius, detail, quick_mode) = - detail == 0 ? [_geom_prj2sphere(points, radius), faces] : - let( - tris = [ - for(face = faces) - [for(i = face) points[i]] - ] - ) - quick_mode ? _geom_info_quick(tris, radius, detail) : _geom_info(tris, radius, detail); \ No newline at end of file + subdivided_all = [ + for(face = faces) + _tri_subdivide([for(i = face) points[i]], detail) + ], + pts_number_per_tri = len(subdivided_all[0][0]), + flatten_points = [ + for(pts_faces = subdivided_all) + for(p = pts_faces[0]) + p / norm(p) * radius + ], + flatten_faces = [ + for(i = [0:len(subdivided_all) - 1]) + let(faces = subdivided_all[i][1]) + for(face = faces) + face + [i, i, i] * pts_number_per_tri + ] + ) + [flatten_points, flatten_faces]; \ No newline at end of file diff --git a/src/polyhedra/dodecahedron.scad b/src/polyhedra/dodecahedron.scad index 5e6c965d..9b9f8191 100644 --- a/src/polyhedra/dodecahedron.scad +++ b/src/polyhedra/dodecahedron.scad @@ -1,6 +1,6 @@ use ; -module dodecahedron(radius, detail = 0, quick_mode = true) { - points_faces = geom_dodecahedron(radius, detail, quick_mode); +module dodecahedron(radius, detail = 0) { + points_faces = geom_dodecahedron(radius, detail); polyhedron(points_faces[0], points_faces[1]); } diff --git a/src/polyhedra/geom_dodecahedron.scad b/src/polyhedra/geom_dodecahedron.scad index c6f4c01d..20a34a9e 100644 --- a/src/polyhedra/geom_dodecahedron.scad +++ b/src/polyhedra/geom_dodecahedron.scad @@ -1,6 +1,6 @@ use <_impl/_geom_platonic_polyhedra.scad>; -function geom_dodecahedron(radius, detail = 0, quick_mode = true) = +function geom_dodecahedron(radius, detail = 0) = let( t = (1 + sqrt(5)) / 2, r = 1 / t, @@ -38,4 +38,4 @@ function geom_dodecahedron(radius, detail = 0, quick_mode = true) = [14, 12, 1], [5, 14, 1], [9, 5, 1] ] ) - _geom_platonic_polyhedra(dodecahedron_points, dodecahedron_faces, radius, detail, quick_mode); \ No newline at end of file + _subdivide_project(dodecahedron_points, dodecahedron_faces, radius, detail); \ No newline at end of file diff --git a/src/polyhedra/geom_hexahedron.scad b/src/polyhedra/geom_hexahedron.scad index b7047d6f..2e63f66d 100644 --- a/src/polyhedra/geom_hexahedron.scad +++ b/src/polyhedra/geom_hexahedron.scad @@ -1,6 +1,6 @@ use <_impl/_geom_platonic_polyhedra.scad>; -function geom_hexahedron(radius, detail = 0, quick_mode = true) = +function geom_hexahedron(radius, detail = 0) = let( t = 1 / sqrt(3), hexahedron_points = [ @@ -16,4 +16,4 @@ function geom_hexahedron(radius, detail = 0, quick_mode = true) = [5, 6, 7], [5, 7, 4] ] ) - _geom_platonic_polyhedra(hexahedron_points, hexahedron_faces, radius, detail, quick_mode); \ No newline at end of file + _subdivide_project(hexahedron_points, hexahedron_faces, radius, detail); \ No newline at end of file diff --git a/src/polyhedra/geom_icosahedron.scad b/src/polyhedra/geom_icosahedron.scad index 18db1bae..ed68f408 100644 --- a/src/polyhedra/geom_icosahedron.scad +++ b/src/polyhedra/geom_icosahedron.scad @@ -1,6 +1,6 @@ use <_impl/_geom_platonic_polyhedra.scad>; -function geom_icosahedron(radius, detail = 0, quick_mode = true) = +function geom_icosahedron(radius, detail = 0) = let( t = (1 + sqrt(5)) / 2 , icosahedron_points = [ @@ -15,5 +15,5 @@ function geom_icosahedron(radius, detail = 0, quick_mode = true) = [5, 9, 4], [11, 4, 2], [10, 2, 6], [7, 6, 8], [1, 8, 9] ] ) - _geom_platonic_polyhedra(icosahedron_points, icosahedron_faces, radius, detail, quick_mode); + _subdivide_project(icosahedron_points, icosahedron_faces, radius, detail); \ No newline at end of file diff --git a/src/polyhedra/geom_octahedron.scad b/src/polyhedra/geom_octahedron.scad index bfb7a735..d32944db 100644 --- a/src/polyhedra/geom_octahedron.scad +++ b/src/polyhedra/geom_octahedron.scad @@ -1,6 +1,6 @@ use <_impl/_geom_platonic_polyhedra.scad>; -function geom_octahedron(radius, detail = 0, quick_mode = true) = +function geom_octahedron(radius, detail = 0) = let( octahedron_points = [ [1, 0, 0], [-1, 0, 0], [0, 1, 0], @@ -12,5 +12,5 @@ function geom_octahedron(radius, detail = 0, quick_mode = true) = [4, 3, 1], [2, 4, 1] ] ) - _geom_platonic_polyhedra(octahedron_points, octahedron_faces, radius, detail, quick_mode); + _subdivide_project(octahedron_points, octahedron_faces, radius, detail); \ No newline at end of file diff --git a/src/polyhedra/geom_tetrahedron.scad b/src/polyhedra/geom_tetrahedron.scad index 56944d4e..ffd451cf 100644 --- a/src/polyhedra/geom_tetrahedron.scad +++ b/src/polyhedra/geom_tetrahedron.scad @@ -1,6 +1,6 @@ use <_impl/_geom_platonic_polyhedra.scad>; -function geom_tetrahedron(radius, detail = 0, quick_mode = true) = +function geom_tetrahedron(radius, detail = 0) = let( t = (1 + sqrt(5)) / 2 , tetrahedron_points = [ @@ -10,5 +10,5 @@ function geom_tetrahedron(radius, detail = 0, quick_mode = true) = [0, 1, 2], [2, 3, 0], [0, 3, 1], [1, 3, 2] ] ) - _geom_platonic_polyhedra(tetrahedron_points, tetrahedron_faces, radius, detail, quick_mode); + _subdivide_project(tetrahedron_points, tetrahedron_faces, radius, detail); \ No newline at end of file diff --git a/src/polyhedra/hexahedron.scad b/src/polyhedra/hexahedron.scad index debdf1dd..2fb8533d 100644 --- a/src/polyhedra/hexahedron.scad +++ b/src/polyhedra/hexahedron.scad @@ -1,6 +1,6 @@ use ; -module hexahedron(radius, detail = 0, quick_mode = true) { - points_faces = geom_hexahedron(radius, detail, quick_mode); +module hexahedron(radius, detail = 0) { + points_faces = geom_hexahedron(radius, detail); polyhedron(points_faces[0], points_faces[1]); } \ No newline at end of file diff --git a/src/polyhedra/icosahedron.scad b/src/polyhedra/icosahedron.scad index a8861634..a28f3f7f 100644 --- a/src/polyhedra/icosahedron.scad +++ b/src/polyhedra/icosahedron.scad @@ -1,6 +1,6 @@ use ; -module icosahedron(radius, detail = 0, quick_mode = true) { - points_faces = geom_icosahedron(radius, detail, quick_mode); +module icosahedron(radius, detail = 0) { + points_faces = geom_icosahedron(radius, detail); polyhedron(points_faces[0], points_faces[1]); } \ No newline at end of file diff --git a/src/polyhedra/octahedron.scad b/src/polyhedra/octahedron.scad index 652c4fef..3c1a9c60 100644 --- a/src/polyhedra/octahedron.scad +++ b/src/polyhedra/octahedron.scad @@ -1,6 +1,6 @@ use ; -module octahedron(radius, detail = 0, quick_mode = true) { - points_faces = geom_octahedron(radius, detail, quick_mode); +module octahedron(radius, detail = 0) { + points_faces = geom_octahedron(radius, detail); polyhedron(points_faces[0], points_faces[1]); } \ No newline at end of file diff --git a/src/polyhedra/tetrahedron.scad b/src/polyhedra/tetrahedron.scad index 83ff2814..35610e77 100644 --- a/src/polyhedra/tetrahedron.scad +++ b/src/polyhedra/tetrahedron.scad @@ -1,6 +1,6 @@ use ; -module tetrahedron(radius, detail = 0, quick_mode = true) { - points_faces = geom_tetrahedron(radius, detail, quick_mode); +module tetrahedron(radius, detail = 0) { + points_faces = geom_tetrahedron(radius, detail); polyhedron(points_faces[0], points_faces[1]); } \ No newline at end of file