More vector operations, add/sub/scale
This commit is contained in:
parent
329692f2b3
commit
bd926b510b
1 changed files with 200 additions and 11 deletions
211
linalg/main.c
211
linalg/main.c
|
@ -3,6 +3,12 @@
|
|||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
|
||||
/*
|
||||
* Simple linear algebra mat/vec operations
|
||||
*
|
||||
* TODO: Normalizations
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief A 2×2 matrix stored in row-major order.
|
||||
*
|
||||
|
@ -58,6 +64,68 @@ inline float vec3_dot(const Vec3 *a, const Vec3 *b);
|
|||
*/
|
||||
Vec3 vec3_cross(const Vec3 *a, const Vec3 *b);
|
||||
|
||||
/**
|
||||
* @brief Subtracts one 3D vector from another.
|
||||
*
|
||||
* @param a Pointer to the minuend vector.
|
||||
* @param b Pointer to the subtrahend vector.
|
||||
* @return The resulting vector (a - b).
|
||||
*/
|
||||
Vec3 vec3_sub(const Vec3 *a, const Vec3 *b);
|
||||
|
||||
/**
|
||||
* @brief Adds two 3D vectors.
|
||||
*
|
||||
* @param a Pointer to the first vector.
|
||||
* @param b Pointer to the second vector.
|
||||
* @return The resulting vector (a + b).
|
||||
*/
|
||||
Vec3 vec3_add(const Vec3 *a, const Vec3 *b);
|
||||
|
||||
/**
|
||||
* @brief Scales a 3D vector by a scalar value.
|
||||
*
|
||||
* @param a Pointer to the vector to scale.
|
||||
* @param scalar The scalar value to multiply with the vector.
|
||||
* @return The scaled vector (a * scalar).
|
||||
*/
|
||||
Vec3 vec3_scale(const Vec3 *a, const float scalar);
|
||||
|
||||
/**
|
||||
* @brief Computes the dot product of two 2D vectors.
|
||||
*
|
||||
* @param a Pointer to the first vector.
|
||||
* @param b Pointer to the second vector.
|
||||
* @return The dot product (a • b).
|
||||
*/
|
||||
inline float vec2_dot(const Vec2 *a, const Vec2 *b);
|
||||
|
||||
/**
|
||||
* @brief Subtracts one 2D vector from another.
|
||||
*
|
||||
* @param a Pointer to the minuend vector.
|
||||
* @param b Pointer to the subtrahend vector.
|
||||
* @return The resulting vector (a - b).
|
||||
*/
|
||||
Vec2 vec2_sub(const Vec2 *a, const Vec2 *b);
|
||||
|
||||
/**
|
||||
* @brief Adds two 2D vectors.
|
||||
*
|
||||
* @param a Pointer to the first vector.
|
||||
* @param b Pointer to the second vector.
|
||||
* @return The resulting vector (a + b).
|
||||
*/
|
||||
Vec2 vec2_add(const Vec2 *a, const Vec2 *b);
|
||||
|
||||
/**
|
||||
* @brief Scales a 2D vector by a scalar value.
|
||||
*
|
||||
* @param a Pointer to the vector to scale.
|
||||
* @param scalar The scalar value to multiply with the vector.
|
||||
* @return The scaled vector (a * scalar).
|
||||
*/
|
||||
Vec2 vec2_scale(const Vec2 *a, const float scalar);
|
||||
/**
|
||||
* @brief Computes the determinant of a 2×2 matrix.
|
||||
*
|
||||
|
@ -112,6 +180,26 @@ bool mat2_approx_eq(const Mat2 *a, const Mat2 *b, float epsilon);
|
|||
*/
|
||||
bool mat3_approx_eq(const Mat3 *a, const Mat3 *b, float epsilon);
|
||||
|
||||
/**
|
||||
* @brief Checks if two 3×3 vectors are approximately equal.
|
||||
*
|
||||
* @param a Pointer to the first vector.
|
||||
* @param b Pointer to the second vector.
|
||||
* @param epsilon Tolerance for comparison.
|
||||
* @return true if all elements are approximately equal within epsilon.
|
||||
*/
|
||||
bool vec3_approx_eq(const Vec3 *a, const Vec3 *b, float epsilon);
|
||||
|
||||
/**
|
||||
* @brief Checks if two 2x2 vectors are approximately equal.
|
||||
*
|
||||
* @param a Pointer to the first vector.
|
||||
* @param b Pointer to the second vector.
|
||||
* @param epsilon Tolerance for comparison.
|
||||
* @return true if all elements are approximately equal within epsilon.
|
||||
*/
|
||||
bool vec2_approx_eq(const Vec2 *a, const Vec2 *b, float epsilon);
|
||||
|
||||
#define MAT2_AT(m, row, col) ((m)->arr[(col) * 2 + (row)])
|
||||
#define MAT3_AT(m, row, col) ((m)->arr[(col) * 3 + (row)])
|
||||
|
||||
|
@ -134,14 +222,75 @@ float mat3_det(const Mat3 *m) {
|
|||
m02 * (m10 * m21 - m11 * m20);
|
||||
}
|
||||
|
||||
inline float vec3_dot(const struct Vec3 *a, const struct Vec3 *b) {
|
||||
inline float vec3_dot(const Vec3 *a, const Vec3 *b) {
|
||||
return a->x * b->x + a->y * b->y + a->z * b->z;
|
||||
}
|
||||
|
||||
struct Vec3 vec3_cross(const struct Vec3 *a, const struct Vec3 *b) {
|
||||
struct Vec3 res = {.x = a->y * b->z - a->z * b->y,
|
||||
.y = a->x * b->z - a->z * b->x,
|
||||
.z = a->x * b->y - a->y * b->x};
|
||||
Vec3 vec3_cross(const Vec3 *a, const Vec3 *b) {
|
||||
Vec3 res = {.x = a->y * b->z - a->z * b->y,
|
||||
.y = a->x * b->z - a->z * b->x,
|
||||
.z = a->x * b->y - a->y * b->x};
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
Vec3 vec3_sub(const Vec3 *a, const Vec3 *b) {
|
||||
Vec3 res = {
|
||||
.x = a->x - b->x,
|
||||
.y = a->y - b->y,
|
||||
.z = a->z - b->z,
|
||||
};
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
Vec3 vec3_add(const Vec3 *a, const Vec3 *b) {
|
||||
Vec3 res = {
|
||||
.x = a->x + b->x,
|
||||
.y = a->y + b->y,
|
||||
.z = a->z + b->z,
|
||||
};
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
Vec3 vec3_scale(const Vec3 *a, const float scalar) {
|
||||
Vec3 res = {
|
||||
.x = a->x * scalar,
|
||||
.y = a->y * scalar,
|
||||
.z = a->z * scalar,
|
||||
};
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
float vec2_dot(const Vec2 *a, const Vec2 *b) {
|
||||
return a->x * b->x + a->y * b->y;
|
||||
}
|
||||
|
||||
Vec2 vec2_sub(const Vec2 *a, const Vec2 *b) {
|
||||
Vec2 res = {
|
||||
.x = a->x - b->x,
|
||||
.y = a->y - b->y,
|
||||
};
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
Vec2 vec2_add(const Vec2 *a, const Vec2 *b) {
|
||||
Vec2 res = {
|
||||
.x = a->x + b->x,
|
||||
.y = a->y + b->y,
|
||||
};
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
Vec2 vec2_scale(const Vec2 *a, const float scalar) {
|
||||
Vec2 res = {
|
||||
.x = a->x * scalar,
|
||||
.y = a->y * scalar,
|
||||
};
|
||||
|
||||
return res;
|
||||
}
|
||||
|
@ -203,6 +352,15 @@ bool mat3_approx_eq(const Mat3 *a, const Mat3 *b, float epsilon) {
|
|||
return true;
|
||||
}
|
||||
|
||||
bool vec2_approx_eq(const Vec2 *a, const Vec2 *b, float epsilon) {
|
||||
return (fabsf(a->x - b->x) <= epsilon) && (fabsf(a->y - b->y) <= epsilon);
|
||||
}
|
||||
|
||||
bool vec3_approx_eq(const Vec3 *a, const Vec3 *b, float epsilon) {
|
||||
return (fabsf(a->x - b->x) <= epsilon) && (fabsf(a->y - b->y) <= epsilon) &&
|
||||
(fabsf(a->z - b->z) <= epsilon);
|
||||
}
|
||||
|
||||
/* Implem end */
|
||||
|
||||
int main(void) {
|
||||
|
@ -222,15 +380,46 @@ int main(void) {
|
|||
printf("Determinant: %f\n", d);
|
||||
}
|
||||
{
|
||||
struct Vec3 a = {10, 10, 10};
|
||||
struct Vec3 b = {5, 5, 5};
|
||||
struct Vec3 c = vec3_cross(&a, &b);
|
||||
/* Vector tests for addition, subtraction and multiplication (scale) */
|
||||
|
||||
/* Vec3 */
|
||||
|
||||
Vec3 a3 = {2, 2, 2};
|
||||
Vec3 b3 = {1, 1, 1};
|
||||
Vec3 c3_sub = vec3_sub(&a3, &b3);
|
||||
Vec3 c3_add = vec3_add(&a3, &b3);
|
||||
Vec3 m3 = vec3_scale(&a3, 1.5);
|
||||
|
||||
Vec3 v3_expected_add = {3, 3, 3};
|
||||
|
||||
assert(vec3_approx_eq(&c3_sub, &b3, 0.01));
|
||||
assert(vec3_approx_eq(&c3_add, &v3_expected_add, 0.01));
|
||||
assert(vec3_approx_eq(&m3, &v3_expected_add, 0.01));
|
||||
|
||||
/* Vec2 */
|
||||
|
||||
Vec2 a2 = {2, 2};
|
||||
Vec2 b2 = {1, 1};
|
||||
Vec2 c2_sub = vec2_sub(&a2, &b2);
|
||||
Vec2 c2_add = vec2_add(&a2, &b2);
|
||||
Vec2 m2 = vec2_scale(&a2, 1.5);
|
||||
|
||||
Vec2 v2_expected_add = {3, 3};
|
||||
|
||||
assert(vec2_approx_eq(&c2_sub, &b2, 0.01));
|
||||
assert(vec2_approx_eq(&c2_add, &v2_expected_add, 0.01));
|
||||
assert(vec2_approx_eq(&m2, &v2_expected_add, 0.01));
|
||||
}
|
||||
{
|
||||
Vec3 a = {10, 10, 10};
|
||||
Vec3 b = {5, 5, 5};
|
||||
Vec3 c = vec3_cross(&a, &b);
|
||||
printf("{ Vec3: %f, %f, %f }\n", c.x, c.y, c.z);
|
||||
}
|
||||
{
|
||||
struct Vec3 a = {0, 1, 0};
|
||||
struct Vec3 b = {0, 0, 1};
|
||||
struct Vec3 c = vec3_cross(&a, &b);
|
||||
Vec3 a = {0, 1, 0};
|
||||
Vec3 b = {0, 0, 1};
|
||||
Vec3 c = vec3_cross(&a, &b);
|
||||
printf("{ Vec3: %f, %f, %f }\n", c.x, c.y, c.z);
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue