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}