Loading...
Searching...
No Matches
Frame.h
1/*
2
3MIT License
4
5Copyright (c) 2017 FMI Open Development / Markus Peura, first.last@fmi.fi
6
7Permission is hereby granted, free of charge, to any person obtaining a copy
8of this software and associated documentation files (the "Software"), to deal
9in the Software without restriction, including without limitation the rights
10to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11copies of the Software, and to permit persons to whom the Software is
12furnished to do so, subject to the following conditions:
13
14The above copyright notice and this permission notice shall be included in all
15copies or substantial portions of the Software.
16
17THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23SOFTWARE.
24
25*/
26/*
27Part of Rack development has been done in the BALTRAD projects part-financed
28by the European Union (European Regional Development Fund and European
29Neighbourhood Partnership Instrument, Baltic Sea Region Programme 2007-2013)
30*/
31
32#ifndef DRAIN_FRAME_H_
33#define DRAIN_FRAME_H_
34
35#include <ostream>
36#include <limits>
37#include <cmath> // isnan
38
39#include <drain/TypeName.h>
40#include <drain/UniTuple.h>
41#include <drain/util/Point.h> // for Box
42//#include "drain/util/Range.h"
43
44
45namespace drain {
46
48
52template <class T>
53class Frame2D : public drain::UniTuple<T,2> {
54
55public:
56
57 T & width;
58 T & height;
59
60 inline
61 Frame2D(T width=0, T height=0) : width(this->next()), height(this->next()){
62 this->set(width, height?height:width);
63 };
64
65 Frame2D(const Frame2D<T> & geometry) : drain::UniTuple<T,2>(), width(this->next()), height(this->next()) {
66 this->set(geometry.width, geometry.height);
67 }
68
69 template <class T2>
70 Frame2D(const Frame2D<T2> & geometry) : width(this->next()), height(this->next()) {
71 this->set(geometry.width, geometry.height);
72 }
73
74 template <class T2>
75 Frame2D(const UniTuple<T2,2> & tuple) : width(this->next()), height(this->next()) {
76 this->set(tuple[0], tuple[1]);
77 }
78
79 // Reference, N>=2
80 template <size_t N>
81 // Frame2D(drain::UniTuple<T,N> & tuple, T i) : // WHY T i, not int index type?size_t
82 Frame2D(drain::UniTuple<T,N> & tuple, size_t i) : // 2025 fixed
83 drain::UniTuple<T,2>(tuple, i),
84 width(this->next()),
85 height(this->next()){
86 //updateTuple();
87 }
88
89 virtual ~Frame2D(){};
90
91
92 Frame2D & operator=(const Frame2D & geometry){
93 this->set(geometry.width, geometry.height);
94 //this->assign(geometry);
95 return *this;
96 }
97
98
99 template <class T2>
100 inline
101 Frame2D & operator=(const T2 & frame){
102 this->set(0,0); // could be init!
103 this->assign(frame);
104 return *this;
105 }
106
107
108 inline
109 void setWidth(T w){
110 width = w;
111 // updateTuple();
112 }
113
114 inline
115 void setHeight(T h){
116 height = h;
117 // updateTuple();
118 }
119
120 inline
121 void setArea(T w, T h){
122 width = w;
123 height = h;
124 }
125
126 void setArea(const drain::UniTuple<T,2> & tuple){
127 width = tuple[0];
128 height = tuple[1];
129 }
130
131
132
133
134 inline
135 T getWidth() const {
136 return width;
137 };
138
139 inline
140 T getHeight() const {
141 return height;
142 };
143
144 inline
145 T getArea() const {
146 return width*height;
147 };
148
149 inline
150 bool empty() const {
151 return (width==0) || (height==0);
152 };
153
154
155
156};
157
158DRAIN_TYPENAME_T(Frame2D, T);
159
160
162template <class T>
163struct Stub : public drain::UniTuple<T,2>{
164
165 typedef T coord_t;
166 coord_t & pos;
167 coord_t & span;
168
169 inline
170 Stub(coord_t pos=0, coord_t span=0) : drain::UniTuple<T,2>(pos, span), pos(this->next()), span(this->next()){
171 };
172
173 inline
174 Stub(const Stub & stub) : drain::UniTuple<T,2>(stub.tuple()), pos(this->next()), span(this->next()){
175 };
176
177
178};
179
180DRAIN_TYPENAME_T(Stub, T);
181
182/*
183template <class T>
184struct StubHorz : public drain::UniTuple<T,2>{
185
186 typedef T coord_t;
187 coord_t & x;
188 coord_t & width;
189
190 inline
191 StubHorz(coord_t x=0, coord_t width=0) : drain::UniTuple<T,2>(x, width), x(this->next()), width(this->next()){
192 };
193
194 inline
195 StubHorz(const StubHorz & stub) : drain::UniTuple<T,2>(stub.tuple()), x(this->next()), width(this->next()){
196 };
197
198
199};
200
201template <class T>
202struct StubVert : public drain::UniTuple<T,2>{
203
204 typedef T coord_t;
205 coord_t & y;
206 coord_t & height;
207
208 inline
209 StubVert(coord_t y=0, coord_t width=0) : drain::UniTuple<T,2>(x, width), x(this->next()), width(this->next()){
210 };
211
212 inline
213 StubVert(const StubVert & stub) : drain::UniTuple<T,2>(stub.tuple()), x(this->next()), width(this->next()){
214 };
215
216};
217*/
218
219
221
224template <class T>
225struct Box : public drain::Point2D<T>, public drain::Frame2D<T> {
226
227public:
228
229
230 typedef T coord_t;
231
232
233 inline
234 Box(coord_t x=0, coord_t y=0, coord_t width=0, coord_t height=0) :
236 }
237
238 inline
239 Box(const Box & box) : drain::Point2D<coord_t>(box), drain::Frame2D<coord_t>(box) {
240 }
241
242 Box & operator=(const Box &) = default;
243
244
245 inline
246 void reset(){
247 this->setArea(0,0);
248 // max is "readable", whereas float-mins approach zero
249 this->setLocation(undefined, undefined);
250 }
251
252 inline
253 void expand(coord_t x, coord_t y){
254 expandHorz(x);
255 expandVert(y);
256 }
257
258 inline
259 void expand(const drain::Point2D<coord_t> & p){
260 expandHorz(p.x);
261 expandVert(p.y);
262 }
263
265 inline
266 void expand(const Box & box){
267 expandHorz(box);
268 expandVert(box);
269 }
270
271 inline
272 void expandHorz(const Box & box){
273 expandHorz(box.x);
274 expandHorz(box.x + box.width);
275 // box.y + box.height);
276 }
277
278 inline
279 void expandVert(const Box & box){
280 expandVert(box.y);
281 expandVert(box.y + box.height);
282 }
283
284 void expandHorz(coord_t x){
285 //if (this->x != undefined){
286 if (!isUndefined(this->x)){
287 const coord_t xMax = std::max(x, this->x + this->width);
288 this->x = std::min(this->x, x);
289 this->width = xMax - this->x;
290 }
291 else {
292 this->x = x;
293 this->width = 0; // probably was already, but ensure
294 }
295 }
296
297 void expandVert(coord_t y){
298 //if (this->y != undefined){
299 if (!isUndefined(this->y)){
300 const coord_t yMax = std::max(y, this->y + this->height);
301 this->y = std::min(this->y, y);
302 this->height = yMax - this->y;
303 }
304 else {
305 this->y = y;
306 this->height = 0; // probably was already, but ensure
307 }
308 }
309
310
311
312 drain::Point2D<coord_t> & getLocation(){
313 return *this;
314 };
315
316 const drain::Point2D<coord_t> & getLocation() const {
317 return *this;
318 };
319
320 drain::Frame2D<coord_t> & getFrame(){
321 return *this;
322 };
323
324 const drain::Frame2D<coord_t> & getFrame() const {
325 return *this;
326 };
327
328 inline
329 bool isDefined() const {
330 return isDefined(this->x) && isDefined(this->y) && isDefined(this->width) && isDefined(this->height);
331 }
332
333//protected:
334 static inline
335 bool isDefined(coord_t coord){
336 return !std::isnan(coord);
337 }
338
339 static inline
340 bool isUndefined(coord_t coord){
341 return std::isnan(coord);
342 }
343
344 /*
345 static inline
346 void setUndefined(coord_t & coord){
347 coord = undefined;
348 }
349 */
350
351
352 // Note: (nan == nan) return false, so don't compare...
353 static const
354 coord_t undefined; // = std::numeric_limits<coord_t>::max();
355
356};
357
358DRAIN_TYPENAME_T(Box, T);
359
360
361template <class T>
362// const T Box<T>::undefined = std::numeric_limits<T>::max();
363const T Box<T>::undefined = std::numeric_limits<T>::quiet_NaN();
364
365
366template <class T>
367std::ostream &operator<<(std::ostream &ostr,const drain::Box<T> &box)
368{
369 ostr << (const drain::Point2D<T> &)box << ' ' << (const drain::Frame2D<T> &)box; // [' << p.x << ',' << p.y << ',' << p.z << ']';
370 return ostr;
371}
372
373} // drain
374
375#endif
Something that has width and height.
Definition Frame.h:53
Tuple of N elements of type T.
Definition UniTuple.h:65
Definition Data.h:1473
std::ostream & operator<<(std::ostream &ostr, const PlainData< DT > &d)
Definition Data.h:631
Something that has coordinates (x,y) and dimensions (width, height).
Definition Frame.h:225
void expand(const Box &box)
Update this box such that it contains the given bbox .
Definition Frame.h:266
Definition Point.h:48
DOC: Add class description.
Definition Frame.h:163