1
0
mirror of https://github.com/JustinSDK/dotSCAD.git synced 2025-08-19 13:01:37 +02:00

rewrite polyhedra

This commit is contained in:
Justin Lin
2021-10-14 18:22:05 +08:00
parent 9c3c92ab13
commit a8ae7c18e4
11 changed files with 72 additions and 99 deletions

View File

@@ -1,82 +1,55 @@
use <../../__comm__/_pt3_hash.scad>; use <../../util/sum.scad>;
use <../../util/map/hashmap.scad>;
use <../../util/map/hashmap_put.scad>;
use <../../util/map/hashmap_get.scad>;
function _tri_subdivide(points) = function _tri_subdivide(points, detail) =
let( let(
p0 = points[0], rows = detail + 1,
p1 = points[1], vc = points[2] - points[0],
p2 = points[2], vr = points[1] - points[0],
m0 = (p0 + p1) / 2, dr = vr / (detail + 1),
m1 = (p1 + p2) / 2, dc = vc / (detail + 1),
m2 = (p2 + p0) / 2 pts = [
) for(ri = [0:rows])
[ let(cols = rows - ri)
[p0, m0, m2], for(ci = [0:cols])
[m0, p1, m1], points[0] + ci * dc + ri * dr
[m1, p2, m2], ],
[m0, m1, m2] 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) = function _subdivide_project(points, faces, radius, detail) =
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) =
let( let(
number_of_buckets = ceil(sqrt(len(points)) * 1.5), subdivided_all = [
hash = function(p) _pt3_hash(p), for(face = faces)
leng = len(points), _tri_subdivide([for(i = face) points[i]], detail)
m_pts = _pimap_pts( ],
radius, pts_number_per_tri = len(subdivided_all[0][0]),
points, flatten_points = [
leng, for(pts_faces = subdivided_all)
hash, for(p = pts_faces[0])
hashmap(number_of_buckets = number_of_buckets) p / norm(p) * radius
), ],
faces = [ flatten_faces = [
for(i = [0:3:leng - 3]) for(i = [0:len(subdivided_all) - 1])
[ let(faces = subdivided_all[i][1])
hashmap_get(m_pts[0], points[i], hash = hash), for(face = faces)
hashmap_get(m_pts[0], points[i + 1], hash = hash), face + [i, i, i] * pts_number_per_tri
hashmap_get(m_pts[0], points[i + 2], hash = hash) ]
] )
] [flatten_points, flatten_faces];
)
[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);

View File

@@ -1,6 +1,6 @@
use <geom_dodecahedron.scad>; use <geom_dodecahedron.scad>;
module dodecahedron(radius, detail = 0, quick_mode = true) { module dodecahedron(radius, detail = 0) {
points_faces = geom_dodecahedron(radius, detail, quick_mode); points_faces = geom_dodecahedron(radius, detail);
polyhedron(points_faces[0], points_faces[1]); polyhedron(points_faces[0], points_faces[1]);
} }

View File

@@ -1,6 +1,6 @@
use <_impl/_geom_platonic_polyhedra.scad>; use <_impl/_geom_platonic_polyhedra.scad>;
function geom_dodecahedron(radius, detail = 0, quick_mode = true) = function geom_dodecahedron(radius, detail = 0) =
let( let(
t = (1 + sqrt(5)) / 2, t = (1 + sqrt(5)) / 2,
r = 1 / t, 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] [14, 12, 1], [5, 14, 1], [9, 5, 1]
] ]
) )
_geom_platonic_polyhedra(dodecahedron_points, dodecahedron_faces, radius, detail, quick_mode); _subdivide_project(dodecahedron_points, dodecahedron_faces, radius, detail);

View File

@@ -1,6 +1,6 @@
use <_impl/_geom_platonic_polyhedra.scad>; use <_impl/_geom_platonic_polyhedra.scad>;
function geom_hexahedron(radius, detail = 0, quick_mode = true) = function geom_hexahedron(radius, detail = 0) =
let( let(
t = 1 / sqrt(3), t = 1 / sqrt(3),
hexahedron_points = [ hexahedron_points = [
@@ -16,4 +16,4 @@ function geom_hexahedron(radius, detail = 0, quick_mode = true) =
[5, 6, 7], [5, 7, 4] [5, 6, 7], [5, 7, 4]
] ]
) )
_geom_platonic_polyhedra(hexahedron_points, hexahedron_faces, radius, detail, quick_mode); _subdivide_project(hexahedron_points, hexahedron_faces, radius, detail);

View File

@@ -1,6 +1,6 @@
use <_impl/_geom_platonic_polyhedra.scad>; use <_impl/_geom_platonic_polyhedra.scad>;
function geom_icosahedron(radius, detail = 0, quick_mode = true) = function geom_icosahedron(radius, detail = 0) =
let( let(
t = (1 + sqrt(5)) / 2 , t = (1 + sqrt(5)) / 2 ,
icosahedron_points = [ 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] [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);

View File

@@ -1,6 +1,6 @@
use <_impl/_geom_platonic_polyhedra.scad>; use <_impl/_geom_platonic_polyhedra.scad>;
function geom_octahedron(radius, detail = 0, quick_mode = true) = function geom_octahedron(radius, detail = 0) =
let( let(
octahedron_points = [ octahedron_points = [
[1, 0, 0], [-1, 0, 0], [0, 1, 0], [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] [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);

View File

@@ -1,6 +1,6 @@
use <_impl/_geom_platonic_polyhedra.scad>; use <_impl/_geom_platonic_polyhedra.scad>;
function geom_tetrahedron(radius, detail = 0, quick_mode = true) = function geom_tetrahedron(radius, detail = 0) =
let( let(
t = (1 + sqrt(5)) / 2 , t = (1 + sqrt(5)) / 2 ,
tetrahedron_points = [ 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] [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);

View File

@@ -1,6 +1,6 @@
use <geom_hexahedron.scad>; use <geom_hexahedron.scad>;
module hexahedron(radius, detail = 0, quick_mode = true) { module hexahedron(radius, detail = 0) {
points_faces = geom_hexahedron(radius, detail, quick_mode); points_faces = geom_hexahedron(radius, detail);
polyhedron(points_faces[0], points_faces[1]); polyhedron(points_faces[0], points_faces[1]);
} }

View File

@@ -1,6 +1,6 @@
use <geom_icosahedron.scad>; use <geom_icosahedron.scad>;
module icosahedron(radius, detail = 0, quick_mode = true) { module icosahedron(radius, detail = 0) {
points_faces = geom_icosahedron(radius, detail, quick_mode); points_faces = geom_icosahedron(radius, detail);
polyhedron(points_faces[0], points_faces[1]); polyhedron(points_faces[0], points_faces[1]);
} }

View File

@@ -1,6 +1,6 @@
use <geom_octahedron.scad>; use <geom_octahedron.scad>;
module octahedron(radius, detail = 0, quick_mode = true) { module octahedron(radius, detail = 0) {
points_faces = geom_octahedron(radius, detail, quick_mode); points_faces = geom_octahedron(radius, detail);
polyhedron(points_faces[0], points_faces[1]); polyhedron(points_faces[0], points_faces[1]);
} }

View File

@@ -1,6 +1,6 @@
use <geom_tetrahedron.scad>; use <geom_tetrahedron.scad>;
module tetrahedron(radius, detail = 0, quick_mode = true) { module tetrahedron(radius, detail = 0) {
points_faces = geom_tetrahedron(radius, detail, quick_mode); points_faces = geom_tetrahedron(radius, detail);
polyhedron(points_faces[0], points_faces[1]); polyhedron(points_faces[0], points_faces[1]);
} }