all: s/f32/Float/g now using customer Float alias.
This commit is contained in:
parent
5d57304d95
commit
95de5863cc
@ -8,6 +8,7 @@ edition = "2018"
|
||||
|
||||
[features]
|
||||
disable_inverse_cache = []
|
||||
float-as-double = []
|
||||
|
||||
[dependencies]
|
||||
anyhow = "1.0.41"
|
||||
|
||||
@ -12,7 +12,9 @@ use rayon::iter::{IntoParallelIterator, ParallelIterator};
|
||||
use serde::Deserialize;
|
||||
use structopt::StructOpt;
|
||||
|
||||
use crate::{canvas::Canvas, matrices::Matrix4x4, rays::Ray, tuples::Tuple, world::World, BLACK};
|
||||
use crate::{
|
||||
canvas::Canvas, matrices::Matrix4x4, rays::Ray, tuples::Tuple, world::World, Float, BLACK,
|
||||
};
|
||||
|
||||
#[derive(Copy, Clone, StructOpt, Debug, Deserialize)]
|
||||
#[serde(rename_all = "kebab-case")]
|
||||
@ -32,12 +34,12 @@ impl FromStr for RenderStrategy {
|
||||
pub struct Camera {
|
||||
hsize: usize,
|
||||
vsize: usize,
|
||||
field_of_view: f32,
|
||||
field_of_view: Float,
|
||||
transform: Matrix4x4,
|
||||
inverse_transform: Matrix4x4,
|
||||
pixel_size: f32,
|
||||
half_width: f32,
|
||||
half_height: f32,
|
||||
pixel_size: Float,
|
||||
half_width: Float,
|
||||
half_height: Float,
|
||||
pub render_strategy: RenderStrategy,
|
||||
}
|
||||
|
||||
@ -55,9 +57,7 @@ impl Camera {
|
||||
///
|
||||
/// # Examples
|
||||
/// ```
|
||||
/// use std::f32::consts::PI;
|
||||
///
|
||||
/// use rtchallenge::{camera::Camera, matrices::Matrix4x4};
|
||||
/// use rtchallenge::{camera::Camera, float::consts::PI, matrices::Matrix4x4};
|
||||
///
|
||||
/// let hsize = 160;
|
||||
/// let vsize = 120;
|
||||
@ -75,15 +75,15 @@ impl Camera {
|
||||
/// let c = Camera::new(150, 200, PI / 2.);
|
||||
/// assert_eq!(c.pixel_size(), 0.01);
|
||||
/// ```
|
||||
pub fn new(hsize: usize, vsize: usize, field_of_view: f32) -> Camera {
|
||||
pub fn new(hsize: usize, vsize: usize, field_of_view: Float) -> Camera {
|
||||
let half_view = (field_of_view / 2.).tan();
|
||||
let aspect = hsize as f32 / vsize as f32;
|
||||
let aspect = hsize as Float / vsize as Float;
|
||||
let (half_width, half_height) = if aspect >= 1. {
|
||||
(half_view, half_view / aspect)
|
||||
} else {
|
||||
(half_view * aspect, half_view)
|
||||
};
|
||||
let pixel_size = 2. * half_width / hsize as f32;
|
||||
let pixel_size = 2. * half_width / hsize as Float;
|
||||
Camera {
|
||||
hsize,
|
||||
vsize,
|
||||
@ -102,7 +102,7 @@ impl Camera {
|
||||
pub fn vsize(&self) -> usize {
|
||||
self.vsize
|
||||
}
|
||||
pub fn field_of_view(&self) -> f32 {
|
||||
pub fn field_of_view(&self) -> Float {
|
||||
self.field_of_view
|
||||
}
|
||||
pub fn transform(&self) -> Matrix4x4 {
|
||||
@ -112,7 +112,7 @@ impl Camera {
|
||||
self.transform = t;
|
||||
self.inverse_transform = t.inverse();
|
||||
}
|
||||
pub fn pixel_size(&self) -> f32 {
|
||||
pub fn pixel_size(&self) -> Float {
|
||||
self.pixel_size
|
||||
}
|
||||
pub fn supersample_rays_for_pixel(&self, px: usize, py: usize, samples: usize) -> Vec<Ray> {
|
||||
@ -121,8 +121,8 @@ impl Camera {
|
||||
(0..samples)
|
||||
.map(|_| {
|
||||
// The offset from the edge of the canvas to the pixel's corner.
|
||||
let xoffset = (px as f32 + rng.gen::<f32>()) * self.pixel_size;
|
||||
let yoffset = (py as f32 + rng.gen::<f32>()) * self.pixel_size;
|
||||
let xoffset = (px as Float + rng.gen::<Float>()) * self.pixel_size;
|
||||
let yoffset = (py as Float + rng.gen::<Float>()) * self.pixel_size;
|
||||
|
||||
// The untransformed coordinates of the pixle in world space.
|
||||
// (Remember that the camera looks toward -z, so +x is to the left.)
|
||||
@ -146,9 +146,9 @@ impl Camera {
|
||||
///
|
||||
/// # Examples
|
||||
/// ```
|
||||
/// use std::f32::consts::PI;
|
||||
///
|
||||
/// use rtchallenge::{camera::Camera, matrices::Matrix4x4, tuples::Tuple};
|
||||
/// 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.);
|
||||
@ -169,14 +169,14 @@ impl Camera {
|
||||
/// assert_eq!(r.origin, Tuple::point(0., 2., -5.));
|
||||
/// assert_eq!(
|
||||
/// r.direction,
|
||||
/// Tuple::vector(2_f32.sqrt() / 2., 0., -2_f32.sqrt() / 2.)
|
||||
/// Tuple::vector((2. as Float).sqrt() / 2., 0., -(2. as Float).sqrt() / 2.)
|
||||
/// );
|
||||
/// ```
|
||||
#[cfg(not(feature = "disable_inverse_cache"))]
|
||||
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 f32 + 0.5) * self.pixel_size;
|
||||
let yoffset = (py as f32 + 0.5) * self.pixel_size;
|
||||
let xoffset = (px as Float + 0.5) * self.pixel_size;
|
||||
let yoffset = (py as Float + 0.5) * self.pixel_size;
|
||||
|
||||
// The untransformed coordinates of the pixle in world space.
|
||||
// (Remember that the camera looks toward -z, so +x is to the left.)
|
||||
@ -195,8 +195,8 @@ impl Camera {
|
||||
#[cfg(feature = "disable_inverse_cache")]
|
||||
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 f32 + 0.5) * self.pixel_size;
|
||||
let yoffset = (py as f32 + 0.5) * self.pixel_size;
|
||||
let xoffset = (px as Float + 0.5) * self.pixel_size;
|
||||
let yoffset = (py as Float + 0.5) * self.pixel_size;
|
||||
|
||||
// The untransformed coordinates of the pixle in world space.
|
||||
// (Remember that the camera looks toward -z, so +x is to the left.)
|
||||
@ -216,10 +216,9 @@ impl Camera {
|
||||
/// Use camera to render an image of the given world.
|
||||
/// # Examples
|
||||
/// ```
|
||||
/// use std::f32::consts::PI;
|
||||
///
|
||||
/// use rtchallenge::{
|
||||
/// camera::Camera,
|
||||
/// float::consts::PI,
|
||||
/// transformations::view_transform,
|
||||
/// tuples::{Color, Tuple},
|
||||
/// world::World,
|
||||
@ -330,7 +329,7 @@ impl Camera {
|
||||
.iter()
|
||||
.map(|ray| w.color_at(&ray))
|
||||
.fold(BLACK, |acc, c| acc + c);
|
||||
row_image.set(x, 0, color / SAMPLES as f32);
|
||||
row_image.set(x, 0, color / SAMPLES as Float);
|
||||
} else {
|
||||
let ray = self.ray_for_pixel(x, y);
|
||||
let color = w.color_at(&ray);
|
||||
|
||||
@ -4,12 +4,12 @@ use crate::{
|
||||
rays::Ray,
|
||||
spheres::Sphere,
|
||||
tuples::{dot, Tuple},
|
||||
EPSILON,
|
||||
Float, EPSILON,
|
||||
};
|
||||
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub struct Intersection<'i> {
|
||||
pub t: f32,
|
||||
pub t: Float,
|
||||
pub object: &'i Sphere,
|
||||
}
|
||||
|
||||
@ -26,7 +26,7 @@ impl<'i> Intersection<'i> {
|
||||
/// assert_eq!(i.t, 3.5);
|
||||
/// assert_eq!(i.object, &s);
|
||||
/// ```
|
||||
pub fn new(t: f32, object: &Sphere) -> Intersection {
|
||||
pub fn new(t: Float, object: &Sphere) -> Intersection {
|
||||
Intersection { t, object }
|
||||
}
|
||||
}
|
||||
@ -137,7 +137,7 @@ impl<'i> Index<usize> for Intersections<'i> {
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct PrecomputedData<'i> {
|
||||
pub t: f32,
|
||||
pub t: Float,
|
||||
pub object: &'i Sphere,
|
||||
pub point: Tuple,
|
||||
pub over_point: Tuple,
|
||||
|
||||
@ -11,7 +11,29 @@ pub mod tuples;
|
||||
pub mod world;
|
||||
|
||||
/// Value considered close enough for PartialEq implementations.
|
||||
pub const EPSILON: f32 = 0.00001;
|
||||
pub const EPSILON: Float = 0.00001;
|
||||
|
||||
pub const BLACK: tuples::Color = tuples::Color::new(0., 0., 0.);
|
||||
pub const WHITE: tuples::Color = tuples::Color::new(1., 1., 1.);
|
||||
|
||||
#[cfg(feature = "float-as-double")]
|
||||
/// submodule to defined types, constants and methods when `Float` is defined as a `f64` using the
|
||||
/// "float-as-double" cargo feature.
|
||||
pub mod float {
|
||||
pub use std::f64::*;
|
||||
/// Alias of the `f64` type, to be used through out the codebase anywhere a default sized
|
||||
/// `Float` is necessary.
|
||||
pub type Float = f64;
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "float-as-double"))]
|
||||
/// submodule to defined types, constants and methods when `Float` is defined as a `f32` when not using the
|
||||
/// "float-as-double" cargo feature.
|
||||
pub mod float {
|
||||
pub use std::f32::*;
|
||||
/// Alias of the `f32` type, to be used through out the codebase anywhere a default sized
|
||||
/// `Float` is necessary.
|
||||
pub type Float = f32;
|
||||
}
|
||||
|
||||
pub use float::Float;
|
||||
|
||||
@ -2,15 +2,15 @@ use crate::{
|
||||
lights::PointLight,
|
||||
tuples::Color,
|
||||
tuples::{dot, reflect, Tuple},
|
||||
BLACK, WHITE,
|
||||
Float, BLACK, WHITE,
|
||||
};
|
||||
#[derive(Debug, PartialEq, Clone)]
|
||||
pub struct Material {
|
||||
pub color: Color,
|
||||
pub ambient: f32,
|
||||
pub diffuse: f32,
|
||||
pub specular: f32,
|
||||
pub shininess: f32,
|
||||
pub ambient: Float,
|
||||
pub diffuse: Float,
|
||||
pub specular: Float,
|
||||
pub shininess: Float,
|
||||
}
|
||||
|
||||
impl Default for Material {
|
||||
@ -51,7 +51,7 @@ impl Default for Material {
|
||||
/// lights::PointLight,
|
||||
/// materials::{lighting, Material},
|
||||
/// tuples::{Color, Tuple},
|
||||
/// WHITE,
|
||||
/// Float, WHITE,
|
||||
/// };
|
||||
///
|
||||
/// let in_shadow = false;
|
||||
@ -66,7 +66,7 @@ impl Default for Material {
|
||||
/// assert_eq!(result, Color::new(1.9, 1.9, 1.9));
|
||||
///
|
||||
/// // Lighting with the eye between the light and the surface, eye offset 45°.
|
||||
/// let eyev = Tuple::vector(0., 2_f32.sqrt() / 2., -2_f32.sqrt() / 2.);
|
||||
/// let eyev = Tuple::vector(0., (2. as Float).sqrt() / 2., -(2. as Float).sqrt() / 2.);
|
||||
/// let normalv = Tuple::vector(0., 0., -1.);
|
||||
/// let light = PointLight::new(Tuple::point(0., 0., -10.), WHITE);
|
||||
/// let result = lighting(&m, &light, position, eyev, normalv, in_shadow);
|
||||
@ -80,7 +80,7 @@ impl Default for Material {
|
||||
/// assert_eq!(result, Color::new(0.7364, 0.7364, 0.7364));
|
||||
///
|
||||
/// // Lighting with the eye in the path of the reflection vector.
|
||||
/// let eyev = Tuple::vector(0., -2_f32.sqrt() / 2., -2_f32.sqrt() / 2.);
|
||||
/// let eyev = Tuple::vector(0., -(2.0 as Float).sqrt() / 2., -(2.0 as Float).sqrt() / 2.);
|
||||
/// let normalv = Tuple::vector(0., 0., -1.);
|
||||
/// let light = PointLight::new(Tuple::point(0., 10., -10.), WHITE);
|
||||
/// let result = lighting(&m, &light, position, eyev, normalv, in_shadow);
|
||||
|
||||
@ -1,15 +1,15 @@
|
||||
use std::fmt;
|
||||
use std::ops::{Index, IndexMut, Mul, Sub};
|
||||
|
||||
use crate::{tuples::Tuple, EPSILON};
|
||||
use crate::{tuples::Tuple, Float, EPSILON};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Matrix2x2 {
|
||||
m: [[f32; 2]; 2],
|
||||
m: [[Float; 2]; 2],
|
||||
}
|
||||
impl Matrix2x2 {
|
||||
/// Create a `Matrix2x2` with each of the given rows.
|
||||
pub fn new(r0: [f32; 2], r1: [f32; 2]) -> Matrix2x2 {
|
||||
pub fn new(r0: [Float; 2], r1: [Float; 2]) -> Matrix2x2 {
|
||||
Matrix2x2 { m: [r0, r1] }
|
||||
}
|
||||
|
||||
@ -24,13 +24,13 @@ impl Matrix2x2 {
|
||||
///
|
||||
/// assert_eq!(a.determinant(), 17.);
|
||||
/// ```
|
||||
pub fn determinant(&self) -> f32 {
|
||||
pub fn determinant(&self) -> Float {
|
||||
let m = self;
|
||||
m[(0, 0)] * m[(1, 1)] - m[(0, 1)] * m[(1, 0)]
|
||||
}
|
||||
}
|
||||
impl Index<(usize, usize)> for Matrix2x2 {
|
||||
type Output = f32;
|
||||
type Output = Float;
|
||||
fn index(&self, (row, col): (usize, usize)) -> &Self::Output {
|
||||
&self.m[row][col]
|
||||
}
|
||||
@ -53,11 +53,11 @@ impl PartialEq for Matrix2x2 {
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Matrix3x3 {
|
||||
m: [[f32; 3]; 3],
|
||||
m: [[Float; 3]; 3],
|
||||
}
|
||||
impl Matrix3x3 {
|
||||
/// Create a `Matrix3x2` with each of the given rows.
|
||||
pub fn new(r0: [f32; 3], r1: [f32; 3], r2: [f32; 3]) -> Matrix3x3 {
|
||||
pub fn new(r0: [Float; 3], r1: [Float; 3], r2: [Float; 3]) -> Matrix3x3 {
|
||||
Matrix3x3 { m: [r0, r1, r2] }
|
||||
}
|
||||
/// submatrix extracts a 2x2 matrix ignoring the 0-based `row` and `col` given.
|
||||
@ -101,7 +101,7 @@ impl Matrix3x3 {
|
||||
/// assert_eq!(b.determinant(), 25.0);
|
||||
/// assert_eq!(b.determinant(), a.minor(1, 0));
|
||||
/// ```
|
||||
pub fn minor(&self, row: usize, col: usize) -> f32 {
|
||||
pub fn minor(&self, row: usize, col: usize) -> Float {
|
||||
self.submatrix(row, col).determinant()
|
||||
}
|
||||
|
||||
@ -117,7 +117,7 @@ impl Matrix3x3 {
|
||||
/// assert_eq!(a.minor(1, 0), 25.);
|
||||
/// assert_eq!(a.cofactor(1, 0), -25.);
|
||||
/// ```
|
||||
pub fn cofactor(&self, row: usize, col: usize) -> f32 {
|
||||
pub fn cofactor(&self, row: usize, col: usize) -> Float {
|
||||
let negate = if (row + col) % 2 == 0 { 1. } else { -1. };
|
||||
self.submatrix(row, col).determinant() * negate
|
||||
}
|
||||
@ -134,12 +134,12 @@ impl Matrix3x3 {
|
||||
/// assert_eq!(a.cofactor(0, 2), -46.);
|
||||
/// assert_eq!(a.determinant(), -196.);
|
||||
/// ```
|
||||
pub fn determinant(&self) -> f32 {
|
||||
pub fn determinant(&self) -> Float {
|
||||
(0..3).map(|i| self.cofactor(0, i) * self[(0, i)]).sum()
|
||||
}
|
||||
}
|
||||
impl Index<(usize, usize)> for Matrix3x3 {
|
||||
type Output = f32;
|
||||
type Output = Float;
|
||||
fn index(&self, (row, col): (usize, usize)) -> &Self::Output {
|
||||
&self.m[row][col]
|
||||
}
|
||||
@ -166,9 +166,7 @@ impl PartialEq for Matrix3x3 {
|
||||
///
|
||||
/// # Examples
|
||||
/// ```
|
||||
/// use std::f32::consts::PI;
|
||||
///
|
||||
/// use rtchallenge::{matrices::Matrix4x4, tuples::Tuple};
|
||||
/// use rtchallenge::{float::consts::PI, matrices::Matrix4x4, tuples::Tuple};
|
||||
///
|
||||
/// // Individual transformations are applied in sequence.
|
||||
/// let p = Tuple::point(1., 0., 1.);
|
||||
@ -195,11 +193,11 @@ impl PartialEq for Matrix3x3 {
|
||||
/// ```
|
||||
#[derive(Copy, Clone, Default)]
|
||||
pub struct Matrix4x4 {
|
||||
m: [[f32; 4]; 4],
|
||||
m: [[Float; 4]; 4],
|
||||
}
|
||||
|
||||
impl From<[f32; 16]> for Matrix4x4 {
|
||||
fn from(t: [f32; 16]) -> Self {
|
||||
impl From<[Float; 16]> for Matrix4x4 {
|
||||
fn from(t: [Float; 16]) -> Self {
|
||||
Matrix4x4 {
|
||||
m: [
|
||||
[t[0], t[1], t[2], t[3]],
|
||||
@ -238,7 +236,7 @@ impl Matrix4x4 {
|
||||
}
|
||||
|
||||
/// Create a `Matrix4x4` with each of the given rows.
|
||||
pub fn new(r0: [f32; 4], r1: [f32; 4], r2: [f32; 4], r3: [f32; 4]) -> Matrix4x4 {
|
||||
pub fn new(r0: [Float; 4], r1: [Float; 4], r2: [Float; 4], r3: [Float; 4]) -> Matrix4x4 {
|
||||
Matrix4x4 {
|
||||
m: [r0, r1, r2, r3],
|
||||
}
|
||||
@ -261,7 +259,7 @@ impl Matrix4x4 {
|
||||
/// let v = Tuple::vector(-3., 4., 5.);
|
||||
/// assert_eq!(transform * v, v);
|
||||
/// ```
|
||||
pub fn translation(x: f32, y: f32, z: f32) -> Matrix4x4 {
|
||||
pub fn translation(x: Float, y: Float, z: Float) -> Matrix4x4 {
|
||||
Matrix4x4::new(
|
||||
[1., 0., 0., x],
|
||||
[0., 1., 0., y],
|
||||
@ -295,7 +293,7 @@ impl Matrix4x4 {
|
||||
/// let p = Tuple::point(2., 3., 4.);
|
||||
/// assert_eq!(transform * p, Tuple::point(-2., 3., 4.));
|
||||
/// ```
|
||||
pub fn scaling(x: f32, y: f32, z: f32) -> Matrix4x4 {
|
||||
pub fn scaling(x: Float, y: Float, z: Float) -> Matrix4x4 {
|
||||
Matrix4x4::new(
|
||||
[x, 0., 0., 0.],
|
||||
[0., y, 0., 0.],
|
||||
@ -309,9 +307,7 @@ impl Matrix4x4 {
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use std::f32::consts::PI;
|
||||
///
|
||||
/// use rtchallenge::{matrices::Matrix4x4, tuples::Tuple};
|
||||
/// use rtchallenge::{float::consts::PI, matrices::Matrix4x4, tuples::Tuple, Float};
|
||||
///
|
||||
/// // A scaling matrix applied to a point.
|
||||
/// let p = Tuple::point(0., 1., 0.);
|
||||
@ -320,11 +316,11 @@ impl Matrix4x4 {
|
||||
///
|
||||
/// assert_eq!(
|
||||
/// half_quarter * p,
|
||||
/// Tuple::point(0., 2_f32.sqrt() / 2., 2_f32.sqrt() / 2.)
|
||||
/// Tuple::point(0., (2.0 as Float).sqrt() / 2., (2.0 as Float).sqrt() / 2.)
|
||||
/// );
|
||||
/// assert_eq!(full_quarter * p, Tuple::point(0., 0., 1.),);
|
||||
/// ```
|
||||
pub fn rotation_x(radians: f32) -> Matrix4x4 {
|
||||
pub fn rotation_x(radians: Float) -> Matrix4x4 {
|
||||
let r = radians;
|
||||
Matrix4x4::new(
|
||||
[1., 0., 0., 0.],
|
||||
@ -339,9 +335,7 @@ impl Matrix4x4 {
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use std::f32::consts::PI;
|
||||
///
|
||||
/// use rtchallenge::{matrices::Matrix4x4, tuples::Tuple};
|
||||
/// use rtchallenge::{float::consts::PI, matrices::Matrix4x4, tuples::Tuple, Float};
|
||||
///
|
||||
/// // A scaling matrix applied to a point.
|
||||
/// let p = Tuple::point(0., 0., 1.);
|
||||
@ -350,11 +344,11 @@ impl Matrix4x4 {
|
||||
///
|
||||
/// assert_eq!(
|
||||
/// half_quarter * p,
|
||||
/// Tuple::point(2_f32.sqrt() / 2., 0., 2_f32.sqrt() / 2.)
|
||||
/// Tuple::point((2.0 as Float).sqrt() / 2., 0., (2.0 as Float).sqrt() / 2.)
|
||||
/// );
|
||||
/// assert_eq!(full_quarter * p, Tuple::point(1., 0., 0.,),);
|
||||
/// ```
|
||||
pub fn rotation_y(radians: f32) -> Matrix4x4 {
|
||||
pub fn rotation_y(radians: Float) -> Matrix4x4 {
|
||||
let r = radians;
|
||||
Matrix4x4::new(
|
||||
[r.cos(), 0., r.sin(), 0.],
|
||||
@ -369,9 +363,7 @@ impl Matrix4x4 {
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use std::f32::consts::PI;
|
||||
///
|
||||
/// use rtchallenge::{matrices::Matrix4x4, tuples::Tuple};
|
||||
/// use rtchallenge::{float::consts::PI, matrices::Matrix4x4, tuples::Tuple, Float};
|
||||
///
|
||||
/// // A scaling matrix applied to a point.
|
||||
/// let p = Tuple::point(0., 1., 0.);
|
||||
@ -380,11 +372,11 @@ impl Matrix4x4 {
|
||||
///
|
||||
/// assert_eq!(
|
||||
/// half_quarter * p,
|
||||
/// Tuple::point(-2_f32.sqrt() / 2., 2_f32.sqrt() / 2., 0.)
|
||||
/// Tuple::point(-(2.0 as Float).sqrt() / 2., (2.0 as Float).sqrt() / 2., 0.)
|
||||
/// );
|
||||
/// assert_eq!(full_quarter * p, Tuple::point(-1., 0., 0.,),);
|
||||
/// ```
|
||||
pub fn rotation_z(radians: f32) -> Matrix4x4 {
|
||||
pub fn rotation_z(radians: Float) -> Matrix4x4 {
|
||||
let r = radians;
|
||||
Matrix4x4::new(
|
||||
[r.cos(), -r.sin(), 0., 0.],
|
||||
@ -462,7 +454,7 @@ impl Matrix4x4 {
|
||||
/// let p = Tuple::point(2.,3.,4.);
|
||||
/// assert_eq!(transform * p, Tuple::point(2.,3.,7.));
|
||||
|
||||
pub fn shearing(xy: f32, xz: f32, yx: f32, yz: f32, zx: f32, zy: f32) -> Matrix4x4 {
|
||||
pub fn shearing(xy: Float, xz: Float, yx: Float, yz: Float, zx: Float, zy: Float) -> Matrix4x4 {
|
||||
Matrix4x4::new(
|
||||
[1., xy, xz, 0.],
|
||||
[yx, 1., yz, 0.],
|
||||
@ -503,7 +495,7 @@ impl Matrix4x4 {
|
||||
for i in 0..4 {
|
||||
let mut irow: usize = 0;
|
||||
let mut icol: usize = 0;
|
||||
let mut big: f32 = 0.;
|
||||
let mut big: Float = 0.;
|
||||
// Choose pivot
|
||||
for j in 0..4 {
|
||||
if ipiv[j] != 1 {
|
||||
@ -538,7 +530,7 @@ impl Matrix4x4 {
|
||||
}
|
||||
|
||||
// Set $m[icol][icol]$ to one by scaling row _icol_ appropriately
|
||||
let pivinv: f32 = minv[icol][icol].recip();
|
||||
let pivinv: Float = minv[icol][icol].recip();
|
||||
minv[icol][icol] = 1.;
|
||||
for j in 0..4 {
|
||||
minv[icol][j] *= pivinv;
|
||||
@ -606,11 +598,11 @@ impl Matrix4x4 {
|
||||
}
|
||||
|
||||
/// Compute minor of a 4x4 matrix.
|
||||
pub fn minor(&self, row: usize, col: usize) -> f32 {
|
||||
pub fn minor(&self, row: usize, col: usize) -> Float {
|
||||
self.submatrix(row, col).determinant()
|
||||
}
|
||||
/// Compute cofactor of a 4x4 matrix.
|
||||
pub fn cofactor(&self, row: usize, col: usize) -> f32 {
|
||||
pub fn cofactor(&self, row: usize, col: usize) -> Float {
|
||||
let negate = if (row + col) % 2 == 0 { 1. } else { -1. };
|
||||
self.submatrix(row, col).determinant() * negate
|
||||
}
|
||||
@ -632,7 +624,7 @@ impl Matrix4x4 {
|
||||
/// assert_eq!(a.cofactor(0, 3), 51.);
|
||||
/// assert_eq!(a.determinant(), -4071.);
|
||||
/// ```
|
||||
pub fn determinant(&self) -> f32 {
|
||||
pub fn determinant(&self) -> Float {
|
||||
(0..4).map(|i| self.cofactor(0, i) * self[(0, i)]).sum()
|
||||
}
|
||||
|
||||
@ -873,7 +865,7 @@ impl PartialEq for Matrix4x4 {
|
||||
}
|
||||
|
||||
impl Index<(usize, usize)> for Matrix4x4 {
|
||||
type Output = f32;
|
||||
type Output = Float;
|
||||
fn index(&self, (row, col): (usize, usize)) -> &Self::Output {
|
||||
&self.m[row][col]
|
||||
}
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
use crate::{matrices::Matrix4x4, tuples::Tuple};
|
||||
use crate::{matrices::Matrix4x4, tuples::Tuple, Float};
|
||||
|
||||
/// Rays have an origin and a direction. This datatype is the 'ray' in 'raytracer'.
|
||||
pub struct Ray {
|
||||
@ -38,7 +38,7 @@ impl Ray {
|
||||
/// assert_eq!(r.position(-1.), Tuple::point(1., 3., 4.));
|
||||
/// assert_eq!(r.position(2.5), Tuple::point(4.5, 3., 4.));
|
||||
/// ```
|
||||
pub fn position(&self, t: f32) -> Tuple {
|
||||
pub fn position(&self, t: Float) -> Tuple {
|
||||
self.origin + self.direction * t
|
||||
}
|
||||
|
||||
|
||||
@ -54,7 +54,7 @@ impl Sphere {
|
||||
///
|
||||
/// # Examples
|
||||
/// ```
|
||||
/// use rtchallenge::{matrices::Matrix4x4, spheres::Sphere, tuples::Tuple};
|
||||
/// use rtchallenge::{matrices::Matrix4x4, spheres::Sphere, tuples::Tuple,Float};
|
||||
///
|
||||
/// // Normal on X-axis
|
||||
/// let s = Sphere::default();
|
||||
@ -74,20 +74,20 @@ impl Sphere {
|
||||
/// // Normal on a sphere at a nonaxial point.
|
||||
/// let s = Sphere::default();
|
||||
/// let n = s.normal_at(Tuple::point(
|
||||
/// 3_f32.sqrt() / 3.,
|
||||
/// 3_f32.sqrt() / 3.,
|
||||
/// 3_f32.sqrt() / 3.,
|
||||
/// (3. as Float).sqrt() / 3.,
|
||||
/// (3. as Float).sqrt() / 3.,
|
||||
/// (3. as Float).sqrt() / 3.,
|
||||
/// ));
|
||||
/// assert_eq!(
|
||||
/// n,
|
||||
/// Tuple::vector(3_f32.sqrt() / 3., 3_f32.sqrt() / 3., 3_f32.sqrt() / 3.,)
|
||||
/// Tuple::vector((3. as Float).sqrt() / 3., (3. as Float).sqrt() / 3., (3. as Float).sqrt() / 3.,)
|
||||
/// );
|
||||
/// // Normals returned are normalized.
|
||||
/// let s = Sphere::default();
|
||||
/// let n = s.normal_at(Tuple::point(
|
||||
/// 3_f32.sqrt() / 3.,
|
||||
/// 3_f32.sqrt() / 3.,
|
||||
/// 3_f32.sqrt() / 3.,
|
||||
/// (3. as Float).sqrt() / 3.,
|
||||
/// (3. as Float).sqrt() / 3.,
|
||||
/// (3. as Float).sqrt() / 3.,
|
||||
/// ));
|
||||
/// assert_eq!(n, n.normalize());
|
||||
///
|
||||
@ -98,11 +98,11 @@ impl Sphere {
|
||||
/// assert_eq!(n, Tuple::vector(0., 0.70711, -0.70711));
|
||||
|
||||
/// // Compute the normal on a transformed sphere.
|
||||
/// use std::f32::consts::PI;
|
||||
/// use rtchallenge::float::consts::PI;
|
||||
///
|
||||
/// let mut s = Sphere::default();
|
||||
/// s.set_transform ( Matrix4x4::scaling(1.,0.5,1.) * Matrix4x4::rotation_z(PI/5.));
|
||||
/// let n = s.normal_at(Tuple::point(0., 2_f32.sqrt()/2., -2_f32.sqrt()/2.));
|
||||
/// let n = s.normal_at(Tuple::point(0., (2. as Float).sqrt()/2., -(2. as Float).sqrt()/2.));
|
||||
/// assert_eq!(n, Tuple::vector(0., 0.97014, -0.24254));
|
||||
/// ```
|
||||
#[cfg(not(feature = "disable_inverse_cache"))]
|
||||
|
||||
@ -1,25 +1,25 @@
|
||||
use std::ops::{Add, Div, Mul, Neg, Sub};
|
||||
|
||||
use crate::EPSILON;
|
||||
use crate::{Float, EPSILON};
|
||||
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub struct Tuple {
|
||||
pub x: f32,
|
||||
pub y: f32,
|
||||
pub z: f32,
|
||||
pub w: f32,
|
||||
pub x: Float,
|
||||
pub y: Float,
|
||||
pub z: Float,
|
||||
pub w: Float,
|
||||
}
|
||||
|
||||
impl Tuple {
|
||||
pub fn point(x: f32, y: f32, z: f32) -> Tuple {
|
||||
pub fn point(x: Float, y: Float, z: Float) -> Tuple {
|
||||
Tuple::new(x, y, z, 1.0)
|
||||
}
|
||||
|
||||
pub fn vector(x: f32, y: f32, z: f32) -> Tuple {
|
||||
pub fn vector(x: Float, y: Float, z: Float) -> Tuple {
|
||||
Tuple::new(x, y, z, 0.0)
|
||||
}
|
||||
|
||||
pub fn new(x: f32, y: f32, z: f32, w: f32) -> Tuple {
|
||||
pub fn new(x: Float, y: Float, z: Float, w: Float) -> Tuple {
|
||||
Tuple { x, y, z, w }
|
||||
}
|
||||
|
||||
@ -31,7 +31,7 @@ impl Tuple {
|
||||
self.w == 0.0
|
||||
}
|
||||
|
||||
pub fn magnitude(&self) -> f32 {
|
||||
pub fn magnitude(&self) -> Float {
|
||||
(self.x * self.x + self.y * self.y + self.z * self.z + self.w * self.w).sqrt()
|
||||
}
|
||||
|
||||
@ -50,7 +50,10 @@ impl Tuple {
|
||||
///
|
||||
/// # Examples
|
||||
/// ```
|
||||
/// use rtchallenge::tuples::{reflect, Tuple};
|
||||
/// use rtchallenge::{
|
||||
/// tuples::{reflect, Tuple},
|
||||
/// Float,
|
||||
/// };
|
||||
///
|
||||
/// // Reflecting a vector approaching at 45°
|
||||
/// let v = Tuple::vector(1., -1., 0.);
|
||||
@ -60,7 +63,7 @@ impl Tuple {
|
||||
///
|
||||
/// // Reflecting off a slanted surface.
|
||||
/// let v = Tuple::vector(0., -1., 0.);
|
||||
/// let n = Tuple::vector(2_f32.sqrt() / 2., 2_f32.sqrt() / 2., 0.);
|
||||
/// let n = Tuple::vector((2. as Float).sqrt() / 2., (2. as Float).sqrt() / 2., 0.);
|
||||
/// let r = reflect(v, n);
|
||||
/// assert_eq!(r, Tuple::vector(1., 0., 0.));
|
||||
/// ```
|
||||
@ -80,9 +83,9 @@ impl Add for Tuple {
|
||||
}
|
||||
}
|
||||
|
||||
impl Div<f32> for Tuple {
|
||||
impl Div<Float> for Tuple {
|
||||
type Output = Self;
|
||||
fn div(self, rhs: f32) -> Self::Output {
|
||||
fn div(self, rhs: Float) -> Self::Output {
|
||||
Self::Output {
|
||||
x: self.x / rhs,
|
||||
y: self.y / rhs,
|
||||
@ -92,9 +95,9 @@ impl Div<f32> for Tuple {
|
||||
}
|
||||
}
|
||||
|
||||
impl Mul<f32> for Tuple {
|
||||
impl Mul<Float> for Tuple {
|
||||
type Output = Self;
|
||||
fn mul(self, rhs: f32) -> Self::Output {
|
||||
fn mul(self, rhs: Float) -> Self::Output {
|
||||
Self::Output {
|
||||
x: self.x * rhs,
|
||||
y: self.y * rhs,
|
||||
@ -104,7 +107,7 @@ impl Mul<f32> for Tuple {
|
||||
}
|
||||
}
|
||||
|
||||
impl Mul<Tuple> for f32 {
|
||||
impl Mul<Tuple> for Float {
|
||||
type Output = Tuple;
|
||||
fn mul(self, rhs: Tuple) -> Self::Output {
|
||||
Self::Output {
|
||||
@ -147,7 +150,7 @@ impl PartialEq for Tuple {
|
||||
&& ((self.w - rhs.w).abs() < EPSILON)
|
||||
}
|
||||
}
|
||||
pub fn dot(a: Tuple, b: Tuple) -> f32 {
|
||||
pub fn dot(a: Tuple, b: Tuple) -> Float {
|
||||
a.x * b.x + a.y * b.y + a.z * b.z + a.w * b.w
|
||||
}
|
||||
pub fn cross(a: Tuple, b: Tuple) -> Tuple {
|
||||
@ -160,12 +163,12 @@ pub fn cross(a: Tuple, b: Tuple) -> Tuple {
|
||||
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
pub struct Color {
|
||||
pub red: f32,
|
||||
pub green: f32,
|
||||
pub blue: f32,
|
||||
pub red: Float,
|
||||
pub green: Float,
|
||||
pub blue: Float,
|
||||
}
|
||||
impl Color {
|
||||
pub const fn new(red: f32, green: f32, blue: f32) -> Color {
|
||||
pub const fn new(red: Float, green: Float, blue: Float) -> Color {
|
||||
Color { red, green, blue }
|
||||
}
|
||||
}
|
||||
@ -187,9 +190,9 @@ impl Add for Color {
|
||||
}
|
||||
}
|
||||
|
||||
impl Div<f32> for Color {
|
||||
impl Div<Float> for Color {
|
||||
type Output = Self;
|
||||
fn div(self, rhs: f32) -> Self::Output {
|
||||
fn div(self, rhs: Float) -> Self::Output {
|
||||
Self::Output {
|
||||
red: self.red / rhs,
|
||||
green: self.green / rhs,
|
||||
@ -198,9 +201,9 @@ impl Div<f32> for Color {
|
||||
}
|
||||
}
|
||||
|
||||
impl Mul<f32> for Color {
|
||||
impl Mul<Float> for Color {
|
||||
type Output = Self;
|
||||
fn mul(self, rhs: f32) -> Self::Output {
|
||||
fn mul(self, rhs: Float) -> Self::Output {
|
||||
Self::Output {
|
||||
red: self.red * rhs,
|
||||
green: self.green * rhs,
|
||||
@ -209,7 +212,7 @@ impl Mul<f32> for Color {
|
||||
}
|
||||
}
|
||||
|
||||
impl Mul<Color> for f32 {
|
||||
impl Mul<Color> for Float {
|
||||
type Output = Color;
|
||||
fn mul(self, rhs: Color) -> Self::Output {
|
||||
Self::Output {
|
||||
@ -253,7 +256,7 @@ impl Sub for Color {
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::{cross, dot, Color, Tuple, EPSILON};
|
||||
use super::{cross, dot, Color, Float, Tuple, EPSILON};
|
||||
#[test]
|
||||
fn is_point() {
|
||||
// A tuple with w = 1 is a point
|
||||
@ -341,8 +344,11 @@ mod tests {
|
||||
assert_eq!(1., Tuple::vector(1., 0., 0.).magnitude());
|
||||
assert_eq!(1., Tuple::vector(0., 1., 0.).magnitude());
|
||||
assert_eq!(1., Tuple::vector(0., 0., 1.).magnitude());
|
||||
assert_eq!(14_f32.sqrt(), Tuple::vector(1., 2., 3.).magnitude());
|
||||
assert_eq!(14_f32.sqrt(), Tuple::vector(-1., -2., -3.).magnitude());
|
||||
assert_eq!((14. as Float).sqrt(), Tuple::vector(1., 2., 3.).magnitude());
|
||||
assert_eq!(
|
||||
(14. as Float).sqrt(),
|
||||
Tuple::vector(-1., -2., -3.).magnitude()
|
||||
);
|
||||
}
|
||||
#[test]
|
||||
fn vector_normalize() {
|
||||
@ -351,7 +357,11 @@ mod tests {
|
||||
Tuple::vector(4., 0., 0.).normalize()
|
||||
);
|
||||
assert_eq!(
|
||||
Tuple::vector(1. / 14_f32.sqrt(), 2. / 14_f32.sqrt(), 3. / 14_f32.sqrt()),
|
||||
Tuple::vector(
|
||||
1. / (14. as Float).sqrt(),
|
||||
2. / (14. as Float).sqrt(),
|
||||
3. / (14. as Float).sqrt()
|
||||
),
|
||||
Tuple::vector(1., 2., 3.).normalize()
|
||||
);
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user