Penrose
a Penrose tiling with the matching-rule arcs stroked on top, where every arc meets a neighbor's across the shared edge, and light pulses outward from the five-fold sun; a click swaps the P3 rhombs for the P2 kites and darts (penroseTiling)
- Run
swift run --package-path Examples Example-Patterns-Penrose- Source
- Examples/Patterns/Penrose/Sketch.swift
import Ollin
/// A Penrose tiling, the two-tile pattern that covers the plane with five-fold
/// symmetry and never repeats. Both built-in variants are here: the P3 thick
/// and thin rhombs, and the P2 kites and darts; click or press a key to swap.
/// The tiles are filled by kind, and the matching-rule arcs are stroked on
/// top: every arc end meets a neighbor's across the shared edge, so the
/// decoration reads as one weave of closed curves in either variant. A slow
/// pulse breathes light along the curves; each tiling is a pure function of
/// the canvas, computed once and held.
@main
final class PenroseRhombs: Sketch {
private var variant: Penrose.Variant = .rhombs
private var tiles: [Penrose.Tile] = []
private let period = 8.0
override var loopDuration: Double? { period }
override func draw() {
if tiles.isEmpty {
tiles = penroseTiling(variant, tileEdge: 72)
}
background(Color(hex: 0x14101E))
noStroke()
for tile in tiles {
fill(tileColor(tile.kind))
drawShape(tile.shape)
}
// The arcs, breathing: brightness sweeps outward from the sun at the
// center, one wavefront per loop.
noFill()
strokeCap(.round)
let center = center
let maxDistance = center.length
for tile in tiles {
let distance = tile.points[0].distance(to: center) / maxDistance
let wave = pingPong(over: period, phase: distance)
for (i, arc) in tile.arcs.enumerated() {
let base = i == 0 ? Color(hex: 0xF2A65A) : Color(hex: 0x2EC4B6)
stroke(Color.mix(base, .white, wave * 0.35).withAlpha(0.55 + wave * 0.45))
strokeWeight((2.5 + wave * 2) * scale)
drawPolyline(arc.points, closed: false)
}
}
drawCaption(variant == .rhombs
? "P3 thick and thin rhombs; click or press a key for the P2 kites and darts"
: "P2 kites and darts; click or press a key for the P3 rhombs")
}
override func mousePressed() { swapVariant() }
override func keyPressed() { swapVariant() }
private func swapVariant() {
variant = variant == .rhombs ? .kitesAndDarts : .rhombs
tiles = []
}
private func tileColor(_ kind: Penrose.TileKind) -> Color {
switch kind {
case .thick: return Color(hex: 0x342A58)
case .thin: return Color(hex: 0x181129)
case .kite: return Color(hex: 0x24504B)
case .dart: return Color(hex: 0x241531)
}
}
}