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 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);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue