Skip to main content

rscad_core/objects/two_dimensional/
circle.rs

1use crate::prelude_::*;
2
3/// Creates a circle at origin
4#[derive(Clone, Copy, Debug)]
5#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
6#[cfg_attr(feature = "reflect", derive(bevy_reflect::Reflect))]
7pub struct Circle {
8    /// Circle radius
9    pub radius: f64,
10    /// minimum angle (in degrees) of each fragment
11    pub fa: f64,
12    /// minimum circumferential length of each fragment
13    pub fs: f64,
14    /// fixed number of fragments in 360 degrees. Values of 3 or more override $fa and $fs
15    pub fn_: usize,
16}
17
18impl Default for Circle {
19    fn default() -> Self {
20        Circle {
21            radius: 1.0,
22            fa: 0.0,
23            fs: 0.0,
24            fn_: 360, // default to 360 fragments
25        }
26    }
27}
28
29const MIN_F: f64 = 0.01f64;
30impl Circle {
31    pub fn new<T: Number>(radius: T, fa: T, fs: T, r#fn: usize) -> Self {
32        Circle {
33            radius: radius.to_f64(),
34            fa: fa.to_f64().max(MIN_F),
35            fs: fs.to_f64().max(MIN_F),
36            fn_: r#fn.max(3), // fn must be at least 3
37        }
38    }
39
40    pub fn with_diameter<T: Number>(self, radius: T) -> Self {
41        Circle {
42            radius: radius.to_f64() / 2.0,
43            ..self
44        }
45    }
46    pub fn with_radius<T: Number>(self, radius: T) -> Self {
47        Circle {
48            radius: radius.to_f64(),
49            ..self
50        }
51    }
52
53    pub fn with_fa<T: Number>(self, fa: T) -> Self {
54        Circle {
55            fa: fa.to_f64(),
56            ..self
57        }
58    }
59
60    pub fn with_fs<T: Number>(self, fs: T) -> Self {
61        Circle {
62            fs: fs.to_f64(),
63            ..self
64        }
65    }
66
67    pub fn with_fn(self, r#fn: usize) -> Self {
68        Circle {
69            fn_: r#fn.max(3), // fn must be at least 3
70            ..self
71        }
72    }
73
74    pub const fn center(&self) -> DVec2 {
75        // By default its not centered at origin so its radius,radius
76        DVec2::new(self.radius, self.radius)
77    }
78}
79
80pub trait CircleExt {
81    fn radius(&self) -> f64;
82    fn diameter(&self) -> f64;
83    fn area(&self) -> f64;
84    fn circumference(&self) -> f64;
85}
86
87impl CircleExt for Circle {
88    fn radius(&self) -> f64 {
89        self.radius
90    }
91    fn diameter(&self) -> f64 {
92        self.radius * 2.0
93    }
94    fn area(&self) -> f64 {
95        core::f64::consts::PI * self.radius.powi(2)
96    }
97    fn circumference(&self) -> f64 {
98        core::f64::consts::PI * self.diameter()
99    }
100}
101
102impl Object for Circle {}