d3_geo_rs/circle/
generator.rs1use 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#[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 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 pub const fn center_set(&mut self, center: &Coord<T>) -> &mut Self {
73 self.center = *center;
74 self
75 }
76
77 #[inline]
79 pub const fn center(&self) -> Coord<T> {
80 self.center
81 }
82
83 pub const fn radius_set(&mut self, radius: T) -> &mut Self {
85 self.radius = radius;
86 self
87 }
88
89 #[inline]
91 pub const fn radius(&self) -> T {
92 self.radius
93 }
94
95 pub const fn precision_set(&mut self, precision: T) -> &mut Self {
99 self.precision = precision;
100 self
101 }
102
103 #[inline]
107 pub const fn precision(&self) -> T {
108 self.precision
109 }
110}