jord-2.0.0.0: src/Data/Geo/Jord/Ellipsoid.hs
-- |
-- Module: Data.Geo.Jord.Ellipsoid
-- Copyright: (c) 2020 Cedric Liegeois
-- License: BSD3
-- Maintainer: Cedric Liegeois <ofmooseandmen@yahoo.fr>
-- Stability: experimental
-- Portability: portable
--
-- Types and functions for working with ellipsoids (including spheres).
--
-- see "Data.Geo.Jord.Ellipsoids" for supported ellipsoids.
module Data.Geo.Jord.Ellipsoid
( Ellipsoid
, equatorialRadius
, polarRadius
, eccentricity
, flattening
, ellispoid
, sphere
, toSphere
, isSphere
, meanRadius
) where
import Data.Geo.Jord.Length
-- | Parameters of an ellispoid describing the surface of a celestial body.
-- An ellispoid is a circle if its 'equatorialRadius' and 'polarRadius' are
-- equal (both its 'eccentricity' and 'flattening' are 0); it is used to represent
-- a celestial body as a sphere.
data Ellipsoid =
Ellipsoid
{ equatorialRadius :: !Length -- ^ equatorial radius or semi-major axis (a).
, polarRadius :: !Length -- ^ polar radius or semi-minor axis (b).
, eccentricity :: !Double -- ^ eccentricity
, flattening :: !Double -- ^ flattening
}
deriving (Eq, Show)
-- | @ellispoid eqr invf@: ellipsoid with equatorial radius @eqr@ and inverse flattening @invf@.
ellispoid :: Length -> Double -> Ellipsoid
ellispoid eqr invf = Ellipsoid eqr (metres b) e f
where
a = toMetres eqr
f = 1.0 / invf
b = a * (1.0 - f)
e = sqrt (1.0 - (b * b) / (a * a))
-- | @sphere r@: ellipsoid with equatorial & polar radius radius @r@.
-- The returned ellipsoid is a sphere.
sphere :: Length -> Ellipsoid
sphere r = Ellipsoid r r 0.0 0.0
-- | @toSphere e@: sphere from mean radius of ellipsoid @e@.
toSphere :: Ellipsoid -> Ellipsoid
toSphere = sphere . meanRadius
-- | @isSphere e@ returns True if ellipsoid @e@ is a sphere.
isSphere :: Ellipsoid -> Bool
isSphere e = eccentricity e == 0.0
-- | @meanRadius e@ computes the mean radius of ellipsoid @e@.
meanRadius :: Ellipsoid -> Length
meanRadius e = metres ((2.0 * a + b) / 3.0)
where
a = toMetres . equatorialRadius $ e
b = toMetres . polarRadius $ e