camera: moving another doctest to unit
This commit is contained in:
parent
e3d8988658
commit
3838efd134
@ -118,27 +118,6 @@ enum Response {
|
||||
impl Camera {
|
||||
/// Create a camera with a canvas of pixel hsize (height) and vsize (width)
|
||||
/// with the given field of view (in radians).
|
||||
///
|
||||
/// # Examples
|
||||
/// ```
|
||||
/// use rtchallenge::{camera::Camera, float::consts::PI, matrices::Matrix4x4, EPSILON};
|
||||
///
|
||||
/// let hsize = 160;
|
||||
/// let vsize = 120;
|
||||
/// let field_of_view = PI / 2.;
|
||||
/// let c = Camera::new(hsize, vsize, field_of_view);
|
||||
/// assert_eq!(c.hsize(), 160);
|
||||
/// assert_eq!(c.vsize(), 120);
|
||||
/// assert_eq!(c.transform(), Matrix4x4::identity());
|
||||
///
|
||||
/// // Pixel size for a horizontal canvas.
|
||||
/// let c = Camera::new(200, 150, PI / 2.);
|
||||
/// assert!((c.pixel_size() - 0.010).abs() < EPSILON);
|
||||
///
|
||||
/// // Pixel size for a horizontal canvas.
|
||||
/// let c = Camera::new(150, 200, PI / 2.);
|
||||
/// assert!((c.pixel_size() - 0.010).abs() < EPSILON);
|
||||
/// ```
|
||||
pub fn new(hsize: usize, vsize: usize, field_of_view: Float) -> Camera {
|
||||
let half_view = (field_of_view / 2.).tan();
|
||||
let aspect = hsize as Float / vsize as Float;
|
||||
@ -208,35 +187,6 @@ impl Camera {
|
||||
|
||||
/// Calculate ray that starts at the camera and passes through the (x,y)
|
||||
/// pixel on the canvas.
|
||||
///
|
||||
/// # Examples
|
||||
/// ```
|
||||
/// use rtchallenge::{
|
||||
/// camera::Camera, float::consts::PI, matrices::Matrix4x4, tuples::Tuple, Float,
|
||||
/// };
|
||||
///
|
||||
/// // Constructing a ray through the center of the canvas.
|
||||
/// let c = Camera::new(201, 101, PI / 2.);
|
||||
/// let r = c.ray_for_pixel(100, 50);
|
||||
/// assert_eq!(r.origin, Tuple::point(0., 0., 0.));
|
||||
/// assert_eq!(r.direction, Tuple::vector(0., 0., -1.));
|
||||
///
|
||||
/// // Constructing a ray through the corner of the canvas.
|
||||
/// let c = Camera::new(201, 101, PI / 2.);
|
||||
/// let r = c.ray_for_pixel(0, 0);
|
||||
/// assert_eq!(r.origin, Tuple::point(0., 0., 0.));
|
||||
/// assert_eq!(r.direction, Tuple::vector(0.66519, 0.33259, -0.66851));
|
||||
///
|
||||
/// // Constructing a ray when the camera is transformed.
|
||||
/// let mut c = Camera::new(201, 101, PI / 2.);
|
||||
/// c.set_transform(Matrix4x4::rotation_y(PI / 4.) * Matrix4x4::translation(0., -2., 5.));
|
||||
/// let r = c.ray_for_pixel(100, 50);
|
||||
/// assert_eq!(r.origin, Tuple::point(0., 2., -5.));
|
||||
/// assert_eq!(
|
||||
/// r.direction,
|
||||
/// Tuple::vector((2. as Float).sqrt() / 2., 0., -(2. as Float).sqrt() / 2.)
|
||||
/// );
|
||||
/// ```
|
||||
pub fn ray_for_pixel(&self, px: usize, py: usize) -> Ray {
|
||||
// The offset from the edge of the canvas to the pixel's corner.
|
||||
let xoffset = (px as Float + 0.5) * self.pixel_size;
|
||||
@ -258,26 +208,6 @@ impl Camera {
|
||||
}
|
||||
|
||||
/// Use camera to render an image of the given world.
|
||||
/// # Examples
|
||||
/// ```
|
||||
/// use rtchallenge::{
|
||||
/// camera::Camera,
|
||||
/// float::consts::PI,
|
||||
/// transformations::view_transform,
|
||||
/// tuples::{Color, Tuple},
|
||||
/// world::World,
|
||||
/// };
|
||||
///
|
||||
/// // Rendering a world with a camera.
|
||||
/// let w = World::test_world();
|
||||
/// let mut c = Camera::new(11, 11, PI / 2.);
|
||||
/// let from = Tuple::point(0., 0., -5.);
|
||||
/// let to = Tuple::point(0., 0., 0.);
|
||||
/// let up = Tuple::vector(0., 1., 0.);
|
||||
/// c.set_transform(view_transform(from, to, up));
|
||||
/// let image = c.render(&w);
|
||||
/// assert_eq!(image.get(5, 5), Color::new(0.38066, 0.47583, 0.2855));
|
||||
/// ```
|
||||
pub fn render(&self, w: &World) -> Canvas {
|
||||
use RenderStrategy::*;
|
||||
|
||||
@ -437,3 +367,70 @@ fn render_worker_task(
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::{
|
||||
camera::Camera,
|
||||
float::consts::PI,
|
||||
matrices::Matrix4x4,
|
||||
transformations::view_transform,
|
||||
tuples::{point, vector},
|
||||
world::World,
|
||||
Float, EPSILON,
|
||||
};
|
||||
#[test]
|
||||
fn new() {
|
||||
let hsize = 160;
|
||||
let vsize = 120;
|
||||
let field_of_view = PI / 2.;
|
||||
let c = Camera::new(hsize, vsize, field_of_view);
|
||||
assert_eq!(c.hsize(), 160);
|
||||
assert_eq!(c.vsize(), 120);
|
||||
assert_eq!(c.transform(), Matrix4x4::identity());
|
||||
|
||||
// Pixel size for a horizontal canvas.
|
||||
let c = Camera::new(200, 150, PI / 2.);
|
||||
assert!((c.pixel_size() - 0.010).abs() < EPSILON);
|
||||
|
||||
// Pixel size for a horizontal canvas.
|
||||
let c = Camera::new(150, 200, PI / 2.);
|
||||
assert!((c.pixel_size() - 0.010).abs() < EPSILON);
|
||||
}
|
||||
#[test]
|
||||
fn ray_for_pixel() {
|
||||
// Constructing a ray through the center of the canvas.
|
||||
let c = Camera::new(201, 101, PI / 2.);
|
||||
let r = c.ray_for_pixel(100, 50);
|
||||
assert_eq!(r.origin, point(0., 0., 0.));
|
||||
assert_eq!(r.direction, vector(0., 0., -1.));
|
||||
|
||||
// Constructing a ray through the corner of the canvas.
|
||||
let c = Camera::new(201, 101, PI / 2.);
|
||||
let r = c.ray_for_pixel(0, 0);
|
||||
assert_eq!(r.origin, point(0., 0., 0.));
|
||||
assert_eq!(r.direction, vector(0.66519, 0.33259, -0.66851));
|
||||
|
||||
// Constructing a ray when the camera is transformed.
|
||||
let mut c = Camera::new(201, 101, PI / 2.);
|
||||
c.set_transform(Matrix4x4::rotation_y(PI / 4.) * Matrix4x4::translation(0., -2., 5.));
|
||||
let r = c.ray_for_pixel(100, 50);
|
||||
assert_eq!(r.origin, point(0., 2., -5.));
|
||||
assert_eq!(
|
||||
r.direction,
|
||||
vector((2. as Float).sqrt() / 2., 0., -(2. as Float).sqrt() / 2.)
|
||||
);
|
||||
}
|
||||
#[test]
|
||||
fn render() {
|
||||
// Rendering a world with a camera.
|
||||
let w = World::test_world();
|
||||
let mut c = Camera::new(11, 11, PI / 2.);
|
||||
let from = point(0., 0., -5.);
|
||||
let to = point(0., 0., 0.);
|
||||
let up = vector(0., 1., 0.);
|
||||
c.set_transform(view_transform(from, to, up));
|
||||
let image = c.render(&w);
|
||||
assert_eq!(image.get(5, 5), [0.38066, 0.47583, 0.2855].into());
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user