const std = @import("std"); const math = std.math; const Point3 = @import("vec3.zig").Point3; const Vec3 = @import("vec3.zig").Vec3; const Ray = @import("ray.zig").Ray; fn degreesToRadians(degrees: f32) f32 { return degrees * math.pi / 180.0; } pub const Camera = struct { origin: Point3, lowerLeftCorner: Point3, horizontal: Vec3, vertical: Vec3, pub fn init( lookFrom: Point3, lookAt: Point3, vup: Vec3, vfov: f32, aspectRatio: f32, ) Camera { const theta = degreesToRadians(vfov); const h = math.tan(theta / 2); const viewportHeight = 2.0 * h; const viewportWidth = aspectRatio * viewportHeight; const w = lookFrom.sub(lookAt).unit(); const u = vup.cross(w).unit(); const v = w.cross(u); const origin = lookFrom; const horizontal = u.mul_s(viewportWidth); const vertical = v.mul_s(viewportHeight); const lowerLeftCorner = origin.sub(horizontal.div(2)).sub(vertical.div(2)).sub(w); return Camera { .origin = origin, .horizontal = horizontal, .vertical = vertical, .lowerLeftCorner = lowerLeftCorner, }; } pub fn getRay(self: Camera, s: f32, t: f32) Ray { return Ray{ .origin = self.origin, .direction = self.lowerLeftCorner.add(self.horizontal.mul_s(s)).add(self.vertical.mul_s(t)).sub(self.origin), }; } };