smallpt 1.0.1

A small ray/pathtracer in Rust, inspired by Kevin Beason's educational 99-lines ray/pathtracer (http://www.kevinbeason.com/smallpt/)
Documentation
use crate::hit::Hit;
use crate::material::Material;
use crate::plane::Plane;
use crate::ray::Ray;
use crate::{PrimitiveType, Traceable, Vec3};

#[derive(Copy, Clone)]
pub struct Rectangle {
	pub position: Vec3,
	pub normal: Vec3,
	pub left: Vec3,
	pub up: Vec3,
	pub width: f32,
	pub height: f32,
	pub material: Material,
}

impl Rectangle {
	pub fn new(
		position: Vec3,
		normal: Vec3,
		left: Vec3,
		up: Vec3,
		width: f32,
		height: f32,
		material: Material,
	) -> Rectangle {
		Rectangle {
			position,
			normal,
			left,
			up,
			width,
			height,
			material,
		}
	}
}

impl Traceable for Rectangle {
	fn intersect(&self, r: &Ray, result: &mut Hit) -> bool {
		let rectangle_plane = Plane::new(self.position, self.normal, self.material);
		let hit = rectangle_plane.intersect(r, result);

		if hit {
			let p = r.origin + r.direction * result.t;
			let v = p - self.position;

			let half_width = self.width * 0.5;
			let half_height = self.height * 0.5;

			if v.dot(&self.left).abs() <= half_width && v.dot(&self.up).abs() <= half_height {
				result.p = p;
				result.n = if self.normal.dot(&r.direction) < 0.0 {
					self.normal
				} else {
					-self.normal
				};
				result.material = self.material;
				return true;
			}
		}

		false
	}

	fn get_primitive_type(&self) -> PrimitiveType {
		PrimitiveType::Rectangle
	}
}