Rev 22 | Rev 27 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
1 | |||
15 | Werner | 2 | #ifndef GRID_H |
3 | #define GRID_H |
||
4 | |||
22 | Werner | 5 | #include <QtCore> |
15 | Werner | 6 | |
7 | |||
8 | #include <stdexcept> |
||
9 | |||
10 | /** Grid class (template). |
||
11 | |||
12 | */ |
||
13 | template <class T> |
||
14 | class Grid { |
||
15 | public: |
||
16 | |||
17 | Grid(); |
||
18 | Grid(int cellsize, int sizex, int sizey) { mData=0; setup(cellsize, sizex, sizey); } |
||
19 | ~Grid() { if (mData) delete[] mData; } |
||
20 | |||
18 | Werner | 21 | bool setup(const float cellsize, const int sizex, const int sizey); |
22 | Werner | 22 | bool setup(const QRectF& rect, const double cellsize); |
15 | Werner | 23 | void initialize(const T& value) {for( T *p = begin();p!=end(); ++p) *p=value;} |
24 | |||
25 | const int sizeX() const { return mSizeX; } |
||
26 | const int sizeY() const { return mSizeY; } |
||
27 | const float metricSizeX() const { return mSizeX*mCellsize; } |
||
28 | const float metricSizeY() const { return mSizeY*mCellsize; } |
||
29 | const float cellsize() const { return mCellsize; } |
||
30 | // query |
||
25 | Werner | 31 | T& valueAtIndex(const QPoint& pos); ///< value at position defined by indices (x,y) |
32 | T& valueAt(const QPointF& posf); ///< value at position defined by metric coordinates |
||
22 | Werner | 33 | QPoint indexAt(const QPointF& pos) { return QPoint(int((pos.x()-mOffset.x()) / mCellsize), int((pos.y()-mOffset.y())/mCellsize)); } /// get index of value at position pos (metric) |
15 | Werner | 34 | bool isIndexValid(const QPoint& pos) { return (pos.x()>=0 && pos.x()<mSizeX && pos.y()>=0 && pos.y()<mSizeY); } /// get index of value at position pos (index) |
35 | void validate(QPoint &pos) { pos.setX( qMax(qMin(pos.x(), mSizeX-1), 0) ); pos.setY( qMax(qMin(pos.y(), mSizeY-1), 0) );} /// ensure that "pos" is a valid key. if out of range, pos is set to minimum/maximum values. |
||
22 | Werner | 36 | QPointF getCellCoordinates(const QPoint &pos) { return QPointF( (pos.x()+0.5)*mCellsize+mOffset.x(), (pos.y()+0.5)*mCellsize + mOffset.y());} /// get metric coordinates of the cells center |
25 | Werner | 37 | inline T* begin() { return mData; } ///< get "iterator" pointer |
38 | inline T* end() { return &(mData[mCount]); } ///< get iterator end-pointer |
||
39 | QPoint indexOf(T* element); ///< retrieve index (x/y) of the pointer element. returns -1/-1 if element is not valid. |
||
15 | Werner | 40 | |
41 | |||
42 | private: |
||
43 | T* mData; |
||
22 | Werner | 44 | QPointF mOffset; |
15 | Werner | 45 | float mCellsize; /// size of a cell in meter |
46 | int mSizeX; /// count of cells in x-direction |
||
47 | int mSizeY; /// count of cells in y-direction |
||
48 | int mCount; |
||
49 | }; |
||
50 | |||
51 | typedef Grid<float> FloatGrid; |
||
52 | |||
22 | Werner | 53 | |
54 | |||
15 | Werner | 55 | template <class T> |
22 | Werner | 56 | T& Grid<T>::valueAtIndex(const QPoint& pos) |
57 | { |
||
58 | if (isIndexValid(pos)) { |
||
59 | return mData[pos.x()*mSizeX + pos.y()]; |
||
60 | } |
||
61 | throw std::logic_error("TGrid: invalid Index!"); |
||
62 | } |
||
63 | |||
64 | template <class T> |
||
65 | T& Grid<T>::valueAt(const QPointF& posf) |
||
66 | { |
||
67 | return valueAtIndex( indexAt(posf) ); |
||
68 | } |
||
69 | |||
70 | template <class T> |
||
15 | Werner | 71 | Grid<T>::Grid() |
72 | { |
||
73 | mData=0; mCellsize=0.f; |
||
74 | } |
||
75 | |||
76 | template <class T> |
||
18 | Werner | 77 | bool Grid<T>::setup(const float cellsize, const int sizex, const int sizey) |
15 | Werner | 78 | { |
79 | mSizeX=sizex; mSizeY=sizey; mCellsize=(float)cellsize; |
||
80 | mCount = mSizeX*mSizeY; |
||
81 | if (mData) |
||
82 | delete[] mData; |
||
83 | if (mCount>0) |
||
84 | mData = new T[mCount]; |
||
85 | return true; |
||
86 | } |
||
87 | |||
88 | template <class T> |
||
22 | Werner | 89 | bool Grid<T>::setup(const QRectF& rect, const double cellsize) |
15 | Werner | 90 | { |
22 | Werner | 91 | mOffset.setX(rect.left()); |
92 | mOffset.setY(rect.top()); |
||
93 | int dx = int(rect.width()/cellsize); |
||
94 | if (mOffset.x()+cellsize*dx<rect.right()) |
||
95 | dx++; |
||
96 | int dy = int(rect.height()/cellsize); |
||
97 | if (mOffset.y()+cellsize*dy<rect.bottom()) |
||
98 | dy++; |
||
99 | return setup(cellsize, dx, dy); |
||
15 | Werner | 100 | } |
101 | |||
25 | Werner | 102 | template <class T> |
103 | QPoint Grid<T>::indexOf(T* element) |
||
104 | { |
||
105 | QPoint result(-1,-1); |
||
106 | if (element==NULL || element<mData || element>=end()) |
||
107 | return result; |
||
108 | int idx = element - mData; |
||
109 | result.setX( idx / mSizeX); |
||
110 | result.setY( idx % mSizeX); |
||
111 | return result; |
||
112 | } |
||
22 | Werner | 113 | |
15 | Werner | 114 | #endif // GRID_H |