Loading...
Searching...
No Matches
CoordinateHandler.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 COORD_HANDLER_H_
33#define COORD_HANDLER_H_
34
35#include <drain/image/CoordinatePolicy.h>
36#include <ostream>
37
38#include "drain/util/Frame.h"
39#include "Geometry.h"
40
41#include "ImageFrame.h"
42#include "Direction.h" //~ "Position.h", experimental
43
44namespace drain {
45
46
47namespace image {
48
49
50
51
53//typedef drain::Flags::ivalue_t coord_overflow_t;
54//enum coord_overflow_t {UNCHANGED=0, X_OVERFLOW=1, X_UNDERFLOW=2, Y_OVERFLOW=4, Y_UNDERFLOW=8, IRREVERSIBLE=128};
55
56//template <>
57//const drain::SingleFlagger<coord_overflow_t>::dict_t drain::SingleFlagger<coord_overflow_t>::dict;
58
59/*
60enum coord_overflow_t {
61 UNCHANGED = 0,
62 X_OVERFLOW = 1,
63 X_UNDERFLOW = 2,
64 Y_OVERFLOW = 4,
65 Y_UNDERFLOW = 8,
66 IRREVERSIBLE = 128, /// Equal move in inverse direction would not result original position.
67};
68
69template <>
70const drain::Enum<coord_overflow_t>::dict_t drain::Enum<coord_overflow_t>::dict;
71*/
72typedef unsigned int coord_overflow_t;
73
74class CoordinateHandler2D { //: protected CoordinatePolicy {
75
76public:
77
79
80
81 static const coord_overflow_t UNCHANGED = 0; // = 0;
82 static const coord_overflow_t X_OVERFLOW = 1; // = 1;
83 static const coord_overflow_t X_UNDERFLOW = 2; // = 2;
84 static const coord_overflow_t Y_OVERFLOW = 4; // = 4;
85 static const coord_overflow_t Y_UNDERFLOW = 8; // 8;
87 static const coord_overflow_t IRREVERSIBLE = 128; // = 128;
88
89
90 CoordinatePolicy policy;
92
93
95 inline
97 set(area, policy);
98 }
99
100 // Copy constructor
101 inline
103 // setLimits(handler.xRange.min, handler.yRange.min, handler.xRange.max+1, handler.yRange.max+1); // +1
104 // setLimits(handler.xRange.min, handler.yRange.min, handler.xRange.max+1, handler.yRange.max+1); // +1
105 xRange.set(handler.getXRange());
106 yRange.set(handler.getYRange());
107 area.set(handler.area);
108 setPolicy(handler.getPolicy());
109 }
110
111 //
112 inline
113 CoordinateHandler2D(const ImageFrame & src){
114 set(src.getGeometry().area, src.getCoordinatePolicy());
115 }
116
117
119
123 inline
124 CoordinateHandler2D(int xUpperLimit, int yUpperLimit, const CoordinatePolicy &policy = CoordinatePolicy()){
125 setLimits(xUpperLimit, yUpperLimit);
126 setPolicy(policy);
127 }
128
129 inline virtual
131
132
133 inline
134 void set(const drain::image::ImageConf & src){
135 setLimits(src.getWidth(), src.getHeight());
136 setPolicy(src.getCoordinatePolicy());
137 }
138
139 inline
140 void set(const drain::image::AreaGeometry & area = AreaGeometry(), const CoordinatePolicy &p = CoordinatePolicy()){
141 setLimits(area.getWidth(), area.getHeight());
142 setPolicy(p);
143 }
144
146 inline
147 void setLimits(int xMin, int yMin, int xUpperLimit, int yUpperLimit){
148 xRange.set(xMin, xUpperLimit - 1);
149 yRange.set(yMin, yUpperLimit - 1);
150 area.set(xUpperLimit, yUpperLimit);
151 }
152
154 void setLimits(int xUpperLimit,int yUpperLimit){
155 setLimits(0, 0, xUpperLimit, yUpperLimit);
156 }
157
158
159 inline
160 const Range<int> & getXRange() const {
161 return xRange;
162 }
163
164 inline
165 const Range<int> & getYRange() const {
166 return yRange;
167 }
168
169
171 inline
173 setPolicy(p.xUnderFlowPolicy, p.yUnderFlowPolicy, p.xOverFlowPolicy, p.yOverFlowPolicy);
174 };
175
177 void setPolicy(EdgePolicy::index_t xUnderFlowPolicy, EdgePolicy::index_t yUnderFlowPolicy, EdgePolicy::index_t xOverFlowPolicy, EdgePolicy::index_t yOverFlowPolicy);
178
180 inline
181 void setPolicy(EdgePolicy::index_t p){
182 setPolicy(p, p, p, p);
183 }
184
185
186 inline
187 const CoordinatePolicy & getPolicy() const {
188 return policy; //*this;
189 }
190
191
193
201 virtual inline
202 coord_overflow_t handle(int &x,int &y) const {
203
204 result = 0;
205
206 if (x < xRange.min)
207 result |= (this->*handleXUnderFlow)(x,y);
208
209 if (x >= area.width)
210 result |= (this->*handleXOverFlow)(x,y);
211
212 if (y < yRange.min)
213 result |= (this->*handleYUnderFlow)(x,y);
214
215 if (y >= area.height)
216 result |= (this->*handleYOverFlow)(x,y);
217
218 return result;
219
220 }
221
223 inline
225 return handle(p.x, p.y);
226 }
227
228 inline // NEW
230 return handle(p.i, p.j);
231 }
232
234 inline
235 bool validate(Point2D<int> &p) const {
236 return (handle(p.x, p.y) & CoordinateHandler2D::IRREVERSIBLE) == 0;
237 }
238
240 inline
241 bool validate(int &x, int &y) const {
242 return (handle(x, y) & CoordinateHandler2D::IRREVERSIBLE) == 0;
243 }
244
245private:
246
247 mutable coord_overflow_t result;
248 //mutable int result;
249
250protected:
251
252 //CoordinatePolicy policy;
253 drain::Range<int> xRange;
254 drain::Range<int> yRange;
255
256 coord_overflow_t (CoordinateHandler2D::*handleXUnderFlow)(int &x, int &y) const;
257 coord_overflow_t (CoordinateHandler2D::*handleXOverFlow)(int &x, int &y) const;
258 coord_overflow_t (CoordinateHandler2D::*handleYUnderFlow)(int &x, int &y) const;
259 coord_overflow_t (CoordinateHandler2D::*handleYOverFlow)(int &x, int &y) const;
260
261
263 coord_overflow_t skipUndefined(int &x, int &y) const {
264 return 0;
265 };
266
267 // LIMIT
269 coord_overflow_t limitXUnderFlow( int &x, int &y) const {
270 x = xRange.min;
271 return X_UNDERFLOW | IRREVERSIBLE;
272 };
273
275 coord_overflow_t limitYUnderFlow( int &x, int &y) const {
276 y = yRange.min;
277 return Y_UNDERFLOW | IRREVERSIBLE;
278 };
279
280 coord_overflow_t limitXOverFlow( int &x, int &y) const {
281 x = xRange.max;
282 return X_OVERFLOW | IRREVERSIBLE;
283 };
284
285 coord_overflow_t limitYOverFlow( int &x, int &y) const {
286 y = yRange.max;
287 return Y_OVERFLOW | IRREVERSIBLE;
288 };
289
290 // WRAP
292 coord_overflow_t wrapXUnderFlow( int &x, int &y) const {
293 // Assuming minValue = 0
294 x = x % area.width + area.width;
295 return X_UNDERFLOW;
296 };
297
299 coord_overflow_t wrapYUnderFlow( int &x, int &y) const {
300 // Assuming minValue = 0
301 y = y % area.height + area.height;
302 return Y_UNDERFLOW;
303 };
304
306 coord_overflow_t wrapXOverFlow( int &x, int &y) const {
307 // Assuming minValue = 0
308 x = x % area.width;
309 return X_OVERFLOW;
310 };
311
313 coord_overflow_t wrapYOverFlow( int &x, int &y) const {
314 // Assuming minValue = 0
315 y = y % area.height;
316 return Y_OVERFLOW;
317 };
318
319 // MIRROR
321 coord_overflow_t mirrorXUnderFlow( int &x, int &y) const {
322 x = xRange.min-x;
323 return X_UNDERFLOW;
324 };
325
327 coord_overflow_t mirrorYUnderFlow( int &x, int &y) const {
328 y = yRange.min-y;
329 return Y_UNDERFLOW;
330 };
331
333 coord_overflow_t mirrorXOverFlow( int &x, int &y) const {
334 x = 2*xRange.max - x;
335 return X_OVERFLOW;
336 };
337
339 coord_overflow_t mirrorYOverFlow( int &x, int &y) const {
340 y = 2*yRange.max - y;
341 return Y_OVERFLOW;
342 };
343
344 // POLAR
346
350 coord_overflow_t polarXUnderFlow( int &x, int &y) const {
351 x = xRange.min - x - 1;
352 y = (y + area.height/2) % area.height;
353 //std::cout << "handleXUnderFlow_Polar ";
354 return X_UNDERFLOW; // ??
355 };
356
358
362 coord_overflow_t polarYUnderFlow( int &x, int &y) const {
363 y = yRange.min - y - 1;
364 x = (x + area.width/2) % area.width;
365 return Y_UNDERFLOW; // ??
366 };
367
369 coord_overflow_t polarXOverFlow( int &x, int &y) const {
370 x = 2*xRange.max - x + 1;
371 y = (y + area.height/2) % area.height;
372 return X_OVERFLOW; // ??
373 };
374
376 coord_overflow_t polarYOverFlow( int &x, int &y) const {
377 y = 2*yRange.max - y + 1;
378 x = (x + area.width/2) % area.width;
379 return X_OVERFLOW; // ??
380 };
381
382 /*
383 Alternative approach would be to coord in dependent have:
384 coord_overflow_t handleAUnderFlow_Limit(const int &a,const int &b,
385 const int &aMin, const int &aMax,
386 const int &bMin, const int &bMax )
387 */
388
389
390 // etc.
391
392};
393
394// using namespace std;
395
396// std::ostream & operator<<(std::ostream & ostr, const CoordinatePolicy & policy);
397
398
399std::ostream & operator<<(std::ostream & ostr, const CoordinateHandler2D & handler);
400
401} // image
402
403} // drain
404#endif
405
406// Drain
Two-way mapping between strings and objects of template class T.
Definition Dictionary.h:61
Something that has width and height.
Definition Frame.h:53
Definition Range.h:52
Definition CoordinateHandler.h:74
bool validate(int &x, int &y) const
Handles the coordinate, returning true if the position is reversible.
Definition CoordinateHandler.h:241
void setPolicy(EdgePolicy::index_t p)
Set the same policy in all the directions.
Definition CoordinateHandler.h:181
CoordinateHandler2D(int xUpperLimit, int yUpperLimit, const CoordinatePolicy &policy=CoordinatePolicy())
Constructor.
Definition CoordinateHandler.h:124
static const coord_overflow_t IRREVERSIBLE
Equal move in inverse direction would not result original position.
Definition CoordinateHandler.h:87
coord_overflow_t polarXUnderFlow(int &x, int &y) const
Definition CoordinateHandler.h:350
coord_overflow_t polarYUnderFlow(int &x, int &y) const
Definition CoordinateHandler.h:362
coord_overflow_t handle(Point2D< int > &p) const
Calls handle(int &x,int &y)
Definition CoordinateHandler.h:224
void setLimits(int xMin, int yMin, int xUpperLimit, int yUpperLimit)
Sets minimum values and outer upper limits for x and y.
Definition CoordinateHandler.h:147
coord_overflow_t skipUndefined(int &x, int &y) const
Does nothing to the coordinates.
Definition CoordinateHandler.h:263
virtual coord_overflow_t handle(int &x, int &y) const
Ensures the validity of the coordinates. If inside limits, arguments (x,y) remain intact and 0 is ret...
Definition CoordinateHandler.h:202
CoordinateHandler2D(const drain::image::AreaGeometry &area=AreaGeometry(), const CoordinatePolicy &policy=CoordinatePolicy())
Default constructor.
Definition CoordinateHandler.h:96
bool validate(Point2D< int > &p) const
Handles the coordinate, returning true if the position is reversible.
Definition CoordinateHandler.h:235
void setPolicy(const CoordinatePolicy &p)
Assigns internal function pointers.
Definition CoordinateHandler.h:172
void setLimits(int xUpperLimit, int yUpperLimit)
Sets outer upper limits for x and y.
Definition CoordinateHandler.h:154
Policies for coordinate underflows and overflows.
Definition CoordinatePolicy.h:100
Struct for image (excluding data)
Definition ImageConf.h:333
Image with static geometry.
Definition ImageFrame.h:62
const CoordinatePolicy & getCoordinatePolicy() const
Coord policy.
Definition ImageLike.h:174
unsigned int coord_overflow_t
typedef drain::GlobalFlags<CoordinatePolicy> coord_overflow_flagger_t;
Definition CoordinateHandler.h:72
Definition DataSelector.cpp:1277
Definition Point.h:48
Definition Direction.h:46