68 lines
1.9 KiB
Rust
68 lines
1.9 KiB
Rust
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
|
|
}
|
|
}
|
|
}
|