Full-featured interactive lozenge tiling generator. Draw arbitrary regions on a triangular grid or use presets like hexagons and letter shapes. Supports multiple rendering modes including 2D lozenge view, path view, dimer view, and 3D height function. Sampling methods include Glauber dynamics and coupling from the past, with options for periodic weights and export to PNG, PDF, SVG, and animated GIF.
About this simulation
- Draw a region on the triangular grid using the pencil tool, or use Hexagon preset
- Click "Make Tileable" if the region shows as invalid
- Click "Perfect Sample" to generate an exact random tiling
- Toggle 3D view to see the height function surface
A region is tileable if it has equal numbers of black and white triangles that can be perfectly matched.
Sampling Methods:
- Glauber dynamics: MCMC with local flips. Converges to target distribution over time.
- Perfect Sample (CFTP): Coupling From The Past — exact sample with no burn-in.
Weight Distributions:
- Uniform (q=1): Equal probability for all tilings
- q-Volume (q≠1): Probability ∝ qvolume
- Periodic weights: k×k matrix of position-dependent q values
Advanced:
- Average Sample: Compute mean height (Limit Shape)
- Fluctuations: Height difference ≈ Gaussian Free Field
- Double Dimer: Superimpose two samples to form loops
Drawing Tools:
- Pan 🤚: Move the view around
- Draw ✏️: Add triangles to region
- Erase 🧹: Remove triangles from region
- Lasso Fill/Erase: Click points to define polygon, click near start to close
- Snap 📐: Snap lasso to grid vertices
Region Tools:
- Scale Up/Down: Double or halve region size
- Make Tileable: Auto-fix invalid regions
- Undo/Redo: Full history support (Ctrl+Z/Y)
Presets: Hexagon (a,b,c), Letters A-Z, Numbers 0-9, Shape of the Month
Visualization:
- 2D Lozenge ◆: Standard flat tiling view
- 2D Paths →: Non-intersecting paths
- 2D Dimer •-•: Matching on dual graph
- 3D Height: Stepped surface, rotate/zoom
Export Options:
- Images: PNG, PDF
- Data: Height CSV, Mathematica array
- Region: JSON import/export
- Share: Copy link with encoded state
Performance: Uses WebGPU when available, falls back to multi-threaded WASM.
Fluctuations & Double Dimers
Export
Help
Drawing Tools
| Tool | Action |
|---|---|
| 🖐 | Pan canvas |
| ✏️ | Draw triangles |
| 🧽 | Erase triangles |
| ⭕+ | Lasso fill |
| ⭕− | Lasso erase |
| 📐 | Snap to grid |
| Key | Action |
|---|---|
| Shift | Toggle draw ↔ erase |
| Cmd-click | Complete lasso |
Keyboard Shortcuts
| Key | Action |
|---|---|
| S | Perfect Sample (CFTP) |
| G | Start/Stop Glauber |
| Space | Pause/Resume Glauber |
| 3 | Toggle 3D view |
| R | Reset view |
| U | Scale Up region (2×) |
| + / - | Zoom in/out |
| C / Shift+C | Next/Previous palette |
| P | Permute colors |
| ← → | Previous/Next palette |
| Z | Undo |
| H | Toggle hole labels |
| L | Cycle render mode (3D) |
| Y | Redo |
| M | Make tileable |
| F | Toggle fullscreen |
| ? | Show this help |
| Esc | Close dialogs |
code
(note: parameters in the code might differ from the ones in simulation results below)-
Link to code(This simulation is interactive, written in JavaScript, see the source code of this page at the link) -
Link to code(C++ code for the simulation (compiled to WebAssembly))