RosettaCodeData/Task/Angles-geometric-normalization-and-conversion/Racket/angles-geometric-normalization-and-conversion.rkt
2023-07-01 13:44:08 -04:00

49 lines
1.7 KiB
Racket

#lang racket
(define (rem n m)
(let* ((m (abs m)) (-m (- m)))
(let recur ((n n))
(cond [(< n -m) (recur (+ n m))]
[(>= n m) (recur (- n m))]
[else n]))))
(define 2.pi (* 2 pi))
(define (deg->deg a) (rem a 360))
(define (grad->grad a) (rem a 400))
(define (mil->mil a) (rem a 6400))
(define (rad->rad a) (rem a 2.pi))
(define (deg->grad a) (grad->grad (* (/ a 360) 400)))
(define (deg->rad a) (rad->rad (* (/ a 360) 2.pi)))
(define (deg->mil a) (mil->mil (* (/ a 360) 6400)))
(define (grad->deg a) (deg->deg (* (/ a 400) 360)))
(define (grad->rad a) (rad->rad (* (/ a 400) 2.pi)))
(define (grad->mil a) (mil->mil (* (/ a 400) 6400)))
(define (mil->deg a) (deg->deg (* (/ a 6400) 360)))
(define (mil->grad a) (grad->grad (* (/ a 6400) 400)))
(define (mil->rad a) (rad->rad (* (/ a 6400) 2.pi)))
(define (rad->deg a) (deg->deg (* (/ a 2.pi) 360)))
(define (rad->grad a) (grad->grad (* (/ a 2.pi) 400)))
(define (rad->mil a) (mil->mil (* (/ a 2.pi) 6400)))
(define (tabulate #:fmt (fmt (λ (v) (~a (exact->inexact v) #:align 'right #:width 15))) head . vs)
(string-join (cons (~a #:width 6 head) (map fmt vs)) " | "))
(define (report-angle a)
(string-join
(list
(tabulate #:fmt (λ (x) (~a x #:width 15 #:align 'center)) "UNIT" "VAL*" "DEG" "GRAD" "MIL" "RAD")
(tabulate "Deg" a (deg->deg a) (deg->grad a) (deg->mil a) (deg->rad a))
(tabulate "Grad" a (grad->deg a) (grad->grad a) (grad->mil a) (grad->rad a))
(tabulate "Mil" a (mil->deg a) (mil->grad a) (mil->mil a) (mil->rad a))
(tabulate "Rad" a (rad->deg a) (rad->grad a) (rad->mil a) (rad->rad a)))
"\n"))
(module+ test
(displayln
(string-join (map report-angle '(-2 -1 0 1 2 6.2831853 16 57.2957795 359 399 6399 1000000))
"\n\n")))