const std = @import("std"); const graphics = @import("root.zig"); pub const Curve = struct { const Self = @This(); const Point = struct { x: u32, y: u32, }; start: Point, middle: Point, end: Point, color: graphics.Color, fn distance(a: u32, b: u32) u32 { if (a > b) { return a - b; } else { return b - a; } } pub fn render(self: *const Self, canvas: *const graphics.Canvas) void { const start_x: f64 = @floatFromInt(self.start.x); const start_y: f64 = @floatFromInt(self.start.y); const middle_x: f64 = @floatFromInt(self.middle.x); const middle_y: f64 = @floatFromInt(self.middle.y); const end_x: f64 = @floatFromInt(self.end.x); const end_y: f64 = @floatFromInt(self.end.y); const resolution = 2 + ( distance(self.start.x, self.end.x) + distance(self.start.y, self.end.y) ) / 8; var last = self.start; canvas.buffer[last.x + last.y * canvas.width] = .{ .red = 0xff, .green = 0xff, .blue = 0xff }; for (1..resolution) |index| { const t: f64 = @as(f64, @floatFromInt(index)) / @as(f64, @floatFromInt(resolution)); const x: u32 = @intFromFloat(@round( (1 - t) * ((1 - t) * start_x + t * middle_x) + t * ((1 - t) * middle_x + t * end_x) )); const y: u32 = @intFromFloat(@round( (1 - t) * ((1 - t) * start_y + t * middle_y) + t * ((1 - t) * middle_y + t * end_y) )); (graphics.Line { .start = .{ .x = last.x, .y = last.y }, .end = .{ .x = x, .y = y }, .color = self.color, }).render(canvas); last = .{ .x = x, .y = y }; } } };