14 * express or implied, and with no claim as to its suitability for any |
14 * express or implied, and with no claim as to its suitability for any |
15 * purpose. |
15 * purpose. |
16 * |
16 * |
17 */ |
17 */ |
18 |
18 |
19 #ifndef LEMON_XY_H |
19 #ifndef LEMON_DIM2_H |
20 #define LEMON_XY_H |
20 #define LEMON_DIM2_H |
21 |
21 |
22 #include <iostream> |
22 #include <iostream> |
23 #include <lemon/bits/utility.h> |
23 #include <lemon/bits/utility.h> |
24 |
24 |
25 ///\ingroup misc |
25 ///\ingroup misc |
26 ///\file |
26 ///\file |
27 ///\brief A simple two dimensional vector and a bounding box implementation |
27 ///\brief A simple two dimensional vector and a bounding box implementation |
28 /// |
28 /// |
29 /// The class \ref lemon::xy "xy" implements |
29 /// The class \ref lemon::dim2::Point "dim2::Point" implements |
30 ///a two dimensional vector with the usual |
30 ///a two dimensional vector with the usual |
31 /// operations. |
31 /// operations. |
32 /// |
32 /// |
33 /// The class \ref lemon::BoundingBox "BoundingBox" can be used to determine |
33 /// The class \ref lemon::dim2::BoundingBox "dim2::BoundingBox" |
34 /// the rectangular bounding box of a set of \ref lemon::xy "xy"'s. |
34 /// can be used to determine |
|
35 /// the rectangular bounding box of a set of |
|
36 /// \ref lemon::dim2::Point "dim2::Point"'s. |
35 /// |
37 /// |
36 ///\author Attila Bernath |
38 ///\author Attila Bernath |
37 |
39 |
38 |
40 |
39 namespace lemon { |
41 namespace lemon { |
|
42 |
|
43 ///Tools for handling two dimensional coordinates |
|
44 |
|
45 ///This namespace is a storage of several |
|
46 ///tools for handling two dimensional coordinates |
|
47 namespace dim2 { |
40 |
48 |
41 /// \addtogroup misc |
49 /// \addtogroup misc |
42 /// @{ |
50 /// @{ |
43 |
51 |
44 /// A simple two dimensional vector (plainvector) implementation |
52 /// A simple two dimensional vector (plainvector) implementation |
45 |
53 |
46 /// A simple two dimensional vector (plainvector) implementation |
54 /// A simple two dimensional vector (plainvector) implementation |
47 ///with the usual vector |
55 ///with the usual vector |
48 /// operators. |
56 /// operators. |
49 /// |
57 /// |
50 ///\note As you might have noticed, this class does not follow the |
|
51 ///\ref naming_conv "LEMON Coding Style" (it should be called \c Xy |
|
52 ///according to it). There is a stupid Hungarian proverb, "A kivétel |
|
53 ///erõsíti a szabályt" ("An exception |
|
54 ///reinforces a rule", which is |
|
55 ///actually a mistranslation of the Latin proverb "Exceptio probat regulam"). |
|
56 ///This class is an example for that. |
|
57 ///\author Attila Bernath |
|
58 template<typename T> |
58 template<typename T> |
59 class xy { |
59 class Point { |
60 |
60 |
61 public: |
61 public: |
62 |
62 |
63 typedef T Value; |
63 typedef T Value; |
64 |
64 |
66 T x; |
66 T x; |
67 ///Second co-ordinate |
67 ///Second co-ordinate |
68 T y; |
68 T y; |
69 |
69 |
70 ///Default constructor |
70 ///Default constructor |
71 xy() {} |
71 Point() {} |
72 |
72 |
73 ///Construct an instance from coordinates |
73 ///Construct an instance from coordinates |
74 xy(T a, T b) : x(a), y(b) { } |
74 Point(T a, T b) : x(a), y(b) { } |
75 |
75 |
76 |
76 |
77 ///Conversion constructor |
77 ///Conversion constructor |
78 template<class TT> xy(const xy<TT> &p) : x(p.x), y(p.y) {} |
78 template<class TT> Point(const Point<TT> &p) : x(p.x), y(p.y) {} |
79 |
79 |
80 ///Give back the square of the norm of the vector |
80 ///Give back the square of the norm of the vector |
81 T normSquare() const { |
81 T normSquare() const { |
82 return x*x+y*y; |
82 return x*x+y*y; |
83 } |
83 } |
84 |
84 |
85 ///Increment the left hand side by u |
85 ///Increment the left hand side by u |
86 xy<T>& operator +=(const xy<T>& u) { |
86 Point<T>& operator +=(const Point<T>& u) { |
87 x += u.x; |
87 x += u.x; |
88 y += u.y; |
88 y += u.y; |
89 return *this; |
89 return *this; |
90 } |
90 } |
91 |
91 |
92 ///Decrement the left hand side by u |
92 ///Decrement the left hand side by u |
93 xy<T>& operator -=(const xy<T>& u) { |
93 Point<T>& operator -=(const Point<T>& u) { |
94 x -= u.x; |
94 x -= u.x; |
95 y -= u.y; |
95 y -= u.y; |
96 return *this; |
96 return *this; |
97 } |
97 } |
98 |
98 |
99 ///Multiply the left hand side with a scalar |
99 ///Multiply the left hand side with a scalar |
100 xy<T>& operator *=(const T &u) { |
100 Point<T>& operator *=(const T &u) { |
101 x *= u; |
101 x *= u; |
102 y *= u; |
102 y *= u; |
103 return *this; |
103 return *this; |
104 } |
104 } |
105 |
105 |
106 ///Divide the left hand side by a scalar |
106 ///Divide the left hand side by a scalar |
107 xy<T>& operator /=(const T &u) { |
107 Point<T>& operator /=(const T &u) { |
108 x /= u; |
108 x /= u; |
109 y /= u; |
109 y /= u; |
110 return *this; |
110 return *this; |
111 } |
111 } |
112 |
112 |
113 ///Return the scalar product of two vectors |
113 ///Return the scalar product of two vectors |
114 T operator *(const xy<T>& u) const { |
114 T operator *(const Point<T>& u) const { |
115 return x*u.x+y*u.y; |
115 return x*u.x+y*u.y; |
116 } |
116 } |
117 |
117 |
118 ///Return the sum of two vectors |
118 ///Return the sum of two vectors |
119 xy<T> operator+(const xy<T> &u) const { |
119 Point<T> operator+(const Point<T> &u) const { |
120 xy<T> b=*this; |
120 Point<T> b=*this; |
121 return b+=u; |
121 return b+=u; |
122 } |
122 } |
123 |
123 |
124 ///Return the neg of the vectors |
124 ///Return the neg of the vectors |
125 xy<T> operator-() const { |
125 Point<T> operator-() const { |
126 xy<T> b=*this; |
126 Point<T> b=*this; |
127 b.x=-b.x; b.y=-b.y; |
127 b.x=-b.x; b.y=-b.y; |
128 return b; |
128 return b; |
129 } |
129 } |
130 |
130 |
131 ///Return the difference of two vectors |
131 ///Return the difference of two vectors |
132 xy<T> operator-(const xy<T> &u) const { |
132 Point<T> operator-(const Point<T> &u) const { |
133 xy<T> b=*this; |
133 Point<T> b=*this; |
134 return b-=u; |
134 return b-=u; |
135 } |
135 } |
136 |
136 |
137 ///Return a vector multiplied by a scalar |
137 ///Return a vector multiplied by a scalar |
138 xy<T> operator*(const T &u) const { |
138 Point<T> operator*(const T &u) const { |
139 xy<T> b=*this; |
139 Point<T> b=*this; |
140 return b*=u; |
140 return b*=u; |
141 } |
141 } |
142 |
142 |
143 ///Return a vector divided by a scalar |
143 ///Return a vector divided by a scalar |
144 xy<T> operator/(const T &u) const { |
144 Point<T> operator/(const T &u) const { |
145 xy<T> b=*this; |
145 Point<T> b=*this; |
146 return b/=u; |
146 return b/=u; |
147 } |
147 } |
148 |
148 |
149 ///Test equality |
149 ///Test equality |
150 bool operator==(const xy<T> &u) const { |
150 bool operator==(const Point<T> &u) const { |
151 return (x==u.x) && (y==u.y); |
151 return (x==u.x) && (y==u.y); |
152 } |
152 } |
153 |
153 |
154 ///Test inequality |
154 ///Test inequality |
155 bool operator!=(xy u) const { |
155 bool operator!=(Point u) const { |
156 return (x!=u.x) || (y!=u.y); |
156 return (x!=u.x) || (y!=u.y); |
157 } |
157 } |
158 |
158 |
159 }; |
159 }; |
160 |
160 |
161 ///Return an xy |
161 ///Return an Point |
162 |
162 |
163 ///Return an xy |
163 ///Return an Point |
164 ///\relates xy |
164 ///\relates Point |
165 template <typename T> |
165 template <typename T> |
166 inline xy<T> make_xy(const T& x, const T& y) { |
166 inline Point<T> make_Point(const T& x, const T& y) { |
167 return xy<T>(x, y); |
167 return Point<T>(x, y); |
168 } |
168 } |
169 |
169 |
170 ///Return a vector multiplied by a scalar |
170 ///Return a vector multiplied by a scalar |
171 |
171 |
172 ///Return a vector multiplied by a scalar |
172 ///Return a vector multiplied by a scalar |
173 ///\relates xy |
173 ///\relates Point |
174 template<typename T> xy<T> operator*(const T &u,const xy<T> &x) { |
174 template<typename T> Point<T> operator*(const T &u,const Point<T> &x) { |
175 return x*u; |
175 return x*u; |
176 } |
176 } |
177 |
177 |
178 ///Read a plainvector from a stream |
178 ///Read a plainvector from a stream |
179 |
179 |
180 ///Read a plainvector from a stream |
180 ///Read a plainvector from a stream |
181 ///\relates xy |
181 ///\relates Point |
182 /// |
182 /// |
183 template<typename T> |
183 template<typename T> |
184 inline std::istream& operator>>(std::istream &is, xy<T> &z) { |
184 inline std::istream& operator>>(std::istream &is, Point<T> &z) { |
185 char c; |
185 char c; |
186 if (is >> c) { |
186 if (is >> c) { |
187 if (c != '(') is.putback(c); |
187 if (c != '(') is.putback(c); |
188 } else { |
188 } else { |
189 is.clear(); |
189 is.clear(); |
204 } |
204 } |
205 |
205 |
206 ///Write a plainvector to a stream |
206 ///Write a plainvector to a stream |
207 |
207 |
208 ///Write a plainvector to a stream |
208 ///Write a plainvector to a stream |
209 ///\relates xy |
209 ///\relates Point |
210 /// |
210 /// |
211 template<typename T> |
211 template<typename T> |
212 inline std::ostream& operator<<(std::ostream &os, const xy<T>& z) |
212 inline std::ostream& operator<<(std::ostream &os, const Point<T>& z) |
213 { |
213 { |
214 os << "(" << z.x << ", " << z.y << ")"; |
214 os << "(" << z.x << ", " << z.y << ")"; |
215 return os; |
215 return os; |
216 } |
216 } |
217 |
217 |
218 ///Rotate by 90 degrees |
218 ///Rotate by 90 degrees |
219 |
219 |
220 ///Returns its parameter rotated by 90 degrees in positive direction. |
220 ///Returns its parameter rotated by 90 degrees in positive direction. |
221 ///\relates xy |
221 ///\relates Point |
222 /// |
222 /// |
223 template<typename T> |
223 template<typename T> |
224 inline xy<T> rot90(const xy<T> &z) |
224 inline Point<T> rot90(const Point<T> &z) |
225 { |
225 { |
226 return xy<T>(-z.y,z.x); |
226 return Point<T>(-z.y,z.x); |
227 } |
227 } |
228 |
228 |
229 ///Rotate by 180 degrees |
229 ///Rotate by 180 degrees |
230 |
230 |
231 ///Returns its parameter rotated by 180 degrees. |
231 ///Returns its parameter rotated by 180 degrees. |
232 ///\relates xy |
232 ///\relates Point |
233 /// |
233 /// |
234 template<typename T> |
234 template<typename T> |
235 inline xy<T> rot180(const xy<T> &z) |
235 inline Point<T> rot180(const Point<T> &z) |
236 { |
236 { |
237 return xy<T>(-z.x,-z.y); |
237 return Point<T>(-z.x,-z.y); |
238 } |
238 } |
239 |
239 |
240 ///Rotate by 270 degrees |
240 ///Rotate by 270 degrees |
241 |
241 |
242 ///Returns its parameter rotated by 90 degrees in negative direction. |
242 ///Returns its parameter rotated by 90 degrees in negative direction. |
243 ///\relates xy |
243 ///\relates Point |
244 /// |
244 /// |
245 template<typename T> |
245 template<typename T> |
246 inline xy<T> rot270(const xy<T> &z) |
246 inline Point<T> rot270(const Point<T> &z) |
247 { |
247 { |
248 return xy<T>(z.y,-z.x); |
248 return Point<T>(z.y,-z.x); |
249 } |
249 } |
250 |
250 |
251 |
251 |
252 |
252 |
253 /// A class to calculate or store the bounding box of plainvectors. |
253 /// A class to calculate or store the bounding box of plainvectors. |
255 /// A class to calculate or store the bounding box of plainvectors. |
255 /// A class to calculate or store the bounding box of plainvectors. |
256 /// |
256 /// |
257 ///\author Attila Bernath |
257 ///\author Attila Bernath |
258 template<typename T> |
258 template<typename T> |
259 class BoundingBox { |
259 class BoundingBox { |
260 xy<T> bottom_left, top_right; |
260 Point<T> bottom_left, top_right; |
261 bool _empty; |
261 bool _empty; |
262 public: |
262 public: |
263 |
263 |
264 ///Default constructor: creates an empty bounding box |
264 ///Default constructor: creates an empty bounding box |
265 BoundingBox() { _empty = true; } |
265 BoundingBox() { _empty = true; } |
266 |
266 |
267 ///Construct an instance from one point |
267 ///Construct an instance from one point |
268 BoundingBox(xy<T> a) { bottom_left=top_right=a; _empty = false; } |
268 BoundingBox(Point<T> a) { bottom_left=top_right=a; _empty = false; } |
269 |
269 |
270 ///Were any points added? |
270 ///Were any points added? |
271 bool empty() const { |
271 bool empty() const { |
272 return _empty; |
272 return _empty; |
273 } |
273 } |
279 |
279 |
280 ///Give back the bottom left corner |
280 ///Give back the bottom left corner |
281 |
281 |
282 ///Give back the bottom left corner. |
282 ///Give back the bottom left corner. |
283 ///If the bounding box is empty, then the return value is not defined. |
283 ///If the bounding box is empty, then the return value is not defined. |
284 xy<T> bottomLeft() const { |
284 Point<T> bottomLeft() const { |
285 return bottom_left; |
285 return bottom_left; |
286 } |
286 } |
287 |
287 |
288 ///Set the bottom left corner |
288 ///Set the bottom left corner |
289 |
289 |
290 ///Set the bottom left corner. |
290 ///Set the bottom left corner. |
291 ///It should only bee used for non-empty box. |
291 ///It should only bee used for non-empty box. |
292 void bottomLeft(xy<T> p) { |
292 void bottomLeft(Point<T> p) { |
293 bottom_left = p; |
293 bottom_left = p; |
294 } |
294 } |
295 |
295 |
296 ///Give back the top right corner |
296 ///Give back the top right corner |
297 |
297 |
298 ///Give back the top right corner. |
298 ///Give back the top right corner. |
299 ///If the bounding box is empty, then the return value is not defined. |
299 ///If the bounding box is empty, then the return value is not defined. |
300 xy<T> topRight() const { |
300 Point<T> topRight() const { |
301 return top_right; |
301 return top_right; |
302 } |
302 } |
303 |
303 |
304 ///Set the top right corner |
304 ///Set the top right corner |
305 |
305 |
306 ///Set the top right corner. |
306 ///Set the top right corner. |
307 ///It should only bee used for non-empty box. |
307 ///It should only bee used for non-empty box. |
308 void topRight(xy<T> p) { |
308 void topRight(Point<T> p) { |
309 top_right = p; |
309 top_right = p; |
310 } |
310 } |
311 |
311 |
312 ///Give back the bottom right corner |
312 ///Give back the bottom right corner |
313 |
313 |
314 ///Give back the bottom right corner. |
314 ///Give back the bottom right corner. |
315 ///If the bounding box is empty, then the return value is not defined. |
315 ///If the bounding box is empty, then the return value is not defined. |
316 xy<T> bottomRight() const { |
316 Point<T> bottomRight() const { |
317 return xy<T>(top_right.x,bottom_left.y); |
317 return Point<T>(top_right.x,bottom_left.y); |
318 } |
318 } |
319 |
319 |
320 ///Set the bottom right corner |
320 ///Set the bottom right corner |
321 |
321 |
322 ///Set the bottom right corner. |
322 ///Set the bottom right corner. |
323 ///It should only bee used for non-empty box. |
323 ///It should only bee used for non-empty box. |
324 void bottomRight(xy<T> p) { |
324 void bottomRight(Point<T> p) { |
325 top_right.x = p.x; |
325 top_right.x = p.x; |
326 bottom_left.y = p.y; |
326 bottom_left.y = p.y; |
327 } |
327 } |
328 |
328 |
329 ///Give back the top left corner |
329 ///Give back the top left corner |
330 |
330 |
331 ///Give back the top left corner. |
331 ///Give back the top left corner. |
332 ///If the bounding box is empty, then the return value is not defined. |
332 ///If the bounding box is empty, then the return value is not defined. |
333 xy<T> topLeft() const { |
333 Point<T> topLeft() const { |
334 return xy<T>(bottom_left.x,top_right.y); |
334 return Point<T>(bottom_left.x,top_right.y); |
335 } |
335 } |
336 |
336 |
337 ///Set the top left corner |
337 ///Set the top left corner |
338 |
338 |
339 ///Set the top left corner. |
339 ///Set the top left corner. |
340 ///It should only bee used for non-empty box. |
340 ///It should only bee used for non-empty box. |
341 void topLeft(xy<T> p) { |
341 void topLeft(Point<T> p) { |
342 top_right.y = p.y; |
342 top_right.y = p.y; |
343 bottom_left.x = p.x; |
343 bottom_left.x = p.x; |
344 } |
344 } |
345 |
345 |
346 ///Give back the bottom of the box |
346 ///Give back the bottom of the box |