defmodule Azan.AstronomyUtility do
@moduledoc """
Documentation for `AstronomyUtility`.
"""
alias Azan.{
Astronomical,
Coordinate,
MathUtils,
SolarCoordinate
}
def corrected_hour_angle(
approximate_transit,
angle,
%Coordinate{latitude: latitude, longitude: longitude},
after_transit,
sidereal_time,
%SolarCoordinate{right_ascension: right_ascension, declination: declination} = _solar,
%SolarCoordinate{
right_ascension: previous_right_ascension,
declination: previous_declination
} = _prev_solar,
%SolarCoordinate{right_ascension: next_right_ascension, declination: next_declination} =
_next_solar
) do
m0 = approximate_transit
h0 = angle
theta0 = sidereal_time
a2 = right_ascension
a1 = previous_right_ascension
a3 = next_right_ascension
d2 = declination
d1 = previous_declination
d3 = next_declination
lw = -1 * longitude
try do
term1 = MathUtils.sin_deg(h0) - MathUtils.sin_deg(latitude) * MathUtils.sin_deg(d2)
term2 = MathUtils.cos_deg(latitude) * MathUtils.cos_deg(d2)
h0_capital = (term1 / term2) |> :math.acos() |> Math.rad2deg()
m = if after_transit, do: m0 + h0_capital / 360, else: m0 - h0_capital / 360
theta = (theta0 + 360.985647 * m) |> MathUtils.unwind_angle()
a = Astronomical.interpolate_angles(a2, a1, a3, m) |> MathUtils.unwind_angle()
delta = Astronomical.interpolate(d2, d1, d3, m)
h_capital = theta - lw - a
h =
Astronomical.altitude_of_celestial_body(
latitude,
delta,
h_capital
)
term3 = h - h0
term4 =
360 * MathUtils.cos_deg(delta) * MathUtils.cos_deg(latitude) *
MathUtils.sin_deg(h_capital)
dm = term3 / term4
(m + dm) * 24
rescue
ArithmeticError -> {:error, :arithmatic_error}
end
end
end