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) : 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 // Reference, N>=2
75 template <size_t N>
76 // Frame2D(drain::UniTuple<T,N> & tuple, T i) : // WHY T i, not int index type?size_t
77 Frame2D(drain::UniTuple<T,N> & tuple, size_t i) : // 2025 fixed
78 drain::UniTuple<T,2>(tuple, i),
79 width(this->next()),
80 height(this->next()){
81 //updateTuple();
82 };
83
84 virtual ~Frame2D(){};
85
86
87 Frame2D & operator=(const Frame2D & geometry){
88 this->set(geometry.width, geometry.height);
89 //this->assign(geometry);
90 return *this;
91 }
92
93
94 template <class T2>
95 inline
96 Frame2D & operator=(const T2 & frame){
97 this->set(0,0); // could be init!
98 this->assign(frame);
99 return *this;
100 }
101
102
103 inline
104 void setWidth(T w){
105 width = w;
106 // updateTuple();
107 }
108
109 inline
110 void setHeight(T h){
111 height = h;
112 // updateTuple();
113 }
114
115 inline
116 void setArea(T w, T h){
117 width = w;
118 height = h;
119 }
120
121 void setArea(const drain::UniTuple<T,2> & tuple){
122 width = tuple[0];
123 height = tuple[1];
124 }
125
126
127
128
129 inline
130 T getWidth() const {
131 return width;
132 };
133
134 inline
135 T getHeight() const {
136 return height;
137 };
138
139 inline
140 T getArea() const {
141 return width*height;
142 };
143
144 inline
145 bool empty() const {
146 return (width==0) || (height==0);
147 };
148
149
150
151};
152
153DRAIN_TYPENAME_T(Frame2D, T);
154
155
156template <class T>
157struct Stub : public drain::UniTuple<T,2>{
158
159 typedef T coord_t;
160 coord_t & pos;
161 coord_t & span;
162
163 inline
164 Stub(coord_t pos=0, coord_t span=0) : drain::UniTuple<T,2>(pos, span), pos(this->next()), span(this->next()){
165 };
166
167 inline
168 Stub(const Stub & stub) : drain::UniTuple<T,2>(stub.tuple()), pos(this->next()), span(this->next()){
169 };
170
171
172};
173
174DRAIN_TYPENAME_T0(Stub, T);
175
176/*
177template <class T>
178struct StubHorz : public drain::UniTuple<T,2>{
179
180 typedef T coord_t;
181 coord_t & x;
182 coord_t & width;
183
184 inline
185 StubHorz(coord_t x=0, coord_t width=0) : drain::UniTuple<T,2>(x, width), x(this->next()), width(this->next()){
186 };
187
188 inline
189 StubHorz(const StubHorz & stub) : drain::UniTuple<T,2>(stub.tuple()), x(this->next()), width(this->next()){
190 };
191
192
193};
194
195template <class T>
196struct StubVert : public drain::UniTuple<T,2>{
197
198 typedef T coord_t;
199 coord_t & y;
200 coord_t & height;
201
202 inline
203 StubVert(coord_t y=0, coord_t width=0) : drain::UniTuple<T,2>(x, width), x(this->next()), width(this->next()){
204 };
205
206 inline
207 StubVert(const StubVert & stub) : drain::UniTuple<T,2>(stub.tuple()), x(this->next()), width(this->next()){
208 };
209
210};
211*/
212
213
215
218template <class T>
219struct Box : public drain::Point2D<T>, public drain::Frame2D<T> {
220
221public:
222
223
224 typedef T coord_t;
225
226
227 inline
228 Box(coord_t x=0, coord_t y=0, coord_t width=0, coord_t height=0) :
230 }
231
232 inline
233 Box(const Box & box) : drain::Point2D<coord_t>(box), drain::Frame2D<coord_t>(box) {
234 }
235
236
237 inline
238 void reset(){
239 this->setArea(0,0);
240 // max is "readable", whereas float-mins approach zero
241 this->setLocation(undefined, undefined);
242 }
243
244 inline
245 void expand(coord_t x, coord_t y){
246 expandHorz(x);
247 expandVert(y);
248 }
249
250 inline
251 void expand(const drain::Point2D<coord_t> & p){
252 expandHorz(p.x);
253 expandVert(p.y);
254 }
255
257 inline
258 void expand(const Box & box){
259 expandHorz(box);
260 expandVert(box);
261 }
262
263 inline
264 void expandHorz(const Box & box){
265 expandHorz(box.x);
266 expandHorz(box.x + box.width);
267 // box.y + box.height);
268 }
269
270 inline
271 void expandVert(const Box & box){
272 expandVert(box.y);
273 expandVert(box.y + box.height);
274 }
275
276 void expandHorz(coord_t x){
277 //if (this->x != undefined){
278 if (!isUndefined(this->x)){
279 const coord_t xMax = std::max(x, this->x + this->width);
280 this->x = std::min(this->x, x);
281 this->width = xMax - this->x;
282 }
283 else {
284 this->x = x;
285 this->width = 0; // probably was already, but ensure
286 }
287 }
288
289 void expandVert(coord_t y){
290 //if (this->y != undefined){
291 if (!isUndefined(this->y)){
292 const coord_t yMax = std::max(y, this->y + this->height);
293 this->y = std::min(this->y, y);
294 this->height = yMax - this->y;
295 }
296 else {
297 this->y = y;
298 this->height = 0; // probably was already, but ensure
299 }
300 }
301
302
303
304 drain::Point2D<coord_t> & getLocation(){
305 return *this;
306 };
307
308 const drain::Point2D<coord_t> & getLocation() const {
309 return *this;
310 };
311
312 drain::Frame2D<coord_t> & getFrame(){
313 return *this;
314 };
315
316 const drain::Frame2D<coord_t> & getFrame() const {
317 return *this;
318 };
319
320 inline
321 bool isDefined() const {
322 return isDefined(this->x) && isDefined(this->y) && isDefined(this->width) && isDefined(this->height);
323 }
324
325//protected:
326 static inline
327 bool isDefined(coord_t coord){
328 return !std::isnan(coord);
329 }
330
331 static inline
332 bool isUndefined(coord_t coord){
333 return std::isnan(coord);
334 }
335
336 /*
337 static inline
338 void setUndefined(coord_t & coord){
339 coord = undefined;
340 }
341 */
342
343
344 // Note: (nan == nan) return false, so don't compare...
345 static const
346 coord_t undefined; // = std::numeric_limits<coord_t>::max();
347
348};
349
350DRAIN_TYPENAME_T(Box, T);
351
352
353template <class T>
354// const T Box<T>::undefined = std::numeric_limits<T>::max();
355const T Box<T>::undefined = std::numeric_limits<T>::quiet_NaN();
356
357
358template <class T>
359std::ostream &operator<<(std::ostream &ostr,const drain::Box<T> &box)
360{
361 ostr << (const drain::Point2D<T> &)box << ' ' << (const drain::Frame2D<T> &)box; // [' << p.x << ',' << p.y << ',' << p.z << ']';
362 return ostr;
363}
364
365} // drain
366
367#endif
Something that has width and height.
Definition Frame.h:53
Tuple of N elements of type T.
Definition UniTuple.h:65
Definition DataSelector.cpp:1277
Something that has coordinates (x,y) and dimensions (width, height).
Definition Frame.h:219
void expand(const Box &box)
Update this box such that it contains the given bbox .
Definition Frame.h:258
Definition Point.h:48
Definition Frame.h:157