mirror of
https://github.com/JustinSDK/dotSCAD.git
synced 2025-08-21 22:05:27 +02:00
use circle_packing
This commit is contained in:
@@ -1,66 +1,27 @@
|
|||||||
use <util/rand.scad>;
|
use <util/rand.scad>;
|
||||||
|
use <experimental/circle_packing.scad>;
|
||||||
|
|
||||||
size = [500, 250];
|
size = [200, 100];
|
||||||
min_radius = 5;
|
density = 2;
|
||||||
max_radius = 50;
|
min_radius = 1;
|
||||||
total_circles = 100;
|
point_numbers = 100;
|
||||||
|
|
||||||
function _packing_circles_out_of_range(size, c) =
|
points = [
|
||||||
c[0] + c[2] >= size[0] ||
|
for(i = [0:point_numbers - 1])
|
||||||
c[0] - c[2] <= 0 ||
|
[rand(0, size.x), rand(0, size.y)]
|
||||||
c[1] + c[2] >= size[1] ||
|
];
|
||||||
c[1] - c[2] <= 0;
|
|
||||||
|
|
||||||
function _packing_circles_overlapping(circles, c, i = 0) =
|
circles = circle_packing(points, density, min_radius);
|
||||||
i == len(circles) ? false :
|
mr = max([for(c = circles) c[1]]);
|
||||||
let(
|
|
||||||
x = c[0] - circles[i][0],
|
|
||||||
y = c[1] - circles[i][1],
|
|
||||||
a = c[2] + circles[i][2],
|
|
||||||
collision = a ^ 2 >= x ^2 + y ^ 2
|
|
||||||
)
|
|
||||||
collision || _packing_circles_overlapping(circles, c, i + 1);
|
|
||||||
|
|
||||||
function _packing_circles_packable(size, circles, c) =
|
|
||||||
!_packing_circles_overlapping(circles, c) &&
|
|
||||||
!_packing_circles_out_of_range(size, c);
|
|
||||||
|
|
||||||
function _packing_circles_new_min_circle(size, min_radius, attempts, circles, i = 0) =
|
|
||||||
i == attempts ? [] :
|
|
||||||
let(c = [rand() * size[0], rand() * size[1], min_radius])
|
|
||||||
_packing_circles_packable(size, circles, c) ? c :
|
|
||||||
_packing_circles_new_min_circle(size, min_radius, attempts, circles, i + 1);
|
|
||||||
|
|
||||||
function _packing_circles_increase_radius(size, circles, c, max_radius) =
|
|
||||||
c[2] == max_radius || !_packing_circles_packable(size, circles, c) ?
|
|
||||||
[c[0], c[1], c[2] - 1] :
|
|
||||||
_packing_circles_increase_radius(size, circles, [c[0], c[1], c[2] + 1], max_radius);
|
|
||||||
|
|
||||||
|
|
||||||
function _packing_circles_new_circle(size, min_radius, max_radius, attempts, circles) =
|
|
||||||
let(c = _packing_circles_new_min_circle(size, min_radius, attempts, circles))
|
|
||||||
c == [] ? [] : _packing_circles_increase_radius(size, circles, c, max_radius);
|
|
||||||
|
|
||||||
function _packing_circles(size, min_radius, max_radius, total_circles, attempts, circles = [], i = 0) =
|
|
||||||
i == total_circles ? circles :
|
|
||||||
let(c = _packing_circles_new_circle(size, min_radius, max_radius, attempts, circles))
|
|
||||||
c == [] ? _packing_circles(size, min_radius, max_radius, total_circles, attempts, circles) :
|
|
||||||
_packing_circles(size, min_radius, max_radius, total_circles, attempts, [each circles, c], i + 1);
|
|
||||||
|
|
||||||
function packing_circles(size, min_radius, max_radius, total_circles, attempts = 100) =
|
|
||||||
_packing_circles(is_num(size) ? [size, size] : size, min_radius, max_radius, total_circles, attempts);
|
|
||||||
|
|
||||||
circles = packing_circles(size, min_radius, max_radius, total_circles);
|
|
||||||
mr = max([for(c = circles) c[2]]);
|
|
||||||
translate([0, 0, mr])
|
translate([0, 0, mr])
|
||||||
for(c = circles) {
|
for(c = circles) {
|
||||||
translate([c[0], c[1]])
|
translate(c[0])
|
||||||
sphere(c[2], $fn = 48);
|
sphere(c[1], $fn = 48);
|
||||||
}
|
}
|
||||||
|
|
||||||
for(c = circles) {
|
for(c = circles) {
|
||||||
translate([c[0], c[1]])
|
translate(c[0])
|
||||||
linear_extrude(mr)
|
linear_extrude(mr)
|
||||||
circle(c[2]/ 3, $fn = 48);
|
circle(c[1]/ 3, $fn = 48);
|
||||||
}
|
}
|
||||||
linear_extrude(1) square(size);
|
linear_extrude(1) square(size);
|
||||||
|
Reference in New Issue
Block a user