; flight planning -- by Jos Koot
(define (square x) (* x x))
(define pi 3.141592653589793)
(define (radian->degree r) (/ r pi 2/360))
(define (degree->radian d) (* d 2/360 pi))
(define (rnd x) (round (inexact->exact x)))
(define (xmodulo x y)
(cond
((<= 0 x y) x)
((< x 0) (xmodulo (+ x y) y))
((>= x y) (xmodulo (- x y) y))))
(define (navigate1 d gt wn ws as)
(let*
((b (- gt wn -180))
(b-radians (degree->radian b))
(sin-b (sin b-radians))
(a (radian->degree (asin (/ (* sin-b ws) as))))
(th (xmodulo (+ gt a) 360))
(gs (+ (* as (cos (degree->radian (- th gt))))
(* ws (cos b-radians))))
(th (+ gt a))
(ft (/ d gs)))
(list
(rnd gs)
(rnd a)
(xmodulo (rnd th) 360)
(rnd (* 60 ft)))))
(define (navigate2 d gt wn ws as)
(let*
((b (xmodulo (- gt wn -180) 360))
(cos-b (cos (degree->radian b)))
(wsqr (square ws))
(asqr (square as))
(det (+ (square (* ws cos-b)) (- wsqr) asqr))
(gs (+ (* ws cos-b) (sqrt det)))
(a (radian->degree (acos (/ (+ asqr (square gs) (- wsqr)) (* 2 gs as)))))
(a ((if (< b 180) + -) a))
(th (+ gt a))
(ft (/ d gs)))
(if (or (< det 0) (< gs 0)) ('error 'navigate "STRANGE" det gs))
(list
(rnd gs)
(rnd a)
(xmodulo (rnd th) 360)
(rnd (* 60 ft)))))
(display (navigate1 180 90 90 20 90)) (newline)
(display (navigate2 180 90 90 20 90)) (newline)