patterns: implement checker pattern.
This commit is contained in:
parent
77215193fa
commit
68709da6c2
@ -45,7 +45,7 @@ pub mod prelude {
|
||||
lights::{PointLight, PointLightBuilder},
|
||||
materials::{Material, MaterialBuilder},
|
||||
matrices::{identity, rotation_x, rotation_y, rotation_z, scaling, shearing, translation},
|
||||
patterns::{gradient_pattern, ring_pattern, stripe_pattern},
|
||||
patterns::{checkers_pattern, gradient_pattern, ring_pattern, stripe_pattern},
|
||||
shapes::{plane, sphere, test_shape},
|
||||
transformations::view_transform,
|
||||
tuples::{point, vector, Color},
|
||||
|
||||
@ -20,6 +20,8 @@ pub enum ColorMapper {
|
||||
Gradient { a: Color, b: Color },
|
||||
/// Bullseye pattern in the XZ plane.
|
||||
Ring { a: Color, b: Color },
|
||||
/// Traditional ray tracer tile floor pattern.
|
||||
Checkers { a: Color, b: Color },
|
||||
}
|
||||
|
||||
#[derive(Builder, Debug, PartialEq, Clone)]
|
||||
@ -150,6 +152,28 @@ pub fn ring_pattern(a: Color, b: Color) -> PatternBuilder {
|
||||
PatternBuilder::default().color(ColorMapper::Ring { a, b })
|
||||
}
|
||||
|
||||
/// Builder for creating a material pattern that alternates between the given colors along the X, Y
|
||||
/// and Z pattern. Creates traditional ray tracer tile floor pattern.
|
||||
///
|
||||
/// # Examples
|
||||
/// ```
|
||||
/// use rtchallenge::{
|
||||
/// patterns::{checkers_pattern, ColorMapper},
|
||||
/// BLACK, WHITE,
|
||||
/// };
|
||||
///
|
||||
/// # fn main() -> Result<(), Box<std::error::Error>> {
|
||||
///
|
||||
/// let pattern = checkers_pattern(BLACK, WHITE).build()?;
|
||||
/// assert_eq!(pattern.color, ColorMapper::Checkers { a: BLACK, b: WHITE });
|
||||
///
|
||||
/// # Ok(())
|
||||
/// # }
|
||||
/// ```
|
||||
pub fn checkers_pattern(a: Color, b: Color) -> PatternBuilder {
|
||||
PatternBuilder::default().color(ColorMapper::Checkers { a, b })
|
||||
}
|
||||
|
||||
/// Generic implementation for mapping points to colors according to the given [ColorMapper].
|
||||
impl Pattern {
|
||||
/// Create a pattern used for testing. The color returned is the pattern space point
|
||||
@ -236,6 +260,25 @@ impl Pattern {
|
||||
}
|
||||
}
|
||||
|
||||
/// Create a pattern that alternates between the given colors along the X, Y and Z axis.
|
||||
///
|
||||
/// # Examples
|
||||
/// ```
|
||||
/// use rtchallenge::{
|
||||
/// patterns::{ColorMapper, Pattern},
|
||||
/// BLACK, WHITE,
|
||||
/// };
|
||||
///
|
||||
/// let pattern = Pattern::checkers(BLACK, WHITE);
|
||||
/// assert_eq!(pattern.color, ColorMapper::Checkers { a: BLACK, b: WHITE });
|
||||
/// ```
|
||||
pub fn checkers(a: Color, b: Color) -> Pattern {
|
||||
Pattern {
|
||||
color: ColorMapper::Checkers { a, b },
|
||||
..Pattern::default()
|
||||
}
|
||||
}
|
||||
|
||||
/// Sample the color at the given point in untranslated object space.
|
||||
///
|
||||
/// # Examples
|
||||
@ -292,6 +335,24 @@ impl Pattern {
|
||||
/// assert_eq!(pattern.pattern_at(point(0., 0., 1.)), BLACK);
|
||||
/// // 0.708 is slight more than 2.sqrt()/2.
|
||||
/// assert_eq!(pattern.pattern_at(point(0.708, 0., 0.708)), BLACK);
|
||||
///
|
||||
/// // Checkers should repeat along X-axis.
|
||||
/// let pattern = Pattern::checkers(WHITE, BLACK);
|
||||
/// assert_eq!(pattern.pattern_at(point(0., 0., 0.)), WHITE);
|
||||
/// assert_eq!(pattern.pattern_at(point(0.99, 0., 0.)), WHITE);
|
||||
/// assert_eq!(pattern.pattern_at(point(1.01, 0., 0.)), BLACK);
|
||||
///
|
||||
/// // Checkers should repeat along Y-axis.
|
||||
/// let pattern = Pattern::checkers(WHITE, BLACK);
|
||||
/// assert_eq!(pattern.pattern_at(point(0., 0., 0.)), WHITE);
|
||||
/// assert_eq!(pattern.pattern_at(point(0., 0.99, 0.)), WHITE);
|
||||
/// assert_eq!(pattern.pattern_at(point(0., 1.01, 0.)), BLACK);
|
||||
///
|
||||
/// // Checkers should repeat along Z-axis.
|
||||
/// let pattern = Pattern::checkers(WHITE, BLACK);
|
||||
/// assert_eq!(pattern.pattern_at(point(0., 0., 0.)), WHITE);
|
||||
/// assert_eq!(pattern.pattern_at(point(0., 0., 0.99)), WHITE);
|
||||
/// assert_eq!(pattern.pattern_at(point(0., 0., 1.01)), BLACK);
|
||||
/// ```
|
||||
pub fn pattern_at(&self, point: Tuple) -> Color {
|
||||
match self.color {
|
||||
@ -319,6 +380,14 @@ impl Pattern {
|
||||
b
|
||||
}
|
||||
}
|
||||
ColorMapper::Checkers { a, b } => {
|
||||
let d = point.x.floor() + point.y.floor() + point.z.floor();
|
||||
if d % 2. == 0. {
|
||||
a
|
||||
} else {
|
||||
b
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/// Sample the color at the given world point on the given object.
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user