This is an alternative site for discovering Elm packages. You may be looking for the official Elm package site instead.

Diagrams.Bezier

Generate bezier paths as lists of points. Adapted from this gist.

bezier : Point -> Point -> Point -> Point -> C.LineStyle -> Diagram t a

Given four points a, cp1, cp2, b, return path diagram which is a bezier curve from a to b, using cp1 and cp2 as control points.

module Diagrams.Bezier (bezier) where

{-| Generate bezier paths as lists of points.
Adapted from [this gist](https://gist.github.com/irrwitz/968b9762819974c92c9f).

@docs bezier
-}

import Graphics.Collage as C
import List as L

import Diagrams.Core exposing (..)
import Diagrams.Geom exposing (..)
import Diagrams.Type exposing (..)

-- TODO: replace this entire module/approach with builtin arcs...

{-| Given four points a, cp1, cp2, b, return path diagram which is a bezier
curve from a to b, using cp1 and cp2 as control points. -}
bezier : Point -> Point -> Point -> Point -> C.LineStyle -> Diagram t a
bezier a cp1 cp2 b ls = path (bezierCurve a cp1 cp2 b) ls

bezierCurve : Point -> Point -> Point -> Point -> List Point
bezierCurve a cp1 cp2 b = L.map (\x -> bezierPoint x [a, cp1, cp2, b]) resolution

bezierPoint : Float -> List Point -> Point
bezierPoint t points =
    case points of
      [x] -> x
      (x::xs) -> bezierPoint t (L.map2 (interpolatePoint t) points xs)
      [] -> Debug.crash "no points"

interpolatePoint : Float -> Point -> Point -> Point
interpolatePoint t (x0, y0) (x1, y1) = (lerp (x0, x1) (0, 1) t, lerp (y0, y1) (0, 1) t)

{--
  An array [0, 0.01, 0.02, ..., 1] which defines the resolution of the curve
--}
resolution : List Float
resolution = generate 0 1.0 0.01

{--
  generate: Creates a array of floats beginning from the given start value 
  until end value. Values in between are start value plus multiples
  of step value until end is reached or exceeded.
--}
generate : Float -> Float -> Float -> List Float
generate start end step =
  if end <= start then
    []
  else if start + step >= end then
    [start, end]
  else
    [start] ++ generate (start + step) end step