commit 8045b97838d4c84051a7655f661662113abcfb5b Author: Alex Selimov Date: Tue Jul 21 16:09:33 2026 -0400 Initial version of Vec3 and Mat3 library diff --git a/vec3/src/vec3.zig b/vec3/src/vec3.zig new file mode 100644 index 0000000..f7f7342 --- /dev/null +++ b/vec3/src/vec3.zig @@ -0,0 +1,211 @@ +const std = @import("std"); + +pub fn Vec3(comptime T: type) type { + return struct { x: T, y: T, z: T }; +} + +pub fn vec3Add(comptime T: type, a: Vec3(T), b: Vec3(T)) Vec3(T) { + return .{ + .x = a.x + b.x, + .y = a.y + b.y, + .z = a.z + b.z, + }; +} + +pub fn vec3Sub(comptime T: type, a: Vec3(T), b: Vec3(T)) Vec3(T) { + return .{ + .x = a.x - b.x, + .y = a.y - b.y, + .z = a.z - b.z, + }; +} + +pub fn vec3Dot(comptime T: type, a: Vec3(T), b: Vec3(T)) T { + return a.x * b.x + a.y * b.y + a.z * b.z; +} + +pub fn vec3Cross(comptime T: type, a: Vec3(T), b: Vec3(T)) Vec3(T) { + const x = a.y * b.z - a.z * b.y; + const y = a.z * b.x - a.x * b.z; + const z = a.x * b.y - a.y * b.x; + return .{ .x = x, .y = y, .z = z }; +} + +pub fn Mat3(comptime T: type) type { + return struct { + row1: Vec3(T), + row2: Vec3(T), + row3: Vec3(T), + }; +} + +pub fn mat3Add(comptime T: type, a: Mat3(T), b: Mat3(T)) Mat3(T) { + return .{ + .row1 = vec3Add(T, a.row1, b.row1), + .row2 = vec3Add(T, a.row2, b.row2), + .row3 = vec3Add(T, a.row3, b.row3), + }; +} + +pub fn mat3Sub(comptime T: type, a: Mat3(T), b: Mat3(T)) Mat3(T) { + return .{ + .row1 = vec3Sub(T, a.row1, b.row1), + .row2 = vec3Sub(T, a.row2, b.row2), + .row3 = vec3Sub(T, a.row3, b.row3), + }; +} + +pub fn mat3Mul(comptime T: type, a: Mat3(T), b: Mat3(T)) Mat3(T) { + const c_row1: Vec3(T) = .{ + .x = a.row1.x * b.row1.x + a.row1.y * b.row2.x + a.row1.z * b.row3.x, + .y = a.row1.x * b.row1.y + a.row1.y * b.row2.y + a.row1.z * b.row3.y, + .z = a.row1.x * b.row1.z + a.row1.y * b.row2.z + a.row1.z * b.row3.z, + }; + + const c_row2: Vec3(T) = .{ + .x = a.row2.x * b.row1.x + a.row2.y * b.row2.x + a.row2.z * b.row3.x, + .y = a.row2.x * b.row1.y + a.row2.y * b.row2.y + a.row2.z * b.row3.y, + .z = a.row2.x * b.row1.z + a.row2.y * b.row2.z + a.row2.z * b.row3.z, + }; + + const c_row3: Vec3(T) = .{ + .x = a.row3.x * b.row1.x + a.row3.y * b.row2.x + a.row3.z * b.row3.x, + .y = a.row3.x * b.row1.y + a.row3.y * b.row2.y + a.row3.z * b.row3.y, + .z = a.row3.x * b.row1.z + a.row3.y * b.row2.z + a.row3.z * b.row3.z, + }; + + return .{ .row1 = c_row1, .row2 = c_row2, .row3 = c_row3 }; +} + +pub fn vec3MulMat3(comptime T: type, a: Vec3(T), b: Mat3(T)) Vec3(T) { + return .{ + .x = a.x * b.row1.x + a.y * b.row2.x + a.z * b.row3.x, + .y = a.x * b.row1.y + a.y * b.row2.y + a.z * b.row3.y, + .z = a.x * b.row1.z + a.y * b.row2.z + a.z * b.row3.z, + }; +} + +test "vec3Add adds properly" { + const a: Vec3(i8) = .{ .x = 1, .y = 2, .z = 3 }; + const b: Vec3(i8) = .{ .x = 3, .y = 1, .z = 0 }; + const c = vec3Add(i8, a, b); + + try std.testing.expect(c.x == 4); + try std.testing.expect(c.y == 3); + try std.testing.expect(c.z == 3); +} +test "vec3Sub subs properly" { + const a: Vec3(i8) = .{ .x = 1, .y = 2, .z = 3 }; + const b: Vec3(i8) = .{ .x = 3, .y = 1, .z = 0 }; + const c = vec3Sub(i8, a, b); + + try std.testing.expect(c.x == -2); + try std.testing.expect(c.y == 1); + try std.testing.expect(c.z == 3); +} +test "vec3Dot dots properly" { + const a: Vec3(i8) = .{ .x = 1, .y = 2, .z = 3 }; + const b: Vec3(i8) = .{ .x = 3, .y = 1, .z = 0 }; + try std.testing.expect(vec3Dot(i8, a, b) == 5); +} +test "vec3Cross crosses properly" { + const a: Vec3(i8) = .{ .x = 1, .y = 2, .z = 3 }; + const b: Vec3(i8) = .{ .x = 3, .y = 1, .z = 0 }; + + const c = vec3Cross(i8, a, b); + + try std.testing.expect(c.x == -3); + try std.testing.expect(c.y == 9); + try std.testing.expect(c.z == -5); +} + +test "Mat3 add works" { + const a: Mat3(i8) = .{ + .row1 = .{ .x = 1, .y = 2, .z = 3 }, + .row2 = .{ .x = 0, .y = 1, .z = 5 }, + .row3 = .{ .x = 0, .y = 0, .z = 9 }, + }; + const b: Mat3(i8) = .{ + .row1 = .{ .x = 0, .y = 1, .z = 0 }, + .row2 = .{ .x = 0, .y = 1, .z = 1 }, + .row3 = .{ .x = 0, .y = 0, .z = 1 }, + }; + + const c = mat3Add(i8, a, b); + + try std.testing.expect(c.row1.x == 1); + try std.testing.expect(c.row1.y == 3); + try std.testing.expect(c.row1.z == 3); + try std.testing.expect(c.row2.x == 0); + try std.testing.expect(c.row2.y == 2); + try std.testing.expect(c.row2.z == 6); + try std.testing.expect(c.row3.x == 0); + try std.testing.expect(c.row3.y == 0); + try std.testing.expect(c.row3.z == 10); +} + +test "Mat3 sub works" { + const a: Mat3(i8) = .{ + .row1 = .{ .x = 1, .y = 2, .z = 3 }, + .row2 = .{ .x = 0, .y = 1, .z = 5 }, + .row3 = .{ .x = 0, .y = 0, .z = 9 }, + }; + const b: Mat3(i8) = .{ + .row1 = .{ .x = 0, .y = 1, .z = 0 }, + .row2 = .{ .x = 0, .y = 1, .z = 1 }, + .row3 = .{ .x = 0, .y = 0, .z = 1 }, + }; + + const c = mat3Sub(i8, a, b); + + try std.testing.expect(c.row1.x == 1); + try std.testing.expect(c.row1.y == 1); + try std.testing.expect(c.row1.z == 3); + try std.testing.expect(c.row2.x == 0); + try std.testing.expect(c.row2.y == 0); + try std.testing.expect(c.row2.z == 4); + try std.testing.expect(c.row3.x == 0); + try std.testing.expect(c.row3.y == 0); + try std.testing.expect(c.row3.z == 8); +} + +test "Mat3 mul works" { + const a: Mat3(i8) = .{ + .row1 = .{ .x = 1, .y = 2, .z = 3 }, + .row2 = .{ .x = 0, .y = 1, .z = 5 }, + .row3 = .{ .x = 0, .y = 0, .z = 9 }, + }; + const b: Mat3(i8) = .{ + .row1 = .{ .x = 0, .y = 1, .z = 0 }, + .row2 = .{ .x = 0, .y = 1, .z = 1 }, + .row3 = .{ .x = 0, .y = 0, .z = 1 }, + }; + + const c = mat3Mul(i8, a, b); + + try std.testing.expect(c.row1.x == 0); + try std.testing.expect(c.row1.y == 3); + try std.testing.expect(c.row1.z == 5); + try std.testing.expect(c.row2.x == 0); + try std.testing.expect(c.row2.y == 1); + try std.testing.expect(c.row2.z == 6); + try std.testing.expect(c.row3.x == 0); + try std.testing.expect(c.row3.y == 0); + try std.testing.expect(c.row3.z == 9); +} + +test "vec3 mul mat3 works" { + const a: Vec3(i8) = .{ .x = 1, .y = 2, .z = 3 }; + + const b: Mat3(i8) = .{ + .row1 = .{ .x = 0, .y = 1, .z = 0 }, + .row2 = .{ .x = 0, .y = 1, .z = 1 }, + .row3 = .{ .x = 0, .y = 0, .z = 1 }, + }; + + const c = vec3MulMat3(i8, a, b); + + try std.testing.expect(c.x == 0); + try std.testing.expect(c.y == 3); + try std.testing.expect(c.z == 5); +}