scop
a small 3D object loader
Loading...
Searching...
No Matches
Math.hpp
Go to the documentation of this file.
1/* ************************************************************************** */
2/* */
3/* ::: :::::::: */
4/* Math.hpp :+: :+: :+: */
5/* +:+ +:+ +:+ */
6/* By: rbourgea <rbourgea@student.42.fr> +#+ +:+ +#+ */
7/* +#+#+#+#+#+ +#+ */
8/* Created: 2024/01/14 17:55:33 by rbourgea #+# #+# */
9/* Updated: 2024/04/09 15:43:21 by rbourgea ### ########.fr */
10/* */
11/* ************************************************************************** */
12
13#ifndef MATH_HPP
14#define MATH_HPP
15
16#include <cmath>
17#include <iostream>
18
19class vec2 {
20public:
21 float x, y;
22
23 // Constructors
24 vec2() : x(0.0f), y(0.0f) {}
25 vec2(float _x, float _y) : x(_x), y(_y) {}
26
27 // Basic operations
28 vec2 operator+(const vec2& other) const {
29 return vec2(x + other.x, y + other.y);
30 }
31
32 vec2 operator-(const vec2& other) const {
33 return vec2(x - other.x, y - other.y);
34 }
35
36 vec2 operator*(float scalar) const {
37 return vec2(x * scalar, y * scalar);
38 }
39
40 vec2 operator/(float scalar) const {
41 float invScalar = 1.0f / scalar;
42 return vec2(x * invScalar, y * invScalar);
43 }
44
45 // Dot product
46 float dot(const vec2& other) const {
47 return x * other.x + y * other.y;
48 }
49
50 // Magnitude (length) of the vector
51 float length() const {
52 return std::sqrt(x * x + y * y);
53 }
54
55 // Normalize the vector
56 vec2 normalize() const {
57 float len = length();
58 if (len != 0.0f)
59 return *this / len;
60 else
61 return *this;
62 }
63};
64
65class vec3 {
66public:
67 float x, y, z;
68
69 // Constructors
70 vec3() : x(0.0f), y(0.0f), z(0.0f) {}
71 vec3(float _x, float _y, float _z) : x(_x), y(_y), z(_z) {}
72 vec3(float value) : x(value), y(value), z(value) {}
73
74 // Unary minus operator
75 vec3 operator-() const {
76 return vec3(-x, -y, -z);
77 }
78
79 // Basic operations
80 vec3 operator+(const vec3& other) const {
81 return vec3(x + other.x, y + other.y, z + other.z);
82 }
83
84 vec3 operator-(const vec3& other) const {
85 return vec3(x - other.x, y - other.y, z - other.z);
86 }
87
88 vec3 operator*(float scalar) const {
89 return vec3(x * scalar, y * scalar, z * scalar);
90 }
91
92 vec3 operator/(float scalar) const {
93 float invScalar = 1.0f / scalar;
94 return vec3(x * invScalar, y * invScalar, z * invScalar);
95 }
96
97 vec3& operator/=(float scalar) {
98 if (scalar != 0.0f) {
99 x /= scalar;
100 y /= scalar;
101 z /= scalar;
102 }
103 return *this;
104 }
105
106 friend vec3 operator*(float scalar, const vec3& v) {
107 return vec3(v.x * scalar, v.y * scalar, v.z * scalar);
108 }
109
110 vec3& operator+=(const vec3& other) {
111 x += other.x;
112 y += other.y;
113 z += other.z;
114 return *this;
115 }
116
117 vec3& operator-=(const vec3& other) {
118 x -= other.x;
119 y -= other.y;
120 z -= other.z;
121 return *this;
122 }
123
124 // Subscript operator
125 float& operator[](int index) {
126 if (index == 0)
127 return x;
128 else if (index == 1)
129 return y;
130 else if (index == 2)
131 return z;
132 else
133 throw std::out_of_range("Index out of range in vec3 subscript operator");
134 }
135
136 const float& operator[](int index) const {
137 if (index == 0)
138 return x;
139 else if (index == 1)
140 return y;
141 else if (index == 2)
142 return z;
143 else
144 throw std::out_of_range("Index out of range in vec3 subscript operator");
145 }
146
147 // Dot product
148 float dot(const vec3& other) const {
149 return x * other.x + y * other.y + z * other.z;
150 }
151
152 // Cross product
153 vec3 cross(const vec3& other) const {
154 return vec3(y * other.z - z * other.y, z * other.x - x * other.z, x * other.y - y * other.x);
155 }
156
157 // Magnitude (length) of the vector
158 float length() const {
159 return std::sqrt(x * x + y * y + z * z);
160 }
161
162 // Normalize the vector
163 vec3 normalize() const {
164 float len = length();
165 if (len != 0.0f)
166 return *this / len;
167 else
168 return *this;
169 }
170};
171
172class mat4 {
173public:
174 float elements[4][4];
175
176 // Constructors
178 for (int i = 0; i < 4; ++i)
179 for (int j = 0; j < 4; ++j)
180 elements[i][j] = (i == j) ? 1.0f : 0.0f;
181 }
182
183 // Constructor that initializes all elements to a single float value
184 mat4(float value) {
185 for (int i = 0; i < 4; ++i)
186 for (int j = 0; j < 4; ++j)
187 elements[i][j] = value;
188 }
189
190 // Copy constructor
191 mat4(const mat4& other) {
192 std::memcpy(elements, other.elements, sizeof(elements));
193 }
194
195 // Copy assignment operator
196 mat4& operator=(const mat4& other) {
197 if (this != &other) {
198 std::memcpy(elements, other.elements, sizeof(elements));
199 }
200 return *this;
201 }
202
203 // Access individual elements
204 float& operator()(int row, int col) {
205 return elements[row][col];
206 }
207
208 const float& operator()(int row, int col) const {
209 return elements[row][col];
210 }
211
212 // Matrix subtraction
213 mat4 operator-(const mat4& other) const {
214 mat4 result;
215 for (int i = 0; i < 4; ++i)
216 for (int j = 0; j < 4; ++j)
217 result(i, j) = elements[i][j] - other(i, j);
218 return result;
219 }
220
221 // Matrix multiplication
222 mat4 operator*(const mat4& other) const {
223 mat4 result(0);
224 for (int i = 0; i < 4; ++i)
225 for (int j = 0; j < 4; ++j)
226 for (int k = 0; k < 4; ++k)
227 result(i, j) += elements[i][k] * other(k, j);
228 return result;
229 }
230
231 // Subscript operator to allow access like mat[1][2]
232 float* operator[](int index) {
233 return elements[index];
234 }
235
236 const float* operator[](int index) const {
237 return elements[index];
238 }
239
240 // Output to stream for debugging
241 friend std::ostream& operator<<(std::ostream& os, const mat4& m) {
242 for (int i = 0; i < 4; ++i) {
243 for (int j = 0; j < 4; ++j) {
244 os << m(i, j) << ' ';
245 }
246 os << '\n';
247 }
248 return os;
249 }
250
251 // Matrix-vector multiplication
252 vec3 operator*(const vec3& v) const {
253 vec3 result(0);
254 for (int i = 0; i < 3; ++i)
255 for (int j = 0; j < 3; ++j)
256 result[i] += elements[i][j] * v[j];
257 return result;
258 }
259};
260
261class quat {
262public:
263 float x, y, z, w;
264
265 // Constructors
266 quat() : x(0.0f), y(0.0f), z(0.0f), w(1.0f) {}
267 quat(float _x, float _y, float _z, float _w) : x(_x), y(_y), z(_z), w(_w) {}
268
269 // Quaternion multiplication
270 quat operator*(const quat& other) const {
271 return quat(
272 w * other.x + x * other.w + y * other.z - z * other.y,
273 w * other.y + y * other.w + z * other.x - x * other.z,
274 w * other.z + z * other.w + x * other.y - y * other.x,
275 w * other.w - x * other.x - y * other.y - z * other.z
276 );
277 }
278
279 // Normalize the quaternion
280 quat normalize() const {
281 float len = std::sqrt(x * x + y * y + z * z + w * w);
282 if (len != 0.0f)
283 return quat(x / len, y / len, z / len, w / len);
284 else
285 return *this;
286 }
287
288 // Convert quaternion to a 4x4 matrix (rotation matrix)
289 mat4 toMat4() const {
290 // const float xx = x * x;
291 const float xy = x * y;
292 const float xz = x * z;
293 const float xw = x * w;
294
295 const float yy = y * y;
296 const float yz = y * z;
297 const float yw = y * w;
298
299 const float zz = z * z;
300 const float zw = z * w;
301
302 const float ww = w * w;
303
304 mat4 result;
305
306 result[0][0] = 1 - 2 * (zz + ww);
307 result[0][1] = 2 * (yz - xw);
308 result[0][2] = 2 * (yw + xz);
309
310 result[1][0] = 2 * (yz + xw);
311 result[1][1] = 1 - 2 * (yy + ww);
312 result[1][2] = 2 * (zw - xy);
313
314 result[2][0] = 2 * (yw - xz);
315 result[2][1] = 2 * (zw + xy);
316 result[2][2] = 1 - 2 * (yy + zz);
317
318 return result;
319 }
320};
321
322class math {
323public:
324 static vec3 min(const vec3& a, const vec3& b) {
325 return vec3(std::min(a.x, b.x), std::min(a.y, b.y), std::min(a.z, b.z));
326 }
327
328 static vec3 max(const vec3& a, const vec3& b) {
329 return vec3(std::max(a.x, b.x), std::max(a.y, b.y), std::max(a.z, b.z));
330 }
331
332 static float length(vec3 v) {
333 return sqrt(v.x * v.x + v.y * v.y + v.z * v.z);
334 }
335
336 static vec3 normalize(const vec3& v) {
337 vec3 result = v;
338 result.normalize();
339 return result;
340 }
341
342 static float lerp(float a, float b, float t) {
343 return a + t * (b - a);
344 }
345
346 static vec3 lerp(const vec3& a, const vec3& b, float t) {
347 return a + t * (b - a);
348 }
349
350 static float radians(float degrees) {
351 return degrees * 0.0174533f;
352 }
353
354 static float degrees(float radians) {
355 return radians * 57.2958f; // 180/π
356 }
357
358 static float clamp(float x, float minVal, float maxVal) {
359 if (x < minVal) {
360 return minVal;
361 } else if (x > maxVal) {
362 return maxVal;
363 } else {
364 return x;
365 }
366 }
367
368 static mat4 translate(const mat4& matrix, const vec3& translation) {
369 mat4 result = matrix;
370
371 for (int i = 0; i < 3; ++i) {
372 result(3, i) += translation[i];
373 }
374
375 return result;
376 }
377
378 static mat4 rotate(float angle, const vec3& axis) {
379 float c = cos(angle);
380 float s = sin(angle);
381 float t = 1.0f - c;
382
383 float x = axis.x;
384 float y = axis.y;
385 float z = axis.z;
386
387 mat4 rotationMatrix;
388
389 rotationMatrix(0, 0) = t * x * x + c;
390 rotationMatrix(0, 1) = t * x * y + s * z;
391 rotationMatrix(0, 2) = t * x * z - s * y;
392
393 rotationMatrix(1, 0) = t * x * y - s * z;
394 rotationMatrix(1, 1) = t * y * y + c;
395 rotationMatrix(1, 2) = t * y * z + s * x;
396
397 rotationMatrix(2, 0) = t * x * z + s * y;
398 rotationMatrix(2, 1) = t * y * z - s * x;
399 rotationMatrix(2, 2) = t * z * z + c;
400
401 return rotationMatrix;
402 }
403
404 static mat4 lookAt(const vec3& eye, const vec3& center, const vec3& up)
405 {
406 vec3 f = (center - eye).normalize();
407 vec3 u = up.normalize();
408 vec3 s = f.cross(u).normalize();
409 u = s.cross(f);
410
411 mat4 Result;
412
413 Result[0][0] = s.x;
414 Result[1][0] = s.y;
415 Result[2][0] = s.z;
416 Result[0][1] = u.x;
417 Result[1][1] = u.y;
418 Result[2][1] = u.z;
419 Result[0][2] = -f.x;
420 Result[1][2] = -f.y;
421 Result[2][2] = -f.z;
422 Result[3][0] = -s.dot(eye);
423 Result[3][1] = -u.dot(eye);
424 Result[3][2] = f.dot(eye);
425
426 return Result;
427 }
428
429 static mat4 perspective(float fov, float aspectRatio, float near, float far) {
430 float tanHalfFov = tan(fov * 0.5f);
431
432 mat4 projMatrix;
433
434 projMatrix(0, 0) = 1.0f / (aspectRatio * tanHalfFov);
435 projMatrix(1, 1) = 1.0f / tanHalfFov;
436 projMatrix(2, 2) = -(far + near) / (far - near);
437 projMatrix(2, 3) = -1.0f;
438 projMatrix(3, 2) = -(2.0f * far * near) / (far - near);
439
440#ifdef MATH_FORCE_DEPTH_ZERO_TO_ONE
441 // Adjust projection matrix for [0, 1] depth range
442 projMatrix(2, 2) = -2.0f / (far - near);
443 projMatrix(2, 3) = -(far + near) / (far - near);
444#endif
445
446 return projMatrix;
447 }
448
449 static vec3 cross(const vec3& a, const vec3& b) {
450 return vec3(a.y * b.z - a.z * b.y, a.z * b.x - a.x * b.z, a.x * b.y - a.y * b.x);
451 }
452
453 static quat angleAxis(float angle, const vec3& axis) {
454 float halfAngle = angle * 0.5f;
455 float sinHalf = std::sin(halfAngle);
456 return quat(std::cos(halfAngle), axis.x * sinHalf, axis.y * sinHalf, axis.z * sinHalf).normalize();
457 }
458
459 static mat4 toMat4(const quat& q) {
460 return q.toMat4();
461 }
462};
463
464#endif
Definition Math.hpp:172
mat4(float value)
Definition Math.hpp:184
mat4 & operator=(const mat4 &other)
Definition Math.hpp:196
friend std::ostream & operator<<(std::ostream &os, const mat4 &m)
Definition Math.hpp:241
float * operator[](int index)
Definition Math.hpp:232
vec3 operator*(const vec3 &v) const
Definition Math.hpp:252
float & operator()(int row, int col)
Definition Math.hpp:204
mat4 operator-(const mat4 &other) const
Definition Math.hpp:213
float elements[4][4]
Definition Math.hpp:174
const float * operator[](int index) const
Definition Math.hpp:236
const float & operator()(int row, int col) const
Definition Math.hpp:208
mat4 operator*(const mat4 &other) const
Definition Math.hpp:222
mat4()
Definition Math.hpp:177
mat4(const mat4 &other)
Definition Math.hpp:191
Definition Math.hpp:322
static mat4 rotate(float angle, const vec3 &axis)
Definition Math.hpp:378
static float length(vec3 v)
Definition Math.hpp:332
static mat4 translate(const mat4 &matrix, const vec3 &translation)
Definition Math.hpp:368
static vec3 max(const vec3 &a, const vec3 &b)
Definition Math.hpp:328
static vec3 normalize(const vec3 &v)
Definition Math.hpp:336
static float degrees(float radians)
Definition Math.hpp:354
static mat4 lookAt(const vec3 &eye, const vec3 &center, const vec3 &up)
Definition Math.hpp:404
static float lerp(float a, float b, float t)
Definition Math.hpp:342
static float radians(float degrees)
Definition Math.hpp:350
static quat angleAxis(float angle, const vec3 &axis)
Definition Math.hpp:453
static vec3 min(const vec3 &a, const vec3 &b)
Definition Math.hpp:324
static mat4 toMat4(const quat &q)
Definition Math.hpp:459
static vec3 lerp(const vec3 &a, const vec3 &b, float t)
Definition Math.hpp:346
static mat4 perspective(float fov, float aspectRatio, float near, float far)
Definition Math.hpp:429
static float clamp(float x, float minVal, float maxVal)
Definition Math.hpp:358
static vec3 cross(const vec3 &a, const vec3 &b)
Definition Math.hpp:449
Definition Math.hpp:261
quat(float _x, float _y, float _z, float _w)
Definition Math.hpp:267
float w
Definition Math.hpp:263
float z
Definition Math.hpp:263
quat()
Definition Math.hpp:266
float x
Definition Math.hpp:263
quat normalize() const
Definition Math.hpp:280
float y
Definition Math.hpp:263
quat operator*(const quat &other) const
Definition Math.hpp:270
mat4 toMat4() const
Definition Math.hpp:289
Definition Math.hpp:19
float x
Definition Math.hpp:21
vec2 operator+(const vec2 &other) const
Definition Math.hpp:28
vec2 operator*(float scalar) const
Definition Math.hpp:36
vec2(float _x, float _y)
Definition Math.hpp:25
float y
Definition Math.hpp:21
vec2 operator-(const vec2 &other) const
Definition Math.hpp:32
vec2 operator/(float scalar) const
Definition Math.hpp:40
vec2 normalize() const
Definition Math.hpp:56
float dot(const vec2 &other) const
Definition Math.hpp:46
float length() const
Definition Math.hpp:51
vec2()
Definition Math.hpp:24
Definition Math.hpp:65
vec3(float value)
Definition Math.hpp:72
vec3 & operator/=(float scalar)
Definition Math.hpp:97
vec3 operator+(const vec3 &other) const
Definition Math.hpp:80
vec3(float _x, float _y, float _z)
Definition Math.hpp:71
vec3 operator/(float scalar) const
Definition Math.hpp:92
float dot(const vec3 &other) const
Definition Math.hpp:148
float x
Definition Math.hpp:67
vec3 cross(const vec3 &other) const
Definition Math.hpp:153
float & operator[](int index)
Definition Math.hpp:125
vec3 & operator+=(const vec3 &other)
Definition Math.hpp:110
float y
Definition Math.hpp:67
vec3 operator-() const
Definition Math.hpp:75
vec3 operator*(float scalar) const
Definition Math.hpp:88
vec3 normalize() const
Definition Math.hpp:163
float z
Definition Math.hpp:67
vec3 & operator-=(const vec3 &other)
Definition Math.hpp:117
const float & operator[](int index) const
Definition Math.hpp:136
float length() const
Definition Math.hpp:158
friend vec3 operator*(float scalar, const vec3 &v)
Definition Math.hpp:106
vec3 operator-(const vec3 &other) const
Definition Math.hpp:84
vec3()
Definition Math.hpp:70