ianmackenzie / elm-units / Angle

An Angle represents an angle in degrees, radians, or turns. It is stored as a number of radians.


type alias Angle =
Quantity Basics.Float Radians


type Radians

Common units

radians : Basics.Float -> Angle

Construct an angle from a number of radians.

inRadians : Angle -> Basics.Float

Convert an angle to a number of radians.

degrees : Basics.Float -> Angle

Construct an angle from a number of degrees.

Angle.degrees 180
--> Angle.radians pi

inDegrees : Angle -> Basics.Float

Convert an angle to a number of degrees.

Angle.turns 2 |> Angle.inDegrees
--> 720

turns : Basics.Float -> Angle

Construct an angle from a number of turns.

Angle.turns -0.25
--> Angle.degrees -90

inTurns : Angle -> Basics.Float

Convert an angle to a number of turns.

Angle.radians pi |> Angle.inTurns
--> 0.5

Minutes and seconds

Angles are sometimes measured in degrees, minutes, and seconds, where 1 minute = 1/60th of a degree and 1 second = 1/60th of a minute.

minutes : Basics.Float -> Angle

Construct an angle from a number of minutes.

Angle.minutes 30
--> Angle.degrees 0.5

inMinutes : Angle -> Basics.Float

Convert an angle to a number of minutes.

Angle.degrees 2 |> Angle.inMinutes
--> 120

seconds : Basics.Float -> Angle

Construct an angle from a number of seconds.

Angle.seconds 120
--> Angle.minutes 2


type Sign
    = Positive
    | Negative

The sign of an angle given in degrees, minutes and seconds.

fromDms : { sign : Sign, degrees : Basics.Int, minutes : Basics.Int, seconds : Basics.Float } -> Angle

Construct an angle given its sign and its degree, minute and second components. The signs of degrees, minutes and seconds will be ignored (their absolute values will be used). Note that only seconds may be fractional! In general minutes and seconds should each be less than 60, but this is not enforced.

Angle.fromDms
    { sign = Angle.Positive
    , degrees = 45
    , minutes = 30
    , seconds = 36
    }
--> Angle.degrees 45.51

Angle.fromDms
    { sign = Angle.Negative
    , degrees = 2
    , minutes = 15
    , seconds = 0
    }
--> Angle.degrees -2.25

toDms : Angle -> { sign : Sign, degrees : Basics.Int, minutes : Basics.Int, seconds : Basics.Float }

Convert an angle to a number of degrees, minutes and seconds, along with its sign. The degrees, minutes and seconds values will all be non-negative, and both minutes and seconds will be less than 60.

Angle.toDms (Angle.degrees 1.5)
--> { sign = Angle.Positive
--> , degrees = 1
--> , minutes = 30
--> , seconds = 0
--> }

Angle.toDms (Angle.degrees -0.751)
--> { sign = Angle.Negative
--> , degrees = 0
--> , minutes = 45
--> , seconds = 3.6
--> }

You could use this to write a string-conversion function for angles, something like:

angleString angle =
    let
        { sign, degrees, minutes, seconds } =
            Angle.toDms angle

        signString =
            case sign of
                Angle.Positive ->
                    ""

                Angle.Negative ->
                    "-"
    in
    String.concat
        [ signString
        , String.fromInt degrees
        , "° "
        , String.fromInt minutes
        , "′ "
        , Round.round 3 seconds
        , "″"
        ]

(Here we're using the myrho/elm-round package to control the number of decimal places used when displaying the number of seconds.)

Trigonometry

If you're using Angle values instead of plain Floats, you'll need to use these functions instead of the corresponding ones in core.

sin : Angle -> Basics.Float

cos : Angle -> Basics.Float

tan : Angle -> Basics.Float

asin : Basics.Float -> Angle

acos : Basics.Float -> Angle

atan : Basics.Float -> Angle

atan2 : Quantity Basics.Float units -> Quantity Basics.Float units -> Angle

Normalization

normalize : Angle -> Angle

Convert an arbitrary angle to the equivalent angle in the range -180 to 180 degrees (-π to π radians), by adding or subtracting some multiple of 360 degrees (2π radians) if necessary.

Angle.normalize (Angle.degrees 45)
--> Angle.degrees 45

Angle.normalize (Angle.degrees 270)
--> Angle.degrees -90

Angle.normalize (Angle.degrees 370)
--> Angle.degrees 10

Angle.normalize (Angle.degrees 181)
--> Angle.degrees -179

Constants

Shorthand for Angle.radians 1, Angle.degrees 1 etc. Can be convenient to use with Quantity.per.

radian : Angle

degree : Angle

turn : Angle

minute : Angle

second : Angle