jord-1.0.0.0: Geographical Position Calculations

Copyright(c) 2020 Cedric Liegeois
LicenseBSD3
MaintainerCedric Liegeois <ofmooseandmen@yahoo.fr>
Stabilityexperimental
Portabilityportable
Safe HaskellSafe
LanguageHaskell2010

Data.Geo.Jord.Kinematics

Contents

Description

Types and functions for working with kinematics calculations assuming a spherical celestial body.

In order to use this module you should start with the following imports:

    import Data.Geo.Jord.Kinematics
    import Data.Geo.Jord.Position

All functions are implemented using the vector-based approached described in Gade, K. (2010). A Non-singular Horizontal Position Representation and in Shudde, Rex H. (1986). Some tactical algorithms for spherical geometry

Synopsis

The Track type.

data Track a Source #

Track represents the state of a vehicle by its current position, bearing and speed.

Constructors

Track 

Fields

Instances
Model a => Eq (Track a) Source # 
Instance details

Defined in Data.Geo.Jord.Kinematics

Methods

(==) :: Track a -> Track a -> Bool #

(/=) :: Track a -> Track a -> Bool #

Model a => Show (Track a) Source # 
Instance details

Defined in Data.Geo.Jord.Kinematics

Methods

showsPrec :: Int -> Track a -> ShowS #

show :: Track a -> String #

showList :: [Track a] -> ShowS #

The Course type.

data Course Source #

Course represents the cardinal direction in which the vehicle is to be steered.

Instances
Eq Course Source # 
Instance details

Defined in Data.Geo.Jord.Kinematics

Methods

(==) :: Course -> Course -> Bool #

(/=) :: Course -> Course -> Bool #

Show Course Source # 
Instance details

Defined in Data.Geo.Jord.Kinematics

The Cpa type.

data Cpa a Source #

Time to, and distance at, closest point of approach (CPA) as well as position of both tracks at CPA.

Instances
Model a => Eq (Cpa a) Source # 
Instance details

Defined in Data.Geo.Jord.Kinematics

Methods

(==) :: Cpa a -> Cpa a -> Bool #

(/=) :: Cpa a -> Cpa a -> Bool #

Model a => Show (Cpa a) Source # 
Instance details

Defined in Data.Geo.Jord.Kinematics

Methods

showsPrec :: Int -> Cpa a -> ShowS #

show :: Cpa a -> String #

showList :: [Cpa a] -> ShowS #

cpaTime :: Cpa a -> Duration Source #

time to CPA.

cpaDistance :: Cpa a -> Length Source #

distance at CPA.

cpaPosition1 :: Cpa a -> Position a Source #

position of track 1 at CPA.

cpaPosition2 :: Cpa a -> Position a Source #

position of track 2 at CPA.

The Intercept type.

data Intercept a Source #

Time, distance and position of intercept as well as speed and initial bearing of interceptor.

Instances
Model a => Eq (Intercept a) Source # 
Instance details

Defined in Data.Geo.Jord.Kinematics

Methods

(==) :: Intercept a -> Intercept a -> Bool #

(/=) :: Intercept a -> Intercept a -> Bool #

Model a => Show (Intercept a) Source # 
Instance details

Defined in Data.Geo.Jord.Kinematics

interceptTime :: Intercept a -> Duration Source #

time to intercept.

interceptDistance :: Intercept a -> Length Source #

distance at intercept.

interceptPosition :: Intercept a -> Position a Source #

position of intercept.

interceptorBearing :: Intercept a -> Angle Source #

initial bearing of interceptor.

interceptorSpeed :: Intercept a -> Speed Source #

speed of interceptor.

Calculations

course :: Spherical a => Position a -> Angle -> Course Source #

course p b computes the course of a vehicle currently at position p and following bearing b.

positionAfter :: Spherical a => Position a -> Angle -> Speed -> Duration -> Position a Source #

positionAfter p b s d computes the position of a vehicle currently at position p following bearing b and travelling at speed s after duration d has elapsed assuming the vehicle maintains a constant altitude.

positionAfter p b s d is a shortcut for positionAfter' (course p b) s d.

Examples

Expand
>>> import Data.Geo.Jord.Kinematics
>>> import Data.Geo.Jord.Position
>>> 
>>> let p = s84Pos 53.321 (-1.729) (metres 15000)
>>> let b = decimalDegrees 96.0217
>>> let s = kilometresPerHour 124.8
>>> positionAfter p b s (hours 1)
53°11'19.368"N,0°8'2.457"E 15.0km (S84)
@

