# `AstroUtils.Angle`
[🔗](https://github.com/jakedjohnson/astro_utils/blob/v0.1.0/lib/astro_utils/angle.ex#L1)

Angle normalization, conversion, and distance functions.

All functions take and return **degrees** unless the name says otherwise
(`deg_to_rad/1`, `rad_to_deg/1`). Inputs may be any real value: the
normalizing functions accept negative and out-of-range angles and fold them
into their documented output range.

    iex> AstroUtils.Angle.normalize_360(-90.0)
    270.0

# `degree`

```elixir
@type degree() :: float()
```

An angle in degrees.

# `angular_distance`

```elixir
@spec angular_distance(number(), number()) :: degree()
```

Unsigned minimal-arc separation between two angles, in `[0, 180]`.

Symmetric in its arguments, and unaffected by adding whole turns to either
input.

## Examples

    iex> AstroUtils.Angle.angular_distance(359.0, 1.0)
    2.0

    iex> AstroUtils.Angle.angular_distance(0.0, 190.0)
    170.0

# `atan2_lon`

```elixir
@spec atan2_lon(number(), number()) :: degree()
```

Compute `atan2(y, x)` and return the result in degrees in `[0, 360)`.

Handy for recovering a longitude from the x/y components of a vector, where
`y` is the component 90° ahead of `x`.

## Examples

    iex> AstroUtils.Angle.atan2_lon(1.0, 0.0)
    90.0

    iex> AstroUtils.Angle.atan2_lon(-1.0, -1.0)
    225.0

# `deg_to_rad`

```elixir
@spec deg_to_rad(number()) :: float()
```

Convert degrees to radians.

## Examples

    iex> AstroUtils.Angle.deg_to_rad(180.0)
    3.141592653589793

# `normalize_360`

```elixir
@spec normalize_360(number()) :: degree()
```

Normalize any angle to `[0, 360)`.

Exactly `360.0` is never returned; values that land on the wrap point come
back as `0.0`.

## Examples

    iex> AstroUtils.Angle.normalize_360(725.0)
    5.0

    iex> AstroUtils.Angle.normalize_360(-90.0)
    270.0

    iex> AstroUtils.Angle.normalize_360(360.0)
    0.0

# `rad_to_deg`

```elixir
@spec rad_to_deg(number()) :: float()
```

Convert radians to degrees.

## Examples

    iex> AstroUtils.Angle.rad_to_deg(:math.pi())
    180.0

# `signed_delta`

```elixir
@spec signed_delta(number(), number()) :: degree()
```

Signed shortest-path delta from `lon1` to `lon2`, in `(-180, 180]`.

Positive means `lon2` is ahead of `lon1` in the direction of increasing
longitude. The exactly-antipodal case is reported as `+180.0`, never
`-180.0`, so the range is half-open on the negative side.

## Examples

    iex> AstroUtils.Angle.signed_delta(359.0, 1.0)
    2.0

    iex> AstroUtils.Angle.signed_delta(1.0, 359.0)
    -2.0

    iex> AstroUtils.Angle.signed_delta(0.0, 180.0)
    180.0

---

*Consult [api-reference.md](api-reference.md) for complete listing*
