diff --git a/src/main.zig b/src/main.zig index 686f6cf..89cd135 100644 --- a/src/main.zig +++ b/src/main.zig @@ -17,20 +17,21 @@ pub fn main() !void { defer rl.closeWindow(); rl.setTargetFPS(60); - - // todo move away from being a loop, a static trigonometry should not be redrawn every frame rl.beginDrawing(); rl.clearBackground(rl.Color.white); - try markAxis(allocator); plotGraph(); drawAxis(); + try markAxis(allocator); rl.endDrawing(); while (!rl.windowShouldClose()) { rl.beginDrawing(); + // DEBUG + // const pos = rl.getMousePosition(); + // std.debug.print("x: {d} y:{}\n", .{ pos.x, pos.y }); rl.endDrawing(); } } @@ -55,7 +56,7 @@ fn markAxis(allocator: std.mem.Allocator) !void { var cnt: usize = 0; var i: i32 = start_x; while (i <= SCREENWIDTH) : (i += SCALE) { - // get + // int to string const text = try std.fmt.bufPrintZ(&buf, "{}", .{cnt}); cnt += 1; // 0 is due to us working with C-style strings @@ -75,17 +76,30 @@ fn markAxis(allocator: std.mem.Allocator) !void { rl.drawText(text_back, SCREENWIDTH - i - diff - diff / 2, start_y + diff, font_size, rl.Color.black); } + // start at 1 as we're not drawing 0 this time + cnt = 1; i = start_y; while (i <= SCREENHEIGHT) : (i += SCALE) { - // +y - rl.drawCircle(start_x, @intCast(i), radius, rl.Color.black); + // skip 0 as it is already rendered during x scale + if (i == start_y) continue; + + const text = try std.fmt.bufPrintZ(&buf, "{}", .{cnt}); + cnt += 1; + var text_back = try allocator.allocSentinel(u8, text.len + 1, 0); + defer allocator.free(text_back); + @memcpy(text_back[0..1], "-"); + @memcpy(text_back[1..], text); // -y + rl.drawCircle(start_x, @intCast(i), radius, rl.Color.black); + rl.drawText(text_back, start_x + diff, @as(i32, @intCast(i)) - diff, font_size, rl.Color.black); + + // +y rl.drawCircle(start_x, SCREENHEIGHT - i, radius, rl.Color.black); + rl.drawText(text, start_x + diff, SCREENHEIGHT - i - diff, font_size, rl.Color.black); } } -// todo in the future we will do calculations only once and just repeat displaying fn plotGraph() void { const diff: f32 = 0.01; const thickness = 2.5; @@ -94,36 +108,36 @@ fn plotGraph() void { while (x_value <= SCREENWIDTH) : (x_value += diff) { const cur_pos = adjustForGridSystem(rl.Vector2{ .x = x_value, - .y = getY(x_value), + .y = getY(x_value) catch { + continue; + }, }); + // this is to ensure the value doesn't wrap around to zero causing the entire Y-axis to be graphed + if (cur_pos.y > SCREENHEIGHT) { + continue; + } + const next_pos = adjustForGridSystem(rl.Vector2{ .x = x_value + diff, - .y = getY(x_value + diff), + .y = getY(x_value + diff) catch { + continue; + }, }); - // test - if (cur_pos.x == 0 or next_pos.x == 0) { - continue; - } - rl.drawLineEx(cur_pos, next_pos, thickness, rl.Color.dark_blue); } } // f(x) -fn getY(x: f32) f32 { - const min_threshold = 1e-3; - const a = x / 10; - var b: f32 = 1.0; - if (b == 0) b = a / min_threshold; - - return a / b; +fn getY(x: f32) !f32 { + return math.calculate(x, -3, .Power); } fn adjustForGridSystem(input_vector: rl.Vector2) rl.Vector2 { // std.debug.print("{d} => {d}\n", .{ input_vector.x, input_vector.x * SCALE }); const new_vector = rl.Vector2{ + // we add screenwidth because in traditional gui libraries the grid starts in top left and not in the center like the coordinate system .x = input_vector.x * SCALE + SCREENWIDTH / 2, .y = -input_vector.y * SCALE + SCREENHEIGHT / 2, // minus is there because y works the opposite in gui libraries than in coordination system }; diff --git a/src/math.zig b/src/math.zig index 6aa5294..25825f5 100644 --- a/src/math.zig +++ b/src/math.zig @@ -1,4 +1,36 @@ -pub fn abs(a: f32) f32 { +const std = @import("std"); + +pub const MathOperation = enum { + Division, + Power, + Root, +}; + +pub fn calculate(first: f32, second: f32, op: MathOperation) !f32 { + switch (op) { + .Division => { + if (second == 0) { + return error.InvalidParam; + } + return first / second; + }, + .Power => { + if (first == 0) std.debug.print("KOK", .{}); + if (first == 0 and second < 0) { + return error.InvalidParam; + } + return pow(first, @intFromFloat(second)); + }, + .Root => { + if (first < 0 or second < 0) { + return error.InvalidParam; + } + return std.math.sqrt(second); + }, + } +} + +fn abs(a: f32) f32 { if (a < 0) { return -a; } @@ -6,7 +38,7 @@ pub fn abs(a: f32) f32 { return a; } -pub fn pow(a: f32, b: i32) f32 { +fn pow(a: f32, b: i32) f32 { var res: f32 = 1.0; var n: usize = undefined; var f: f32 = undefined;