1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
use crate::{Abs, FloatingScalar, FloatingVector2, Pow, Vector2, ZeroOneTwo};
pub trait Circle: Copy {
type Scalar: FloatingScalar;
type Vector: FloatingVector2<Scalar = Self::Scalar>;
fn new(center: Self::Vector, radius: Self::Scalar) -> Self;
fn center(self) -> Self::Vector;
fn radius(self) -> Self::Scalar;
fn map_into<C>(self) -> C
where
C: Circle,
C::Scalar: From<Self::Scalar>,
{
C::new(
C::Vector::new(
C::Scalar::from(self.center().x()),
C::Scalar::from(self.center().y()),
),
C::Scalar::from(self.radius()),
)
}
fn map_with<C, F>(self, mut f: F) -> C
where
C: Circle,
F: FnMut(Self::Scalar) -> <<C as Circle>::Vector as Vector2>::Scalar,
{
C::new(
C::Vector::new(f(self.center().x()), f(self.center().y())),
f(self.radius()),
)
}
fn with_center(self, center: Self::Vector) -> Self {
Self::new(center, self.radius())
}
fn with_radius(self, radius: Self::Scalar) -> Self {
Self::new(self.center(), radius)
}
fn diameter(self) -> Self::Scalar {
self.radius() * Self::Scalar::TWO
}
fn circumference(self) -> Self::Scalar {
self.radius() * Self::Scalar::TAU
}
fn area(self) -> Self::Scalar {
self.radius().pow(Self::Scalar::TWO) * Self::Scalar::pi()
}
fn translated(self, offset: Self::Vector) -> Self {
self.with_center(self.center().add(offset))
}
fn scaled(self, scale: Self::Scalar) -> Self {
self.with_radius(self.radius() * scale)
}
fn to_square(self) -> [Self::Scalar; 4] {
let radius = self.radius();
[
self.center().x() - radius,
self.center().y() - radius,
radius * Self::Scalar::TWO,
radius * Self::Scalar::TWO,
]
}
fn contains(self, point: Self::Vector) -> bool {
self.center().dist(point) <= self.radius().abs()
}
fn cntains(self, point: Self::Vector) -> bool {
self.contains(point)
}
fn contains_all<I>(self, points: I) -> bool
where
I: IntoIterator<Item = Self::Vector>,
{
points.into_iter().all(|point| self.contains(point))
}
fn contains_any<I>(self, points: I) -> bool
where
I: IntoIterator<Item = Self::Vector>,
{
points.into_iter().any(|point| self.contains(point))
}
}
impl<S, V> Circle for (V, S)
where
S: FloatingScalar,
V: FloatingVector2<Scalar = S>,
{
type Scalar = S;
type Vector = V;
fn new(center: Self::Vector, radius: Self::Scalar) -> Self {
(center, radius)
}
fn center(self) -> Self::Vector {
self.0
}
fn radius(self) -> Self::Scalar {
self.1
}
}