use crate::Manifold;
#[must_use]
pub fn menger_sponge(n: u32) -> Manifold {
let result = Manifold::cube(1.0, 1.0, 1.0, true);
if n == 0 {
return result;
}
let mut holes: Vec<Manifold> = Vec::new();
fractal(&mut holes, &result, 1.0, [0.0, 0.0], 1, n);
let hole = Manifold::batch_union(&holes);
let r1 = &result - &hole;
let hole_y = hole.rotate(90.0, 0.0, 0.0);
let r2 = &r1 - &hole_y;
let hole_x = hole_y.rotate(0.0, 0.0, 90.0);
&r2 - &hole_x
}
fn fractal(
holes: &mut Vec<Manifold>,
hole: &Manifold,
w: f64,
position: [f64; 2],
depth: u32,
max_depth: u32,
) {
let w = w / 3.0;
holes.push(
hole.scale(w, w, 1.0)
.translate(position[0], position[1], 0.0),
);
if depth == max_depth {
return;
}
let offsets = [
[-w, -w],
[-w, 0.0],
[-w, w],
[0.0, w],
[w, w],
[w, 0.0],
[w, -w],
[0.0, -w],
];
for off in offsets {
fractal(
holes,
hole,
w,
[position[0] + off[0], position[1] + off[1]],
depth + 1,
max_depth,
);
}
}