Add some helpers for math turns and mat2s

master
 `@ -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)` ``` ```