library: core: document film module

This commit is contained in:
Antoine Martin 2020-03-21 19:24:07 +01:00
parent 07dbad95b5
commit b71f0aee5a
1 changed files with 92 additions and 0 deletions

View File

@ -1,3 +1,5 @@
//! Camera film logic
use crate::{Point, Vector};
/// Represent an abstract camera film, to know where each pixel is in space.
@ -11,6 +13,23 @@ pub struct Film {
}
impl Film {
/// Creates a new `Film`.
///
/// # Examples
///
/// ```
/// # use pathtracer::core::Film;
/// # use pathtracer::{Point, Vector};
/// #
/// let film = Film::new(
/// 1080,
/// 1080,
/// 10.0,
/// Point::origin(),
/// Vector::new(0.0, 1.0, 0.0),
/// Vector::new(1.0, 0.0, 0.0)
/// );
/// ```
pub fn new(x: u32, y: u32, screen_size: f32, center: Point, up: Vector, right: Vector) -> Self {
let (x_size, y_size) = if x > y {
(screen_size, screen_size * y as f32 / x as f32)
@ -26,30 +45,103 @@ impl Film {
}
}
/// Get the `Film`'s width.
///
/// # Examples
///
/// ```
/// # use pathtracer::core::Film;
/// #
/// let film = Film::default();
/// let width: u32 = film.width();
/// ```
pub fn width(&self) -> u32 {
self.x
}
/// Get the `Film`'s height.
///
/// # Examples
///
/// ```
/// # use pathtracer::core::Film;
/// #
/// let film = Film::default();
/// let height: u32 = film.height();
/// ```
pub fn height(&self) -> u32 {
self.y
}
/// Get a ratio of the pixel's position on the screen.
///
/// # Examples
///
/// ```
/// # use pathtracer::core::Film;
/// #
/// let film = Film::default(); // 1080x1080 film, width of 1.0
/// let (x, y) = film.pixel_ratio(108.0, 972.0);
/// assert_eq!(x, 0.1);
/// assert_eq!(y, 0.9);
/// ```
pub fn pixel_ratio(&self, x: f32, y: f32) -> (f32, f32) {
(x / self.x as f32, y / self.y as f32)
}
/// Get a pixel's absolute position from a relative screen ratio.
///
/// # Examples
///
/// ```
/// # use pathtracer::core::Film;
/// use pathtracer::Point;
///
/// let film = Film::default(); // 1080x1080 film, width of 1.0
/// let (x, y) = film.pixel_ratio(108.0, 1080.0);
/// let pos: Point = film.pixel_at_ratio(x, y);
/// assert_eq!(pos, Point::new(-0.4, -0.5, 0.0));
/// ```
pub fn pixel_at_ratio(&self, x: f32, y: f32) -> Point {
let delt_x = x - 0.5;
let delt_y = 0.5 - y;
self.center + self.ratio_right * delt_x + self.ratio_up * delt_y
}
/// Get a pixel's absolute position from screen coordinates.
///
/// # Examples
///
/// ```
/// # use pathtracer::core::Film;
/// use pathtracer::Point;
///
/// let film = Film::default(); // 1080x1080 film, width of 1.0
/// let pos: Point = film.pixel_at_coord(108, 1080);
/// assert_eq!(pos, Point::new(-0.4, -0.5, 0.0));
/// ```
pub fn pixel_at_coord(&self, x: u32, y: u32) -> Point {
let (x, y) = self.pixel_ratio(x as f32, y as f32);
self.pixel_at_ratio(x, y)
}
}
impl Default for Film {
/// Creates a simple 1080x1080 `Film`.
///
/// The screen size is 1.0, and the screen is centered at the origin.
fn default() -> Self {
Film::new(
1080,
1080,
1.0,
Point::origin(),
Vector::new(0.0, 1.0, 0.0),
Vector::new(1.0, 0.0, 0.0),
)
}
}
#[cfg(test)]
mod test {
use super::*;