aboutsummaryrefslogtreecommitdiff
path: root/include/math/vec3.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/math/vec3.h')
-rw-r--r--include/math/vec3.h44
1 files changed, 40 insertions, 4 deletions
diff --git a/include/math/vec3.h b/include/math/vec3.h
index 641c02f..d8e1248 100644
--- a/include/math/vec3.h
+++ b/include/math/vec3.h
@@ -51,14 +51,14 @@ static inline vec3 vec3_div(vec3 a, vec3 b) {
51 return (vec3){a.x / b.x, a.y / b.y, a.z / b.z}; 51 return (vec3){a.x / b.x, a.y / b.y, a.z / b.z};
52} 52}
53 53
54/// Scale a vector by a scalar value. 54/// Scale the vector.
55static inline vec3 vec3_scale(vec3 v, R s) { 55static inline vec3 vec3_scale(vec3 v, R s) {
56 return (vec3){v.x * s, v.y * s, v.z * s}; 56 return (vec3){v.x * s, v.y * s, v.z * s};
57} 57}
58 58
59/// Compare two vectors for equality. 59/// Compare two vectors for equality.
60static inline bool vec3_eq(vec3 a, vec3 b) { 60static inline bool vec3_eq(vec3 a, vec3 b, R eps) {
61 return a.x == b.x && a.y == b.y && a.z == b.z; 61 return R_eq(a.x, b.x, eps) && R_eq(a.y, b.y, eps) && R_eq(a.z, b.z, eps);
62} 62}
63 63
64/// Return the absolute value of the vector. 64/// Return the absolute value of the vector.
@@ -67,7 +67,9 @@ static inline vec3 vec3_abs(vec3 v) {
67} 67}
68 68
69/// Compare two vectors for inequality. 69/// Compare two vectors for inequality.
70static inline bool vec3_ne(vec3 a, vec3 b) { return !(vec3_eq(a, b)); } 70static inline bool vec3_ne(vec3 a, vec3 b, R eps) {
71 return !(vec3_eq(a, b, eps));
72}
71 73
72/// Return the vector's squared magnitude. 74/// Return the vector's squared magnitude.
73static inline R vec3_norm2(vec3 v) { return v.x * v.x + v.y * v.y + v.z * v.z; } 75static inline R vec3_norm2(vec3 v) { return v.x * v.x + v.y * v.y + v.z * v.z; }
@@ -123,6 +125,40 @@ static inline vec3 vec3_pow(vec3 v, R p) {
123 return (vec3){pow(v.x, p), pow(v.y, p), pow(v.z, p)}; 125 return (vec3){pow(v.x, p), pow(v.y, p), pow(v.z, p)};
124} 126}
125 127
128/// Linearly interpolate two vectors.
129static inline vec3 vec3_lerp(vec3 a, vec3 b, R t) {
130 return (vec3){
131 .x = a.x + t * (b.x - a.x),
132 .y = a.y + t * (b.y - a.y),
133 .z = a.z + t * (b.z - a.z)};
134}
135
136/// Interpolate two unit vectors using spherical linear interpolation.
137///
138/// Note: You might want to normalize the result.
139static inline vec3 vec3_slerp(vec3 a, vec3 b, R t) {
140 assert(0.0 <= t);
141 assert(t <= 1.0);
142 const R eps = 1e-5;
143 (void)eps;
144 assert(R_eq(vec3_norm2(a), 1.0, eps));
145 assert(R_eq(vec3_norm2(b), 1.0, eps));
146 R dot = vec3_dot(a, b);
147 // For numerical stability, perform linear interpolation when the two vectors
148 // are close to each other.
149 R ta, tb;
150 if (1.0 - dot > 1e-6) {
151 const R theta = acos(dot);
152 const R sin_theta = sqrt(1.0 - dot * dot);
153 ta = sin((1.0 - t) * theta) / sin_theta;
154 tb = sin(t * theta) / sin_theta;
155 } else { // Linear interpolation.
156 ta = 1.0 - t;
157 tb = t;
158 }
159 return vec3_add(vec3_scale(a, ta), vec3_scale(b, tb));
160}
161
126/// The (1, 0, 0) vector. 162/// The (1, 0, 0) vector.
127static inline vec3 right3() { return (vec3){1.0, 0.0, 0.0}; } 163static inline vec3 right3() { return (vec3){1.0, 0.0, 0.0}; }
128 164