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