iron_shapes/
concepts_impl.rs1use crate::concepts::*;
8use crate::isotropy::*;
9use crate::prelude as types;
10use crate::prelude::{CoordinateType, IntoEdges, Scale};
11
12impl<C> PointBase<C> for types::Point<C::Coord>
13where
14 C: CoordinateBase,
15{
16 fn new(x: C::Coord, y: C::Coord) -> Self {
17 types::Point::new(x, y)
18 }
19
20 fn get(&self, orient: Orientation2D) -> C::Coord {
21 match orient {
22 Orientation2D::Horizontal => self.x,
23 Orientation2D::Vertical => self.y,
24 }
25 }
26
27 fn set(&mut self, orient: Orientation2D, value: C::Coord) {
28 let c = match orient {
29 Orientation2D::Horizontal => &mut self.x,
30 Orientation2D::Vertical => &mut self.y,
31 };
32 *c = value
33 }
34}
35
36impl<C> PointConcept<C> for types::Point<C::Coord> where C: CoordinateConcept {}
37
38impl<C> Segment<C> for types::REdge<C::Coord>
39where
40 C: CoordinateConcept,
41{
42 type Point = types::Point<C::Coord>;
43
44 fn get_point(&self, dir: Direction1D) -> Self::Point {
45 match dir {
46 Direction1D::Low => self.start(),
47 Direction1D::High => self.end(),
48 }
49 }
50}
51
52impl<C> Interval<C> for types::Interval<C>
53where
54 C: CoordinateType,
55{
56 fn get(&self, d: Direction1D) -> C {
57 match d {
58 Direction1D::Low => self.start(),
59 Direction1D::High => self.end(),
60 }
61 }
62}
63
64impl<C> Rectangle<C> for types::Rect<C::Coord>
65where
66 C: CoordinateConcept,
67{
68 type Interval = types::Interval<C::Coord>;
69
70 fn get(&self, orientation: Orientation2D) -> Self::Interval {
71 let (start, end) = match orientation {
74 Orientation2D::Horizontal => (self.lower_left().x, self.upper_right().x),
75 Orientation2D::Vertical => (self.lower_left().y, self.upper_right().y),
76 };
77 types::Interval::new(start, end)
78 }
79}
80
81impl<C> Polygon90<C> for types::Rect<C::Coord>
82where
83 C: CoordinateConcept,
84{
85 type CompactIterator = std::vec::IntoIter<C::Coord>;
86
87 fn compact_iter(&self) -> Self::CompactIterator {
88 vec![
89 self.lower_left.x,
90 self.lower_left.y,
91 self.upper_right.x,
92 self.upper_right.y,
93 ]
94 .into_iter()
95 }
96}
97
98impl<C> Polygon<C> for types::Rect<C::Coord>
99where
100 C: CoordinateConcept,
101{
102 fn set(&mut self, _iter: impl Iterator<Item = <Self as PolygonSet<C>>::Point>) {
103 unimplemented!()
106 }
107}
108
109impl<C> PolygonWithHoles<C> for types::Rect<C::Coord>
110where
111 C: CoordinateConcept,
112{
113 fn num_holes(&self) -> usize {
114 0
115 }
116}
117
118impl<C> Polygon90WithHoles<C> for types::Rect<C::Coord> where C: CoordinateConcept {}
119
120impl<C> Polygon90Set<C> for types::Rect<C::Coord> where C: CoordinateConcept {}
121
122impl<C> IntoSegments<C> for types::Rect<C::Coord>
123where
124 C: CoordinateConcept,
125{
126 type Segment = types::REdge<C::Coord>;
127 type SegmentIter = types::RectEdgeIterator<C::Coord>;
128
129 fn into_segments(self) -> Self::SegmentIter {
130 self.into_edges()
131 }
132}
133
134impl<C> IntoPoints<C> for types::Rect<C::Coord>
135where
136 C: CoordinateConcept,
137{
138 type Point = types::Point<C::Coord>;
139 type PointIter = <Self as IntoIterator>::IntoIter;
140
141 fn into_points(self) -> Self::PointIter {
142 self.into_iter()
143 }
144}
145
146impl<C> PolygonSet<C> for types::Rect<C::Coord>
147where
148 C: CoordinateConcept,
149{
150 type Point = types::Point<C::Coord>;
151 type Segment = types::REdge<C::Coord>;
152 type AllPoints = <Self as IntoIterator>::IntoIter;
153
154 fn num_polygons(&self) -> usize {
155 1
156 }
157
158 fn convolved(mut self, p: &Self::Point) -> Self {
159 self.lower_left = self.lower_left + p;
160 self.upper_right = self.upper_right + p;
161 self
162 }
163
164 fn convolve(&mut self, p: &Self::Point) {
165 self.lower_left = self.lower_left + p;
166 self.upper_right = self.upper_right + p;
167 }
168
169 fn scaled(self, scale: C::Coord) -> Self {
170 self.scale(scale);
171 self
172 }
173
174 fn scale(&mut self, scale: C::Coord) {
175 self.upper_right = self.upper_right * scale;
176 self.lower_left = self.lower_left * scale;
177 }
178
179 fn all_points(&self) -> Self::AllPoints {
180 self.into_iter()
181 }
182}
183
184#[test]
185fn test_point() {
186 fn some_point_function<P: PointBase<C>, C: CoordinateBase>(p: P) -> C::Coord {
187 p.x() + p.y()
188 }
189
190 let p = types::Point::new(1, 2);
191 assert_eq!(some_point_function::<_, i32>(p), 3);
192}