How to resolve the algorithm Dragon curve step by step in the Elm programming language

Published on 12 May 2024 09:40 PM

How to resolve the algorithm Dragon curve step by step in the Elm programming language

Table of Contents

Problem Statement

Create and display a dragon curve fractal. (You may either display the curve directly or write it to an image file.)

Here are some brief notes the algorithms used and how they might suit various languages. This always has F at even positions and S at odd. Eg. after 3 levels F_S_F_S_F_S_F_S. The +/- turns in between bend to the left or right the same as the "successive approximation" method above. Read more at for instance Joel Castellanos' L-system page. Variations are possible if you have only a single symbol for line draw, for example the Icon and Unicon and Xfractint code. The angles can also be broken into 45-degree parts to keep the expansion in a single direction rather than the endpoint rotating around. The string rewrites can be done recursively without building the whole string, just follow its instructions at the target level. See for example C by IFS Drawing code. The effect is the same as "recursive with parameter" above but can draw other curves defined by L-systems.

Let's start with the solution:

Step by Step solution about How to resolve the algorithm Dragon curve step by step in the Elm programming language

Source code in the elm programming language

import Color exposing (..)
import Collage exposing (..)
import Element exposing (..)
import Time exposing (..)
import Html exposing (..)
import Html.App exposing (program)


type alias Point = (Float, Float)

type alias Model =
  { points : List Point
  , level : Int
  , frame : Int
  }

maxLevel = 12
frameCount = 100

type Msg = Tick Time

init : (Model,Cmd Msg)
init = ( { points = [(-200.0, -70.0), (200.0, -70.0)]
         , level = 0 
         , frame = 0
         }
       , Cmd.none )

-- New point between two existing points.  Offset to left or right
newPoint : Point -> Point -> Float -> Point
newPoint  (x0,y0) (x1,y1) offset = 
  let (vx, vy) = ((x1 - x0) / 2.0, (y1 - y0) / 2.0) 
      (dx, dy) = (-vy * offset , vx * offset )
  in  (x0 + vx + dx, y0 + vy + dy) --offset from midpoint 

-- Insert between existing points. Offset to left or right side.
newPoints : Float -> List Point -> List Point
newPoints offset points = 
  case points of
    [] -> []
    [p0] -> [p0]  
    p0::p1::rest -> p0 :: newPoint p0 p1 offset :: newPoints -offset (p1::rest)

update : Msg -> Model -> (Model, Cmd Msg)
update _ model = 
  let mo = if (model.level == maxLevel)
           then model
           else let nextFrame = model.frame + 1
                in if (nextFrame == frameCount) 
                   then { points = newPoints 1.0 model.points 
                        , level = model.level+1
                        , frame = 0
                        }
                   else { model | frame = nextFrame
                        }
  in (mo, Cmd.none)

-- break a list up into n equal sized lists.
breakupInto : Int -> List a -> List (List a)
breakupInto n ls = 
    let segmentCount = (List.length ls) - 1 
        breakup n ls = case ls of
          [] -> []
          _ -> List.take (n+1) ls :: breakup n (List.drop n ls)
    in if n > segmentCount 
       then [ls]
       else breakup (segmentCount // n) ls

view : Model -> Html Msg
view model = 
  let offset = toFloat (model.frame) / toFloat frameCount
      colors = [red, orange, green, blue] 
  in toHtml 
       <| layers
            [ collage 700 500
              (model.points 
                |> newPoints offset
                |> breakupInto (List.length colors) -- for coloring
                |> List.map path 
                |> List.map2 (\color path -> traced (solid color) path ) colors )
              , show model.level
            ]

subscriptions : Model -> Sub Msg
subscriptions _ = 
    Time.every (5*millisecond) Tick

main =
  program 
      { init = init
      , view = view
      , update = update
      , subscriptions = subscriptions
      }


  

You may also check:How to resolve the algorithm Dinesman's multiple-dwelling problem step by step in the J programming language
You may also check:How to resolve the algorithm Define a primitive data type step by step in the FreeBASIC programming language
You may also check:How to resolve the algorithm Semordnilap step by step in the Common Lisp programming language
You may also check:How to resolve the algorithm Increment a numerical string step by step in the SenseTalk programming language
You may also check:How to resolve the algorithm Simple windowed application step by step in the IDL programming language