use crate::tuples::{Color, Tuple}; #[derive(Debug, PartialEq, Clone)] pub struct StripePattern { pub a: Color, pub b: Color, } /// Create a material pattern that alternates between the given colors along each unit of the /// X-axis. The strip extends infinitely in the positive and negative Y and Z axes. /// /// # Examples /// ``` /// use rtchallenge::{patterns::stripe_pattern, BLACK, WHITE}; /// /// let pattern = stripe_pattern(BLACK, WHITE); /// assert_eq!(pattern.a, BLACK); /// assert_eq!(pattern.b, WHITE); /// ``` pub fn stripe_pattern(a: Color, b: Color) -> StripePattern { StripePattern { a, b } } impl StripePattern { /// Sample the color at the given point. /// /// # Examples /// ``` /// use rtchallenge::{patterns::stripe_pattern, tuples::point, BLACK, WHITE}; /// /// let pattern = stripe_pattern(WHITE, BLACK); /// /// for (p, want) in &[ /// // A stripe pattern is constant in y. /// (point(0., 0., 0.), WHITE), /// (point(0., 1., 0.), WHITE), /// (point(0., 2., 0.), WHITE), /// // A stripe pattern is constant in z. /// (point(0., 0., 0.), WHITE), /// (point(0., 0., 1.), WHITE), /// (point(0., 0., 2.), WHITE), /// // A stripe pattern alternates in z. /// (point(0., 0., 0.), WHITE), /// (point(0.9, 0., 0.), WHITE), /// (point(1., 0., 0.), BLACK), /// (point(-0.1, 0., 0.), BLACK), /// (point(-1., 0., 0.), BLACK), /// (point(-1.1, 0., 0.), WHITE), /// ] { /// assert_eq!(pattern.stripe_at(*p), *want, "{:?}", p); /// } /// ``` pub fn stripe_at(&self, point: Tuple) -> Color { let x = point.x.floor() as i64; // Shift negative valued to get correct striping. if x < 0 { x - 1 } else { x }; if x % 2 == 0 { self.a } else { self.b } } }