const std = @import("std"); const matrix = @import("matrix.zig"); const sdl = @import("sdl.zig"); const Cube = struct { points: [8][3]f32, }; pub fn draw_cube(instance: sdl.instance, cube: Cube) void { var c = cube.points; sdl.draw_color(instance, 255, 255, 255, 0); sdl.draw_line(instance, &c[0], &c[1]); sdl.draw_line(instance, &c[0], &c[2]); sdl.draw_line(instance, &c[0], &c[4]); sdl.draw_line(instance, &c[7], &c[6]); sdl.draw_line(instance, &c[7], &c[5]); sdl.draw_line(instance, &c[7], &c[3]); sdl.draw_line(instance, &c[2], &c[3]); sdl.draw_line(instance, &c[4], &c[5]); sdl.draw_line(instance, &c[1], &c[5]); sdl.draw_line(instance, &c[6], &c[2]); sdl.draw_line(instance, &c[3], &c[1]); sdl.draw_line(instance, &c[4], &c[6]); } pub fn get_shifted_cube(cube: Cube, x: f32, y: f32, z: f32) Cube { var shifted_cube = Cube{ .points = undefined }; for (cube.points) |point, i| { shifted_cube.points[i][0] = point[0] + x; shifted_cube.points[i][1] = point[1] + y; shifted_cube.points[i][2] = point[2] + z; } return shifted_cube; } pub fn get_centered_cube(cube: Cube, offset: f32) Cube { var centered_cube = Cube{ .points = undefined }; for (cube.points) |point, i| { for (point) |dimension, j| { centered_cube.points[i][j] = dimension + offset; } } return centered_cube; } pub fn get_projected_cube(cube: Cube, alpha: f32, beta: f32) Cube { var projected_cube = Cube{ .points = undefined }; var ax = [_]f32{ 1, 0, 0, 0, @cos(alpha), @sin(alpha), 0, -@sin(alpha), @cos(alpha), }; var a = matrix.new(3, 3, &ax); var bx = [_]f32{ @cos(beta), 0, -@sin(beta), 0, 1, 0, @sin(beta), 0, @cos(beta), }; var b = matrix.new(3, 3, &bx); var cx = [_]f32{ 1, 0, 0, 0, 1, 0, 0, 0, 0, }; var c = matrix.new(3, 3, &cx); for (cube.points) |point, i| { var p = point; var x = matrix.multiply(c, matrix.multiply(matrix.multiply(a, b), matrix.new(3, 1, &p))).x.items; projected_cube.points[i][0] = x[0]; projected_cube.points[i][1] = x[1]; } return projected_cube; } pub fn get_scaled_cube(cube: Cube, scale: f32) Cube { var scaled_cube = Cube{ .points = undefined }; for (cube.points) |point, i| { for (point) |dimension, j| { scaled_cube.points[i][j] = dimension * scale; } } return scaled_cube; } pub fn main() anyerror!void { var instance = sdl.init(); const unit_cube = Cube{ .points = [8][3]f32{ [3]f32{ 01, 01, 01 }, [3]f32{ 01, 01, -1 }, [3]f32{ 01, -1, 01 }, [3]f32{ 01, -1, -1 }, [3]f32{ -1, 01, 01 }, [3]f32{ -1, 01, -1 }, [3]f32{ -1, -1, 01 }, [3]f32{ -1, -1, -1 }, }, }; var beta: f32 = 0; var alpha: f32 = 0; while (true) { var event = sdl.get_event(); if (event.mode == sdl.modes.quit) { break; } else if (event.mode == sdl.modes.key) { switch (event.key) { sdl.keys.q => break, else => continue, } } sdl.draw_color(instance, 0, 0, 0, 0); sdl.clear(instance); var cube = get_projected_cube(unit_cube, alpha, beta); cube = get_scaled_cube(cube, 50); cube = get_centered_cube(cube, 250); draw_cube(instance, cube); cube = get_projected_cube(unit_cube, alpha + 90, beta + 90); cube = get_scaled_cube(cube, 25); cube = get_centered_cube(cube, 250); draw_cube(instance, cube); cube = get_shifted_cube(unit_cube, 5, 0, 0); cube = get_projected_cube(cube, alpha, beta); cube = get_scaled_cube(cube, 25); cube = get_centered_cube(cube, 250); draw_cube(instance, cube); cube = get_shifted_cube(unit_cube, -5, 0, 0); cube = get_projected_cube(cube, alpha, beta); cube = get_scaled_cube(cube, 25); cube = get_centered_cube(cube, 250); draw_cube(instance, cube); beta += 0.01; alpha += 0.01; sdl.present(instance); sdl.delay(10); } sdl.quit(instance); }