stocking

git clone https://git.bradleygannon.com/stocking.git
Log | Files | Refs

color.rs (3604B)


      1 use std::ops::{Add, AddAssign, Div, Mul};
      2 
      3 use crate::random::RandomNumberGenerator;
      4 
      5 #[derive(Clone, Copy, Debug, Default, PartialEq, PartialOrd)]
      6 pub struct GammaColor {
      7     red: f64,
      8     green: f64,
      9     blue: f64,
     10 }
     11 
     12 impl GammaColor {
     13     pub const fn red(&self) -> f64 {
     14         self.red
     15     }
     16 
     17     pub const fn green(&self) -> f64 {
     18         self.green
     19     }
     20 
     21     pub const fn blue(&self) -> f64 {
     22         self.blue
     23     }
     24 }
     25 
     26 #[derive(Clone, Copy, Debug, Default, PartialEq, PartialOrd)]
     27 pub struct LinearColor {
     28     red: f64,
     29     green: f64,
     30     blue: f64,
     31 }
     32 
     33 impl LinearColor {
     34     const MIN: f64 = 0.;
     35     const MAX: f64 = 1.;
     36 
     37     pub const fn new(red: f64, green: f64, blue: f64) -> Self {
     38         LinearColor {
     39             red: red.clamp(LinearColor::MIN, LinearColor::MAX),
     40             green: green.clamp(LinearColor::MIN, LinearColor::MAX),
     41             blue: blue.clamp(LinearColor::MIN, LinearColor::MAX),
     42         }
     43     }
     44 
     45     pub fn as_gamma(&self) -> GammaColor {
     46         GammaColor {
     47             red: if self.red > 0. { self.red.sqrt() } else { 0. },
     48             green: if self.green > 0. {
     49                 self.green.sqrt()
     50             } else {
     51                 0.
     52             },
     53             blue: if self.blue > 0. { self.blue.sqrt() } else { 0. },
     54         }
     55     }
     56 
     57     pub const fn red(&self) -> f64 {
     58         self.red
     59     }
     60 
     61     pub const fn green(&self) -> f64 {
     62         self.green
     63     }
     64 
     65     pub const fn blue(&self) -> f64 {
     66         self.blue
     67     }
     68 
     69     pub fn random(rng: &mut RandomNumberGenerator) -> Self {
     70         LinearColor::new(rng.next_f64(), rng.next_f64(), rng.next_f64())
     71     }
     72 
     73     pub fn random_in_range(min: f64, max: f64, rng: &mut RandomNumberGenerator) -> Self {
     74         LinearColor {
     75             red: rng.next_f64_in_range(min, max),
     76             green: rng.next_f64_in_range(min, max),
     77             blue: rng.next_f64_in_range(min, max),
     78         }
     79     }
     80 }
     81 
     82 impl Add<LinearColor> for LinearColor {
     83     type Output = LinearColor;
     84 
     85     fn add(self, rhs: LinearColor) -> Self::Output {
     86         LinearColor {
     87             red: (self.red + rhs.red).clamp(LinearColor::MIN, LinearColor::MAX),
     88             green: (self.green + rhs.green).clamp(LinearColor::MIN, LinearColor::MAX),
     89             blue: (self.blue + rhs.blue).clamp(LinearColor::MIN, LinearColor::MAX),
     90         }
     91     }
     92 }
     93 
     94 impl AddAssign<LinearColor> for LinearColor {
     95     fn add_assign(&mut self, rhs: LinearColor) {
     96         self.red += rhs.red;
     97         self.green += rhs.green;
     98         self.blue += rhs.blue;
     99     }
    100 }
    101 
    102 impl Mul<f64> for LinearColor {
    103     type Output = LinearColor;
    104 
    105     fn mul(self, rhs: f64) -> Self::Output {
    106         LinearColor {
    107             red: (self.red * rhs).clamp(LinearColor::MIN, LinearColor::MAX),
    108             green: (self.green * rhs).clamp(LinearColor::MIN, LinearColor::MAX),
    109             blue: (self.blue * rhs).clamp(LinearColor::MIN, LinearColor::MAX),
    110         }
    111     }
    112 }
    113 
    114 impl Mul<LinearColor> for f64 {
    115     type Output = LinearColor;
    116 
    117     fn mul(self, rhs: LinearColor) -> Self::Output {
    118         rhs * self
    119     }
    120 }
    121 
    122 impl Mul<LinearColor> for LinearColor {
    123     type Output = LinearColor;
    124 
    125     fn mul(self, rhs: LinearColor) -> Self::Output {
    126         LinearColor {
    127             red: (self.red * rhs.red).clamp(LinearColor::MIN, LinearColor::MAX),
    128             green: (self.green * rhs.green).clamp(LinearColor::MIN, LinearColor::MAX),
    129             blue: (self.blue * rhs.blue).clamp(LinearColor::MIN, LinearColor::MAX),
    130         }
    131     }
    132 }
    133 
    134 impl Div<f64> for LinearColor {
    135     type Output = LinearColor;
    136 
    137     fn div(self, rhs: f64) -> Self::Output {
    138         self * (1. / rhs)
    139     }
    140 }