Compare commits

...

5 Commits

Author SHA1 Message Date
ac4f5eb9a6 git-hooks: remove debug printing.
All checks were successful
continuous-integration/drone/push Build is passing
2021-07-17 08:14:51 -07:00
f846da18ad envmap: cargo fmt. 2021-07-17 08:14:35 -07:00
e59029a94a git-hooks: add pre-commit hook for fmt and testing checks. 2021-07-17 08:14:08 -07:00
339ce84903 tuples: whitespace cleanup for consistency. 2021-07-17 07:58:15 -07:00
6e7bd1c136 spheres: implement normal_at. 2021-07-17 07:57:59 -07:00
5 changed files with 96 additions and 1 deletions

8
git-hooks/README.md Normal file
View File

@ -0,0 +1,8 @@
# Installing
Symlink the files in this directory into your `.git/hooks/` directory to
enable policies for this project. Example:
```bash
$ cd .git/hooks
$ ln -s ../../git-hooks/pre-commit .
```

26
git-hooks/pre-commit Executable file
View File

@ -0,0 +1,26 @@
#!/usr/bin/env bash
set -e
pushd () {
command pushd "$@" > /dev/null
}
popd () {
command popd "$@" > /dev/null
}
for workspace in rtchallenge rtiow; do
pushd ${workspace:?}
cargo fmt -- --check || (echo "To fix, run: cd ${workspace:?} && cargo fmt" && false)
popd
done
RT=rtchallenge
AFFECTED="$(git diff-index --cached --name-only HEAD)"
#echo "AFFECTED $AFFECTED"
RT_AFFECTED=$(echo "${AFFECTED:?}" | grep ${RT:?} || true)
if [ ! -z "$RT_AFFECTED" ]; then
echo "Files for the rt challenge were touched, running tests"
cd ${RT:?} && cargo build --examples && cargo test
fi
# Uncomment to debug presubmit.
#exit 1

View File

@ -3,6 +3,7 @@ use crate::{
matrices::Matrix4x4,
rays::Ray,
tuples::{dot, Tuple},
EPSILON,
};
#[derive(Debug, PartialEq)]
@ -34,6 +35,65 @@ impl Default for Sphere {
}
}
impl Sphere {
/// Find the normal at the point on the sphere.
///
/// # Examples
/// ```
/// use rtchallenge::{matrices::Matrix4x4, spheres::Sphere, tuples::Tuple};
///
/// // Normal on X-axis
/// let s = Sphere::default();
/// let n = s.normal_at(Tuple::point(1., 0., 0.));
/// assert_eq!(n, Tuple::vector(1., 0., 0.));
///
/// // Normal on Y-axis
/// let s = Sphere::default();
/// let n = s.normal_at(Tuple::point(0., 1., 0.));
/// assert_eq!(n, Tuple::vector(0., 1., 0.));
///
/// // Normal on Z-axis
/// let s = Sphere::default();
/// let n = s.normal_at(Tuple::point(0., 0., 1.));
/// assert_eq!(n, Tuple::vector(0., 0., 1.));
///
/// // 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.,
/// ));
/// assert_eq!(
/// n,
/// Tuple::vector(3_f32.sqrt() / 3., 3_f32.sqrt() / 3., 3_f32.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.,
/// ));
/// assert_eq!(n, n.normalize());
/// ```
/// ```should_panic
/// use rtchallenge::{spheres::Sphere, tuples::Tuple};
///
/// // In debug builds points not on the sphere should fail.
/// let s = Sphere::default();
/// let n = s.normal_at(Tuple::point(0., 0., 0.5));
/// ```
pub fn normal_at(&self, point: Tuple) -> Tuple {
debug_assert!(
((point - Tuple::point(0., 0., 0.)).magnitude() - 1.).abs() < EPSILON,
"{} != 1.",
(point - Tuple::point(0., 0., 0.)).magnitude()
);
(point - Tuple::point(0., 0., 0.)).normalize()
}
}
/// Intersect a ray with a sphere.
///
/// # Examples

View File

@ -34,6 +34,7 @@ impl Tuple {
pub fn magnitude(&self) -> f32 {
(self.x * self.x + self.y * self.y + self.z * self.z + self.w * self.w).sqrt()
}
pub fn normalize(&self) -> Tuple {
let m = self.magnitude();
Tuple {