Spatial Math Layer¶
A lightweight spatial-math module: modern type aliases (Rust/NumPy style), 2D/3D/4D vectors with anonymous-union component aliasing, fixed-size matrices, and quaternions. Everything is a plain value type — no allocation, no GC tracking, no free needed.
Type aliases¶
abs.h defines the modern fixed-width aliases used throughout this layer:
| Alias | C type | Alias | C type |
|---|---|---|---|
i8 / i16 / i32 / i64 |
int8_t / int16_t / int32_t / int64_t |
u8 / u16 / u32 / u64 |
uint8_t / uint16_t / uint32_t / uint64_t |
isize |
ptrdiff_t |
usize |
size_t |
f32 |
float |
f64 |
double |
b8 |
bool |
b32 |
uint32_t |
byte |
unsigned char |
Vectors¶
Anonymous-union vectors overlap their components, so v.x, v.u, and v.raw[0] all read the same memory. vec3 also exposes color aliases (r/g/b) and vec4 adds alpha (a).
| Type | Components | Aliases |
|---|---|---|
vec2 / vec2d / ivec2 |
x, y |
u, v (and raw[]) |
vec3 / vec3d / ivec3 |
x, y, z |
r, g, b |
vec4 / vec4d / ivec4 |
x, y, z, w |
r, g, b, a |
quat |
x, y, z (vector), w (scalar) |
raw[] |
Construct with the static inline helpers v2, v3, v4, iv2, iv3, iv4, and q4.
vec2 p = v2(1.0f, 2.0f);
vec3 c = v3(0.2f, 0.4f, 0.6f);
printf("%f %f %f\n", (double)c.r, (double)c.g, (double)c.b);
vec4 rgba = v4(1.0f, 0.5f, 0.25f, 0.1f);
printf("%f\n", (double)rgba.a); /* 0.10 */
vec2 operations¶
| Function | Description |
|---|---|
vec2 abs_v2_add(vec2 a, vec2 b) |
Component-wise addition. |
vec2 abs_v2_sub(vec2 a, vec2 b) |
Component-wise subtraction. |
vec2 abs_v2_scale(vec2 a, f32 s) |
Multiply by a scalar. |
f32 abs_v2_dot(vec2 a, vec2 b) |
Dot product. |
f32 abs_v2_cross(vec2 a, vec2 b) |
2D cross product (a.x*b.y - a.y*b.x). |
f32 abs_v2_len(vec2 v) |
Length (Euclidean norm). |
f32 abs_v2_dist(vec2 a, vec2 b) |
Distance between two points. |
vec2 abs_v2_norm(vec2 v) |
Unit vector (zero for the zero vector). |
vec2 abs_v2_lerp(vec2 a, vec2 b, f32 t) |
Linear interpolation. |
vec2 abs_v2_reflect(vec2 v, vec2 n) |
Reflect v about a unit normal n: v - 2*dot(v,n)*n. |
void abs_v2_print(vec2 v, const char *name) |
Print name = (x, y). |
vec3 operations¶
abs_v3_add, abs_v3_sub, abs_v3_scale, abs_v3_dot, abs_v3_cross, abs_v3_len, abs_v3_dist, abs_v3_norm, abs_v3_lerp, abs_v3_reflect, and abs_v3_print mirror the 2D set, with abs_v3_cross returning the proper 3D cross product.
vec4 operations¶
abs_v4_add, abs_v4_sub, abs_v4_scale, abs_v4_dot, abs_v4_len, abs_v4_dist, abs_v4_norm, abs_v4_lerp, and abs_v4_print.
Quaternions¶
| Function | Description |
|---|---|
quat abs_quat_ident(void) |
The identity quaternion (0, 0, 0, 1). |
quat abs_quat_mul(quat a, quat b) |
Hamilton product; composes rotation b (applied first), then a. |
quat abs_quat_norm(quat q) |
Unit quaternion (identity for a zero quaternion). |
quat abs_quat_from_axis_angle(f32 ax, f32 ay, f32 az, f32 angle) |
Rotation about an axis by angle radians. |
vec3 abs_quat_rotate_vec3(quat q, vec3 v) |
Rotate v by q (via v + 2w(r×v) + 2(r×(r×v))). |
void abs_quat_print(quat q, const char *name) |
Print name = (x, y, z, w). |
quat q = abs_quat_from_axis_angle(0, 0, 1, ABS_PI / 2);
vec3 p = abs_quat_rotate_vec3(q, v3(1, 0, 0));
/* p == (0, 1, 0): a 90-degree turn about +Z */
quat twice = abs_quat_mul(q, q); /* 180 degrees about +Z */
vec3 p2 = abs_quat_rotate_vec3(twice, v3(1, 0, 0));
/* p2 == (-1, 0, 0) */
mat4¶
Column-major 4×4 matrices, so m.m[col][row] addresses a column first and the columns are readable directly as vec4s via m.cols[i].
| Function | Description |
|---|---|
mat4 abs_mat4_identity(void) |
Identity matrix. |
mat4 abs_mat4_mul(mat4 a, mat4 b) |
Matrix product (a applied after b). |
vec4 abs_mat4_mul_vec4(mat4 m, vec4 v) |
Transform a point/homogeneous vector. |
mat4 abs_mat4_translate(f32 x, f32 y, f32 z) |
Translation matrix. |
mat4 abs_mat4_scale(f32 x, f32 y, f32 z) |
Scaling matrix. |
mat4 abs_mat4_rotate_x(f32 angle) |
Rotation about the X axis. |
mat4 abs_mat4_rotate_y(f32 angle) |
Rotation about the Y axis. |
mat4 abs_mat4_rotate_z(f32 angle) |
Rotation about the Z axis. |
mat4 abs_mat4_perspective(f32 fov_y, f32 aspect, f32 near, f32 far) |
OpenGL-style perspective projection. |
mat4 abs_mat4_look_at(vec3 eye, vec3 center, vec3 up) |
Right-handed view matrix. |
void abs_mat4_print(mat4 m, const char *name) |
Print the matrix row by row. |
mat4 model = abs_mat4_translate(10.0f, 0.0f, 5.0f);
model = abs_mat4_mul(model, abs_mat4_scale(2.0f, 2.0f, 2.0f));
model = abs_mat4_mul(model, abs_mat4_rotate_y(ABS_PI / 4.0f));
vec4 world = abs_mat4_mul_vec4(model, v4(1.0f, 1.0f, 1.0f, 1.0f));
/* world == (12.83, 2.00, 5.00, 1.00) */
mat4 view = abs_mat4_look_at(v3(0, 0, 5), v3(0, 0, 0), v3(0, 1, 0));
mat4 proj = abs_mat4_perspective((f32)(60 * ABS_PI / 180), 16.0f / 9.0f, 0.1f, 100.0f);
Example¶
See examples/geom_demo.c (build/examples/geom_demo), which prints the type aliases, bounces a 2D ball off the ground, computes a cross-product normal, rotates a point with a quaternion, builds a model matrix, and projects through a camera.
Back to README.
For the matrix types and operations this layer's mat4 complements, see Matrices, Statistics, and More.