diff options
| -rw-r--r-- | include/math/vec2.h | 117 | ||||
| -rw-r--r-- | include/math/vec3.h | 11 | ||||
| -rw-r--r-- | include/math/vec4.h | 121 |
3 files changed, 239 insertions, 10 deletions
diff --git a/include/math/vec2.h b/include/math/vec2.h index 0a3f692..ebf0d78 100644 --- a/include/math/vec2.h +++ b/include/math/vec2.h | |||
| @@ -2,9 +2,126 @@ | |||
| 2 | 2 | ||
| 3 | #include "defs.h" | 3 | #include "defs.h" |
| 4 | 4 | ||
| 5 | #include <assert.h> | ||
| 6 | #include <stdbool.h> | ||
| 7 | |||
| 8 | /// A 2D vector. | ||
| 5 | typedef struct vec2 { | 9 | typedef struct vec2 { |
| 6 | R x, y; | 10 | R x, y; |
| 7 | } vec2; | 11 | } vec2; |
| 8 | 12 | ||
| 9 | /// Construct a vector from 2 coordinates. | 13 | /// Construct a vector from 2 coordinates. |
| 10 | static inline vec2 vec2_make(R x, R y) { return (vec2){x, y}; } | 14 | static inline vec2 vec2_make(R x, R y) { return (vec2){x, y}; } |
| 15 | |||
| 16 | /// Construct a vector from an array. | ||
| 17 | static inline vec2 vec2_from_array(const R xy[2]) { | ||
| 18 | return (vec2){xy[0], xy[1] }; | ||
| 19 | } | ||
| 20 | |||
| 21 | /// Construct a vector from a single scalar value. | ||
| 22 | /// x = y = z = val. | ||
| 23 | static inline vec2 vec2_from_scalar(R val) { return (vec2){val, val}; } | ||
| 24 | |||
| 25 | /// Return the vector's ith coordinate. | ||
| 26 | static inline R vec2_ith(vec2 v, int i) { | ||
| 27 | assert(i >= 0 && i < 2); | ||
| 28 | return ((const R*)&v)[i]; | ||
| 29 | } | ||
| 30 | |||
| 31 | /// Negate the given vector. | ||
| 32 | static inline vec2 vec2_neg(vec2 v) { return (vec2){-v.x, -v.y}; } | ||
| 33 | |||
| 34 | /// Add two vectors. | ||
| 35 | static inline vec2 vec2_add(vec2 a, vec2 b) { | ||
| 36 | return (vec2){a.x + b.x, a.y + b.y}; | ||
| 37 | } | ||
| 38 | |||
| 39 | /// Subtract two vectors. | ||
| 40 | static inline vec2 vec2_sub(vec2 a, vec2 b) { | ||
| 41 | return (vec2){a.x - b.x, a.y - b.y}; | ||
| 42 | } | ||
| 43 | |||
| 44 | /// Modulate two vectors (component-wise multiplication). | ||
| 45 | static inline vec2 vec2_mul(vec2 a, vec2 b) { | ||
| 46 | return (vec2){a.x * b.x, a.y * b.y}; | ||
| 47 | } | ||
| 48 | |||
| 49 | /// Divide two vectors component-wise. | ||
| 50 | static inline vec2 vec2_div(vec2 a, vec2 b) { | ||
| 51 | return (vec2){a.x / b.x, a.y / b.y}; | ||
| 52 | } | ||
| 53 | |||
| 54 | /// Scale a vector by a scalar value. | ||
| 55 | static inline vec2 vec2_scale(vec2 v, R s) { | ||
| 56 | return (vec2){v.x * s, v.y * s}; | ||
| 57 | } | ||
| 58 | |||
| 59 | /// Compare two vectors for equality. | ||
| 60 | static inline bool vec2_eq(vec2 a, vec2 b) { | ||
| 61 | return a.x == b.x && a.y == b.y; | ||
| 62 | } | ||
| 63 | |||
| 64 | /// Return the absolute value of the vector. | ||
| 65 | static inline vec2 vec2_abs(vec2 v) { | ||
| 66 | return (vec2){rabs(v.x), rabs(v.y)}; | ||
| 67 | } | ||
| 68 | |||
| 69 | /// Compare two vectors for inequality. | ||
| 70 | static inline bool vec2_ne(vec2 a, vec2 b) { return !(vec2_eq(a, b)); } | ||
| 71 | |||
| 72 | /// Return the vector's squared magnitude. | ||
| 73 | static inline R vec2_norm2(vec2 v) { return v.x * v.x + v.y * v.y; } | ||
| 74 | |||
| 75 | /// Return the vector's magnitude. | ||
| 76 | static inline R vec2_norm(vec2 v) { return sqrt(vec2_norm2(v)); } | ||
| 77 | |||
| 78 | /// Return the squared distance between two points. | ||
| 79 | static inline R vec2_dist2(vec2 a, vec2 b) { | ||
| 80 | const vec2 v = vec2_sub(b, a); | ||
| 81 | return vec2_norm2(v); | ||
| 82 | } | ||
| 83 | |||
| 84 | /// Return the distance between two points. | ||
| 85 | static inline R vec2_dist(vec2 a, vec2 b) { return sqrt(vec2_dist2(a, b)); } | ||
| 86 | |||
| 87 | /// Return the given vector divided by its magnitude. | ||
| 88 | static inline vec2 vec2_normalize(vec2 v) { | ||
| 89 | const R n = vec2_norm(v); | ||
| 90 | assert(n > 0); | ||
| 91 | return (vec2){v.x / n, v.y / n}; | ||
| 92 | } | ||
| 93 | |||
| 94 | /// Return the dot product of two vectors. | ||
| 95 | static inline R vec2_dot(vec2 a, vec2 b) { | ||
| 96 | return a.x * b.x + a.y * b.y; | ||
| 97 | } | ||
| 98 | |||
| 99 | /// Reflect the vector about the normal. | ||
| 100 | static inline vec2 vec2_reflect(vec2 v, vec2 n) { | ||
| 101 | // r = v - 2 * dot(v, n) * n | ||
| 102 | return vec2_sub(v, vec2_scale(n, 2 * vec2_dot(v, n))); | ||
| 103 | } | ||
| 104 | |||
| 105 | /// Refract the vector about the normal. | ||
| 106 | static inline vec2 vec2_refract(vec2 v, vec2 n, R e) { | ||
| 107 | // k = 1 - e^2(1 - dot(n,v) * dot(n,v)) | ||
| 108 | const R k = 1.0 - e * e * (1.0 - vec2_dot(n, v) * vec2_dot(n, v)); | ||
| 109 | assert(k >= 0); | ||
| 110 | // r = e*v - (e * dot(n,v) + sqrt(k)) * n | ||
| 111 | return vec2_sub(vec2_scale(v, e), | ||
| 112 | vec2_scale(n, e * vec2_dot(n, v) * sqrt(k))); | ||
| 113 | } | ||
| 114 | |||
| 115 | /// Elevate the vector to a power. | ||
| 116 | static inline vec2 vec2_pow(vec2 v, R p) { | ||
| 117 | return (vec2){pow(v.x, p), pow(v.y, p)}; | ||
| 118 | } | ||
| 119 | |||
| 120 | /// The (1, 0) vector. | ||
| 121 | static inline vec2 right2() { return (vec2){1.0, 0.0}; } | ||
| 122 | |||
| 123 | /// The (0, 1) vector. | ||
| 124 | static inline vec2 up2() { return (const vec2){0.0, 1.0}; } | ||
| 125 | |||
| 126 | /// The (0, 0) vector. | ||
| 127 | static inline vec2 zero2() { return (const vec2){0.0, 0.0}; } | ||
diff --git a/include/math/vec3.h b/include/math/vec3.h index 3c3b053..caa212e 100644 --- a/include/math/vec3.h +++ b/include/math/vec3.h | |||
| @@ -22,13 +22,6 @@ static inline vec3 vec3_from_array(const R xyz[3]) { | |||
| 22 | /// x = y = z = val. | 22 | /// x = y = z = val. |
| 23 | static inline vec3 vec3_from_scalar(R val) { return (vec3){val, val, val}; } | 23 | static inline vec3 vec3_from_scalar(R val) { return (vec3){val, val, val}; } |
| 24 | 24 | ||
| 25 | /// Normalize the vector. | ||
| 26 | static inline vec3 vec3_normalize(vec3 v) { | ||
| 27 | R n = sqrt(v.x * v.x + v.y * v.y + v.z * v.z); | ||
| 28 | assert(n > 0); | ||
| 29 | return (vec3){v.x / n, v.y / n, v.z / n}; | ||
| 30 | } | ||
| 31 | |||
| 32 | /// Return the vector's ith coordinate. | 25 | /// Return the vector's ith coordinate. |
| 33 | static inline R vec3_ith(vec3 v, int i) { | 26 | static inline R vec3_ith(vec3 v, int i) { |
| 34 | assert(i >= 0 && i < 3); | 27 | assert(i >= 0 && i < 3); |
| @@ -92,7 +85,7 @@ static inline R vec3_dist2(vec3 a, vec3 b) { | |||
| 92 | static inline R vec3_dist(vec3 a, vec3 b) { return sqrt(vec3_dist2(a, b)); } | 85 | static inline R vec3_dist(vec3 a, vec3 b) { return sqrt(vec3_dist2(a, b)); } |
| 93 | 86 | ||
| 94 | /// Return the given vector divided by its magnitude. | 87 | /// Return the given vector divided by its magnitude. |
| 95 | static inline vec3 normalize(vec3 v) { | 88 | static inline vec3 vec3_normalize(vec3 v) { |
| 96 | const R n = vec3_norm(v); | 89 | const R n = vec3_norm(v); |
| 97 | assert(n > 0); | 90 | assert(n > 0); |
| 98 | return (vec3){v.x / n, v.y / n, v.z / n}; | 91 | return (vec3){v.x / n, v.y / n, v.z / n}; |
| @@ -116,7 +109,7 @@ static inline vec3 vec3_reflect(vec3 v, vec3 n) { | |||
| 116 | } | 109 | } |
| 117 | 110 | ||
| 118 | /// Refract the vector about the normal. | 111 | /// Refract the vector about the normal. |
| 119 | static inline vec3 refract(vec3 v, vec3 n, R e) { | 112 | static inline vec3 vec3_refract(vec3 v, vec3 n, R e) { |
| 120 | // k = 1 - e^2(1 - dot(n,v) * dot(n,v)) | 113 | // k = 1 - e^2(1 - dot(n,v) * dot(n,v)) |
| 121 | const R k = 1.0 - e * e * (1.0 - vec3_dot(n, v) * vec3_dot(n, v)); | 114 | const R k = 1.0 - e * e * (1.0 - vec3_dot(n, v) * vec3_dot(n, v)); |
| 122 | assert(k >= 0); | 115 | assert(k >= 0); |
diff --git a/include/math/vec4.h b/include/math/vec4.h index 4ab843b..60da464 100644 --- a/include/math/vec4.h +++ b/include/math/vec4.h | |||
| @@ -2,8 +2,12 @@ | |||
| 2 | 2 | ||
| 3 | #include "defs.h" | 3 | #include "defs.h" |
| 4 | 4 | ||
| 5 | #include <assert.h> | ||
| 6 | #include <stdbool.h> | ||
| 7 | |||
| 8 | /// A 4D vector. | ||
| 5 | typedef struct vec4 { | 9 | typedef struct vec4 { |
| 6 | R x, y, w, z; | 10 | R x, y, z, w; |
| 7 | } vec4; | 11 | } vec4; |
| 8 | 12 | ||
| 9 | /// Construct a vector from 4 coordinates. | 13 | /// Construct a vector from 4 coordinates. |
| @@ -13,3 +17,118 @@ static inline vec4 vec4_make(R x, R y, R z, R w) { return (vec4){x, y, z, w}; } | |||
| 13 | static inline vec4 vec4_from_array(const R xyzw[4]) { | 17 | static inline vec4 vec4_from_array(const R xyzw[4]) { |
| 14 | return (vec4){xyzw[0], xyzw[1], xyzw[2], xyzw[3]}; | 18 | return (vec4){xyzw[0], xyzw[1], xyzw[2], xyzw[3]}; |
| 15 | } | 19 | } |
| 20 | |||
| 21 | /// Construct a vector from a single scalar value. | ||
| 22 | /// x = y = z = val. | ||
| 23 | static inline vec4 vec4_from_scalar(R val) { | ||
| 24 | return (vec4){val, val, val, val}; | ||
| 25 | } | ||
| 26 | |||
| 27 | /// Return the vector's ith coordinate. | ||
| 28 | static inline R vec4_ith(vec4 v, int i) { | ||
| 29 | assert(i >= 0 && i < 4); | ||
| 30 | return ((const R*)&v)[i]; | ||
| 31 | } | ||
| 32 | |||
| 33 | /// Negate the given vector. | ||
| 34 | static inline vec4 vec4_neg(vec4 v) { return (vec4){-v.x, -v.y, -v.z, -v.w}; } | ||
| 35 | |||
| 36 | /// Add two vectors. | ||
| 37 | static inline vec4 vec4_add(vec4 a, vec4 b) { | ||
| 38 | return (vec4){a.x + b.x, a.y + b.y, a.z + b.z, a.w + b.w}; | ||
| 39 | } | ||
| 40 | |||
| 41 | /// Subtract two vectors. | ||
| 42 | static inline vec4 vec4_sub(vec4 a, vec4 b) { | ||
| 43 | return (vec4){a.x - b.x, a.y - b.y, a.z - b.z, a.w - b.w}; | ||
| 44 | } | ||
| 45 | |||
| 46 | /// Modulate two vectors (component-wise multiplication). | ||
| 47 | static inline vec4 vec4_mul(vec4 a, vec4 b) { | ||
| 48 | return (vec4){a.x * b.x, a.y * b.y, a.z * b.z, a.w * b.w}; | ||
| 49 | } | ||
| 50 | |||
| 51 | /// Divide two vectors component-wise. | ||
| 52 | static inline vec4 vec4_div(vec4 a, vec4 b) { | ||
| 53 | return (vec4){a.x / b.x, a.y / b.y, a.z / b.z, a.w / b.w}; | ||
| 54 | } | ||
| 55 | |||
| 56 | /// Scale a vector by a scalar value. | ||
| 57 | static inline vec4 vec4_scale(vec4 v, R s) { | ||
| 58 | return (vec4){v.x * s, v.y * s, v.z * s, v.w * s}; | ||
| 59 | } | ||
| 60 | |||
| 61 | /// Compare two vectors for equality. | ||
| 62 | static inline bool vec4_eq(vec4 a, vec4 b) { | ||
| 63 | return a.x == b.x && a.y == b.y && a.z == b.z && a.w == b.w; | ||
| 64 | } | ||
| 65 | |||
| 66 | /// Return the absolute value of the vector. | ||
| 67 | static inline vec4 vec4_abs(vec4 v) { | ||
| 68 | return (vec4){rabs(v.x), rabs(v.y), rabs(v.z), rabs(v.w)}; | ||
| 69 | } | ||
| 70 | |||
| 71 | /// Compare two vectors for inequality. | ||
| 72 | static inline bool vec4_ne(vec4 a, vec4 b) { return !(vec4_eq(a, b)); } | ||
| 73 | |||
| 74 | /// Return the vector's squared magnitude. | ||
| 75 | static inline R vec4_norm2(vec4 v) { | ||
| 76 | return v.x * v.x + v.y * v.y + v.z * v.z + v.w * v.w; | ||
| 77 | } | ||
| 78 | |||
| 79 | /// Return the vector's magnitude. | ||
| 80 | static inline R vec4_norm(vec4 v) { return sqrt(vec4_norm2(v)); } | ||
| 81 | |||
| 82 | /// Return the squared distance between two points. | ||
| 83 | static inline R vec4_dist2(vec4 a, vec4 b) { | ||
| 84 | const vec4 v = vec4_sub(b, a); | ||
| 85 | return vec4_norm2(v); | ||
| 86 | } | ||
| 87 | |||
| 88 | /// Return the distance between two points. | ||
| 89 | static inline R vec4_dist(vec4 a, vec4 b) { return sqrt(vec4_dist2(a, b)); } | ||
| 90 | |||
| 91 | /// Return the given vector divided by its magnitude. | ||
| 92 | static inline vec4 vec4_normalize(vec4 v) { | ||
| 93 | const R n = vec4_norm(v); | ||
| 94 | assert(n > 0); | ||
| 95 | return (vec4){v.x / n, v.y / n, v.z / n, v.w / n}; | ||
| 96 | } | ||
| 97 | |||
| 98 | /// Return the dot product of two vectors. | ||
| 99 | static inline R vec4_dot(vec4 a, vec4 b) { | ||
| 100 | return a.x * b.x + a.y * b.y + a.z * b.z + a.w * b.w; | ||
| 101 | } | ||
| 102 | |||
| 103 | /// Reflect the vector about the normal. | ||
| 104 | static inline vec4 vec4_reflect(vec4 v, vec4 n) { | ||
| 105 | // r = v - 2 * dot(v, n) * n | ||
| 106 | return vec4_sub(v, vec4_scale(n, 2 * vec4_dot(v, n))); | ||
| 107 | } | ||
| 108 | |||
| 109 | /// Refract the vector about the normal. | ||
| 110 | static inline vec4 vec4_refract(vec4 v, vec4 n, R e) { | ||
| 111 | // k = 1 - e^2(1 - dot(n,v) * dot(n,v)) | ||
| 112 | const R k = 1.0 - e * e * (1.0 - vec4_dot(n, v) * vec4_dot(n, v)); | ||
| 113 | assert(k >= 0); | ||
| 114 | // r = e*v - (e * dot(n,v) + sqrt(k)) * n | ||
| 115 | return vec4_sub(vec4_scale(v, e), | ||
| 116 | vec4_scale(n, e * vec4_dot(n, v) * sqrt(k))); | ||
| 117 | } | ||
| 118 | |||
| 119 | /// Elevate the vector to a power. | ||
| 120 | static inline vec4 vec4_pow(vec4 v, R p) { | ||
| 121 | return (vec4){pow(v.x, p), pow(v.y, p), pow(v.z, p), pow(v.w, p)}; | ||
| 122 | } | ||
| 123 | |||
| 124 | /// The (1, 0, 0, 0) vector. | ||
| 125 | static inline vec4 right4() { return (vec4){1.0, 0.0, 0.0, 0.0}; } | ||
| 126 | |||
| 127 | /// The (0, 1, 0, 0) vector. | ||
| 128 | static inline vec4 up4() { return (const vec4){0.0, 1.0, 0.0, 0.0}; } | ||
| 129 | |||
| 130 | /// The (0, 0, -1, 0) vector. | ||
| 131 | static inline vec4 forward4() { return (const vec4){0.0, 0.0, -1.0, 0.0}; } | ||
| 132 | |||
| 133 | /// The (0, 0, 0, 0) vector. | ||
| 134 | static inline vec4 zero4() { return (const vec4){0.0, 0.0, 0.0, 0.0}; } | ||
