Skip to main content

use_projection/
lib.rs

1#![forbid(unsafe_code)]
2#![doc = include_str!("../README.md")]
3
4use use_point::Point2;
5
6/// Broad projection families.
7#[derive(Debug, Clone, Copy, PartialEq, Eq)]
8pub enum ProjectionKind {
9    /// Orthographic projection.
10    Orthographic,
11    /// Perspective projection.
12    Perspective,
13}
14
15/// A tiny 2D projection descriptor.
16#[derive(Debug, Clone, Copy, PartialEq)]
17pub struct Projection2 {
18    kind: ProjectionKind,
19    scale: f64,
20}
21
22impl Projection2 {
23    /// Creates a projection with a positive finite scale.
24    #[must_use]
25    pub const fn new(kind: ProjectionKind, scale: f64) -> Option<Self> {
26        if scale.is_finite() && scale > 0.0 {
27            Some(Self { kind, scale })
28        } else {
29            None
30        }
31    }
32
33    /// Returns the projection kind.
34    #[must_use]
35    pub const fn kind(self) -> ProjectionKind {
36        self.kind
37    }
38
39    /// Returns the projection scale.
40    #[must_use]
41    pub const fn scale(self) -> f64 {
42        self.scale
43    }
44
45    /// Projects a point onto the x axis and applies the projection scale.
46    #[must_use]
47    pub fn project_x_axis(self, point: Point2) -> f64 {
48        point.x() * self.scale
49    }
50}
51
52#[cfg(test)]
53mod tests {
54    use super::{Projection2, ProjectionKind};
55    use use_point::Point2;
56
57    #[test]
58    fn projects_points_to_axis() {
59        let projection = Projection2::new(ProjectionKind::Orthographic, 2.0).expect("valid");
60
61        assert_eq!(projection.kind(), ProjectionKind::Orthographic);
62        assert_eq!(projection.scale(), 2.0);
63        assert_eq!(projection.project_x_axis(Point2::new(3.0, 4.0)), 6.0);
64        assert_eq!(Projection2::new(ProjectionKind::Perspective, 0.0), None);
65    }
66}