In today’s Programming Praxis exercise we have to implement two algorithms for flight planning.
Our import:
import Data.Fixed
We will need to some degree-radian conversion, so let’s define some convenience functions.
toDeg, toRad :: Floating a => a -> a toDeg d = d * 180 / pi toRad d = d * pi / 180
Both navigation algorithms are really nothing more than a lot of math, so it’s just a matter of converting the math to Haskell notation.
navigate1 :: Float -> Float -> Float -> Float -> Float -> [Int] navigate1 d gt wn ws as = map round [gs, a, th, ft] where b = toRad $ gt - wn + 180 a = toDeg $ asin (ws * sin b / as) th = mod' (gt + a) 360 gs = (cos . toRad $ th - gt) * as + ws * cos b ft = d / gs * 60 navigate2 :: Float -> Float -> Float -> Float -> Float -> [Int] navigate2 d gt wn ws as = if det < 0 || gs < 0 then error "strange" else map round [gs, a, th, ft] where b = mod' (gt - wn + 180) 360 x = ws * cos (toRad b) det = x^2 - ws^2 + as^2 gs = x + sqrt det a = (if b < 180 then id else negate) . toDeg . acos $ (as^2 + gs^2 - ws^2) / (2 * gs * as) th = gt + a ft = d / gs * 60
A test shows that everything is working correctly.
main :: IO () main = do print $ navigate1 180 90 90 20 90 print $ navigate2 180 90 90 20 90
Tags: bonsai, code, flight, Haskell, kata, planning, praxis, programming