{-|
Module: Data.Astro.Moon
Description: Calculation characteristics of the Moon
Copyright: Alexander Ignatyev, 2016

Calculation characteristics of the Moon.

= Example

@
import Data.Astro.Time.JulianDate
import Data.Astro.Coordinate
import Data.Astro.Types
import Data.Astro.Effects
import Data.Astro.CelestialObject.RiseSet
import Data.Astro.Moon

ro :: GeographicCoordinates
ro = GeoC (fromDMS 51 28 40) (-(fromDMS 0 0 5))

dt :: LocalCivilTime
dt = lctFromYMDHMS (DH 1) 2017 6 25 10 29 0

today :: LocalCivilDate
today = lcdFromYMD (DH 1) 2017 6 25

jd :: JulianDate
jd = lctUniversalTime dt

-- distance from the Earth to the Moon in kilometres
mdu :: MoonDistanceUnits
mdu = moonDistance1 j2010MoonDetails jd
-- MDU 0.9550170577020396

distance :: Double
distance = mduToKm mdu
-- 367109.51199772174

-- Angular Size
angularSize :: DecimalDegrees
angularSize = moonAngularSize mdu
-- DD 0.5425033990980761

-- The Moon's coordinates
position :: JulianDate -> EquatorialCoordinates1
position = moonPosition1 j2010MoonDetails

ec1 :: EquatorialCoordinates1
ec1 = position jd
-- EC1 {e1Declination = DD 18.706180658927323, e1RightAscension = DH 7.56710547682055}

hc :: HorizonCoordinates
hc = ec1ToHC ro jd ec1
-- HC {hAltitude = DD 34.57694951316064, hAzimuth = DD 103.91119101451832}

-- Rise and Set
riseSet :: RiseSetMB
riseSet = riseAndSet2 0.000001 position ro verticalShift today
-- RiseSet
--    (Just (2017-06-25 06:22:51.4858 +1.0,DD 57.81458864497365))
--    (Just (2017-06-25 22:28:20.3023 +1.0,DD 300.4168238905249))

-- Phase
phase :: Double
phase = moonPhase j2010MoonDetails jd
-- 2.4716141948212922e-2


sunEC1 :: EquatorialCoordinates1
sunEC1 = sunPosition2 jd
-- EC1 {e1Declination = DD 23.37339098989099, e1RightAscension = DH 6.29262026252748}

limbAngle :: DecimalDegrees
limbAngle = moonBrightLimbPositionAngle ec1 sunEC1
-- DD 287.9869373767473
@
-}

module Data.Astro.Moon
(
  moonPosition1
  , moonPosition2
  , moonDistance1
  , moonAngularSize
  , moonHorizontalParallax
  , moonPhase
  , moonBrightLimbPositionAngle
)

where

import qualified Data.Astro.Utils as U
import Data.Astro.Types (DecimalDegrees(..), GeographicCoordinates, toRadians, fromRadians, kmToAU)
import Data.Astro.Time.JulianDate (JulianDate(..), numberOfDays)
import Data.Astro.Coordinate (EquatorialCoordinates1(..), EclipticCoordinates(..), eclipticToEquatorial)
import Data.Astro.Planet (planetBrightLimbPositionAngle)
import Data.Astro.Sun (sunDetails, sunMeanAnomaly2, sunEclipticLongitude2)
import Data.Astro.Moon.MoonDetails (MoonDetails(..), MoonDistanceUnits(..), j2010MoonDetails, mduToKm)
import Data.Astro.Effects (parallax)


-- | Reduce the value to the range [0, 360)

reduceDegrees :: DecimalDegrees -> DecimalDegrees
reduceDegrees :: DecimalDegrees -> DecimalDegrees
reduceDegrees = DecimalDegrees -> DecimalDegrees -> DecimalDegrees
forall a. RealFrac a => a -> a -> a
U.reduceToZeroRange DecimalDegrees
360


-- | Calculate Equatorial Coordinates of the Moon with the given MoonDetails and at the given JulianDate.

-- 

-- It is recommended to use 'j2010MoonDetails' as a first parameter.

moonPosition1 :: MoonDetails -> JulianDate -> EquatorialCoordinates1
moonPosition1 :: MoonDetails -> JulianDate -> EquatorialCoordinates1
moonPosition1 MoonDetails
md JulianDate
ut =
  let sd :: SunDetails
sd = JulianDate -> SunDetails
sunDetails JulianDate
ut
      lambdaS :: DecimalDegrees
