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