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