From 31272bceac9205a9080a0d1dbe00d92018b4d9c3 Mon Sep 17 00:00:00 2001 From: Bruno BELANYI Date: Mon, 16 Mar 2020 16:07:44 +0100 Subject: [PATCH] library: core: color: add arithmetic operations The only operations that are not supported right now are term-by-term division and multiplication between two colors. I deemed the multiplication and division by a scalar more important than those operations for the moment. --- src/core/color.rs | 199 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 198 insertions(+), 1 deletion(-) diff --git a/src/core/color.rs b/src/core/color.rs index 2ded4e6..26067ed 100644 --- a/src/core/color.rs +++ b/src/core/color.rs @@ -1,6 +1,203 @@ -#[derive(Debug)] +use derive_more::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Sub, SubAssign}; + +#[derive( + Debug, Clone, PartialEq, Add, AddAssign, Div, DivAssign, Mul, MulAssign, Sub, SubAssign, +)] +/// A structure to represent operations in the linear RGB colorspace. pub struct LinearColor { pub r: f64, pub g: f64, pub b: f64, } + +impl LinearColor { + pub fn black() -> Self { + LinearColor { + r: 0., + g: 0., + b: 0., + } + } + + pub fn new(r: f64, g: f64, b: f64) -> Self { + LinearColor { r, g, b } + } +} + +impl Default for LinearColor { + fn default() -> Self { + Self::black() + } +} + +#[cfg(test)] +mod test { + use super::*; + + #[test] + fn black_is_black() { + let black = LinearColor::black(); + assert_eq!( + black, + LinearColor { + r: 0., + g: 0., + b: 0. + } + ) + } + + #[test] + fn default_is_black() { + assert_eq!(::default(), LinearColor::black()) + } + + #[test] + fn red_is_red() { + let red = LinearColor::new(1., 0., 0.); + assert_eq!( + red, + LinearColor { + r: 1., + g: 0., + b: 0. + } + ) + } + + #[test] + fn green_is_green() { + let green = LinearColor::new(0., 1., 0.); + assert_eq!( + green, + LinearColor { + r: 0., + g: 1., + b: 0. + } + ) + } + + #[test] + fn blue_is_blue() { + let blue = LinearColor::new(0., 0., 1.); + assert_eq!( + blue, + LinearColor { + r: 0., + g: 0., + b: 1. + } + ) + } + + #[test] + fn mul_by_float_works() { + let color = LinearColor::new(0.125, 0.25, 0.0625); + assert_eq!( + color * 4., + LinearColor { + r: 0.5, + g: 1., + b: 0.25, + } + ) + } + + #[test] + fn div_by_float_works() { + let color = LinearColor::new(0.2, 0.4, 0.6); + assert_eq!( + color / 2., + LinearColor { + r: 0.1, + g: 0.2, + b: 0.3, + } + ) + } + + #[test] + fn mulassign_by_float_works() { + let mut color = LinearColor::new(0.125, 0.25, 0.0625); + color *= 4.; + assert_eq!( + color, + LinearColor { + r: 0.5, + g: 1., + b: 0.25, + } + ) + } + + #[test] + fn divassign_by_float_works() { + let mut color = LinearColor::new(0.2, 0.4, 0.6); + color /= 2.; + assert_eq!( + color, + LinearColor { + r: 0.1, + g: 0.2, + b: 0.3, + } + ) + } + + #[test] + fn add_works() { + let lhs = LinearColor::new(1., 0., 0.125); + let rhs = LinearColor::new(0., 0.5, 0.25); + assert_eq!( + lhs + rhs, + LinearColor { + r: 1., + g: 0.5, + b: 0.375, + } + ); + } + + #[test] + fn sub_works() { + let lhs = LinearColor::new(1., 0.5, 0.25); + let rhs = LinearColor::new(0.5, 0.125, 0.25); + assert_eq!( + lhs - rhs, + LinearColor { + r: 0.5, + g: 0.375, + b: 0., + } + ); + } + + #[test] + fn addassign_works() { + let mut lhs = LinearColor::new(1., 0., 0.125); + lhs += LinearColor::new(0., 0.5, 0.25); + assert_eq!( + lhs, + LinearColor { + r: 1., + g: 0.5, + b: 0.375, + } + ); + } + + #[test] + fn subassign_works() { + let mut lhs = LinearColor::new(1., 0.5, 0.25); + lhs -= LinearColor::new(0.5, 0.125, 0.25); + assert_eq!( + lhs, + LinearColor { + r: 0.5, + g: 0.375, + b: 0., + } + ); + } +}