;;; Chickadee Game Toolkit ;;; Copyright © 2016 David Thompson ;;; ;;; Licensed under the Apache License, Version 2.0 (the "License"); ;;; you may not use this file except in compliance with the License. ;;; You may obtain a copy of the License at ;;; ;;; http://www.apache.org/licenses/LICENSE-2.0 ;;; ;;; Unless required by applicable law or agreed to in writing, software ;;; distributed under the License is distributed on an "AS IS" BASIS, ;;; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ;;; See the License for the specific language governing permissions and ;;; limitations under the License. (define-module (chickadee math) #:export (pi pi/2 tau cotan clamp min max lerp degrees->radians radians->degrees) #:replace (min max)) (define pi 3.1415926535897932) (define pi/2 1.5707963267948966) (define tau 6.283185307179586) ;; AKA 2pi (define-inlinable (cotan z) "Return the cotangent of Z." (/ 1.0 (tan z))) (define-inlinable (clamp min max x) "Restrict X to the range defined by MIN and MAX. Assumes that MIN is actually less than MAX." (cond ((< x min) min) ((> x max) max) (else x))) ;; Some macro trickery to inline calls to min/max with 2 arguments. ;; We often call min/max on floating point values, so inlining such ;; calls allows the compiler to unbox many of these operations, ;; reducing allocation. (define-syntax min (syntax-rules () ((_ a b) (if (< a b) a b)) ((_ a b ...) (let ((m (min b ...))) (if (< a m) a m))))) (define-syntax max (syntax-rules () ((_ a b) (if (> a b) a b)) ((_ a b ...) (let ((m (max b ...))) (if (> a m) a m))))) (define-inlinable (lerp start end alpha) (+ (* start (- 1.0 alpha)) (* end alpha))) (define-inlinable (degrees->radians degrees) (/ (* pi degrees) 180.0)) (define-inlinable (radians->degrees radians) (/ (* 180.0 radians) pi))