1#![forbid(unsafe_code)]
2#![doc = include_str!("../README.md")]
3
4use use_coordinate::GeometryError;
5use use_point::Point2;
6
7#[derive(Debug, Clone, Copy, PartialEq)]
9pub struct Inversion {
10 center: Point2,
11 radius: f64,
12}
13
14impl Inversion {
15 pub fn try_new(center: Point2, radius: f64) -> Result<Self, GeometryError> {
21 let center = center.validate()?;
22
23 if !radius.is_finite() {
24 return Err(GeometryError::NonFiniteRadius(radius));
25 }
26
27 if radius <= 0.0 {
28 return Err(GeometryError::NegativeRadius(radius));
29 }
30
31 Ok(Self { center, radius })
32 }
33
34 #[must_use]
36 pub const fn center(self) -> Point2 {
37 self.center
38 }
39
40 #[must_use]
42 pub const fn radius(self) -> f64 {
43 self.radius
44 }
45
46 #[must_use]
48 pub const fn radius_squared(self) -> f64 {
49 self.radius * self.radius
50 }
51}
52
53#[cfg(test)]
54mod tests {
55 use super::Inversion;
56 use use_coordinate::GeometryError;
57 use use_point::Point2;
58
59 #[test]
60 fn validates_inversion_radius() {
61 let inversion = Inversion::try_new(Point2::origin(), 2.0).expect("valid inversion");
62
63 assert_eq!(inversion.center(), Point2::origin());
64 assert_eq!(inversion.radius(), 2.0);
65 assert_eq!(inversion.radius_squared(), 4.0);
66 assert_eq!(
67 Inversion::try_new(Point2::origin(), 0.0),
68 Err(GeometryError::NegativeRadius(0.0))
69 );
70 }
71}