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/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);
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];

View File

@@ -1,6 +1,6 @@
use <geom_dodecahedron.scad>;
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]);
}

View File

@@ -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);
_subdivide_project(dodecahedron_points, dodecahedron_faces, radius, detail);

View File

@@ -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);
_subdivide_project(hexahedron_points, hexahedron_faces, radius, detail);

View File

@@ -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);

View File

@@ -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);

View File

@@ -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);

View File

@@ -1,6 +1,6 @@
use <geom_hexahedron.scad>;
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]);
}

View File

@@ -1,6 +1,6 @@
use <geom_icosahedron.scad>;
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]);
}

View File

@@ -1,6 +1,6 @@
use <geom_octahedron.scad>;
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]);
}

View File

@@ -1,6 +1,6 @@
use <geom_tetrahedron.scad>;
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]);
}