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

add voronoi_lines

This commit is contained in:
Justin Lin
2020-03-02 15:49:56 +08:00
parent f668445d0e
commit ecf2e96a42

View File

@@ -0,0 +1,65 @@
use <experimental/tri_delaunay.scad>;
use <experimental/tri_circumcircle.scad>;
function _voronoi_lines_tri_vertex(tri, p) =
tri[0] == p || tri[1] == p || tri[2] == p;
function _voronoi_lines_tri_same(tri1, tri2) =
_voronoi_lines_tri_vertex(tri1, tri2[0]) && _voronoi_lines_tri_vertex(tri1, tri2[1]) && _voronoi_lines_tri_vertex(tri1, tri2[2]);
function _voronoi_lines_tri_coedge(tri1, tri2) =
let(
n1 = _voronoi_lines_tri_vertex(tri2, tri1[0]) ? 1 : 0,
n2 = _voronoi_lines_tri_vertex(tri2, tri1[1]) ? 1 : 0,
n = n1 + n2
)
(n > 1) || ((n + (_voronoi_lines_tri_vertex(tri2, tri1[2]) ? 1 : 0)) > 1);
function _voronoi_lines_tri_neighbors_impl(tris, me, leng, nbrs = [], i = 0) =
len(nbrs) == 3 || i == leng ? nbrs :
!_voronoi_lines_tri_same(me, tris[i]) && _voronoi_lines_tri_coedge(me, tris[i]) ? _voronoi_lines_tri_neighbors_impl(tris, me, leng, concat(nbrs, [tris[i]]), i + 1) :
_voronoi_lines_tri_neighbors_impl(tris, me, leng, nbrs, i + 1);
function _voronoi_lines_tri_neighbors(tris, me) =
_voronoi_lines_tri_neighbors_impl(tris, me, len(tris));
function _voronoi_lines_line_has(line, p) =
p == line[0] || p == line[1];
function _voronoi_lines_same_line(line1, line2) =
_voronoi_lines_line_has(line1, line2[0]) && _voronoi_lines_line_has(line1, line2[1]);
function _voronoi_lines_lines_has(lines, line, leng, i = 0) =
i == leng ? false :
_voronoi_lines_same_line(lines[i], line) ? true : _voronoi_lines_lines_has(lines, line, leng, i + 1);
function _voronoi_lines_dedup_lines_impl(src, dest, leng, i = 0) =
i == leng ? dest :
_voronoi_lines_lines_has(dest, src[i], len(dest)) ? _voronoi_lines_dedup_lines_impl(src, dest, leng, i + 1) : _voronoi_lines_dedup_lines_impl(src, concat(dest, [src[i]]), leng, i + 1);
function _voronoi_lines_dedup_lines(lines) = _voronoi_lines_dedup_lines_impl(lines, [], len(lines));
function voronoi_lines(points) =
let(
tris = [
for(idxes = tri_delaunay(points))
[points[idxes[0]], points[idxes[1]], points[idxes[2]]]
],
lines = [for(me = tris)
let(
nbrs = _voronoi_lines_tri_neighbors(tris, me),
circumcircle_cpts = [
for(nbr = concat([me], nbrs))
tri_circumcircle(nbr)[0]
],
leng = len(circumcircle_cpts),
lines = leng <= 1 ? [] :
[
for(i = [1:len(circumcircle_cpts) - 1])
[circumcircle_cpts[0], circumcircle_cpts[i]]
]
)
each lines
]
)
_voronoi_lines_dedup_lines(lines);