lambdaS = SunDetails -> DecimalDegrees
sunEclipticLongitude2 SunDetails
sd
      ms :: DecimalDegrees
ms = SunDetails -> DecimalDegrees
sunMeanAnomaly2 SunDetails
sd
      mmq :: MoonQuantities
mmq = MoonDetails -> JulianDate -> MoonQuantities
meanMoonQuantities MoonDetails
md JulianDate
ut
      MQ DecimalDegrees
lm'' DecimalDegrees
_ DecimalDegrees
nm' = DecimalDegrees
-> DecimalDegrees -> MoonQuantities -> MoonQuantities
correctedMoonQuantities DecimalDegrees
lambdaS DecimalDegrees
ms MoonQuantities
mmq
      a :: Double
a = DecimalDegrees -> Double
toRadians (DecimalDegrees -> Double) -> DecimalDegrees -> Double
forall a b. (a -> b) -> a -> b
$ DecimalDegrees
lm''DecimalDegrees -> DecimalDegrees -> DecimalDegrees
forall a. Num a => a -> a -> a
-DecimalDegrees
nm'
      i :: Double
i = DecimalDegrees -> Double
toRadians (DecimalDegrees -> Double) -> DecimalDegrees -> Double
forall a b. (a -> b) -> a -> b
$ MoonDetails -> DecimalDegrees
mdI MoonDetails
md
      y :: Double
y = (Double -> Double
forall a. Floating a => a -> a
sin Double
a) Double -> Double -> Double
forall a. Num a => a -> a -> a
* (Double -> Double
forall a. Floating a => a -> a
cos Double
i)
      x :: Double
x = Double -> Double
forall a. Floating a => a -> a
cos Double
a
      at :: DecimalDegrees
at = DecimalDegrees -> DecimalDegrees
reduceDegrees (DecimalDegrees -> DecimalDegrees)
-> DecimalDegrees -> DecimalDegrees
forall a b. (a -> b) -> a -> b
$ Double -> DecimalDegrees
fromRadians (Double -> DecimalDegrees) -> Double -> DecimalDegrees
forall a b. (a -> b) -> a -> b
$ Double -> Double -> Double
forall a. RealFloat a => a -> a -> a
atan2 Double
y Double
x
      lambdaM :: DecimalDegrees
lambdaM = DecimalDegrees
at DecimalDegrees -> DecimalDegrees -> DecimalDegrees
forall a. Num a => a -> a -> a
+ DecimalDegrees
nm'
      betaM :: DecimalDegrees
betaM = Double -> DecimalDegrees
fromRadians (Double -> DecimalDegrees) -> Double -> DecimalDegrees
forall a b. (a -> b) -> a -> b
$ Double -> Double
forall a. Floating a => a -> a
asin (Double -> Double) -> Double -> Double
forall a b. (a -> b) -> a -> b
$ (Double -> Double
forall a. Floating a => a -> a
sin Double
a) Double -> Double -> Double
forall a. Num a => a -> a -> a
* (Double -> Double
forall a. Floating a => a -> a
sin Double
i)
  in EclipticCoordinates -> JulianDate -> EquatorialCoordinates1
eclipticToEquatorial (DecimalDegrees -> DecimalDegrees -> EclipticCoordinates
EcC DecimalDegrees
betaM DecimalDegrees
lambdaM) JulianDate
ut


-- | Calculate Equatorial Coordinates of the Moon with the given MoonDetails,

-- distance to the Moon, geographic coordinates of the onserver,

-- height above sea-level of the observer measured in metres (20 is a good reasonable value for the height)

-- and at the given JulianDate.

-- 

-- It is recommended to use 'j2010MoonDetails' as a first parameter,

-- to obtain the distance to the Moon you can use `moonDistance1` function.

-- `moonPosition2` takes into account parallax effect.

moonPosition2 :: MoonDetails -> MoonDistanceUnits -> GeographicCoordinates -> Double -> JulianDate -> EquatorialCoordinates1
moonPosition2 :: MoonDetails
-> MoonDistanceUnits
-> GeographicCoordinates
-> Double
-> JulianDate
-> EquatorialCoordinates1
moonPosition2 MoonDetails
md MoonDistanceUnits
distance GeographicCoordinates
coords Double
height JulianDate
jd =
  let p :: EquatorialCoordinates1
p = MoonDetails -> JulianDate -> EquatorialCoordinates1
moonPosition1 MoonDetails
md JulianDate
jd
  in GeographicCoordinates
