use crate::calculus::calculus::Point3; use crate::interval::Interval; // "Ideal" aspect ratio, allowing fraction pub const ASPECT_RATIO: f32 = 16.0f32 / 9.0f32; pub const IMG_WIDTH: usize = 1000; pub const IMG_HEIGHT: usize = get_image_height(IMG_WIDTH, ASPECT_RATIO); pub const VIEWPORT_HEIGHT: f32 = 2.0; pub const FOCAL_LENGTH: f32 = 1.0; pub const CAMERA_CENTER: Point3 = Point3 { x: 0f32, y: 0f32, z: 0f32 }; pub const SAMPLES_PER_PIXEL: usize = 100; pub const fn get_image_height(image_width: usize, aspect_ratio: f32) -> usize { let image_height = (image_width as f32 / aspect_ratio) as usize; if image_width < 1 { 1 } else { image_height } } pub struct Color { pub r: f32, pub g: f32, pub b: f32, } impl Color { pub fn new(r: f32, g: f32, b: f32) -> Self { Self { r, g, b } } pub fn mul_scalar(&self, scalar: f32) -> Color { Self { r: self.r * scalar, g: self.g * scalar, b: self.b * scalar, } } pub fn add(&self, other: &Self) -> Color { Self { r: self.r + other.r, g: self.g + other.g, b: self.b + other.b } } } #[derive(Debug, Copy, Clone)] pub struct Pixel { pub r: u8, pub g: u8, pub b: u8, } impl Pixel { pub fn from_frac(r: f32, g: f32, b: f32) -> Self { let intensity = Interval::new(0.0, 0.999); Self { r: (256.0 * intensity.clamp(r)) as u8, g: (256.0 * intensity.clamp(g)) as u8, b: (256.0 * intensity.clamp(b)) as u8, } } pub fn from_color(color: &Color) -> Self { let (r, g, b) = (color.r, color.g, color.b); Self::from_frac(r, g, b) } } impl Default for Pixel { fn default() -> Self { Pixel { r:0, g:0, b:0 } } } pub type DisplayBuffer = [[Pixel; IMG_WIDTH]; IMG_HEIGHT];