Skip to main content

arcs/algorithms/
length.rs

1use crate::{Arc, Line, Vector};
2
3/// Something which has a finite length.
4pub trait Length {
5    /// Calculate the length.
6    fn length(&self) -> f64;
7}
8
9impl<'a, L: Length + ?Sized> Length for &'a L {
10    fn length(&self) -> f64 { (*self).length() }
11}
12
13impl Length for Line {
14    /// Calculates the length of the line.
15    ///
16    /// ```rust
17    /// # use arcs::{algorithms::Length, Line, Point};
18    /// let line = Line::new(Point::zero(), Point::new(5.0, 0.0));
19    ///
20    /// assert_eq!(line.length(), 5.0);
21    /// ```
22    fn length(&self) -> f64 { self.displacement().length() }
23}
24
25impl Length for Vector {
26    /// Calculates the [`Vector`]'s magnitude.
27    ///
28    /// ```rust
29    /// # use arcs::{algorithms::Length, Vector};
30    /// let vector = Vector::new(3.0, 4.0);
31    ///
32    /// assert_eq!(vector.length(), 5.0);
33    /// ```
34    fn length(&self) -> f64 { euclid::Vector2D::length(self) }
35}
36
37impl Length for Arc {
38    /// Calculates the length of an [`Arc`].
39    ///
40    /// ```rust
41    /// # use arcs::{algorithms::Length, Arc, Point, Angle};
42    /// # use std::f64::consts::PI;
43    /// let radius = 50.0;
44    /// let arc = Arc::from_centre_radius(
45    ///     Point::zero(),
46    ///     radius,
47    ///     Angle::zero(),
48    ///     Angle::two_pi(),
49    /// );
50    ///
51    /// assert_eq!(arc.length(), 2.0 * radius * PI);
52    /// ```
53    fn length(&self) -> f64 { self.radius() * self.sweep_angle().radians.abs() }
54}
55
56#[cfg(test)]
57mod tests {
58    use super::*;
59    use crate::{Angle, Point};
60
61    #[test]
62    fn line() {
63        let thing = Line::new(Point::zero(), Point::new(3.0, 4.0));
64
65        assert_eq!(thing.length(), 5.0);
66    }
67
68    #[test]
69    fn arc() {
70        let arc = Arc::from_centre_radius(
71            Point::zero(),
72            10.0,
73            Angle::zero(),
74            Angle::pi(),
75        );
76
77        assert_eq!(
78            arc.length(),
79            arc.sweep_angle().radians.abs() * arc.radius()
80        );
81    }
82}