-> Double
-> AstronomicalUnits
-> JulianDate
-> EquatorialCoordinates1
-> EquatorialCoordinates1
parallax GeographicCoordinates
coords Double
height (Double -> AstronomicalUnits
kmToAU (Double -> AstronomicalUnits) -> Double -> AstronomicalUnits
forall a b. (a -> b) -> a -> b
$ MoonDistanceUnits -> Double
mduToKm MoonDistanceUnits
distance) JulianDate
jd EquatorialCoordinates1
p


-- | Calculates the Moon's Distance at the given julian date.

-- Returns distance to the Moon

-- moonDistance1 :: JulianDate -> MoonDistanceUnits

-- you can use 'mduToKm' (defined in "Data.Astro.Moon.MoonDetails") to convert result to kilometers

moonDistance1 :: MoonDetails -> JulianDate -> MoonDistanceUnits
moonDistance1 :: MoonDetails -> JulianDate -> MoonDistanceUnits
moonDistance1 MoonDetails
md JulianDate
ut =
  let sd :: SunDetails
sd = JulianDate -> SunDetails
sunDetails JulianDate
ut
      lambdaS :: DecimalDegrees
lambdaS = SunDetails -> DecimalDegrees
sunEclipticLongitude2 SunDetails
sd
      ms :: DecimalDegrees
ms = SunDetails -> DecimalDegrees
sunMeanAnomaly2 SunDetails
sd
      mmq :: MoonQuantities
mmq = MoonDetails -> JulianDate -> MoonQuantities
meanMoonQuantities MoonDetails
md JulianDate
ut
      cmq :: MoonQuantities
cmq = DecimalDegrees
-> DecimalDegrees -> MoonQuantities -> MoonQuantities
correctedMoonQuantities DecimalDegrees
lambdaS DecimalDegrees
ms MoonQuantities
mmq
      mm' :: Double
mm' = DecimalDegrees -> Double
toRadians (DecimalDegrees -> Double) -> DecimalDegrees -> Double
forall a b. (a -> b) -> a -> b
$ MoonQuantities -> DecimalDegrees
mqAnomaly MoonQuantities
cmq
      ec :: Double
ec = DecimalDegrees -> Double
toRadians (DecimalDegrees -> Double) -> DecimalDegrees -> Double
forall a b. (a -> b) -> a -> b
$ Double -> DecimalDegrees
centreEquation Double
mm'
      e :: Double
e = MoonDetails -> Double
mdE MoonDetails
md
  in Double -> MoonDistanceUnits
MDU (Double -> MoonDistanceUnits) -> Double -> MoonDistanceUnits
forall a b. (a -> b) -> a -> b
$ (Double
1 Double -> Double -> Double
forall a. Num a => a -> a -> a
- Double
eDouble -> Double -> Double
forall a. Num a => a -> a -> a
*Double
e)Double -> Double -> Double
forall a. Fractional a => a -> a -> a
/(Double
1Double -> Double -> Double
forall a. Num a => a -> a -> a
+Double
eDouble -> Double -> Double
forall a. Num a => a -> a -> a
*(Double -> Double
forall a. Floating a => a -> a
cos(Double
mm'Double -> Double -> Double
forall a. Num a => a -> a -> a
+Double
ec)))


-- | Calculate the Moon's angular size at the given distance.

moonAngularSize :: MoonDistanceUnits -> DecimalDegrees
moonAngularSize :: MoonDistanceUnits -> DecimalDegrees
moonAngularSize (MDU Double
p) = (MoonDetails -> DecimalDegrees
mdBigTheta MoonDetails
j2010MoonDetails) DecimalDegrees -> DecimalDegrees -> DecimalDegrees
forall a. Fractional a => a -> a -> a
/ (Double -> DecimalDegrees
DD Double
p)


-- | Calculates the Moon's horizontal parallax at the given distance.

moonHorizontalParallax :: MoonDistanceUnits -> DecimalDegrees
moonHorizontalParallax :: MoonDistanceUnits -> DecimalDegrees
moonHorizontalParallax (MDU Double
p) = (MoonDetails -> DecimalDegrees
mdPi MoonDetails
j2010MoonDetails) DecimalDegrees -> DecimalDegrees -> DecimalDegrees
forall a. Fractional a => a -> a -> a
/ (Double -> DecimalDegrees
DD Double
p)


