Skip to content

Instantly share code, notes, and snippets.

@VincentTam
Created September 19, 2025 08:20
Show Gist options
  • Select an option

  • Save VincentTam/cb946f2437dbe22ab09a31e72b019270 to your computer and use it in GitHub Desktop.

Select an option

Save VincentTam/cb946f2437dbe22ab09a31e72b019270 to your computer and use it in GitHub Desktop.
Typst simulation for Sierpiński triangle
#set page(height: auto, width: auto, margin: 5pt)
#import "@preview/cetz:0.4.2": canvas, draw, vector
#let n = 4
// a list of directions to place triangles in
#let dirs = range(3).map(i => (calc.cos(120deg*i+90deg), calc.sin(120deg*i+90deg)))
#canvas({
import draw: *;
// set segment style
set-style(stroke: yellow + 0.3pt)
// outermost triangle
polygon((0, 0), angle: 90deg, radius: 2, 3)
// smooth intersection of segments
set-style(stroke: (join: "bevel"))
// a queue of centers of triangles to be drawn
let curr-centers = ((0,0),)
// a queue of centers to triangles to be drawn during next iteration
let next-centers = ()
let curr-R = 2
for k in range(n) {
curr-R = curr-R / 2
// While queue is not empty, remove and draw first element,
// then add its rotated copies to the end of the next-queue
while curr-centers.len() > 0 {
let curr-center = curr-centers.remove(0);
polygon(curr-center, radius: curr-R, angle: 30deg, 3)
for dir in dirs {
let new-center = vector.add(curr-center, vector.scale(dir, curr-R))
next-centers.push(new-center)
}
}
// Reset queues for next iteration
curr-centers = next-centers
next-centers = ()
}
})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment