]> git.mxchange.org Git - simgear.git/blob - simgear/math/SGRect.hxx
use the proper namespace
[simgear.git] / simgear / math / SGRect.hxx
1 // Class representing a rectangular region
2 //
3 // Copyright (C) 2012  Thomas Geymayer <tomgey@gmail.com>
4 //
5 // This library is free software; you can redistribute it and/or
6 // modify it under the terms of the GNU Library General Public
7 // License as published by the Free Software Foundation; either
8 // version 2 of the License, or (at your option) any later version.
9 //
10 // This library is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13 // Library General Public License for more details.
14 //
15 // You should have received a copy of the GNU Library General Public
16 // License along with this library; if not, write to the Free Software
17 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA
18
19 #ifndef SG_RECT_HXX_
20 #define SG_RECT_HXX_
21
22 #include "SGLimits.hxx"
23 #include "SGVec2.hxx"
24
25 template<typename T>
26 class SGRect
27 {
28   public:
29
30     SGRect():
31       _min(SGLimits<T>::max(), SGLimits<T>::max()),
32       _max(-SGLimits<T>::max(), -SGLimits<T>::max())
33     {
34
35     }
36
37     explicit SGRect(const SGVec2<T>& pt):
38       _min(pt),
39       _max(pt)
40     {
41
42     }
43
44     SGRect(T x, T y):
45       _min(x, y),
46       _max(x, y)
47     {
48
49     }
50
51     SGRect(const SGVec2<T>& min, const SGVec2<T>& max):
52       _min(min),
53       _max(max)
54     {
55
56     }
57
58     SGRect(T x, T y, T w, T h):
59       _min(x, y),
60       _max(x + w, y + h)
61     {
62
63     }
64
65     template<typename S>
66     explicit SGRect(const SGRect<S>& rect):
67       _min(rect.getMin()),
68       _max(rect.getMax())
69     {
70
71     }
72
73     void setMin(const SGVec2<T>& min) { _min = min; }
74     const SGVec2<T>& getMin() const { return _min; }
75
76     void setMax(const SGVec2<T>& max) { _max = max; }
77     const SGVec2<T>& getMax() const { return _max; }
78
79     void set(T x, T y, T w, T h)
80     {
81       _min.x() = x;
82       _min.y() = y;
83       _max.x() = x + w;
84       _max.y() = y + h;
85     }
86
87     T x() const { return _min.x(); }
88     T y() const { return _min.y(); }
89     T width() const { return _max.x() - _min.x(); }
90     T height() const { return _max.y() - _min.y(); }
91     SGVec2<T> const& pos() const { return _min; }
92     SGVec2<T> size() const { return SGVec2<T>(width(), height()); }
93
94     void setX(T x) { T w = width(); _min.x() = x; _max.x() = x + w; }
95     void setY(T y) { T h = height(); _min.y() = y; _max.y() = y + h; }
96     void setWidth(T w) { _max.x() = _min.x() + w; }
97     void setHeight(T h) { _max.y() = _min.y() + h; }
98     void setPos(const SGVec2<T>& p) { setX(p.x()); setY(p.y()); }
99     void setSize(const SGVec2<T>& s) { setWidth(s.x()); setHeight(s.y()); }
100
101     T l() const { return _min.x(); }
102     T r() const { return _max.x(); }
103     T t() const { return _min.y(); }
104     T b() const { return _max.y(); }
105
106     T& l() { return _min.x(); }
107     T& r() { return _max.x(); }
108     T& t() { return _min.y(); }
109     T& b() { return _max.y(); }
110
111     void setLeft(T l) { _min.x() = l; }
112     void setRight(T r) { _max.x() = r; }
113     void setTop(T t) { _min.y() = t; }
114     void setBottom(T b) { _max.y() = b; }
115
116     /**
117      * Expand rectangle to include the given position
118      */
119     void expandBy(T x, T y)
120     {
121       if( x < _min.x() ) _min.x() = x;
122       if( x > _max.x() ) _max.x() = x;
123
124       if( y < _min.y() ) _min.y() = y;
125       if( y > _max.y() ) _max.y() = y;
126     }
127
128     /**
129      * Move rect by vector
130      */
131     SGRect& operator+=(const SGVec2<T>& offset)
132     {
133       _min += offset;
134       _max += offset;
135       return *this;
136     }
137
138     /**
139      * Move rect by vector in inverse direction
140      */
141     SGRect& operator-=(const SGVec2<T>& offset)
142     {
143       _min -= offset;
144       _max -= offset;
145       return *this;
146     }
147
148     bool operator==(const SGRect<T>& rhs) const
149     {
150       return _min == rhs._min
151           && _max == rhs._max;
152     }
153
154     bool operator!=(const SGRect<T>& rhs) const
155     {
156       return !(*this == rhs);
157     }
158
159     bool contains(T x, T y) const
160     {
161       return _min.x() <= x && x <= _max.x()
162           && _min.y() <= y && y <= _max.y();
163     }
164
165     bool contains(T x, T y, T margin) const
166     {
167       return (_min.x() - margin) <= x && x <= (_max.x() + margin)
168           && (_min.y() - margin) <= y && y <= (_max.y() + margin);
169     }
170
171   private:
172     SGVec2<T> _min,
173               _max;
174 };
175
176 template<typename T>
177 inline SGRect<T> operator+(SGRect<T> rect, const SGVec2<T>& offset)
178 {
179   return rect += offset;
180 }
181
182 template<typename T>
183 inline SGRect<T> operator+(const SGVec2<T>& offset, SGRect<T> rect)
184 {
185   return rect += offset;
186 }
187
188 template<typename T>
189 inline SGRect<T> operator-(SGRect<T> rect, const SGVec2<T>& offset)
190 {
191   return rect -= offset;
192 }
193
194 template<typename T>
195 inline SGRect<T> operator-(const SGVec2<T>& offset, SGRect<T> rect)
196 {
197   return rect -= offset;
198 }
199
200 template<typename char_type, typename traits_type, typename T>
201 inline
202 std::basic_ostream<char_type, traits_type>&
203 operator<<(std::basic_ostream<char_type, traits_type>& s, const SGRect<T>& rect)
204 { return s << "min = " << rect.getMin() << ", max = " << rect.getMax(); }
205
206 typedef SGRect<int> SGRecti;
207 typedef SGRect<float> SGRectf;
208 typedef SGRect<double> SGRectd;
209
210 #endif /* SG_RECT_HXX_ */