Create the color and the canvas

This commit is contained in:
Savanni D'Gerinel 2024-06-09 14:57:33 -04:00
parent d0a8be63e9
commit 3c8536deb6
3 changed files with 160 additions and 0 deletions

View File

@ -0,0 +1,41 @@
use crate::types::Color;
pub struct Canvas {
width: usize,
height: usize,
pixels: Vec<Color>,
}
impl Canvas {
pub fn new(width: usize, height: usize) -> Self {
Self {
width,
height,
pixels: vec![Color::default(); width * height],
}
}
#[inline]
pub fn width(&self) -> usize {
self.width
}
#[inline]
pub fn height(&self) -> usize {
self.height
}
pub fn pixel(&self, row: usize, column: usize) -> &Color {
&self.pixels[self.addr(row, column)]
}
pub fn pixel_mut<'a>(&'a mut self, row: usize, column: usize) -> &'a mut Color {
let addr = self.addr(row, column);
&mut self.pixels[addr]
}
#[inline]
fn addr(&self, row: usize, column: usize) -> usize {
row * self.width() + column
}
}

View File

@ -0,0 +1,87 @@
use crate::types::Tuple;
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct Color(Tuple);
impl Color {
pub fn new(red: f64, green: f64, blue: f64) -> Self {
Self(Tuple(red, green, blue, 0.))
}
#[inline]
pub fn red(&self) -> f64 {
self.0.0
}
#[inline]
pub fn green(&self) -> f64 {
self.0.1
}
#[inline]
pub fn blue(&self) -> f64 {
self.0.2
}
}
impl Default for Color {
fn default() -> Self {
Self::new(0., 0., 0.)
}
}
impl From<Tuple> for Color {
fn from(tuple: Tuple) -> Self {
assert_eq!(tuple.3, 0.0);
Self(tuple)
}
}
impl std::ops::Deref for Color {
type Target = Tuple;
fn deref(&self) -> &Tuple {
&self.0
}
}
impl std::ops::Add for Color {
type Output = Color;
fn add(self, r: Self) -> Self {
Color::from(self.0 + r.0)
}
}
impl std::ops::Sub for Color {
type Output = Color;
fn sub(self, r: Self) -> Self {
Color::from(self.0 - r.0)
}
}
impl std::ops::Neg for Color {
type Output = Color;
fn neg(self) -> Self::Output {
let mut t = -self.0;
t.0 = 0.;
Color::from(t)
}
}
impl std::ops::Mul for Color {
type Output = Color;
fn mul(self, r: Color) -> Self {
let red = self.red() * r.red();
let green = self.green() * r.green();
let blue = self.blue() * r.blue();
Self::new(red, green, blue)
}
}
impl std::ops::Mul<f64> for Color {
type Output = Color;
fn mul(self, r: f64) -> Self {
Color::from(self.0 * r)
}
}

View File

@ -1,7 +1,11 @@
mod canvas;
mod color;
mod point;
mod tuple;
mod vector;
pub use canvas::Canvas;
pub use color::Color;
pub use point::Point;
pub use tuple::Tuple;
pub use vector::Vector;
@ -116,4 +120,32 @@ mod tests {
Vector::new(1., -2., 1.)
);
}
#[test]
fn multiply_colors() {
let c1 = Color::new(1., 0.2, 0.4);
let c2 = Color::new(0.9, 1., 0.1);
assert_eq!(c1 * c2, Color::new(0.9, 0.2, 0.04));
}
#[test]
fn it_creates_a_canvas() {
let c = Canvas::new(10, 20);
assert_eq!(c.width(), 10);
assert_eq!(c.height(), 20);
for row in 0..20 {
for col in 0..10 {
assert_eq!(*c.pixel(row, col), Color::default());
}
}
}
#[test]
fn it_can_write_pixel() {
let mut c = Canvas::new(10, 20);
let red = Color::new(1., 0., 0.);
*c.pixel_mut(2, 3) = red;
assert_eq!(*c.pixel(2, 3), red);
}
}