cube-core 1.0.1

Cube core for 'kostka' simulation
Documentation
#[derive(Debug, Clone, Copy)]
pub struct Point2D {
    pub x: isize,
    pub y: isize,
}

#[derive(Debug, Clone, Copy)]
pub struct Point3D {
    pub x: f32,
    pub y: f32,
    pub z: f32,
}

impl Point3D {
    pub fn add(&self, other: &Point3D) -> Point3D {
        Point3D { 
            x: self.x + other.x,
            y: self.y + other.y,
            z: self.z + other.z, 
        }
    }

    pub fn subtract(&self, other: &Point3D) -> Point3D {
        Point3D { 
            x: self.x - other.x,
            y: self.y - other.y,
            z: self.z - other.z, 
        }
    }

    pub fn scalar_multiply(&self, scalar: f32) -> Point3D {
        Point3D { 
            x: scalar * self.x,
            y: scalar * self.y,
            z: scalar * self.z, 
        }
    }

    pub fn rotate_around_axis(&self, axis: Point3D, origin: Point3D, angle_rad: f32) -> Point3D {
        let axis = axis.normalize();
        let v = self.subtract(&origin);
        let cos = angle_rad.cos();
        let sin = angle_rad.sin();

        let dot = v.dot(&axis);
        let cross = v.cross(&axis);

        let rotated = v.scalar_multiply(cos)
            .add(&cross.scalar_multiply(sin))
            .add(&axis.scalar_multiply(dot * (1.0 - cos)));

        rotated.add(&origin)
    }

    pub fn rotate_y(self, angle: f32) -> Self {
        let (sin, cos) = (angle.sin(), angle.cos());
        Self {
            x: self.x * cos + self.z * sin,
            y: self.y,
            z: -self.x * sin + self.z * cos,
        }
    }

    pub fn rotate_x(self, angle: f32) -> Self {
        let (sin, cos) = (angle.sin(), angle.cos());
        Self {
            x: self.x,
            y: self.y * cos - self.z * sin,
            z: self.y * sin + self.z * cos,
        }
    }

    pub fn rotate_z(self, angle: f32) -> Self {
        let (sin, cos) = (angle.sin(), angle.cos());
        Self {
            x: self.x * cos - self.y * sin,
            y: self.x * sin + self.y * cos,
            z: self.z,
        }
    }

    pub fn translate(self, offset: Point3D) -> Self {
        Self {
            x: self.x + offset.x,
            y: self.y + offset.y,
            z: self.z + offset.z,
        }
    }

    pub fn dot(&self, other: &Point3D) -> f32 {
        self.x * other.x + self.y * other.y + self.z * other.z
    }

    pub fn cross(&self, other: &Point3D) -> Point3D {
        Point3D {
            x: self.y * other.z - self.z * other.y,
            y: self.z * other.x - self.x * other.z,
            z: self.x * other.y - self.y * other.x,
        }
    }

    pub fn normalize(&self) -> Point3D {
        let len = (self.x * self.x + self.y * self.y + self.z * self.z).sqrt();
        Point3D {
            x: self.x / len,
            y: self.y / len,
            z: self.z / len,
        }
    }
}

pub struct Triangle (
    pub Point2D,
    pub Point2D,
    pub Point2D,
);

impl Triangle {
    pub fn point_in_triangle(&self, p: Point2D) -> bool {
        let Self(a, b, c) = self;
        let area = |p1: &Point2D, p2: &Point2D, p3: &Point2D| -> isize {
            (p1.x * (p2.y - p3.y) +
            p2.x * (p3.y - p1.y) +
            p3.x * (p1.y - p2.y)).abs()
        };

        let total = area(a, b, c);
        let a1 = area(&p, b, c);
        let a2 = area(a, &p, c);
        let a3 = area(a, b, &p);

        a1 + a2 + a3 <= total + 1
    }
}