Browse Source

Add some helpers for math turns and mat2s

master
Macoy Madson 3 weeks ago
parent
commit
8197da7931
  1. 86
      src/Math.cake

86
src/Math.cake

@ -47,6 +47,28 @@
(defun radians-to-degrees (angle-radians float &return float)
(return (/ (* angle-radians 180.f) g-pi)))
;; See https://www.computerenhance.com/p/turns-are-better-than-radians
(defun turns-to-radians (num-turns float &return float)
(return (* num-turns 2.f g-pi)))
(defun radians-to-turns (radians float &return float)
(return (/ radians 2.f g-pi)))
(defun turns-to-degrees (turns float &return float)
(return (* turns 360.f)))
(defun degrees-to-turns (degrees float &return float)
(return (/ degrees 360.f)))
;; Normalize turn to a range of 0.f to +1.f
(defun normalize-turns (num-turns float &return float)
(var normalized-turns float num-turns)
;; Remove redundant turns
(set normalized-turns (- normalized-turns (truncf normalized-turns)))
(when (< normalized-turns 0.f)
(set normalized-turns (+ 1.f normalized-turns)))
(return normalized-turns))
;;
;; Vectors
;;
@ -120,17 +142,49 @@
(< (vec-x point-to-test) (vec-x bottom-right))
(< (vec-y point-to-test) (vec-y bottom-right)))))
(defun vec2-equals-tolerance (vec-a vec2 vec-b vec2 tolerance float
&return bool)
(var difference vec2 (vec2-subtract vec-a vec-b))
;; TODO This doesn't quite solve the nan angles issue
(when (and (< (fabs (field difference X)) tolerance)
(< (fabs (field difference Y)) tolerance))
(return true))
(return false))
;; Turns will be signed, i.e. -0.25 instead of 0.75. Call normalize-turns if you want the latter
(defun get-angle-turns-between-vec2 (vec-a vec2 vec-b vec2 &return float)
(var c-minimum-vector-difference-for-angles (const float) 0.01f)
(when (vec2-equals-tolerance vec-a vec-b c-minimum-vector-difference-for-angles)
(return 0.f))
(var vec-a-normalized vec2 (vec2-normalize vec-a))
(var vec-b-normalized vec2 (vec2-normalize vec-b))
(var angle float
(acosf (vec2-dot
vec-a-normalized
vec-b-normalized)))
;; We need to find the perpendicular vector to know which way we need to rotate
(var perpendicular vec2 vec-a-normalized)
;; In 2D we can find the perpendicular vector by swapping the axes and negating one
(var temp float (field perpendicular X))
(set (field perpendicular X) (field perpendicular Y))
(set (field perpendicular Y) (negate temp))
(var sign float (vec2-dot vec-b-normalized perpendicular))
(set angle (radians-to-turns angle))
(when (> sign 0.f)
(set angle (negate angle)))
(return angle))
;; Expand vector to each of its components
;; TODO: Change to any, prevent multiple eval?
(defmacro vec-xy (vec symbol)
;; TODO: Prevent multiple eval?
(defmacro vec-xy (vec any)
(tokenize-push output
(field (token-splice vec) X)
(field (token-splice vec) Y))
(return true))
;; Expand vector to each of its components
;; TODO: Change to any, prevent multiple eval?
(defmacro vec-xyz (vec symbol)
;; TODO: Prevent multiple eval?
(defmacro vec-xyz (vec any)
(tokenize-push output
(field (token-splice vec) X)
(field (token-splice vec) Y)
@ -138,8 +192,8 @@
(return true))
;; Expand vector to each of its components
;; TODO: Change to any, prevent multiple eval?
(defmacro vec-xyzw (vec symbol)
;; TODO: Prevent multiple eval?
(defmacro vec-xyzw (vec any)
(tokenize-push output
(field (token-splice vec) X)
(field (token-splice vec) Y)
@ -187,6 +241,26 @@
(tokenize-push output (mat4-diagonal 1.f))
(return true))
(defstruct mat2
elements (array 2 (array 2 float)))
(defun mat2-rotate-turns (num-turns float &return mat2)
(var angle float (turns-to-radians num-turns))
(var rotation-matrix mat2 (array
(array (array (cosf angle) (negate (sinf angle)))
(array (sinf angle) (cosf angle)))))
(return rotation-matrix))
(defun mat2-transform-vec2 (mat mat2 vector vec2 &return vec2)
(var result vec2)
(set (field result X)
(+ (* (at 0 0 (field mat elements)) (field vector X))
(* (at 0 1 (field mat elements)) (field vector Y))))
(set (field result Y)
(+ (* (at 1 0 (field mat elements)) (field vector X))
(* (at 1 1 (field mat elements)) (field vector Y))))
(return result))
;; Must multiply in reverse order of desired transformation (first arg = last transform operation)
(def-c-function-alias mat4-multiply HMM_MultiplyMat4) ;; (left mat4 right mat4 &return mat4)

Loading…
Cancel
Save