chemrust_nasl/geometry/primitives/
plane.rs

1use nalgebra::{Point3, UnitVector3, Vector3};
2
3#[derive(Debug, Clone, Copy)]
4/// n1*x + n2*y + n3*z + d = 0
5/// # Note
6/// The normal is a unit vector
7/// So if two planes have different d and cross product of two norms is a 0 vector,
8/// they must be parallel to each other.
9pub struct Plane {
10    normal: UnitVector3<f64>,
11    d: f64,
12}
13
14impl Plane {
15    pub fn new(normal: UnitVector3<f64>, d: f64) -> Self {
16        Self { normal, d }
17    }
18    pub fn from_normal_and_point(normal: UnitVector3<f64>, point: Point3<f64>) -> Self {
19        let op: Vector3<f64> = point - Point3::origin();
20        let d = normal.dot(&op) * -1.0;
21        Self { normal, d }
22    }
23
24    pub fn normal(&self) -> UnitVector3<f64> {
25        self.normal
26    }
27    pub fn d(&self) -> f64 {
28        self.d
29    }
30    pub fn point_in_plane(&self, point: Point3<f64>) -> bool {
31        let op = point - Point3::origin();
32        // Original f64::EPSILON seems to be too strict
33        (self.normal.dot(&op) + self.d).abs() < f64::EPSILON * 5.0
34    }
35}
36
37#[cfg(test)]
38mod plane_test {
39    use nalgebra::{Point3, UnitVector3, Vector3};
40
41    use super::Plane;
42
43    #[test]
44    fn point_in_plane() {
45        let normal = UnitVector3::new_normalize(Vector3::new(2.0, 3.0, 2.0));
46        let p = Point3::new(1.0, 2.0, 3.0);
47        let plane = Plane::from_normal_and_point(normal, p);
48        let tp1 = Point3::new(2.0, 2.0, 3.0);
49        let tp2 = Point3::new(3.0, 3.0, -0.5);
50        let tp3 = Point3::new(9.0, -1.0, -0.5);
51        let tp4 = Point3::new(5.0, 0.0, 2.0);
52        assert!(!plane.point_in_plane(tp1));
53        assert!(plane.point_in_plane(tp2));
54        assert!(plane.point_in_plane(tp3));
55        assert!(plane.point_in_plane(tp4));
56    }
57}