Frame.h
1 /*
2 
3 MIT License
4 
5 Copyright (c) 2017 FMI Open Development / Markus Peura, first.last@fmi.fi
6 
7 Permission is hereby granted, free of charge, to any person obtaining a copy
8 of this software and associated documentation files (the "Software"), to deal
9 in the Software without restriction, including without limitation the rights
10 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 copies of the Software, and to permit persons to whom the Software is
12 furnished to do so, subject to the following conditions:
13 
14 The above copyright notice and this permission notice shall be included in all
15 copies or substantial portions of the Software.
16 
17 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23 SOFTWARE.
24 
25 */
26 /*
27 Part of Rack development has been done in the BALTRAD projects part-financed
28 by the European Union (European Regional Development Fund and European
29 Neighbourhood 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 <stdexcept>
37 
38 #include <drain/Log.h>
39 #include <drain/UniTuple.h>
40 #include <drain/Type.h>
41 #include <drain/util/Point.h> // for Box
42 //#include "drain/util/Range.h"
43 
44 
45 namespace drain {
46 
48 
52 template <class T>
53 class Frame2D : public drain::UniTuple<T,2> {
54 
55 public:
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 
153 DRAIN_TYPENAME_T(Frame2D, T);
154 
156 
159 template <class T>
160 struct Box : public drain::Point2D<T>, public drain::Frame2D<T> {
161 // struct Box : public drain::UniTuple<T,4> {
162 
163 public:
164 
165  /*
166  typedef drain::UniTuple<T,4> tuple_t;
167  drain::Point2D<T> location;
168  drain::Frame2D<T> frame;
169 
170  inline
171  Box(T x=0, T y=0, T width=0, T height=0) : tuple_t(), location((tuple_t &)*this, 0), frame((tuple_t &)*this, 2) {
172  location.setLocation(x, y);
173  frame.setArea(width, height);
174  }
175 
176  inline
177  Box(const Box<T> & box) : tuple_t(), location((tuple_t &)*this, 0), frame((tuple_t &)*this, 2){
178  location.setLocation(box.location);
179  frame.setArea(box.frame);
180  }
181  */
182 
183 
184  inline
185  Box(T x=0, T y=0, T width=0, T height=0) : drain::Point2D<T>(x, y), drain::Frame2D<T>(width, height) {
186  }
187 
188  inline
189  Box(const Box & box) : drain::Point2D<T>(box), drain::Frame2D<T>(box) {
190  }
191 
192 
194  void expand(const Box & box){
195  /*
196  const T xMax = std::max(this->x + this->width, box.x+box.width);
197  const T yMax = std::max(this->y + this->height, box.y+box.height);
198  this->x = std::min(this->x, box.x);
199  this->y = std::min(this->y, box.y);
200  this->width = xMax - this->x;
201  this->height = yMax - this->y;
202  expand(box.x, box.y);
203  */
204  expand(box.x, box.y);
205  expand(box.x + box.width, box.y + box.height);
206  }
207 
208  void expand(const T & x, const T & y){
209  // Logic fails if width or height is negative?
210  T m;
211 
212  m = std::max(this->x + this->width, x);
213  this->x = std::min(this->x, x);
214  this->width = m - this->x;
215 
216  m = std::max(this->y + this->height, y);
217  this->y = std::min(this->y, y);
218  this->height = m - this->y;
219 
220  }
221 
222  inline
223  void expand(const drain::Point2D<T> & p){
224  expand(p.x, p.y);
225  }
226 
227  drain::Point2D<T> & getLocation(){
228  return *this;
229  };
230 
231  const drain::Point2D<T> & getLocation() const {
232  return *this;
233  };
234 
235  drain::Frame2D<T> & getFrame(){
236  return *this;
237  };
238 
239  const drain::Frame2D<T> & getFrame() const {
240  return *this;
241  };
242 
243 };
244 
245 DRAIN_TYPENAME_T(Box, T);
246 
247 
248 template <class T>
249 std::ostream &operator<<(std::ostream &ostr,const drain::Box<T> &box)
250 {
251  ostr << (const drain::Point2D<T> &)box << ' ' << (const drain::Frame2D<T> &)box; // [' << p.x << ',' << p.y << ',' << p.z << ']';
252  return ostr;
253 }
254 
255 } // drain
256 
257 #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:160
void expand(const Box &box)
Update this box such that it contains the given bbox .
Definition: Frame.h:194
Definition: Point.h:48