1#![forbid(unsafe_code)]
2#![doc = include_str!("../README.md")]
3
4use use_point::Point2;
5
6#[derive(Debug, Clone, Copy, PartialEq, Eq)]
8pub enum ProjectionKind {
9 Orthographic,
11 Perspective,
13}
14
15#[derive(Debug, Clone, Copy, PartialEq)]
17pub struct Projection2 {
18 kind: ProjectionKind,
19 scale: f64,
20}
21
22impl Projection2 {
23 #[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 #[must_use]
35 pub const fn kind(self) -> ProjectionKind {
36 self.kind
37 }
38
39 #[must_use]
41 pub const fn scale(self) -> f64 {
42 self.scale
43 }
44
45 #[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}