Percolation
site percolation sweeping back and forth through the critical threshold: clusters are tinted by size, and the spanning cluster lights up with its outline traced (Percolation)
- Run
swift run --package-path Examples Example-Patterns-Percolation- Source
- Examples/Patterns/Percolation/Sketch.swift
import Ollin
/// **Percolation**: chance, acting together.
///
/// Every cell rolled one fixed random value at the start. A slowly breathing
/// probability decides which cells count as open, so the same landscape floods
/// and drains as the threshold sweeps. Below the critical probability (about
/// 0.5927) the open cells are scattered islands; just past it, one giant
/// cluster suddenly reaches from the top edge to the bottom. Clusters are
/// tinted by size, and the spanning cluster, when it exists, lights up warm
/// with its traced outline.
///
/// Try it: hold `probability` still just under 0.59 and watch how large the
/// islands get without ever connecting.
@main
final class Percolation_Example: Sketch {
private let columns = 72, rows = 72
private var values: [Double] = []
override func setup() {
seed(7)
values = (0 ..< columns * rows).map { _ in random() }
}
override func draw() {
background(Color(hex: 0x10141B))
let p = Percolation.criticalProbability + 0.05 * sin(time * 0.3)
let grid = Percolation(columns: columns, rows: rows,
openCells: values.map { $0 < p })
let area = canvasRectangle.inset(by: .all(70))
let spanning = grid.spanningClusterIndex
noStroke()
for k in 0 ..< grid.clusterCount {
if k == spanning { continue }
let size = Double(grid.clusterSizes[k])
let t = min(size / 400, 1)
fill(Color.mix(Color(hex: 0x24506B), Color(hex: 0x88C7E8), t))
for cell in grid.cellRects(of: k, in: area) { drawRect(cell) }
}
if let spanning {
fill(Color(hex: 0xE8B44A))
for cell in grid.cellRects(of: spanning, in: area) { drawRect(cell) }
stroke(Color(hex: 0xF2E8DC))
strokeWeight(2)
noFill()
for loop in grid.outlines(of: spanning, in: area) {
drawPolygon(loop.points)
}
}
drawCaption(String(format: "p = %.3f, %@",
p, spanning == nil ? "islands" : "the grid spans"))
}
}