-- | Calculates the Moon's phase (the area of the visible segment expressed as a fraction of the whole disk)

-- at the given universal time.

moonPhase :: MoonDetails -> JulianDate -> Double
moonPhase :: MoonDetails -> JulianDate -> Double
moonPhase MoonDetails
md JulianDate
ut =
  let sd :: SunDetails
sd = JulianDate -> SunDetails
sunDetails JulianDate
ut
      lambdaS :: DecimalDegrees
lambdaS = SunDetails -> DecimalDegrees
sunEclipticLongitude2 SunDetails
sd
      ms :: DecimalDegrees
ms = SunDetails -> DecimalDegrees
sunMeanAnomaly2 SunDetails
sd
      mmq :: MoonQuantities
mmq = MoonDetails -> JulianDate -> MoonQuantities
meanMoonQuantities MoonDetails
md JulianDate
ut
      MQ DecimalDegrees
ml DecimalDegrees
_ DecimalDegrees
_ = DecimalDegrees
-> DecimalDegrees -> MoonQuantities -> MoonQuantities
correctedMoonQuantities DecimalDegrees
lambdaS DecimalDegrees
ms MoonQuantities
mmq
      d :: Double
d = DecimalDegrees -> Double
toRadians (DecimalDegrees -> Double) -> DecimalDegrees -> Double
forall a b. (a -> b) -> a -> b
$ DecimalDegrees
ml DecimalDegrees -> DecimalDegrees -> DecimalDegrees
forall a. Num a => a -> a -> a
- DecimalDegrees
lambdaS
      f :: Double
f = Double
0.5 Double -> Double -> Double
forall a. Num a => a -> a -> a
* (Double
1 Double -> Double -> Double
forall a. Num a => a -> a -> a
- Double -> Double
forall a. Floating a => a -> a
cos Double
d)
  in Double
f



-- | Calculate the Moon's position-angle of the bright limb.

-- It takes the Moon's coordinates and the Sun's coordinates.

-- Position-angle is the angle of the midpoint of the illuminated limb

-- measured eastwards from the north point of the disk.

moonBrightLimbPositionAngle :: EquatorialCoordinates1 -> EquatorialCoordinates1 -> DecimalDegrees
moonBrightLimbPositionAngle :: EquatorialCoordinates1 -> EquatorialCoordinates1 -> DecimalDegrees
moonBrightLimbPositionAngle = EquatorialCoordinates1 -> EquatorialCoordinates1 -> DecimalDegrees
planetBrightLimbPositionAngle


-- | The Moon's quantities

-- Used to store intermidiate results

data MoonQuantities = MQ {
  MoonQuantities -> DecimalDegrees
mqLongitude :: DecimalDegrees        -- ^ the Moon's longitude

  , MoonQuantities -> DecimalDegrees
mqAnomaly :: DecimalDegrees        -- ^ the Moon's anomaly

  , MoonQuantities -> DecimalDegrees
mqAscendingNode :: DecimalDegrees  -- ^ the Moon's ascending node's longitude

  }


-- | Calculates the Moon's mean quantities on the given date.

-- It takes the Moon's orbita details and julian date

meanMoonQuantities :: MoonDetails -> JulianDate -> MoonQuantities
meanMoonQuantities :: MoonDetails -> JulianDate -> MoonQuantities
meanMoonQuantities MoonDetails
md JulianDate
ut =
  let d :: DecimalDegrees
d = Double -> DecimalDegrees
DD (Double -> DecimalDegrees) -> Double -> DecimalDegrees
forall a b. (a -> b) -> a -> b
$ JulianDate -> JulianDate -> Double
numberOfDays (MoonDetails -> JulianDate
mdEpoch MoonDetails
md) JulianDate
ut
      lm :: DecimalDegrees
lm = DecimalDegrees -> DecimalDegrees
reduceDegrees (DecimalDegrees -> DecimalDegrees)
-> DecimalDegrees -> DecimalDegrees
forall a b. (a -> b) -> a -> b
$ (MoonDetails -> DecimalDegrees
mdL MoonDetails
md) DecimalDegrees -> DecimalDegrees -> DecimalDegrees
forall a. Num a => a -> a -> a
+ DecimalDegrees
13.1763966DecimalDegrees -> DecimalDegrees -> DecimalDegrees
forall a. Num a => a -> a -> a
*DecimalDegrees
d  -- Moon's mean longitude

      mm :: DecimalDegrees