trackPositionAfter :: Spherical a => Track a -> Duration -> Position a Source #

trackPositionAfter t d computes the position of a track t after duration d has elapsed assuming the vehicle maintains a constant altitude.

trackPositionAfter (Track p b s) d is a equivalent to positionAfter' p (course p b) s d.

Examples

Expand
>>> import Data.Geo.Jord.Kinematics
>>> import Data.Geo.Jord.Position
>>> 
>>> let p = s84Pos 53.321 (-1.729) (metres 15000)
>>> let b = decimalDegrees 96.0217
>>> let s = kilometresPerHour 124.8
>>> trackPositionAfter (Track p b s) (hours 1)
53°11'19.368"N,0°8'2.457"E 15.0km (S84)

cpa :: Spherical a => Track a -> Track a -> Maybe (Cpa a) Source #

cpa t1 t2 computes the closest point of approach between tracks t1 and t2 disregarding their respective altitude. If a closest point of approach is found, height of cpaPosition1 - respectively cpaPosition2, will be the altitude of the first - respectively second, track.

Examples

Expand
>>> import Data.Geo.Jord.Kinematics
>>> import Data.Geo.Jord.Position
>>> 
>>> let p1 = s84Pos 20 (-60) zero
>>> let b1 = decimalDegrees 10
>>> let s1 = knots 15
>>> let p2 = s84Pos 34 (-50) zero
>>> let b2 = decimalDegrees 220
>>> let s2 = knots 300
>>> let t1 = Track p1 b1 s1
>>> let t2 = Track p2 b2 s2
>>> let c = cpa t1 t2
>>> fmap cpaTime c
Just 3H9M56.155S
>>> fmap cpaDistance c
Just 124.2317453km

intercept :: Spherical a => Track a -> Position a -> Maybe (Intercept a) Source #

intercept t p computes the minimum speed of interceptor at position p needed for an intercept with target track t to take place. Intercept time, position, distance and interceptor bearing are derived from this minimum speed. Returns Nothing if intercept cannot be achieved e.g.:

  • interceptor and target are at the same position
  • interceptor is "behind" the target

If found, interceptPosition is at the altitude of the track.

Examples

Expand
>>> import Data.Geo.Jord.Kinematics
>>> import Data.Geo.Jord.Position
>>> 
>>> let t = Track (s84Pos 34 (-50) zero) (decimalDegrees 220) (knots 600)
>>> let ip = s84Pos 20 (-60) zero
>>> let i = intercept t ip
>>> fmap (toKnots . interceptorSpeed) i
Just 52.633367756059
>>> fmap (toSeconds . interceptTime) i
Just 5993.831

interceptBySpeed :: Spherical a => Track a -> Position a -> Speed -> Maybe (Intercept a) Source #

interceptBySpeed t p s computes the time needed by interceptor at position p and travelling at speed s to intercept target track t. Returns Nothing if intercept cannot be achieved e.g.:

  • interceptor and target are at the same position
  • interceptor speed is below minimum speed returned by intercept

If found, interceptPosition is at the altitude of the track.

interceptByTime :: Spherical a => Track a -> Position a -> Duration -> Maybe (Intercept a) Source #

interceptByTime t p d computes the speed of interceptor at position p needed for an intercept with target track t to take place after duration d. Returns Nothing if given duration is <= 0 or interceptor and target are at the same position.

If found, interceptPosition is at the altitude of the track.

Note: contrary to intercept and interceptBySpeed this function handles cases where the interceptor has to catch up the target.

Examples

Expand
>>> import Data.Geo.Jord.Kinematics
>>> import Data.Geo.Jord.Position
>>> 
>>> let t = Track (s84Pos 34 (-50) zero) (decimalDegrees 220) (knots 600)
>>> let ip = s84Pos 20 (-60) zero
>>> let d = seconds 2700
>>> let i = interceptByTime t ip d
>>> fmap (toKnots . interceptorSpeed) i
Just 730.959238
>>> 
>>> fmap interceptorBearing i
Just 26°7'11.649"
>>> 
>>> fmap interceptPosition i
Just 28°8'12.047"N,55°27'21.411"W 0.0m (S84)
>>> 
>>> fmap interceptDistance i
Just 1015.3023506km
>>> 
>>> fmap (toSeconds . interceptTime) i
Just 2700

re-exported for convenience