Copyright | (c) 2020 Cedric Liegeois |
---|---|
License | BSD3 |
Maintainer | Cedric Liegeois <ofmooseandmen@yahoo.fr> |
Stability | experimental |
Portability | portable |
Safe Haskell | Safe |
Language | Haskell2010 |
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
- data Track a = Track {
- trackPosition :: Position a
- trackBearing :: Angle
- trackSpeed :: Speed
- data Course
- data Cpa a
- cpaTime :: Cpa a -> Duration
- cpaDistance :: Cpa a -> Length
- cpaPosition1 :: Cpa a -> Position a
- cpaPosition2 :: Cpa a -> Position a
- data Intercept a
- interceptTime :: Intercept a -> Duration
- interceptDistance :: Intercept a -> Length
- interceptPosition :: Intercept a -> Position a
- interceptorBearing :: Intercept a -> Angle
- interceptorSpeed :: Intercept a -> Speed
- course :: Spherical a => Position a -> Angle -> Course
- positionAfter :: Spherical a => Position a -> Angle -> Speed -> Duration -> Position a
- trackPositionAfter :: Spherical a => Track a -> Duration -> Position a
- cpa :: Spherical a => Track a -> Track a -> Maybe (Cpa a)
- intercept :: Spherical a => Track a -> Position a -> Maybe (Intercept a)
- interceptBySpeed :: Spherical a => Track a -> Position a -> Speed -> Maybe (Intercept a)
- interceptByTime :: Spherical a => Track a -> Position a -> Duration -> Maybe (Intercept a)
- module Data.Geo.Jord.Duration
- module Data.Geo.Jord.Speed
The Track
type.
Track
represents the state of a vehicle by its current position, bearing and speed.
Track | |
|
The Course
type.
Course
represents the cardinal direction in which the vehicle is to be steered.
The Cpa
type.
Time to, and distance at, closest point of approach (CPA) as well as position of both tracks at 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.
Time, distance and position of intercept as well as speed and initial bearing of interceptor.
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
>>>
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 (
is a equivalent to Track
p b s) dpositionAfter' p (
.course
p b) s d
Examples
>>>
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
>>>
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
>>>
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
>>>
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
module Data.Geo.Jord.Duration
module Data.Geo.Jord.Speed