Skip to content

Instantly share code, notes, and snippets.

@dela3499
Created December 30, 2015 23:54
Show Gist options
  • Save dela3499/ebf9cd2b5697494e12d2 to your computer and use it in GitHub Desktop.
Save dela3499/ebf9cd2b5697494e12d2 to your computer and use it in GitHub Desktop.
module Penrose where
import List exposing (foldr, map)
import Graphics.Collage exposing (..)
import Graphics.Element exposing (..)
import Color exposing (..)
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
then tr
else subDivideTriangles (foldr (\t l -> subDivide t ++ l) [] tr) (i-1)
toForm : Triangle -> Form
toForm tr =
case tr of
Kite (p1,p2,p3) -> (filled red (polygon [p1,p2,p3]))
Dart (p1,p2,p3) -> (filled blue (polygon [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 8
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