mm = DecimalDegrees -> DecimalDegrees
reduceDegrees (DecimalDegrees -> DecimalDegrees)
-> DecimalDegrees -> DecimalDegrees
forall a b. (a -> b) -> a -> b
$ DecimalDegrees
lm DecimalDegrees -> DecimalDegrees -> DecimalDegrees
forall a. Num a => a -> a -> a
- DecimalDegrees
0.1114041DecimalDegrees -> DecimalDegrees -> DecimalDegrees
forall a. Num a => a -> a -> a
*DecimalDegrees
d DecimalDegrees -> DecimalDegrees -> DecimalDegrees
forall a. Num a => a -> a -> a
- (MoonDetails -> DecimalDegrees
mdP MoonDetails
md)  -- Moon's mean anomaly

      nm :: DecimalDegrees
nm = DecimalDegrees -> DecimalDegrees
reduceDegrees (DecimalDegrees -> DecimalDegrees)
-> DecimalDegrees -> DecimalDegrees
forall a b. (a -> b) -> a -> b
$ (MoonDetails -> DecimalDegrees
mdN MoonDetails
md) DecimalDegrees -> DecimalDegrees -> DecimalDegrees
forall a. Num a => a -> a -> a
- DecimalDegrees
0.0529539DecimalDegrees -> DecimalDegrees -> DecimalDegrees
forall a. Num a => a -> a -> a
*DecimalDegrees
d  -- ascending node's mean longitude

  in DecimalDegrees
-> DecimalDegrees -> DecimalDegrees -> MoonQuantities
MQ DecimalDegrees
lm DecimalDegrees
mm DecimalDegrees
nm


-- | Calculates correction for the equation of the centre

-- It takes the Moon's corrected anomaly in radians

centreEquation :: Double -> DecimalDegrees
centreEquation :: Double -> DecimalDegrees
centreEquation Double
mm = Double -> DecimalDegrees
DD (Double -> DecimalDegrees) -> Double -> DecimalDegrees
forall a b. (a -> b) -> a -> b
$ Double
6.2886 Double -> Double -> Double
forall a. Num a => a -> a -> a
* (Double -> Double
forall a. Floating a => a -> a
sin Double
mm)


-- | Calculates the Moon's corrected longitude, anomaly and asceding node's longitude

-- It takes the Sun's longitude, the Sun's mean anomaly and the Moon's mean quantities

correctedMoonQuantities :: DecimalDegrees -> DecimalDegrees -> MoonQuantities -> MoonQuantities
correctedMoonQuantities :: DecimalDegrees
-> DecimalDegrees -> MoonQuantities -> MoonQuantities
correctedMoonQuantities DecimalDegrees
lambdaS DecimalDegrees
ms (MQ DecimalDegrees
lm DecimalDegrees
mm DecimalDegrees
nm) =
  let ms' :: Double
ms' = DecimalDegrees -> Double
toRadians DecimalDegrees
ms
      c :: DecimalDegrees
c = DecimalDegrees
lm DecimalDegrees -> DecimalDegrees -> DecimalDegrees
forall a. Num a => a -> a -> a
- DecimalDegrees
lambdaS
      ev :: DecimalDegrees
ev = Double -> DecimalDegrees
DD (Double -> DecimalDegrees) -> Double -> DecimalDegrees
forall a b. (a -> b) -> a -> b
$ Double
1.2739 Double -> Double -> Double
forall a. Num a => a -> a -> a
* (Double -> Double
forall a. Floating a => a -> a
sin (Double -> Double) -> Double -> Double
forall a b. (a -> b) -> a -> b
$ DecimalDegrees -> Double
toRadians (DecimalDegrees -> Double) -> DecimalDegrees -> Double
forall a b. (a -> b) -> a -> b
$ DecimalDegrees
2DecimalDegrees -> DecimalDegrees -> DecimalDegrees
forall a. Num a => a -> a -> a
*DecimalDegrees
c DecimalDegrees -> DecimalDegrees -> DecimalDegrees
forall a. Num a => a -> a -> a
- DecimalDegrees
mm)  -- correction for evection

      ae :: DecimalDegrees
