From 92ed513b57e4c4ccf3a413cad763278e3a8372f7 Mon Sep 17 00:00:00 2001 From: Tom Barrett Date: Thu, 1 Jul 2021 17:35:12 +0200 Subject: we now use points, split up projection rotation, and added an axis --- src/main.zig | 214 ++++++++++++++++++++++++++++++++++++++++------------------- src/sdl.zig | 5 +- 2 files changed, 147 insertions(+), 72 deletions(-) (limited to 'src') diff --git a/src/main.zig b/src/main.zig index 9a26a6c..89ce7d8 100644 --- a/src/main.zig +++ b/src/main.zig @@ -3,107 +3,175 @@ const matrix = @import("matrix.zig"); const sdl = @import("sdl.zig"); const Cube = struct { - points: [8][3]f32, + points: [8]Point, +}; + +pub const Point = struct { + x: f32, + y: f32, + z: 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, cube.points[0], cube.points[1]); + sdl.draw_line(instance, cube.points[0], cube.points[2]); + sdl.draw_line(instance, cube.points[0], cube.points[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, cube.points[7], cube.points[6]); + sdl.draw_line(instance, cube.points[7], cube.points[5]); + sdl.draw_line(instance, cube.points[7], cube.points[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, cube.points[2], cube.points[3]); + sdl.draw_line(instance, cube.points[4], cube.points[5]); + sdl.draw_line(instance, cube.points[1], cube.points[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]); + sdl.draw_line(instance, cube.points[6], cube.points[2]); + sdl.draw_line(instance, cube.points[3], cube.points[1]); + sdl.draw_line(instance, cube.points[4], cube.points[6]); } -pub fn get_shifted_cube(cube: Cube, x: f32, y: f32, z: f32) Cube { +pub fn shift_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; + shifted_cube.points[i].x = point.x + x; + shifted_cube.points[i].y = point.y + y; + shifted_cube.points[i].z = point.z + z; } - return shifted_cube; } -pub fn get_centered_cube(cube: Cube, offset: f32) Cube { +pub fn center_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; - } + centered_cube.points[i] = center_point(point, offset); } return centered_cube; } -pub fn get_projected_cube(cube: Cube, alpha: f32, beta: f32) Cube { +pub fn center_point(point: Point, offset: f32) Point { + return Point{ + .x = point.x + offset, + .y = point.y + offset, + .z = 0, + }; +} + +pub fn rotate_cube(cube: Cube, alpha: f32, beta: f32) Cube { + var rotated_cube = Cube{ .points = undefined }; + + var a = matrix.new( + 3, + 3, + &[_]f32{ + 1, 0, 0, + 0, @cos(alpha), @sin(alpha), + 0, -@sin(alpha), @cos(alpha), + }, + ); + + var b = matrix.new( + 3, + 3, + &[_]f32{ + @cos(beta), 0, -@sin(beta), + 0, 1, 0, + @sin(beta), 0, @cos(beta), + }, + ); + + for (cube.points) |point, i| { + var m = matrix.multiply( + matrix.multiply(a, b), + matrix.new(3, 1, &[3]f32{ point.x, point.y, point.z }), + ).x.items; + rotated_cube.points[i].x = m[0]; + rotated_cube.points[i].y = m[1]; + rotated_cube.points[i].z = m[2]; + } + + return rotated_cube; +} + +pub fn project_cube(cube: Cube) 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); + for (cube.points) |point, i| { + projected_cube.points[i] = project_point(point); + } - var bx = [_]f32{ - @cos(beta), 0, -@sin(beta), - 0, 1, 0, - @sin(beta), 0, @cos(beta), - }; - var b = matrix.new(3, 3, &bx); + return projected_cube; +} +pub fn project_point(p: Point) Point { var cx = [_]f32{ 1, 0, 0, 0, 1, 0, 0, 0, 0, }; var c = matrix.new(3, 3, &cx); + var m = matrix.multiply(c, matrix.new(3, 1, &[3]f32{ p.x, p.y, p.z })).x.items; - 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]; - } + var projected_point = Point{ + .x = m[0], + .y = m[1], + .z = m[2], + }; - return projected_cube; + return projected_point; } -pub fn get_scaled_cube(cube: Cube, scale: f32) Cube { +pub fn scale_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; - } + scaled_cube.points[i].x = point.x * scale; + scaled_cube.points[i].y = point.y * scale; + scaled_cube.points[i].z = point.z * scale; } return scaled_cube; } +pub fn draw_axis(instance: sdl.instance) void { + var o = center_point( + project_point(Point{ .x = 00, .y = 00, .z = 00 }), + 250, + ); + var x = center_point( + project_point(Point{ .x = 50, .y = 00, .z = 00 }), + 250, + ); + var y = center_point( + project_point(Point{ .x = 00, .y = 50, .z = 00 }), + 250, + ); + var z = center_point( + project_point(Point{ .x = 00, .y = 00, .z = 50 }), + 250, + ); + + sdl.draw_color(instance, 255, 0, 0, 0); + sdl.draw_line(instance, o, x); + + sdl.draw_color(instance, 0, 255, 0, 0); + sdl.draw_line(instance, o, y); + + sdl.draw_color(instance, 0, 0, 255, 0); + sdl.draw_line(instance, o, z); +} + 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 }, + .points = [8]Point{ + Point{ .x = 01, .y = 01, .z = 01 }, + Point{ .x = 01, .y = 01, .z = -1 }, + Point{ .x = 01, .y = -1, .z = 01 }, + Point{ .x = 01, .y = -1, .z = -1 }, + Point{ .x = -1, .y = 01, .z = 01 }, + Point{ .x = -1, .y = 01, .z = -1 }, + Point{ .x = -1, .y = -1, .z = 01 }, + Point{ .x = -1, .y = -1, .z = -1 }, }, }; @@ -123,28 +191,34 @@ pub fn main() anyerror!void { 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); + var cube = rotate_cube(unit_cube, alpha, beta); + cube = scale_cube(cube, 50); + cube = project_cube(cube); + cube = center_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); + cube = rotate_cube(unit_cube, alpha + 90, beta + 90); + cube = scale_cube(cube, 25); + cube = project_cube(cube); + cube = center_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); + cube = shift_cube(unit_cube, 5, 0, 0); + cube = rotate_cube(cube, 2 * alpha, 2 * beta); + cube = scale_cube(cube, 25); + cube = project_cube(cube); + cube = center_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); + cube = shift_cube(unit_cube, -5, 0, 0); + cube = rotate_cube(cube, 2 * alpha, 2 * beta); + cube = scale_cube(cube, 25); + cube = project_cube(cube); + cube = center_cube(cube, 250); draw_cube(instance, cube); + draw_axis(instance); + beta += 0.01; alpha += 0.01; diff --git a/src/sdl.zig b/src/sdl.zig index c7b9906..b84bbfb 100644 --- a/src/sdl.zig +++ b/src/sdl.zig @@ -1,5 +1,6 @@ const std = @import("std"); const sdl = @cImport(@cInclude("SDL2/SDL.h")); +const Point = @import("main.zig").Point; pub const instance = struct { renderer: ?*sdl.SDL_Renderer, @@ -29,8 +30,8 @@ pub fn init() instance { }; } -pub fn draw_line(i: instance, p1: []f32, p2: []f32) void { - _ = sdl.SDL_RenderDrawLineF(i.renderer, p1[0], p1[1], p2[0], p2[1]); +pub fn draw_line(i: instance, p1: Point, p2: Point) void { + _ = sdl.SDL_RenderDrawLineF(i.renderer, p1.x, p1.y, p2.x, p2.y); } pub fn delay(t: u32) void { -- cgit v1.2.3