module Main exposing (..) import Html exposing (..) import Svg exposing (..) import Svg.Attributes exposing (..) type alias Point = { x : Float, y : Float } type alias Line = { start : Point, end : Point } add a b = Point (a.x + b.x) (a.y + b.y) scale s p = Point (s * p.x) (s * p.y) diff start end = add end (scale -1 start) midpoint s line = add line.start (scale s (diff line.start line.end)) rotateMinus90Deg p = Point p.y -p.x tip line = diff line.start line.end |> rotateMinus90Deg |> scale (sqrt 3 / 6) |> add (midpoint 0.5 line) kochDivide line = [ Line line.start (midpoint (1 / 3) line) , Line (midpoint (1 / 3) line) (tip line) , Line (tip line) (midpoint (2 / 3) line) , Line (midpoint (2 / 3) line) line.end ] kochIteration iterations lineList = if iterations == 0 then lineList else List.concatMap kochDivide lineList |> kochIteration (iterations - 1) lineToSvg : Line -> Svg.Svg msg lineToSvg line = Svg.line [ x1 (String.fromFloat line.start.x) , y1 (String.fromFloat line.start.y) , x2 (String.fromFloat line.end.x) , y2 (String.fromFloat line.end.y) ] [] baseHeight = 250 startLine = Line (Point 0 baseHeight) (Point 400 baseHeight) main = div [ class "tile" ] [ h2 [] [ Html.text "Koch" ] , div [] [ svg [ width "400px" , height "400px" , Svg.Attributes.style "fill: none; stroke: purple; stroke-width: 1;" ] ([ startLine ] |> kochIteration 5 |> List.map lineToSvg) ] ]