Everything in the parent project is de Bruijn's: n families of parallel lines at exactly 2π/n, and a dual tiling in the corresponding cyclotomic field. This corner is about a different object. penrose-mosaic builds Penrose tilings on the integer lattice — every vertex has exact integer coordinates at every generation, and inflation is an integer substitution. That mode is called quadrille, and it is drawn here on the paper it belongs to.
The natural assumption is that such a construction is a rational approximant: that as it inflates its directions converge to the Euclidean 36° and 72°. They do not. The substitution has its own dominant eigenvector, and its limiting slopes are algebraic of degree 2 over ℚ, in ℚ(√5) — a simpler field than the true tangents, which need nested radicals. Two geometries, not one rounded off.
The wheel on show is the P wheel. Writing r for a pentagon's minor radius — its inradius, center to edge — and R for the major one, center to vertex: P is 2r, the vector from one pentagon's center to its neighbor's, which is what the tiling is laid out on. D is R, one pentagon's own radius, center to vertex. The picker carries all four penrose-mosaic stores. S is a pentagon's center to the near diamond's, T two star centers with their feet touching. The figure on the right draws the thing being measured, and each wheel connects a different pair of figures: P a pentaflake, one pentagon and the five that share its edges; S a pentagon and the five near diamonds, long axis pointing in; T a star and the five stars it meshes with, tip into dimple; D one pentagon with its spokes running out to its own corners. Which wheel you take sets the scale and nothing else — they share the substitution, so they share its dominant eigenvector and land on the same limiting directions. Their ratio tends to 2r/R = 2 cos 36° = φ, though the seeds are coarse enough at generation 0 to read 1.387 rather than 1.618.
Whole generations and the half steps between them; past the end, the limit. Scrolling over either figure steps the ladder too. Generation 1 is the seed, as penrose-mosaic numbers it.
The wheel is ten lattice points, but only the first three are ever stored — the other seven are those three reflected (negate x, negate y, negate both), so they carry nothing new. Three free seeds, and the reflections fill the turn.
Inflation replaces each seed with the sum of three consecutive entries, and because the two reflections act on the two coordinates differently, x and y evolve under two different integer matrices. That asymmetry is the whole story — a similarity would use one matrix for both.
⎡1 0 0⎤ ⎡1 2 0⎤
Mx = ⎢1 1 1⎥ My = ⎢1 1 1⎥
⎣0 1 2⎦ ⎣0 1 0⎦
char(Mx) = (1−λ)(λ²−3λ+1) char(My) = (1+λ)(λ²−3λ+1)
Both carry φ² and φ⁻², so the growth ratio is φ² — proved, not measured. Mx carries an extra eigenvalue 1: x₀ never moves, which is why the first seed sits on the vertical at every generation. My carries an extra −1: an alternating component that neither grows nor decays, and it is exactly the ±2 that turns up if you take a half step. The two free angles are
The numbering is penrose-mosaic's. Its makeWheels puts the
seed at index 1 and one deflation of it at index 0, so that the wheel
index matches the shape generation the drawing code asks for —
wheels.p[gen] — and that is what
measurements.html prints. Generation 1 is the seed here too.
The φ² ladder, and its missing halves. The stored wheels hold only even powers of φ, so their x-components are alternate Fibonacci numbers — 3, 8, 21, 55. The half step is a two-term sum instead of a three-term one (drop the middle), and interleaved the sequence is Fibonacci exactly: 3, 5, 8, 13, 21, 34, 55, 89. It is a half step on x term for term, and on y up to that alternating ±2 — which is why φ² is where the two coordinates agree. Below zero there is one more positive half generation, then the conjugate ψ = −1/φ takes over. See NOTES.
penrose-mosaic holds four wheels and eight tile outlines, all of them found by hand and typed in as coordinates. Keep only the five ordered points of one pentagon and the rest follows: the wheels are one operator at four strides, and every tile is a closed walk in the pentagon's own edges, so a rotation is an index shift. Drag a corner and the tiling follows — including corners that leave it with no mirror symmetry at all.
Five directions, unequally spaced, mirror symmetric about the vertical. Every step of de Bruijn's construction that reads the direction array still works — crossings, K-tuples, the dual map. What breaks is everything that assumed the spacing was even:
The page that does it is dual.html: the multigrid on one canvas and its dual on the other, with the two switches those bullets imply — the grid's spacing and the dual's edge vectors, which de Bruijn's construction uses one array for and which come apart the moment the directions are unequal.