fractals_3d_webgl · MengerSponge3DLevel3
3D Menger sponge level-3 wireframe
A level-3 3D Menger sponge explicitly generated as 20^3 = 8000 kept sub-cubes and rasterised as a 12-edge wireframe projection. The construction recursively replaces each cube with 20 of the 27 sub-cubes in a 3x3x3 partition, keeping only the eight corners (the centre, six face-centres, and twelve edge-centres are removed at each step). Hausdorff dimension is log(20)/log(3) ~= 2.727. The full 3D cube cloud is sorted back-to-front, then orthographically projected from a slow camera orbit into a 2D canvas, with depth fading the wire colour from near-white to cool blue at the far side.
Original: https://en.wikipedia.org/wiki/Menger_sponge
▶ Try the live demo (JS port) ▶ Run reference.py via Pyodide 10 formulas have instant JS ports. The Pyodide path runs the actual Python in your browser — first load is ~6 MB, then instant.
Math essence
Per level, divide each cube into 3x3x3 = 27 equal sub-cubes; keep sub-cube (i, j, k) iff at most one of (i, j, k) is 1. This leaves 8 corner sub-cubes. After N levels there are 20^N kept cubes, each of side length 2/3^N. Here N = 3, so 8000 cubes. Project each cube centre by a 3D pitch/yaw rotation, sort by projected depth, rasterise each cube as 12 line segments using np.linspace on (x, y) endpoints, and blend the wire colour by (1 - depth) to dim the far side.
Parameters
| Name | Type | Default | Range | Description |
|---|---|---|---|---|
dim | int | 256 | 128–512 | Square canvas side length in pixels. |
level | int | 3 | 1–3 | Recursion depth (level N has 20^N sub-cubes; level 3 = 8000). |
camera_pitch | float | 0.85 | -1.2–1.2 | Camera pitch (radians), animated by step(). |
camera_yaw | float | 0.6 | -1.2–1.2 | Camera yaw (radians), animated by step(). |
orbit_speed | float | 0.1 | 0–0.4 | Per-step camera phase increment. |
wire_color | tuple | 245,250,255 | — | Wire colour at the near side (low depth). |
far_color | tuple | 110,140,220 | — | Wire colour at the far side (high depth). |
background | tuple | 8,10,20 | — | Background colour. |
depth_fade | float | 0.85 | 0–1 | Depth-based wire alpha multiplier. |
seed | int | 7 | 0–999 | RNG seed. |
Reference
First 60 lines of reference.py. Full source:
library_external/fractals_3d_webgl/MengerSponge3DLevel3/reference.py
from __future__ import annotations
from typing import ClassVar
import numpy as np
def _is_menger_kept(i: int, j: int, k: int) -> bool:
"""Return True if the (i, j, k) sub-cube (each in {0, 1, 2}) of a
3x3x3 macro-cell is *kept* in the Menger sponge construction.
Per Wikipedia (Menger sponge): keep the cube iff at most one of
(i, j, k) is 1. Equivalently, drop the centre, the six
face-centres, and the twelve edge-centres; keep the eight corners.
"""
ones = (i == 1) + (j == 1) + (k == 1)
return ones <= 1
def _generate_menger_cubes(
level: int, kept: bool = True
) -> tuple[np.ndarray, np.ndarray, np.ndarray, np.ndarray]:
"""Recursively generate the kept (``kept=True``) or removed
(``kept=False``) sub-cubes of a level-``level`` Menger sponge
centred at the origin with side length 2.
Returns (xs, ys, zs, sizes) for every kept cube, where each array
has shape (N,). Coordinates are cube centres; ``sizes`` is the
side length of each cube. N is 20^level (kept) or 7^level
(removed).
"""
cubes: list[tuple[float, float, float, float]] = [(0.0, 0.0, 0.0, 2.0)]
for _ in range(level):
new: list[tuple[float, float, float, float]] = []
for cx, cy, cz, side in cubes:
child = side / 3.0
for i in range(3):
for j in range(3):
for k in range(3):
is_kept = _is_menger_kept(i, j, k)
if (kept and is_kept) or (not kept and not is_kept):
ox = (i - 1) * child
oy = (j - 1) * child
oz = (k - 1) * child
new.append((cx + ox, cy + oy, cz + oz, child))
cubes = new
arr = np.array(cubes, dtype=np.float32)
return arr[:, 0], arr[:, 1], arr[:, 2], arr[:, 3]
def _project_cube_wireframe(
px: np.ndarray,
py: np.ndarray,
d: int,
scale: float,
ox: float,
oy: float,
color: np.ndarray,
frame: np.ndarray,
line_alpha: float = 0.85, Try running it locally
The reference implementation is self-contained Python with numpy. Install the package and run:
python library_external/fractals_3d_webgl/MengerSponge3DLevel3/reference.py Need help? See Learn for the standard environment setup, or Playground for an in-browser sketchbook.
More from fractals_3d_webgl
Mandelbox fold-scale 2D projection
fractals_3d_webgl · MandelboxFoldScale
A 2D orthographic projection of Tom Lowe's Mandelbox (2010) escape-time field.
Mandelbulb power-8 2D projection
fractals_3d_webgl · Mandelbulb2DProjection
A 2D orthographic projection of the iconic power-8 Mandelbulb escape-time field.
Poincare-disk hyperbolic tiling (Escher / Coxeter)
fractals_3d_webgl · HyperbolicTilingPoincare3D
A 3D hyperboloid-lifted rendering of the (p, q) hyperbolic tessellation in the Poincare disk model.
Sierpinski tetrahedron (tetrix) 3D chaos game
fractals_3d_webgl · SierpinskiTetrahedron3D
A 3D chaos-game rendering of the Sierpinski tetrahedron (tetrix): a regular tetrahedron recursively replaced by four half-size copies at its corners (Hausdorff dimension log(4)/log(2) = 2).