{-# language QuasiQuotes #-}
module Physics.Orbit.StateVectors
  ( 
    StateVectors(..)
  , Position
  , Velocity
    
  , stateVectorsAtTrueAnomaly
  , positionAtTrueAnomaly
  , positionInPlaneAtTrueAnomaly
  , velocityAtTrueAnomaly
  , velocityInPlaneAtTrueAnomaly
    
  , elementsFromStateVectors
  , eccentricityVector
  , trueAnomalyAtPosition
    
  , orbitalPlaneQuaternion
  , rotateToPlane
  , rotateFromPlane
    
  , flightPathAngleAtTrueAnomaly
  , specificAngularMomentumVector
  ) where
import           Control.Lens.Operators         ( (^.) )
import           Data.Coerce
import           Data.Constants.Mechanics.Extra
import           Data.Metrology
import           Data.Metrology.Extra
import           Data.Metrology.Unsafe          ( Qu(..) )
import           Data.Units.SI.Parser
import           Linear.Conjugate
import           Linear.Quaternion
import           Linear.V3
import           Physics.Orbit
type Position a = V3 (Distance a)
type Velocity a = V3 (Speed a)
data StateVectors a = StateVectors
  { forall a. StateVectors a -> Position a
position :: Position a
  , forall a. StateVectors a -> Velocity a
velocity :: Velocity a
  }
  deriving (Int -> StateVectors a -> ShowS
forall a. Show a => Int -> StateVectors a -> ShowS
forall a. Show a => [StateVectors a] -> ShowS
forall a. Show a => StateVectors a -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [StateVectors a] -> ShowS
$cshowList :: forall a. Show a => [StateVectors a] -> ShowS
show :: StateVectors a -> String
$cshow :: forall a. Show a => StateVectors a -> String
showsPrec :: Int -> StateVectors a -> ShowS
$cshowsPrec :: forall a. Show a => Int -> StateVectors a -> ShowS
Show, StateVectors a -> StateVectors a -> Bool
forall a. Eq a => StateVectors a -> StateVectors a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: StateVectors a -> StateVectors a -> Bool
$c/= :: forall a. Eq a => StateVectors a -> StateVectors a -> Bool
== :: StateVectors a -> StateVectors a -> Bool
$c== :: forall a. Eq a => StateVectors a -> StateVectors a -> Bool
Eq)
positionAtTrueAnomaly
  :: (Conjugate a, RealFloat a) => Orbit a -> Angle a -> Position a
positionAtTrueAnomaly :: forall a.
(Conjugate a, RealFloat a) =>
Orbit a -> Angle a -> Position a
positionAtTrueAnomaly Orbit a
o = forall a (u :: [Factor (*)]) (l :: LCSU (*)).
(Conjugate a, RealFloat a) =>
Orbit a -> V3 (Qu u l a) -> V3 (Qu u l a)
rotateFromPlane Orbit a
o forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. (Ord a, Floating a) => Orbit a -> Angle a -> Position a
positionInPlaneAtTrueAnomaly Orbit a
o
positionInPlaneAtTrueAnomaly
  :: (Ord a, Floating a) => Orbit a -> Angle a -> Position a
positionInPlaneAtTrueAnomaly :: forall a. (Ord a, Floating a) => Orbit a -> Angle a -> Position a
positionInPlaneAtTrueAnomaly Orbit a
o Angle a
ν = V3
  (Qu
     (Normalize ('[] @@+ Reorder '[ 'F Length One] '[])) 'DefaultLCSU a)
r
 where
  radius :: Distance a
radius = forall a. (Ord a, Floating a) => Orbit a -> Angle a -> Distance a
radiusAtTrueAnomaly Orbit a
o Angle a
ν
  r :: V3
  (Qu
     (Normalize ('[] @@+ Reorder '[ 'F Length One] '[])) 'DefaultLCSU a)
r      = forall a. a -> a -> a -> V3 a
V3 (forall a. Floating a => Angle a -> Unitless a
qCos Angle a
ν forall n (a :: [Factor (*)]) (l :: LCSU (*)) (b :: [Factor (*)]).
Num n =>
Qu a l n -> Qu b l n -> Qu (Normalize (a @+ b)) l n
|*| Distance a
radius) (forall a. Floating a => Angle a -> Unitless a
qSin Angle a
ν forall n (a :: [Factor (*)]) (l :: LCSU (*)) (b :: [Factor (*)]).
Num n =>
Qu a l n -> Qu b l n -> Qu (Normalize (a @+ b)) l n
|*| Distance a
radius) forall n (dimspec :: [Factor (*)]) (l :: LCSU (*)).
Num n =>
Qu dimspec l n
zero
velocityAtTrueAnomaly
  :: (Conjugate a, RealFloat a) => Orbit a -> Angle a -> Velocity a
velocityAtTrueAnomaly :: forall a.
(Conjugate a, RealFloat a) =>
Orbit a -> Angle a -> Velocity a
velocityAtTrueAnomaly Orbit a
o = forall a (u :: [Factor (*)]) (l :: LCSU (*)).
(Conjugate a, RealFloat a) =>
Orbit a -> V3 (Qu u l a) -> V3 (Qu u l a)
rotateFromPlane Orbit a
o forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. (Ord a, Floating a) => Orbit a -> Angle a -> Velocity a
velocityInPlaneAtTrueAnomaly Orbit a
o
velocityInPlaneAtTrueAnomaly
  :: (Ord a, Floating a) => Orbit a -> Angle a -> Velocity a
velocityInPlaneAtTrueAnomaly :: forall a. (Ord a, Floating a) => Orbit a -> Angle a -> Velocity a
velocityInPlaneAtTrueAnomaly Orbit a
o Angle a
ν = V3
  (Qu
     (Normalize
        ('[ 'F Length One, 'F Time ('P 'Zero)]
         @@+ Reorder '[] '[ 'F Length One, 'F Time ('P 'Zero)]))
     'DefaultLCSU
     a)
v
 where
  μ :: Quantity
  ((Meter :^ Succ (Succ (Succ 'Zero)))
   :* (Second :^ Pred (Pred 'Zero)))
  a
μ    = forall a.
Orbit a
-> Quantity
     ((Meter :^ Succ (Succ (Succ 'Zero)))
      :* (Second :^ Pred (Pred 'Zero)))
     a
primaryGravitationalParameter Orbit a
o
  e :: Unitless a
e    = forall a. Orbit a -> Unitless a
eccentricity Orbit a
o
  r :: Distance a
r    = forall a. (Ord a, Floating a) => Orbit a -> Angle a -> Distance a
radiusAtTrueAnomaly Orbit a
o Angle a
ν
  h :: Quantity ((Meter :^ Succ (Succ 'Zero)) :* (Second :^ Pred 'Zero)) a
h    = forall a.
Floating a =>
Orbit a
-> Quantity
     ((Meter :^ Succ (Succ 'Zero)) :* (Second :^ Pred 'Zero)) a
specificAngularMomentum Orbit a
o
  cosν :: Unitless a
cosν = forall a. Floating a => Angle a -> Unitless a
qCos Angle a
ν
  sinν :: Unitless a
sinν = forall a. Floating a => Angle a -> Unitless a
qSin Angle a
ν
  vr :: Qu
  (Normalize
     (Normalize
        (Normalize
           ('[ 'F Length ('S ('S One)), 'F Time ('P ('P 'Zero))]
            @@+ Reorder
                  '[] '[ 'F Length ('S ('S One)), 'F Time ('P ('P 'Zero))])
         @@+ Reorder
               '[]
               (Normalize
                  ('[ 'F Length ('S ('S One)), 'F Time ('P ('P 'Zero))]
                   @@+ Reorder
                         '[] '[ 'F Length ('S ('S One)), 'F Time ('P ('P 'Zero))])))
      @- '[ 'F Length ('S One), 'F Time ('P 'Zero)]))
  'DefaultLCSU
  a
vr   = Quantity
  ((Meter :^ Succ (Succ (Succ 'Zero)))
   :* (Second :^ Pred (Pred 'Zero)))
  a
μ forall n (a :: [Factor (*)]) (l :: LCSU (*)) (b :: [Factor (*)]).
Num n =>
Qu a l n -> Qu b l n -> Qu (Normalize (a @+ b)) l n
|*| Unitless a
e forall n (a :: [Factor (*)]) (l :: LCSU (*)) (b :: [Factor (*)]).
Num n =>
Qu a l n -> Qu b l n -> Qu (Normalize (a @+ b)) l n
|*| Unitless a
sinν forall n (a :: [Factor (*)]) (l :: LCSU (*)) (b :: [Factor (*)]).
Fractional n =>
Qu a l n -> Qu b l n -> Qu (Normalize (a @- b)) l n
|/| Quantity ((Meter :^ Succ (Succ 'Zero)) :* (Second :^ Pred 'Zero)) a
h
  vtA :: Qu
  (Normalize
     ('[ 'F Length ('S One), 'F Time ('P 'Zero)] @- '[ 'F Length One]))
  'DefaultLCSU
  a
vtA  = Quantity ((Meter :^ Succ (Succ 'Zero)) :* (Second :^ Pred 'Zero)) a
h forall n (a :: [Factor (*)]) (l :: LCSU (*)) (b :: [Factor (*)]).
Fractional n =>
Qu a l n -> Qu b l n -> Qu (Normalize (a @- b)) l n
|/| Distance a
r
  v :: V3
  (Qu
     (Normalize
        ('[ 'F Length One, 'F Time ('P 'Zero)]
         @@+ Reorder '[] '[ 'F Length One, 'F Time ('P 'Zero)]))
     'DefaultLCSU
     a)
v    = forall a. a -> a -> a -> V3 a
V3 (Qu
  (Normalize
     (Normalize
        (Normalize
           ('[ 'F Length ('S ('S One)), 'F Time ('P ('P 'Zero))]
            @@+ Reorder
                  '[] '[ 'F Length ('S ('S One)), 'F Time ('P ('P 'Zero))])
         @@+ Reorder
               '[]
               (Normalize
                  ('[ 'F Length ('S ('S One)), 'F Time ('P ('P 'Zero))]
                   @@+ Reorder
                         '[] '[ 'F Length ('S ('S One)), 'F Time ('P ('P 'Zero))])))
      @- '[ 'F Length ('S One), 'F Time ('P 'Zero)]))
  'DefaultLCSU
  a
vr forall n (a :: [Factor (*)]) (l :: LCSU (*)) (b :: [Factor (*)]).
Num n =>
Qu a l n -> Qu b l n -> Qu (Normalize (a @+ b)) l n
|*| Unitless a
cosν forall (d1 :: [Factor (*)]) (d2 :: [Factor (*)]) n (l :: LCSU (*)).
(d1 @~ d2, Num n) =>
Qu d1 l n -> Qu d2 l n -> Qu d1 l n
|-| Qu
  (Normalize
     ('[ 'F Length ('S One), 'F Time ('P 'Zero)] @- '[ 'F Length One]))
  'DefaultLCSU
  a
vtA forall n (a :: [Factor (*)]) (l :: LCSU (*)) (b :: [Factor (*)]).
Num n =>
Qu a l n -> Qu b l n -> Qu (Normalize (a @+ b)) l n
|*| Unitless a
sinν) (Qu
  (Normalize
     (Normalize
        (Normalize
           ('[ 'F Length ('S ('S One)), 'F Time ('P ('P 'Zero))]
            @@+ Reorder
                  '[] '[ 'F Length ('S ('S One)), 'F Time ('P ('P 'Zero))])
         @@+ Reorder
               '[]
               (Normalize
                  ('[ 'F Length ('S ('S One)), 'F Time ('P ('P 'Zero))]
                   @@+ Reorder
                         '[] '[ 'F Length ('S ('S One)), 'F Time ('P ('P 'Zero))])))
      @- '[ 'F Length ('S One), 'F Time ('P 'Zero)]))
  'DefaultLCSU
  a
vr forall n (a :: [Factor (*)]) (l :: LCSU (*)) (b :: [Factor (*)]).
Num n =>
Qu a l n -> Qu b l n -> Qu (Normalize (a @+ b)) l n
|*| Unitless a
sinν forall (d1 :: [Factor (*)]) (d2 :: [Factor (*)]) n (l :: LCSU (*)).
(d1 @~ d2, Num n) =>
Qu d1 l n -> Qu d2 l n -> Qu d1 l n
|+| Qu
  (Normalize
     ('[ 'F Length ('S One), 'F Time ('P 'Zero)] @- '[ 'F Length One]))
  'DefaultLCSU
  a
vtA forall n (a :: [Factor (*)]) (l :: LCSU (*)) (b :: [Factor (*)]).
Num n =>
Qu a l n -> Qu b l n -> Qu (Normalize (a @+ b)) l n
|*| Unitless a
cosν) forall n (dimspec :: [Factor (*)]) (l :: LCSU (*)).
Num n =>
Qu dimspec l n
zero
stateVectorsAtTrueAnomaly
  :: (Conjugate a, RealFloat a) => Orbit a -> Angle a -> StateVectors a
stateVectorsAtTrueAnomaly :: forall a.
(Conjugate a, RealFloat a) =>
Orbit a -> Angle a -> StateVectors a
stateVectorsAtTrueAnomaly Orbit a
o Angle a
ν = forall a. Position a -> Velocity a -> StateVectors a
StateVectors Position a
r Velocity a
v
 where
  r :: Position a
r = forall a.
(Conjugate a, RealFloat a) =>
Orbit a -> Angle a -> Position a
positionAtTrueAnomaly Orbit a
o Angle a
ν
  v :: Velocity a
v = forall a.
(Conjugate a, RealFloat a) =>
Orbit a -> Angle a -> Velocity a
velocityAtTrueAnomaly Orbit a
o Angle a
ν
elementsFromStateVectors
  :: (Ord a, Floating a, Conjugate a, RealFloat a, Show a)
  => Quantity [si| m^3 s^-2 |] a
  -> StateVectors a
  -> (Orbit a, Angle a)
elementsFromStateVectors :: forall a.
(Ord a, Floating a, Conjugate a, RealFloat a, Show a) =>
Quantity
  ((Meter :^ Succ (Succ (Succ 'Zero)))
   :* (Second :^ Pred (Pred 'Zero)))
  a
-> StateVectors a -> (Orbit a, Angle a)
elementsFromStateVectors Quantity
  ((Meter :^ Succ (Succ (Succ 'Zero)))
   :* (Second :^ Pred (Pred 'Zero)))
  a
μ sv :: StateVectors a
sv@(StateVectors Position a
r Velocity a
v) = (Orbit a
o, Angle a
ν)
 where
  o :: Orbit a
o     = forall a.
Unitless a
-> Distance a
-> InclinationSpecifier a
-> PeriapsisSpecifier a
-> Quantity
     ((Meter :^ Succ (Succ (Succ 'Zero)))
      :* (Second :^ Pred (Pred 'Zero)))
     a
-> Orbit a
Orbit Qu '[] 'DefaultLCSU a
e Qu
  (Normalize
     (Normalize
        ('[ 'F Length ('S One), 'F Time ('P 'Zero)]
         @@+ '[ 'F Length ('S One), 'F Time ('P 'Zero)])
      @- Normalize
           ('[]
            @@+ Reorder
                  '[ 'F Length ('S ('S One)), 'F Time ('P ('P 'Zero))] '[])))
  'DefaultLCSU
  a
q InclinationSpecifier a
inclinationSpecifier' PeriapsisSpecifier a
periapsisSpecifier' Quantity
  ((Meter :^ Succ (Succ (Succ 'Zero)))
   :* (Second :^ Pred (Pred 'Zero)))
  a
μ
  h :: V3 (Quantity ((Meter :^ Succ (Succ 'Zero)) :/ Second) a)
h     = forall a.
Num a =>
StateVectors a
-> V3 (Quantity ((Meter :^ Succ (Succ 'Zero)) :/ Second) a)
specificAngularMomentumVector StateVectors a
sv
  n :: V3 (Qu '[ 'F Length ('S One), 'F Time ('P 'Zero)] 'DefaultLCSU a)
n     = forall a. a -> a -> a -> V3 a
V3 (forall n (d :: [Factor (*)]) (l :: LCSU (*)).
Num n =>
Qu d l n -> Qu d l n
qNegate (V3 (Quantity ((Meter :^ Succ (Succ 'Zero)) :/ Second) a)
h forall s a. s -> Getting a s a -> a
^. forall (t :: * -> *) a. R2 t => Lens' (t a) a
_y)) (V3 (Quantity ((Meter :^ Succ (Succ 'Zero)) :/ Second) a)
h forall s a. s -> Getting a s a -> a
^. forall (t :: * -> *) a. R1 t => Lens' (t a) a
_x) forall n (dimspec :: [Factor (*)]) (l :: LCSU (*)).
Num n =>
Qu dimspec l n
zero
  e' :: V3 (Unitless a)
e'    = forall a.
Floating a =>
Quantity
  ((Meter :^ Succ (Succ (Succ 'Zero)))
   :* (Second :^ Pred (Pred 'Zero)))
  a
-> StateVectors a -> V3 (Unitless a)
eccentricityVector Quantity
  ((Meter :^ Succ (Succ (Succ 'Zero)))
   :* (Second :^ Pred (Pred 'Zero)))
  a
μ StateVectors a
sv
  e :: Qu '[] 'DefaultLCSU a
e     = forall (u :: [Factor (*)]) (l :: LCSU (*)) a.
Floating a =>
V3 (Qu u l a) -> Qu u l a
qNorm V3 (Unitless a)
e'
  eNorm :: V3 (Qu '[] 'DefaultLCSU a)
eNorm = (forall a. Fractional a => a -> a
recip Qu '[] 'DefaultLCSU a
e forall a. Num a => a -> a -> a
*) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> V3 (Unitless a)
e'
  aInv :: Qu (Normalize ('[] @- '[ 'F Length One])) 'DefaultLCSU a
aInv  = (Qu '[] 'DefaultLCSU a
2 forall n (a :: [Factor (*)]) (l :: LCSU (*)) (b :: [Factor (*)]).
Fractional n =>
Qu a l n -> Qu b l n -> Qu (Normalize (a @- b)) l n
|/| forall (u :: [Factor (*)]) (l :: LCSU (*)) a.
Floating a =>
V3 (Qu u l a) -> Qu u l a
qNorm Position a
r) forall (d1 :: [Factor (*)]) (d2 :: [Factor (*)]) n (l :: LCSU (*)).
(d1 @~ d2, Num n) =>
Qu d1 l n -> Qu d2 l n -> Qu d1 l n
|-| (forall (u :: [Factor (*)]) (l :: LCSU (*)) a.
Num a =>
V3 (Qu u l a) -> Qu (Normalize (u @@+ Reorder u u)) l a
qQuadrance Velocity a
v forall n (a :: [Factor (*)]) (l :: LCSU (*)) (b :: [Factor (*)]).
Fractional n =>
Qu a l n -> Qu b l n -> Qu (Normalize (a @- b)) l n
|/| Quantity
  ((Meter :^ Succ (Succ (Succ 'Zero)))
   :* (Second :^ Pred (Pred 'Zero)))
  a
μ)
  a :: Qu
  (Normalize ('[] @- Normalize ('[] @- '[ 'F Length One])))
  'DefaultLCSU
  a
a     = forall (u :: [Factor (*)]) (l :: LCSU (*)) a.
Fractional a =>
Qu u l a -> Qu (Normalize ('[] @- u)) l a
qRecip Qu (Normalize ('[] @- '[ 'F Length One])) 'DefaultLCSU a
aInv
  q :: Qu
  (Normalize
     (Normalize
        ('[ 'F Length ('S One), 'F Time ('P 'Zero)]
         @@+ '[ 'F Length ('S One), 'F Time ('P 'Zero)])
      @- Normalize
           ('[]
            @@+ Reorder
                  '[ 'F Length ('S ('S One)), 'F Time ('P ('P 'Zero))] '[])))
  'DefaultLCSU
  a
q     = if Qu (Normalize ('[] @- '[ 'F Length One])) 'DefaultLCSU a
aInv forall a. Eq a => a -> a -> Bool
== forall n (dimspec :: [Factor (*)]) (l :: LCSU (*)).
Num n =>
Qu dimspec l n
zero 
    then forall (u :: [Factor (*)]) (l :: LCSU (*)) a.
Num a =>
V3 (Qu u l a) -> Qu (Normalize (u @@+ Reorder u u)) l a
qQuadrance V3 (Quantity ((Meter :^ Succ (Succ 'Zero)) :/ Second) a)
h forall n (a :: [Factor (*)]) (l :: LCSU (*)) (b :: [Factor (*)]).
Fractional n =>
Qu a l n -> Qu b l n -> Qu (Normalize (a @- b)) l n
|/| (Qu '[] 'DefaultLCSU a
2 forall n (a :: [Factor (*)]) (l :: LCSU (*)) (b :: [Factor (*)]).
Num n =>
Qu a l n -> Qu b l n -> Qu (Normalize (a @+ b)) l n
|*| Quantity
  ((Meter :^ Succ (Succ (Succ 'Zero)))
   :* (Second :^ Pred (Pred 'Zero)))
  a
μ)
    else Qu
  (Normalize ('[] @- Normalize ('[] @- '[ 'F Length One])))
  'DefaultLCSU
  a
a forall n (a :: [Factor (*)]) (l :: LCSU (*)) (b :: [Factor (*)]).
Num n =>
Qu a l n -> Qu b l n -> Qu (Normalize (a @+ b)) l n
|*| (Qu '[] 'DefaultLCSU a
1 forall a. Num a => a -> a -> a
- Qu '[] 'DefaultLCSU a
e)
  ν :: Angle a
ν = if Qu '[] 'DefaultLCSU a
e forall a. Eq a => a -> a -> Bool
== forall n (dimspec :: [Factor (*)]) (l :: LCSU (*)).
Num n =>
Qu dimspec l n
zero
    then 
         forall a.
(Conjugate a, RealFloat a) =>
Orbit a -> Position a -> Angle a
trueAnomalyAtPosition Orbit a
o Position a
r
    else
      let cosν :: Qu
  (Normalize
     ('[]
      @@+ Reorder
            (Normalize
               (Normalize ('[] @- '[ 'F Length One])
                @@+ Reorder
                      '[ 'F Length One] (Normalize ('[] @- '[ 'F Length One]))))
            '[]))
  'DefaultLCSU
  a
cosν = V3 (Qu '[] 'DefaultLCSU a)
eNorm forall (u :: [Factor (*)]) (v :: [Factor (*)]) (l :: LCSU (*)) a.
Num a =>
V3 (Qu u l a)
-> V3 (Qu v l a) -> Qu (Normalize (u @@+ Reorder v u)) l a
`qDot` forall n (b :: [Factor (*)]) (l :: LCSU (*)).
Floating n =>
V3 (Qu b l n)
-> V3
     (Qu
        (Normalize
           (Normalize ('[] @- b) @@+ Reorder b (Normalize ('[] @- b))))
        l
        n)
qNormalize Position a
r
      in  if Position a
r forall (u :: [Factor (*)]) (v :: [Factor (*)]) (l :: LCSU (*)) a.
Num a =>
V3 (Qu u l a)
-> V3 (Qu v l a) -> Qu (Normalize (u @@+ Reorder v u)) l a
`qDot` Velocity a
v forall a. Ord a => a -> a -> Bool
>= forall n (dimspec :: [Factor (*)]) (l :: LCSU (*)).
Num n =>
Qu dimspec l n
zero then forall a. Floating a => Unitless a -> Angle a
qArcCos Qu
  (Normalize
     ('[]
      @@+ Reorder
            (Normalize
               (Normalize ('[] @- '[ 'F Length One])
                @@+ Reorder
                      '[ 'F Length One] (Normalize ('[] @- '[ 'F Length One]))))
            '[]))
  'DefaultLCSU
  a
cosν else forall a. Floating a => PlaneAngle a
turn forall (d1 :: [Factor (*)]) (d2 :: [Factor (*)]) n (l :: LCSU (*)).
(d1 @~ d2, Num n) =>
Qu d1 l n -> Qu d2 l n -> Qu d1 l n
|-| forall a. Floating a => Unitless a -> Angle a
qArcCos Qu
  (Normalize
     ('[]
      @@+ Reorder
            (Normalize
               (Normalize ('[] @- '[ 'F Length One])
                @@+ Reorder
                      '[ 'F Length One] (Normalize ('[] @- '[ 'F Length One]))))
            '[]))
  'DefaultLCSU
  a
cosν
  inclinationSpecifier' :: InclinationSpecifier a
inclinationSpecifier' =
    let i :: Angle a
i    = forall a. Floating a => Unitless a -> Angle a
qArcCos ((V3 (Quantity ((Meter :^ Succ (Succ 'Zero)) :/ Second) a)
h forall s a. s -> Getting a s a -> a
^. forall (t :: * -> *) a. R3 t => Lens' (t a) a
_z) forall n (a :: [Factor (*)]) (l :: LCSU (*)) (b :: [Factor (*)]).
Fractional n =>
Qu a l n -> Qu b l n -> Qu (Normalize (a @- b)) l n
|/| forall (u :: [Factor (*)]) (l :: LCSU (*)) a.
Floating a =>
V3 (Qu u l a) -> Qu u l a
qNorm V3 (Quantity ((Meter :^ Succ (Succ 'Zero)) :/ Second) a)
h)
        cosΩ :: Qu
  (Normalize
     ('[ 'F Length ('S One), 'F Time ('P 'Zero)]
      @- '[ 'F Length ('S One), 'F Time ('P 'Zero)]))
  'DefaultLCSU
  a
cosΩ = V3 (Qu '[ 'F Length ('S One), 'F Time ('P 'Zero)] 'DefaultLCSU a)
n forall s a. s -> Getting a s a -> a
^. forall (t :: * -> *) a. R1 t => Lens' (t a) a
_x forall n (a :: [Factor (*)]) (l :: LCSU (*)) (b :: [Factor (*)]).
Fractional n =>
Qu a l n -> Qu b l n -> Qu (Normalize (a @- b)) l n
|/| forall (u :: [Factor (*)]) (l :: LCSU (*)) a.
Floating a =>
V3 (Qu u l a) -> Qu u l a
qNorm V3 (Qu '[ 'F Length ('S One), 'F Time ('P 'Zero)] 'DefaultLCSU a)
n
        _Ω :: Angle a
_Ω   = if V3 (Qu '[ 'F Length ('S One), 'F Time ('P 'Zero)] 'DefaultLCSU a)
n forall s a. s -> Getting a s a -> a
^. forall (t :: * -> *) a. R2 t => Lens' (t a) a
_y forall a. Ord a => a -> a -> Bool
>= forall n (dimspec :: [Factor (*)]) (l :: LCSU (*)).
Num n =>
Qu dimspec l n
zero then forall a. Floating a => Unitless a -> Angle a
qArcCos Qu
  (Normalize
     ('[ 'F Length ('S One), 'F Time ('P 'Zero)]
      @- '[ 'F Length ('S One), 'F Time ('P 'Zero)]))
  'DefaultLCSU
  a
cosΩ else forall a. Floating a => PlaneAngle a
turn forall (d1 :: [Factor (*)]) (d2 :: [Factor (*)]) n (l :: LCSU (*)).
(d1 @~ d2, Num n) =>
Qu d1 l n -> Qu d2 l n -> Qu d1 l n
|-| forall a. Floating a => Unitless a -> Angle a
qArcCos Qu
  (Normalize
     ('[ 'F Length ('S One), 'F Time ('P 'Zero)]
      @- '[ 'F Length ('S One), 'F Time ('P 'Zero)]))
  'DefaultLCSU
  a
cosΩ
    in  if V3 (Quantity ((Meter :^ Succ (Succ 'Zero)) :/ Second) a)
h forall s a. s -> Getting a s a -> a
^. forall (t :: * -> *) a. R1 t => Lens' (t a) a
_x forall a. Eq a => a -> a -> Bool
== forall n (dimspec :: [Factor (*)]) (l :: LCSU (*)).
Num n =>
Qu dimspec l n
zero Bool -> Bool -> Bool
&& V3 (Quantity ((Meter :^ Succ (Succ 'Zero)) :/ Second) a)
h forall s a. s -> Getting a s a -> a
^. forall (t :: * -> *) a. R2 t => Lens' (t a) a
_y forall a. Eq a => a -> a -> Bool
== forall n (dimspec :: [Factor (*)]) (l :: LCSU (*)).
Num n =>
Qu dimspec l n
zero
          then forall a. InclinationSpecifier a
NonInclined
          else forall a. Angle a -> Angle a -> InclinationSpecifier a
Inclined Angle a
_Ω Angle a
i
  
  
  periapsisSpecifier' :: PeriapsisSpecifier a
periapsisSpecifier' =
    let cosω :: Qu (Normalize ('[] @@+ Reorder '[] '[])) 'DefaultLCSU a
cosω = case InclinationSpecifier a
inclinationSpecifier' of
          Inclined Angle a
_ Angle a
_ -> forall n (b :: [Factor (*)]) (l :: LCSU (*)).
Floating n =>
V3 (Qu b l n)
-> V3
     (Qu
        (Normalize
           (Normalize ('[] @- b) @@+ Reorder b (Normalize ('[] @- b))))
        l
        n)
qNormalize V3 (Qu '[ 'F Length ('S One), 'F Time ('P 'Zero)] 'DefaultLCSU a)
n forall (u :: [Factor (*)]) (v :: [Factor (*)]) (l :: LCSU (*)) a.
Num a =>
V3 (Qu u l a)
-> V3 (Qu v l a) -> Qu (Normalize (u @@+ Reorder v u)) l a
`qDot` V3 (Qu '[] 'DefaultLCSU a)
eNorm
          InclinationSpecifier a
NonInclined  -> V3 (Qu '[] 'DefaultLCSU a)
eNorm forall s a. s -> Getting a s a -> a
^. forall (t :: * -> *) a. R1 t => Lens' (t a) a
_x
        
        ω :: Angle a
ω = case InclinationSpecifier a
inclinationSpecifier' of
          Inclined Angle a
_ Angle a
_ ->
            if (V3 (Unitless a)
e' forall s a. s -> Getting a s a -> a
^. forall (t :: * -> *) a. R3 t => Lens' (t a) a
_z) forall a. Ord a => a -> a -> Bool
>= forall n (dimspec :: [Factor (*)]) (l :: LCSU (*)).
Num n =>
Qu dimspec l n
zero then forall a. Floating a => Unitless a -> Angle a
qArcCos Qu (Normalize ('[] @@+ Reorder '[] '[])) 'DefaultLCSU a
cosω else forall a. Floating a => PlaneAngle a
turn forall (d1 :: [Factor (*)]) (d2 :: [Factor (*)]) n (l :: LCSU (*)).
(d1 @~ d2, Num n) =>
Qu d1 l n -> Qu d2 l n -> Qu d1 l n
|-| forall a. Floating a => Unitless a -> Angle a
qArcCos Qu (Normalize ('[] @@+ Reorder '[] '[])) 'DefaultLCSU a
cosω
          InclinationSpecifier a
NonInclined ->
            let sinω :: Qu '[] 'DefaultLCSU a
sinω = V3 (Qu '[] 'DefaultLCSU a)
eNorm forall s a. s -> Getting a s a -> a
^. forall (t :: * -> *) a. R2 t => Lens' (t a) a
_y in forall a. RealFloat a => Unitless a -> Unitless a -> Angle a
qArcTan2 Qu '[] 'DefaultLCSU a
sinω Qu (Normalize ('[] @@+ Reorder '[] '[])) 'DefaultLCSU a
cosω forall a (u :: [Factor (*)]) (l :: LCSU (*)).
Real a =>
Qu u l a -> Qu u l a -> Qu u l a
`mod'` forall a. Floating a => PlaneAngle a
turn
    in  if Qu '[] 'DefaultLCSU a
e forall a. Eq a => a -> a -> Bool
== forall n (dimspec :: [Factor (*)]) (l :: LCSU (*)).
Num n =>
Qu dimspec l n
zero then forall a. PeriapsisSpecifier a
Circular else forall a. Angle a -> PeriapsisSpecifier a
Eccentric Angle a
ω
trueAnomalyAtPosition
  :: (Conjugate a, RealFloat a) => Orbit a -> Position a -> Angle a
trueAnomalyAtPosition :: forall a.
(Conjugate a, RealFloat a) =>
Orbit a -> Position a -> Angle a
trueAnomalyAtPosition Orbit a
o Position a
r = Qu '[ 'F PlaneAngle One] 'DefaultLCSU a
ν
 where
  V3 (Qu a
x) (Qu a
y) Qu '[ 'F Length One] 'DefaultLCSU a
_ = forall a (u :: [Factor (*)]) (l :: LCSU (*)).
(Conjugate a, RealFloat a) =>
Orbit a -> V3 (Qu u l a) -> V3 (Qu u l a)
rotateToPlane Orbit a
o Position a
r
  ν :: Qu '[ 'F PlaneAngle One] 'DefaultLCSU a
ν                  = forall a. RealFloat a => a -> a -> a
atan2 a
y a
x forall (dim :: [Factor (*)]) unit n.
(ValidDLU dim 'DefaultLCSU unit, Fractional n) =>
n -> unit -> Qu dim 'DefaultLCSU n
% [si|rad|]
specificAngularMomentumVector
  :: Num a => StateVectors a -> V3 (Quantity [si|m^2 / s|] a)
specificAngularMomentumVector :: forall a.
Num a =>
StateVectors a
-> V3 (Quantity ((Meter :^ Succ (Succ 'Zero)) :/ Second) a)
specificAngularMomentumVector (StateVectors Position a
r Velocity a
v) = Position a
r forall n (a :: [Factor (*)]) (l :: LCSU (*)) (b :: [Factor (*)]).
Num n =>
V3 (Qu a l n)
-> V3 (Qu b l n) -> V3 (Qu (Normalize (a @@+ Reorder b a)) l n)
`qCross` Velocity a
v
eccentricityVector
  :: Floating a
  => Quantity [si| m^3 s^-2 |] a
  -> StateVectors a
  -> V3 (Unitless a)
eccentricityVector :: forall a.
Floating a =>
Quantity
  ((Meter :^ Succ (Succ (Succ 'Zero)))
   :* (Second :^ Pred (Pred 'Zero)))
  a
-> StateVectors a -> V3 (Unitless a)
eccentricityVector Quantity
  ((Meter :^ Succ (Succ (Succ 'Zero)))
   :* (Second :^ Pred (Pred 'Zero)))
  a
μ sv :: StateVectors a
sv@(StateVectors Position a
r Velocity a
v) = V3
  (Qu
     (Normalize
        (Normalize
           ('[] @- '[ 'F Length ('S ('S One)), 'F Time ('P ('P 'Zero))])
         @@+ Reorder
               (Normalize
                  ('[ 'F Length One, 'F Time ('P 'Zero)]
                   @@+ Reorder
                         '[ 'F Length ('S One), 'F Time ('P 'Zero)]
                         '[ 'F Length One, 'F Time ('P 'Zero)]))
               (Normalize
                  ('[] @- '[ 'F Length ('S ('S One)), 'F Time ('P ('P 'Zero))]))))
     'DefaultLCSU
     a)
e
 where
  e :: V3
  (Qu
     (Normalize
        (Normalize
           ('[] @- '[ 'F Length ('S ('S One)), 'F Time ('P ('P 'Zero))])
         @@+ Reorder
               (Normalize
                  ('[ 'F Length One, 'F Time ('P 'Zero)]
                   @@+ Reorder
                         '[ 'F Length ('S One), 'F Time ('P 'Zero)]
                         '[ 'F Length One, 'F Time ('P 'Zero)]))
               (Normalize
                  ('[] @- '[ 'F Length ('S ('S One)), 'F Time ('P ('P 'Zero))]))))
     'DefaultLCSU
     a)
e = (Velocity a
v forall n (a :: [Factor (*)]) (l :: LCSU (*)) (b :: [Factor (*)]).
Num n =>
V3 (Qu a l n)
-> V3 (Qu b l n) -> V3 (Qu (Normalize (a @@+ Reorder b a)) l n)
`qCross` V3 (Quantity ((Meter :^ Succ (Succ 'Zero)) :/ Second) a)
h) forall (f :: * -> *) n (b :: [Factor (*)]) (l :: LCSU (*))
       (u :: [Factor (*)]).
(Functor f, Fractional n) =>
f (Qu b l n)
-> Qu u l n
-> f (Qu
        (Normalize
           (Normalize ('[] @- u) @@+ Reorder b (Normalize ('[] @- u))))
        l
        n)
|^/| Quantity
  ((Meter :^ Succ (Succ (Succ 'Zero)))
   :* (Second :^ Pred (Pred 'Zero)))
  a
μ forall (f :: * -> *) (u :: [Factor (*)]) (l :: LCSU (*)) a.
(Additive f, Applicative f, Num a) =>
f (Qu u l a) -> f (Qu u l a) -> f (Qu u l a)
|^-^| forall n (b :: [Factor (*)]) (l :: LCSU (*)).
Floating n =>
V3 (Qu b l n)
-> V3
     (Qu
        (Normalize
           (Normalize ('[] @- b) @@+ Reorder b (Normalize ('[] @- b))))
        l
        n)
qNormalize Position a
r
  h :: V3 (Quantity ((Meter :^ Succ (Succ 'Zero)) :/ Second) a)
h = forall a.
Num a =>
StateVectors a
-> V3 (Quantity ((Meter :^ Succ (Succ 'Zero)) :/ Second) a)
specificAngularMomentumVector StateVectors a
sv
rotateFromPlane
  :: (Conjugate a, RealFloat a)
  => Orbit a
  -> V3 (Qu u l a)
  -> V3 (Qu u l a)
rotateFromPlane :: forall a (u :: [Factor (*)]) (l :: LCSU (*)).
(Conjugate a, RealFloat a) =>
Orbit a -> V3 (Qu u l a) -> V3 (Qu u l a)
rotateFromPlane = forall a (q :: * -> *).
(Coercible (q a) a, Conjugate a, RealFloat a) =>
Quaternion a -> V3 (q a) -> V3 (q a)
qRotate forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. RealFloat a => Orbit a -> Quaternion a
orbitalPlaneQuaternion
rotateToPlane
  :: (Conjugate a, RealFloat a) => Orbit a -> V3 (Qu u l a) -> V3 (Qu u l a)
rotateToPlane :: forall a (u :: [Factor (*)]) (l :: LCSU (*)).
(Conjugate a, RealFloat a) =>
Orbit a -> V3 (Qu u l a) -> V3 (Qu u l a)
rotateToPlane = forall a (q :: * -> *).
(Coercible (q a) a, Conjugate a, RealFloat a) =>
Quaternion a -> V3 (q a) -> V3 (q a)
qRotate forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Conjugate a => a -> a
conjugate forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. RealFloat a => Orbit a -> Quaternion a
orbitalPlaneQuaternion
orbitalPlaneQuaternion :: RealFloat a => Orbit a -> Quaternion a
orbitalPlaneQuaternion :: forall a. RealFloat a => Orbit a -> Quaternion a
orbitalPlaneQuaternion Orbit a
o = Quaternion a
lon forall a. Num a => a -> a -> a
* Quaternion a
per
 where
  per :: Quaternion a
per = case forall a. Orbit a -> PeriapsisSpecifier a
periapsisSpecifier Orbit a
o of
    Eccentric Angle a
ω -> forall a. Floating a => Angle a -> Quaternion a
rotateZ Angle a
ω
    PeriapsisSpecifier a
Circular    -> Quaternion a
1
  lon :: Quaternion a
lon = case forall a. Orbit a -> InclinationSpecifier a
inclinationSpecifier Orbit a
o of
    Inclined Angle a
_Ω Angle a
i -> forall a. Floating a => Angle a -> Quaternion a
rotateZ Angle a
_Ω forall a. Num a => a -> a -> a
* forall a. Floating a => Angle a -> Quaternion a
rotateX Angle a
i
    InclinationSpecifier a
NonInclined   -> Quaternion a
1
flightPathAngleAtTrueAnomaly
  :: (Real a, Floating a) => Orbit a -> Angle a -> Angle a
flightPathAngleAtTrueAnomaly :: forall a. (Real a, Floating a) => Orbit a -> Angle a -> Angle a
flightPathAngleAtTrueAnomaly Orbit a
o Angle a
ν = Qu '[ 'F PlaneAngle One] 'DefaultLCSU a
-> Qu '[ 'F PlaneAngle One] 'DefaultLCSU a
sign (forall a. Floating a => Unitless a -> Angle a
qArcCos Qu
  (Normalize
     ('[ 'F Length ('S One), 'F Time ('P 'Zero)]
      @- Normalize
           ('[ 'F Length One]
            @@+ Reorder
                  '[ 'F Length One, 'F Time ('P 'Zero)] '[ 'F Length One])))
  'DefaultLCSU
  a
cosφ)
 where
  cosφ :: Qu
  (Normalize
     ('[ 'F Length ('S One), 'F Time ('P 'Zero)]
      @- Normalize
           ('[ 'F Length One]
            @@+ Reorder
                  '[ 'F Length One, 'F Time ('P 'Zero)] '[ 'F Length One])))
  'DefaultLCSU
  a
cosφ = Quantity ((Meter :^ Succ (Succ 'Zero)) :* (Second :^ Pred 'Zero)) a
h forall n (a :: [Factor (*)]) (l :: LCSU (*)) (b :: [Factor (*)]).
Fractional n =>
Qu a l n -> Qu b l n -> Qu (Normalize (a @- b)) l n
|/| (Distance a
r forall n (a :: [Factor (*)]) (l :: LCSU (*)) (b :: [Factor (*)]).
Num n =>
Qu a l n -> Qu b l n -> Qu (Normalize (a @+ b)) l n
|*| Speed a
v)
  sign :: Qu '[ 'F PlaneAngle One] 'DefaultLCSU a
-> Qu '[ 'F PlaneAngle One] 'DefaultLCSU a
sign = if (Angle a
ν forall a (u :: [Factor (*)]) (l :: LCSU (*)).
Real a =>
Qu u l a -> Qu u l a -> Qu u l a
`mod'` forall a. Floating a => PlaneAngle a
turn) forall a. Ord a => a -> a -> Bool
< forall a. Floating a => PlaneAngle a
halfTurn then forall a. a -> a
id else forall n (d :: [Factor (*)]) (l :: LCSU (*)).
Num n =>
Qu d l n -> Qu d l n
qNegate
  r :: Distance a
r    = forall a. (Ord a, Floating a) => Orbit a -> Angle a -> Distance a
radiusAtTrueAnomaly Orbit a
o Angle a
ν
  v :: Speed a
v    = forall a. (Ord a, Floating a) => Orbit a -> Angle a -> Speed a
speedAtTrueAnomaly Orbit a
o Angle a
ν
  h :: Quantity ((Meter :^ Succ (Succ 'Zero)) :* (Second :^ Pred 'Zero)) a
h    = forall a.
Floating a =>
Orbit a
-> Quantity
     ((Meter :^ Succ (Succ 'Zero)) :* (Second :^ Pred 'Zero)) a
specificAngularMomentum Orbit a
o
qRotate
  :: forall a q
   . (Coercible (q a) a, Conjugate a, RealFloat a)
  => Quaternion a
  -> V3 (q a)
  -> V3 (q a)
qRotate :: forall a (q :: * -> *).
(Coercible (q a) a, Conjugate a, RealFloat a) =>
Quaternion a -> V3 (q a) -> V3 (q a)
qRotate = coerce :: forall a b. Coercible a b => a -> b
coerce (forall a.
(Conjugate a, RealFloat a) =>
Quaternion a -> V3 a -> V3 a
rotate @a)
rotateX :: Floating a => Angle a -> Quaternion a
rotateX :: forall a. Floating a => Angle a -> Quaternion a
rotateX Angle a
θ = forall a. a -> V3 a -> Quaternion a
Quaternion (forall a. Floating a => a -> a
cos a
half) (forall a. a -> a -> a -> V3 a
V3 (forall a. Floating a => a -> a
sin a
half) a
0 a
0)
  where half :: a
half = (Angle a
θ forall (dim :: [Factor (*)]) unit n.
(ValidDLU dim 'DefaultLCSU unit, Fractional n) =>
Qu dim 'DefaultLCSU n -> unit -> n
# [si|rad|]) forall a. Fractional a => a -> a -> a
/ a
2
_rotateY :: Floating a => Angle a -> Quaternion a
_rotateY :: forall a. Floating a => Angle a -> Quaternion a
_rotateY Angle a
θ = forall a. a -> V3 a -> Quaternion a
Quaternion (forall a. Floating a => a -> a
cos a
half) (forall a. a -> a -> a -> V3 a
V3 a
0 (forall a. Floating a => a -> a
sin a
half) a
0)
  where half :: a
half = (Angle a
θ forall (dim :: [Factor (*)]) unit n.
(ValidDLU dim 'DefaultLCSU unit, Fractional n) =>
Qu dim 'DefaultLCSU n -> unit -> n
# [si|rad|]) forall a. Fractional a => a -> a -> a
/ a
2
rotateZ :: Floating a => Angle a -> Quaternion a
rotateZ :: forall a. Floating a => Angle a -> Quaternion a
rotateZ Angle a
θ = forall a. a -> V3 a -> Quaternion a
Quaternion (forall a. Floating a => a -> a
cos a
half) (forall a. a -> a -> a -> V3 a
V3 a
0 a
0 (forall a. Floating a => a -> a
sin a
half))
  where half :: a
half = (Angle a
θ forall (dim :: [Factor (*)]) unit n.
(ValidDLU dim 'DefaultLCSU unit, Fractional n) =>
Qu dim 'DefaultLCSU n -> unit -> n
# [si|rad|]) forall a. Fractional a => a -> a -> a
/ a
2