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

{-| Curves in `elm-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 clamped, checked, value


# Ranges

@docs steps, leading, trailing, midpoints, range


# Arithmetic

@docs midpoint, oneMinus

-}


{-| A parameter value between 0 and 1. Curve types such as [`Arc2d`](Arc2d) and
[`CubicSpline3d`](CubicSpline3d) use `ParameterValue` arguments for curve
evaluation functions such as `Arc2d.pointOn` or `CubicSpline3d.samplesAt`.
-}
type ParameterValue
    = ParameterValue Float


{-| The parameter value 0.

    ParameterValue.value (ParameterValue.zero)
    --> 0

-}
zero : ParameterValue
zero =
    ParameterValue 0


{-| The parameter value 0.5.

    ParameterValue.value (ParameterValue.half)
    --> 0.5

-}
half : ParameterValue
half =
    ParameterValue 0.5


{-| The parameter value 1.

    ParameterValue.value (ParameterValue.one)
    --> 1

-}
one : ParameterValue
one =
    ParameterValue 1


{-| Construct a valid parameter value by clamping a plain `Float` value to
between 0 and 1.

    ParameterValue.value (ParameterValue.clamped 0.75)
    --> 0.75

    ParameterValue.value (ParameterValue.clamped -0.25)
    --> 0

    ParameterValue.value (ParameterValue.clamped 1.25)
    --> 1

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


{-| If the given value is between 0 and 1, return `Just` that value as a
`ParameterValue`. Otherwise, return `Nothing`.

    ParameterValue.checked 0.75
        |> Maybe.map ParameterValue.value
    --> Just 0.75

    ParameterValue.checked -0.25
    --> Nothing

    ParameterValue.checked 1.25
    --> Nothing

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


{-| Find the midpoint between two parameter values.

    ParameterValue.midpoint
        ParameterValue.zero
        ParameterValue.one
    --> ParameterValue.half

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


{-| Construct a parameter value by subtracting an existing parameter value from
1.0. This can be thought of as the 'negation' or 'complement' of a parameter
value.

    ParameterValue.oneMinus ParameterValue.one
    --> ParameterValue.zero

    ParameterValue.oneMinus ParameterValue.zero
    --> ParameterValue.one

    ParameterValue.oneMinus ParameterValue.half
    --> ParameterValue.half

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


{-| Construct a list of parameter values by taking a given number of steps from
0 to 1. Note that the number of returned values will in general be one greater
than the number of steps!

    ParameterValue.steps 0
    --> []

    ParameterValue.steps 1
    --> [ ParameterValue.zero, ParameterValue.one ]
<commit_msg>Expand ParameterValue.oneMinus docs a bit<commit_after>module Curve.ParameterValue
    exposing
        ( ParameterValue
        , checked
        , clamped
        , half
        , leading
        , midpoint
        , midpoints
        , one
        , oneMinus
        , range
        , steps
        , trailing
        , value
        , zero
        )

{-| Curves in `elm-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 clamped, checked, value


# Ranges

@docs steps, leading, trailing, midpoints, range


# Arithmetic

@docs midpoint, oneMinus

-}


{-| A parameter value between 0 and 1. Curve types such as [`Arc2d`](Arc2d) and
[`CubicSpline3d`](CubicSpline3d) use `ParameterValue` arguments for curve
evaluation functions such as `Arc2d.pointOn` or `CubicSpline3d.samplesAt`.
-}
type ParameterValue
    = ParameterValue Float


{-| The parameter value 0.

    ParameterValue.value (ParameterValue.zero)
    --> 0

-}
zero : ParameterValue
zero =
    ParameterValue 0


{-| The parameter value 0.5.

    ParameterValue.value (ParameterValue.half)
    --> 0.5

-}
half : ParameterValue
half =
    ParameterValue 0.5


{-| The parameter value 1.

    ParameterValue.value (ParameterValue.one)
    --> 1

-}
one : ParameterValue
one =
    ParameterValue 1


{-| Construct a valid parameter value by clamping a plain `Float` value to
between 0 and 1.

    ParameterValue.value (ParameterValue.clamped 0.75)
    --> 0.75

    ParameterValue.value (ParameterValue.clamped -0.25)
    --> 0

    ParameterValue.value (ParameterValue.clamped 1.25)
    --> 1

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


{-| If the given value is between 0 and 1, return `Just` that value as a
`ParameterValue`. Otherwise, return `Nothing`.

    ParameterValue.checked 0.75
        |> Maybe.map ParameterValue.value
    --> Just 0.75

    ParameterValue.checked -0.25
    --> Nothing

    ParameterValue.checked 1.25
    --> Nothing

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


{-| Find the midpoint between two parameter values.

    ParameterValue.midpoint
        ParameterValue.zero
        ParameterValue.one
    --> ParameterValue.half

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


{-| Subtract a parameter value from 1 to give a new parameter value.

    ParameterValue.oneMinus ParameterValue.one
    --> ParameterValue.zero

    ParameterValue.oneMinus ParameterValue.zero
    --> ParameterValue.one

    ParameterValue.oneMinus ParameterValue.half
    --> ParameterValue.half

This can be thought of as the 'negation' or 'complement' of a parameter value.
For example, evaluating a reversed curve at a parameter value `t` is generally
equivalent to evaluating the original curve at a parameter value
<code>1&nbsp;-&nbsp;t</code>, and vice versa.

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


{-| Construct a list of parameter values by taking a given number of steps from
0 to 1. Note that the number of returned values will in general be one greater
than the number of steps!

    ParameterValue.steps 0
    --> []

    ParameterValue.steps 1
    --> [ ParameterValue.zero, ParameterValue.one ]

{'fraction_non_alphanumeric': 0.08135890685721449, 'fraction_numerical': 0.01704901592077222, 'mean_word_length': 2.876579203109815, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 47, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6512432', 'n_tokens_mistral': 2373, 'n_tokens_neox': 2198, 'n_words': 793}