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

Curve.ParameterValue

Curves in opensolid/geometry are parameterized by a value that ranges from 0 to 1. A value of 0 corresponds to the start point of the curve and a value of 1 corresponds to the end point. This module contains functionality for:

  • Constructing parameter values that are guaranteed to be in the range 0 to 1
  • Constructing ranges of evenly-spaced parameter values
type ParameterValue = ParameterValue Float

Constants

zero : ParameterValue
half : ParameterValue
one : ParameterValue

Conversion to and from Float values

value : ParameterValue -> Float
clamped : Float -> ParameterValue
checked : Float -> Maybe ParameterValue
unsafe : Float -> ParameterValue

Ranges

steps : Int -> List ParameterValue
leading : Int -> List ParameterValue
trailing : Int -> List ParameterValue
midpoints : Int -> List ParameterValue
range : { numSteps : Int, includeStart : Bool, includeEnd : Bool } -> List ParameterValue

Arithmetic

midpoint : ParameterValue -> ParameterValue -> ParameterValue
oneMinus : ParameterValue -> ParameterValue
module Curve.ParameterValue
    exposing
        ( ParameterValue
        , checked
        , clamped
        , half
        , leading
        , midpoint
        , midpoints
        , one
        , oneMinus
        , range
        , steps
        , trailing
        , unsafe
        , value
        , zero
        )

{-| Curves in `opensolid/geometry` are [parameterized](https://en.wikipedia.org/wiki/Parametric_equation)
by a value that ranges from 0 to 1. A value of 0 corresponds to the start point
of the curve and a value of 1 corresponds to the end point. This module contains
functionality for:

  - Constructing parameter values that are guaranteed to be in the range 0 to 1
  - Constructing ranges of evenly-spaced parameter values

@docs ParameterValue


# Constants

@docs zero, half, one


# Conversion to and from `Float` values

@docs value, clamped, checked, unsafe


# Ranges

@docs steps, leading, trailing, midpoints, range


# Arithmetic

@docs midpoint, oneMinus

-}


{-| -}
type ParameterValue
    = ParameterValue Float


{-| -}
zero : ParameterValue
zero =
    ParameterValue 0


{-| -}
half : ParameterValue
half =
    ParameterValue 0.5


{-| -}
one : ParameterValue
one =
    ParameterValue 1


{-| -}
clamped : Float -> ParameterValue
clamped givenValue =
    if isNaN givenValue then
        ParameterValue givenValue
    else
        ParameterValue (clamp 0 1 givenValue)


{-| -}
checked : Float -> Maybe ParameterValue
checked givenValue =
    if isNaN givenValue then
        Nothing
    else if 0 <= givenValue && givenValue <= 1 then
        Just (ParameterValue givenValue)
    else
        Nothing


{-| -}
unsafe : Float -> ParameterValue
unsafe =
    ParameterValue


{-| -}
midpoint : ParameterValue -> ParameterValue -> ParameterValue
midpoint (ParameterValue firstValue) (ParameterValue secondValue) =
    ParameterValue (firstValue + (secondValue - firstValue) / 2)


{-| -}
oneMinus : ParameterValue -> ParameterValue
oneMinus (ParameterValue value_) =
    ParameterValue (1 - value_)


{-| -}
steps : Int -> List ParameterValue
steps n =
    if n < 1 then
        []
    else
        endpointsHelp 0 n (toFloat n) []


{-| -}
leading : Int -> List ParameterValue
leading n =
    if n < 1 then
        []
    else
        endpointsHelp 0 (n - 1) (toFloat n) []


{-| -}
trailing : Int -> List ParameterValue
trailing n =
    if n < 1 then
        []
    else
        endpointsHelp 1 n (toFloat n) []


endpointsHelp : Int -> Int -> Float -> List ParameterValue -> List ParameterValue
endpointsHelp startIndex index divisor accumulated =
    let
        parameterValue =
            ParameterValue (toFloat index / divisor)

        newAccumulated =
            parameterValue :: accumulated
    in
    if index == startIndex then
        newAccumulated
    else
        endpointsHelp startIndex (index - 1) divisor newAccumulated


{-| -}
midpoints : Int -> List ParameterValue
midpoints n =
    if n < 1 then
        []
    else
        midpointsHelp (2 * n - 1) (2 * toFloat n) []


midpointsHelp : Int -> Float -> List ParameterValue -> List ParameterValue
midpointsHelp index divisor accumulated =
    let
        parameterValue =
            ParameterValue (toFloat index / divisor)

        newAccumulated =
            parameterValue :: accumulated
    in
    if index == 1 then
        newAccumulated
    else
        midpointsHelp (index - 2) divisor newAccumulated


{-| -}
range : { numSteps : Int, includeStart : Bool, includeEnd : Bool } -> List ParameterValue
range { numSteps, includeStart, includeEnd } =
    if numSteps < 1 then
        []
    else
        let
            startIndex =
                if includeStart then
                    0
                else
                    1

            endIndex =
                if includeEnd then
                    numSteps
                else
                    numSteps - 1
        in
        if startIndex <= endIndex then
            endpointsHelp startIndex endIndex (toFloat numSteps) []
        else
            []


{-| -}
value : ParameterValue -> Float
value (ParameterValue value_) =
    value_