acme
Foundational cross-platform layer of the ca2 framework
Loading...
Searching...
No Matches
rectangle_array.h
1#pragma once
2
3
4#include "rectangle.h"
5
6
7template < prototype_number NUMBER >
9public ::array_base < ::rectangle_type < NUMBER > >
10{
11public:
12
13 using BASE_ARRAY = ::array_base < ::rectangle_type < NUMBER > >;
14 //using RECTANGLE_BASE_TYPE = ::rectangle_type < NUMBER >;
15 //using UNIT_TYPE = typename ::rectangle_type < NUMBER >::UNIT_TYPE;
16 using UNIT_TYPE = NUMBER;
17 //using POINT_TYPE = typename ::rectangle_type < NUMBER >::POINT_TYPE;
18 //using SIZE_TYPE = typename ::rectangle_type < NUMBER >::SIZE_TYPE;
19
20
21 using BASE_ARRAY::BASE_ARRAY;
22 using BASE_ARRAY::operator =;
23 //rectangle_array_base(const rectangle_array_base & a) noexcept : array < ::rectangle_type < NUMBER > > (a) { }
24 //rectangle_array_base(rectangle_array_base && a) noexcept : array < ::rectangle_type < NUMBER > >(::transfer(a)) { }
25
26
27 //~rectangle_array_base();
28
29 using array_base < ::rectangle_type < NUMBER > >::add;
30 void add(const ::rectangle_type < NUMBER > & rectangle);
31 void add(UNIT_TYPE left, UNIT_TYPE top, UNIT_TYPE right, UNIT_TYPE bottom);
32 void add(const ::point_type < NUMBER > & point, const ::size_type < NUMBER > & size);
33 void add(const ::size_type < NUMBER > & size);
34 void add_if_none_contains(const ::rectangle_type < NUMBER > & rectangle)
35 {
36 if (!this->any_contains(rectangle)) add(rectangle);
37 }
38 template < prototype_container CONTAINER >
39 void append_if_none_contains(const CONTAINER & container)
40 {
41 for (auto & r : container) add_if_none_contains(r);
42 }
43 void intersect(const ::rectangle_type < NUMBER > & rectangle);
44 bool any_contains(const ::rectangle_type < NUMBER > & rectangle) const
45 {
46 for (auto & r : *this) if (r.contains(rectangle)) return true;
47 return false;
48 }
49
50 void add_dim(UNIT_TYPE x, UNIT_TYPE y, UNIT_TYPE cx, UNIT_TYPE cy);
51
52 ::collection::index max_normal_intersect_area(const ::rectangle_type < NUMBER > & rectangle, const ::rectangle_type < NUMBER > & rectangleModel);
53
54
55 void get_box(::rectangle_type < NUMBER > * prectangle);
56
57
58 ::rectangle_type < NUMBER > union_rect();
59
60 void offset(UNIT_TYPE cx, UNIT_TYPE cy);
61 void offset(::point_type < NUMBER > point);
62
63 UNIT_TYPE total_area(::collection::index iStart = 0, ::collection::count c = -1) const
64 {
65
66 UNIT_TYPE i = 0;
67
68 this->predicate_each([&i](auto& r)
69 {
70
71 i += r.area();
72
73 }, iStart, c);
74
75 return i;
76
77 }
78
79 //rectangle_array_base& operator = (const rectangle_array_base& array) { ::array < ::rectangle_type < NUMBER > >::operator=(array); return *this; }
80 //rectangle_array_base& operator = (rectangle_array_base&& array) { ::array < ::rectangle_type < NUMBER > >::operator=(::transfer(array)); return *this; }
81 //rectangle_array_base& operator = (std::initializer_list < ::rectangle_type < NUMBER > > initializer_list) { ::array < ::rectangle_type < NUMBER > > ::operator=(initializer_list); return *this; }
82
83
84};
85
86template < prototype_number NUMBER >
87inline void rectangle_array_base < NUMBER >::offset(::point_type < NUMBER > point)
88{
89 offset(point.x, point.y);
90}
91
92
93
94
95//template < prototype_number NUMBER >
96//rectangle_array_base < NUMBER >::~rectangle_array_base()
97//{
98//
99//}
100
101template < prototype_number NUMBER >
102void rectangle_array_base < NUMBER >::offset(UNIT_TYPE cx, UNIT_TYPE cy)
103{
104
105 for (::i32 i = 0; i < this->get_size(); i++)
106 {
107
108 ::rectangle_type < NUMBER > & rectangle = this->element_at(i);
109
110 rectangle.left += cx;
111 rectangle.top += cy;
112 rectangle.right += cx;
113 rectangle.bottom += cy;
114
115 }
116
117}
118
119
120template < prototype_number NUMBER >
121::rectangle_type < NUMBER > rectangle_array_base < NUMBER >::union_rect()
122{
123
124 if(this->is_empty())
125 {
126
127 return {};
128
129 }
130
131 ::rectangle_type < NUMBER > rectangleUnion(0, 0, 0, 0);
132
133 rectangleUnion = this->first();
134
135 for (::i32 i = 1; i < this->get_size(); i++)
136 {
137
138 rectangleUnion.unite(rectangleUnion, this->element_at(i));
139 //this->element_at(i).expand_bounding_box(rectangleUnion.top_left(), rectangleUnion.bottom_right());
140 }
141
142 return rectangleUnion;
143
144}
145
146
147template < prototype_number NUMBER >
148void rectangle_array_base < NUMBER >::get_box(::rectangle_type < NUMBER > * prectangle)
149
150{
151
152 *prectangle = union_rect();
153
154
155}
156
157
158template < prototype_number NUMBER >
159void rectangle_array_base < NUMBER >::intersect(const ::rectangle_type < NUMBER > & rectangle)
160{
161
162 for (::collection::index i = 0; i < this->get_size();)
163 {
164
165 this->element_at(i).intersect(this->element_at(i), rectangle);
166
167 if (this->element_at(i).is_null())
168 {
169
170 this->erase_at(i);
171
172 }
173 else
174 {
175
176 i++;
177
178 }
179
180 }
181
182}
183
184
185template < prototype_number NUMBER >
186void rectangle_array_base < NUMBER >::add(const ::rectangle_type < NUMBER > & rectangle)
187{
188 array_base < ::rectangle_type < NUMBER > >::add(rectangle);
189}
190
191
192template < prototype_number NUMBER >
193void rectangle_array_base < NUMBER >::add(UNIT_TYPE left, UNIT_TYPE top, UNIT_TYPE right, UNIT_TYPE bottom)
194{
195 add(::rectangle_type < NUMBER >(left, top, right, bottom));
196}
197
198
199template < prototype_number NUMBER >
200void rectangle_array_base < NUMBER >::add_dim(UNIT_TYPE x, UNIT_TYPE y, UNIT_TYPE cx, UNIT_TYPE cy)
201{
202 add(i32_rectangle_dimension(x, y, cx, cy));
203}
204
205
206template < prototype_number NUMBER >
207void rectangle_array_base < NUMBER >::add(const ::point_type < NUMBER > & point, const ::size_type < NUMBER > & size)
208{
209 add(::rectangle_type < NUMBER >(point, size));
210}
211
212
213template < prototype_number NUMBER >
214void rectangle_array_base < NUMBER >::add(const ::size_type < NUMBER > & size)
215{
216 this->add(::rectangle_type < NUMBER >(size));
217}
218
219
220template < prototype_number NUMBER >
221::collection::index rectangle_array_base < NUMBER >::max_normal_intersect_area(const ::rectangle_type < NUMBER > & rectangleParam, const ::rectangle_type < NUMBER > & rectangleModel)
222{
223
224 ::collection::index iFound = -1;
225 ::rectangle_type < NUMBER > rectangle;
226 auto iModelArea = rectangleModel.width() * rectangleModel.height();
227 decltype(iModelArea) iArea;
228 decltype(iModelArea) iAreaMax = 0;
229
230 if (iModelArea == 0)
231 return -1;
232
233 for (::collection::index i = 0; i < this->get_count(); i++)
234 {
235
236 if (rectangle.intersect(&rectangleParam, this->element_at(i)))
237 {
238
239 iArea = rectangle.area() * iModelArea / this->element_at(i).area();
240
241 if (iArea > iAreaMax)
242 {
243
244 iFound = i;
245
246 iAreaMax = iArea;
247
248 }
249
250
251 }
252
253 }
254
255 return iFound;
256
257}
258
259
260CLASS_DECL_ACME i32_rectangle_array_base get_top_left_oriented_damaged_areas_by_resizing(const ::i32_rectangle & rectangleNew, const ::i32_rectangle & rectangleOld, bool bOnlyGrowing = true);
261
262
263
Definition rectangle_array.h:10