Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Penrose Tiling in Elm
module Penrose where
import List(foldr, map)
import Graphics.Collage(..)
import Graphics.Element(..)
import Color(..)
goldenRatio = (1 + sqrt 5) / 2
type alias Point = (Float, Float)
type Triangle
= Kite (Point, Point, Point)
| Dart (Point, Point, Point)
interpolate : Float -> Float -> Float
interpolate v0 v1 = v0 + (v1-v0) / goldenRatio
split : Point-> Point -> Point
split (x1,y1) (x2,y2) = (interpolate x1 x2, interpolate y1 y2)
subDivide : Triangle -> List Triangle
subDivide tr =
case tr of
Kite (p1,p2,p3) ->
let p4 = split p1 p2
in [
Kite (p3, p4, p2),
Dart (p4, p3, p1)
]
Dart (p1,p2,p3) ->
let p4 = split p2 p1
p5 = split p2 p3
in [
Dart (p5, p3, p1),
Dart (p4, p5, p2),
Kite (p5, p4, p1)
]
subDivideTriangles : List Triangle -> number-> List Triangle
subDivideTriangles tr i =
if | i == 0 -> tr
| otherwise -> subDivideTriangles (foldr (\t l -> subDivide t ++ l) [] tr) (i-1)
toForm : Triangle -> Form
toForm tr =
case tr of
Kite (p1,p2,p3) -> (filled red [p1,p2,p3])
Dart (p1,p2,p3) -> (filled blue [p1,p2,p3])
pointOnCircle : Point ->Float -> Float -> Point
pointOnCircle (x,y) r a = (x + cos a * r, y + sin a * r)
createTriangle : Float -> Triangle
createTriangle i =
let
o = if (round i) % 2 == 0 then 1 else -1
a1 = (2*i - 1 * o) * pi / 10
a2 = (2*i + 1 * o) * pi / 10
c = (-100.0, 40.0)
pointAt = pointOnCircle c 400
in
Kite (c, pointAt a1, pointAt a2)
trs = map createTriangle [1..10]
path = subDivideTriangles trs 4
main : Element
main = collage 800 800 (map toForm path)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.