summaryrefslogtreecommitdiff
path: root/strigoform/math.scm
diff options
context:
space:
mode:
Diffstat (limited to 'strigoform/math.scm')
-rw-r--r--strigoform/math.scm144
1 files changed, 144 insertions, 0 deletions
diff --git a/strigoform/math.scm b/strigoform/math.scm
new file mode 100644
index 0000000..b769572
--- /dev/null
+++ b/strigoform/math.scm
@@ -0,0 +1,144 @@
+(library (strigoform math)
+ (export fmod
+ pi
+ pi/2
+ tau
+ do-circle
+ clamp
+ smoothstep
+ lerp
+
+ s32-ref
+ s32-set!
+ f64-ref
+ f64-set!
+
+ vec2
+ vec2?
+ vec2-x
+ vec2-y
+ set-vec2-x!
+ set-vec2-y!
+ vec2-add!
+ vec2-sub!
+ vec2-mul-scalar!
+ vec2-magnitude
+ vec2-normalize!
+ vec2-clamp!
+
+ make-rect
+ rect-x
+ rect-y
+ rect-w
+ rect-h
+ within?
+ rect-within?)
+ (import (scheme base)
+ (scheme inexact)
+ (only (hoot bytevectors)
+ bytevector-s32-native-ref
+ bytevector-s32-native-set!
+ bytevector-ieee-double-native-ref
+ bytevector-ieee-double-native-set!)
+ (strigoform type))
+
+ (define (assert-float x)
+ (unless (and (number? x) (inexact? x) (rational? x))
+ (error "expected inexact rational" x)))
+
+ (define (fmod x y)
+ (assert-float x)
+ (assert-float y)
+ (- x (* (truncate (/ x y)) y)))
+
+ (define pi (* 4.0 (atan 1.0)))
+ (define pi/2 (/ pi 2.0))
+ (define tau (* pi 2.0))
+
+ (define (do-circle proc k)
+ (do ((i 0 (+ i 1)))
+ ((= i k))
+ (proc (* tau (inexact (/ i k))))))
+
+ (define (clamp x min max)
+ (cond ((< x min) min)
+ ((> x max) max)
+ (else x)))
+
+ (define (smoothstep t)
+ (* t t (- 3.0 (* 2.0 t))))
+
+ (define (lerp start end alpha)
+ (+ (* start (- 1.0 alpha))
+ (* end alpha)))
+
+ (define s32-ref bytevector-s32-native-ref)
+ (define s32-set! bytevector-s32-native-set!)
+ (define f64-ref bytevector-ieee-double-native-ref)
+ (define f64-set! bytevector-ieee-double-native-set!)
+
+ (define-type vec2
+ make-vec2
+ vec2?
+ (bv vec2-bv set-vec2-bv!))
+ (define (vec2 x y)
+ (let ((v (make-vec2 (make-bytevector 16))))
+ (set-vec2-x! v x)
+ (set-vec2-y! v y)
+ v))
+ (define (vec2-x v)
+ (f64-ref (vec2-bv v) 0))
+ (define (vec2-y v)
+ (f64-ref (vec2-bv v) 8))
+ (define (set-vec2-x! v x)
+ (f64-set! (vec2-bv v) 0 x))
+ (define (set-vec2-y! v y)
+ (f64-set! (vec2-bv v) 8 y))
+ (define (vec2-add! v w)
+ (set-vec2-x! v (+ (vec2-x v) (vec2-x w)))
+ (set-vec2-y! v (+ (vec2-y v) (vec2-y w))))
+ (define (vec2-sub! v w)
+ (set-vec2-x! v (- (vec2-x v) (vec2-x w)))
+ (set-vec2-y! v (- (vec2-y v) (vec2-y w))))
+ (define (vec2-mul-scalar! v x)
+ (set-vec2-x! v (* (vec2-x v) x))
+ (set-vec2-y! v (* (vec2-y v) x)))
+ (define (vec2-magnitude v)
+ (sqrt (+ (* (vec2-x v) (vec2-x v)) (* (vec2-y v) (vec2-y v)))))
+ (define (vec2-normalize! v)
+ (unless (and (= (vec2-x v) 0.0) (= (vec2-y v) 0.0))
+ (let ((m (vec2-magnitude v)))
+ (set-vec2-x! v (/ (vec2-x v) m))
+ (set-vec2-y! v (/ (vec2-y v) m)))))
+ (define (vec2-clamp! v xmin ymin xmax ymax)
+ (set-vec2-x! v (clamp (vec2-x v) xmin xmax))
+ (set-vec2-y! v (clamp (vec2-y v) ymin ymax)))
+
+ (define (make-rect x y w h)
+ (let ((r (make-bytevector (* 8 4))))
+ (f64-set! r 0 x)
+ (f64-set! r 8 y)
+ (f64-set! r 16 w)
+ (f64-set! r 24 h)
+ r))
+ (define (rect-x r)
+ (f64-ref r 0))
+ (define (rect-y r)
+ (f64-ref r 8))
+ (define (rect-w r)
+ (f64-ref r 16))
+ (define (rect-h r)
+ (f64-ref r 24))
+
+ (define (within? x y rx ry rw rh)
+ (and (>= x rx)
+ (>= y ry)
+ (< x (+ rx rw))
+ (< y (+ ry rh))))
+ (define (rect-within? ax ay aw ah bx by bw bh)
+ (let ((ax* (+ ax aw))
+ (ay* (+ ay ah)))
+ (or (within? ax ay bx by bw bh)
+ (within? ax* ay bx by bw bh)
+ (within? ax* ay* bx by bw bh)
+ (within? ax ay* bx by bw bh)))))