Every site (or bond, in bond mode) on the N×N square lattice is given a fixed random number in [0,1) once, when the grid is generated. A cell is "occupied" whenever its number is below the probability p you set — so dragging p doesn't re-randomize the lattice, it just reveals more of the same fixed randomness, exactly like slowly turning up a valve.
Connectivity between occupied neighbours is tracked with a weighted quick-union / path-compression union–find structure — the same data structure used in Kruskal's MST algorithm. Two invisible "virtual" nodes are wired to the top row and bottom row; the lattice percolates the instant those two virtual nodes land in the same set, which is an O(α(n)) check every time p changes.
- Site percolation, square lattice: p_c ≈ 0.592746 (Toivonen constant, numerically determined — there's no closed form)
- Bond percolation, square lattice: p_c = 1/2 exactly (proven by duality)
Near p_c the spanning cluster is a fractal with dimension ≈ 91/48 ≈ 1.896 in 2D — visibly more tangled and holey than a solid blob, which is why the colour map is worth watching as you sweep through the threshold.