Create the color and the canvas
This commit is contained in:
parent
d0a8be63e9
commit
3c8536deb6
|
@ -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
|
||||||
|
}
|
||||||
|
}
|
|
@ -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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,7 +1,11 @@
|
||||||
|
mod canvas;
|
||||||
|
mod color;
|
||||||
mod point;
|
mod point;
|
||||||
mod tuple;
|
mod tuple;
|
||||||
mod vector;
|
mod vector;
|
||||||
|
|
||||||
|
pub use canvas::Canvas;
|
||||||
|
pub use color::Color;
|
||||||
pub use point::Point;
|
pub use point::Point;
|
||||||
pub use tuple::Tuple;
|
pub use tuple::Tuple;
|
||||||
pub use vector::Vector;
|
pub use vector::Vector;
|
||||||
|
@ -116,4 +120,32 @@ mod tests {
|
||||||
Vector::new(1., -2., 1.)
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue