d3_geo_rs/circle/
generator.rs

1use core::fmt::Debug;
2
3use geo::CoordFloat;
4use geo::LineString;
5use geo_types::Coord;
6use num_traits::FloatConst;
7
8use crate::rot::rotate_radians;
9use crate::rot::rotate_radians::RotateRadians;
10use crate::rot::rotation_identity::RotationIdentity;
11
12use super::stream::Stream;
13use super::stream_fn::stream_fn;
14
15/// Allow for circle to be defined and then input to a stream.
16#[derive(Clone, Debug)]
17pub struct Generator<T>
18where
19    T: CoordFloat,
20{
21    center: Coord<T>,
22    radius: T,
23    precision: T,
24    stream: Stream<T>,
25}
26
27impl<T> Default for Generator<T>
28where
29    T: CoordFloat,
30{
31    #[inline]
32    fn default() -> Self {
33        Self {
34            center: Coord {
35                x: T::zero(),
36                y: T::zero(),
37            },
38            radius: T::from(90_f64).unwrap(),
39            precision: T::from(2.5).unwrap(),
40            stream: Stream::default(),
41        }
42    }
43}
44
45impl<T> Generator<T>
46where
47    T: CoordFloat + FloatConst,
48{
49    /// Injects the previously defined circle into the stream.
50    pub fn circle(&mut self) -> LineString<T> {
51        let c = self.center;
52        let r = self.radius.to_radians();
53        let p = self.precision.to_radians();
54
55        self.stream.rotate =
56            rotate_radians([-c.x.to_radians(), -c.y.to_radians(), T::zero()]);
57        stream_fn(&mut self.stream, r, p, T::one(), None, None);
58        let mut coordinates = vec![];
59        core::mem::swap(&mut coordinates, &mut self.stream.ring);
60
61        self.stream.rotate = RotateRadians::I(RotationIdentity::default());
62
63        LineString(coordinates)
64    }
65}
66
67impl<T> Generator<T>
68where
69    T: CoordFloat,
70{
71    /// Center is used to program the generator.
72    pub const fn center_set(&mut self, center: &Coord<T>) -> &mut Self {
73        self.center = *center;
74        self
75    }
76
77    /// Returns the currently programmed center.
78    #[inline]
79    pub const fn center(&self) -> Coord<T> {
80        self.center
81    }
82
83    /// Sets the radius on the generator.
84    pub const fn radius_set(&mut self, radius: T) -> &mut Self {
85        self.radius = radius;
86        self
87    }
88
89    /// Returns the currently programmed radius.
90    #[inline]
91    pub const fn radius(&self) -> T {
92        self.radius
93    }
94
95    /// Sets the precision
96    ///
97    /// (Number of steps in degrees )
98    pub const fn precision_set(&mut self, precision: T) -> &mut Self {
99        self.precision = precision;
100        self
101    }
102
103    /// Returns the precision
104    ///
105    /// (Number of steps in degrees )
106    #[inline]
107    pub const fn precision(&self) -> T {
108        self.precision
109    }
110}