ae = Double -> DecimalDegrees
DD (Double -> DecimalDegrees) -> Double -> DecimalDegrees
forall a b. (a -> b) -> a -> b
$ Double
0.1858 Double -> Double -> Double
forall a. Num a => a -> a -> a
* (Double -> Double
forall a. Floating a => a -> a
sin Double
ms')  -- correction for annual equation

      a3 :: DecimalDegrees
a3 = Double -> DecimalDegrees
DD (Double -> DecimalDegrees) -> Double -> DecimalDegrees
forall a b. (a -> b) -> a -> b
$ Double
0.37 Double -> Double -> Double
forall a. Num a => a -> a -> a
* (Double -> Double
forall a. Floating a => a -> a
sin Double
ms')  -- third correction

      mm' :: DecimalDegrees
mm' = DecimalDegrees
mm DecimalDegrees -> DecimalDegrees -> DecimalDegrees
forall a. Num a => a -> a -> a
+ (DecimalDegrees
ev DecimalDegrees -> DecimalDegrees -> DecimalDegrees
forall a. Num a => a -> a -> a
- DecimalDegrees
ae DecimalDegrees -> DecimalDegrees -> DecimalDegrees
forall a. Num a => a -> a -> a
- DecimalDegrees
a3) -- Moon's corrected anomaly

      mm'' :: Double
mm'' = DecimalDegrees -> Double
toRadians DecimalDegrees
mm'
      ec :: DecimalDegrees
ec = Double -> DecimalDegrees
centreEquation Double
mm''  -- correction for the equation of the centre

      a4 :: DecimalDegrees
a4 = Double -> DecimalDegrees
DD (Double -> DecimalDegrees) -> Double -> DecimalDegrees
forall a b. (a -> b) -> a -> b
$ Double
0.214 Double -> Double -> Double
forall a. Num a => a -> a -> a
* (Double -> Double
forall a. Floating a => a -> a
sin (Double -> Double) -> Double -> Double
forall a b. (a -> b) -> a -> b
$ Double
2Double -> Double -> Double
forall a. Num a => a -> a -> a
*Double
mm'') -- fourth correction term

      lm' :: DecimalDegrees
lm' = DecimalDegrees
lm DecimalDegrees -> DecimalDegrees -> DecimalDegrees
forall a. Num a => a -> a -> a
+ (DecimalDegrees
ev DecimalDegrees -> DecimalDegrees -> DecimalDegrees
forall a. Num a => a -> a -> a
+ DecimalDegrees
ec DecimalDegrees -> DecimalDegrees -> DecimalDegrees
forall a. Num a => a -> a -> a
-DecimalDegrees
ae DecimalDegrees -> DecimalDegrees -> DecimalDegrees
forall a. Num a => a -> a -> a
+ DecimalDegrees
a4) -- Moon's corrected longitude

      v :: DecimalDegrees
v = Double -> DecimalDegrees
DD (Double -> DecimalDegrees) -> Double -> DecimalDegrees
forall a b. (a -> b) -> a -> b
$ Double
0.6583 Double -> Double -> Double
forall a. Num a => a -> a -> a
* (Double -> Double
forall a. Floating a => a -> a
sin (Double -> Double) -> Double -> Double
forall a b. (a -> b) -> a -> b
$ DecimalDegrees -> Double
toRadians (DecimalDegrees -> Double) -> DecimalDegrees -> Double
forall a b. (a -> b) -> a -> b
$ DecimalDegrees
2DecimalDegrees -> DecimalDegrees -> DecimalDegrees
forall a. Num a => a -> a -> a
*(DecimalDegrees
lm' DecimalDegrees -> DecimalDegrees -> DecimalDegrees
forall a. Num a => a -> a -> a
- DecimalDegrees
lambdaS))-- correction for variation

      lm'' :: DecimalDegrees
lm'' = DecimalDegrees
lm' DecimalDegrees -> DecimalDegrees -> DecimalDegrees
forall a. Num a => a -> a -> a
+ DecimalDegrees
v -- Moon's true orbital longitude

      nm' :: DecimalDegrees
nm' = DecimalDegrees
nm DecimalDegrees -> DecimalDegrees -> DecimalDegrees
forall a. Num a => a -> a -> a
- (Double -> DecimalDegrees
DD (Double -> DecimalDegrees) -> Double -> DecimalDegrees
forall a b. (a -> b) -> a -> b
$ Double
0.16 Double -> Double -> Double
forall a. Num a => a -> a -> a
* (Double -> Double
forall a. Floating a => a -> a
sin Double
ms')) -- ascending node's corrected longitude

  in DecimalDegrees
-> DecimalDegrees -> DecimalDegrees -> MoonQuantities
MQ DecimalDegrees
lm'' DecimalDegrees
mm' DecimalDegrees
nm'