use glam::Vec3;
pub struct Plane {
pub normal: Vec3,
pub origin_dist: f32,
}
impl Plane {
pub fn new(normal: Vec3, point: Vec3) -> Self {
let normal = normal.normalize();
let origin_dist = -normal.dot(point);
Plane {
normal,
origin_dist,
}
}
pub fn point_dist(&self, point: Vec3) -> f32 {
self.normal.dot(point) + self.origin_dist
}
pub fn project_point(&self, point: Vec3) -> Vec3 {
point - self.normal * self.point_dist(point)
}
}
#[cfg(test)]
mod test {
use super::*;
#[test]
fn up_plane() {
let p = Plane::new(Vec3::new(0.0, 1.0, 0.0), Vec3::ZERO);
assert_eq!(p.point_dist(Vec3::new(0.0, 0.0, 0.0)), 0.0);
assert_eq!(p.point_dist(Vec3::new(1.0, 1.0, 1.0)), 1.0);
assert_eq!(p.point_dist(Vec3::new(0.0, 1.0, 1.0)), 1.0);
assert_eq!(p.point_dist(Vec3::new(0.0, 1.0, 0.0)), 1.0);
assert_eq!(p.point_dist(Vec3::new(0.0, -1.0, 0.0)), -1.0);
}
#[test]
fn angled_plane() {
let p = Plane::new(Vec3::new(1.0, 1.0, 1.0), Vec3::ZERO);
assert_eq!(p.point_dist(Vec3::new(0.0, 0.0, 0.0)), 0.0);
assert_eq!(p.point_dist(Vec3::new(1.0, 0.0, 0.0)), 0.57735026);
assert_eq!(p.point_dist(Vec3::new(0.0, 1.0, 0.0)), 0.57735026);
assert_eq!(p.point_dist(Vec3::new(0.0, 0.0, 1.0)), 0.57735026);
assert_eq!(p.point_dist(Vec3::new(0.0, -1.0, 0.0)), -0.57735026);
}
}