1 // -*- c++ -*- |
|
2 #ifndef HUGO_XY_H |
|
3 #define HUGO_XY_H |
|
4 |
|
5 #include <iostream> |
|
6 |
|
7 ///\ingroup misc |
|
8 ///\file |
|
9 ///\brief A simple two dimensional vector and a bounding box implementation |
|
10 /// |
|
11 /// The class \ref hugo::xy "xy" implements |
|
12 ///a two dimensional vector with the usual |
|
13 /// operations. |
|
14 /// |
|
15 /// The class \ref hugo::BoundingBox "BoundingBox" can be used to determine |
|
16 /// the rectangular bounding box a set of \ref hugo::xy "xy"'s. |
|
17 /// |
|
18 ///\author Attila Bernath |
|
19 |
|
20 |
|
21 namespace hugo { |
|
22 |
|
23 /// \addtogroup misc |
|
24 /// @{ |
|
25 |
|
26 /// A two dimensional vector (plainvector) implementation |
|
27 |
|
28 /// A two dimensional vector (plainvector) implementation |
|
29 ///with the usual vector |
|
30 /// operators. |
|
31 /// |
|
32 ///\author Attila Bernath |
|
33 template<typename T> |
|
34 class xy { |
|
35 |
|
36 public: |
|
37 |
|
38 T x,y; |
|
39 |
|
40 ///Default constructor: both coordinates become 0 |
|
41 xy() : x(0), y(0) {} |
|
42 |
|
43 ///Constructing the instance from coordinates |
|
44 xy(T a, T b) : x(a), y(b) { } |
|
45 |
|
46 |
|
47 ///Gives back the square of the norm of the vector |
|
48 T normSquare(){ |
|
49 return x*x+y*y; |
|
50 }; |
|
51 |
|
52 ///Increments the left hand side by u |
|
53 xy<T>& operator +=(const xy<T>& u){ |
|
54 x += u.x; |
|
55 y += u.y; |
|
56 return *this; |
|
57 }; |
|
58 |
|
59 ///Decrements the left hand side by u |
|
60 xy<T>& operator -=(const xy<T>& u){ |
|
61 x -= u.x; |
|
62 y -= u.y; |
|
63 return *this; |
|
64 }; |
|
65 |
|
66 ///Multiplying the left hand side with a scalar |
|
67 xy<T>& operator *=(const T &u){ |
|
68 x *= u; |
|
69 y *= u; |
|
70 return *this; |
|
71 }; |
|
72 |
|
73 ///Dividing the left hand side by a scalar |
|
74 xy<T>& operator /=(const T &u){ |
|
75 x /= u; |
|
76 y /= u; |
|
77 return *this; |
|
78 }; |
|
79 |
|
80 ///Returns the scalar product of two vectors |
|
81 T operator *(const xy<T>& u){ |
|
82 return x*u.x+y*u.y; |
|
83 }; |
|
84 |
|
85 ///Returns the sum of two vectors |
|
86 xy<T> operator+(const xy<T> &u) const { |
|
87 xy<T> b=*this; |
|
88 return b+=u; |
|
89 }; |
|
90 |
|
91 ///Returns the difference of two vectors |
|
92 xy<T> operator-(const xy<T> &u) const { |
|
93 xy<T> b=*this; |
|
94 return b-=u; |
|
95 }; |
|
96 |
|
97 ///Returns a vector multiplied by a scalar |
|
98 xy<T> operator*(const T &u) const { |
|
99 xy<T> b=*this; |
|
100 return b*=u; |
|
101 }; |
|
102 |
|
103 ///Returns a vector divided by a scalar |
|
104 xy<T> operator/(const T &u) const { |
|
105 xy<T> b=*this; |
|
106 return b/=u; |
|
107 }; |
|
108 |
|
109 ///Testing equality |
|
110 bool operator==(const xy<T> &u){ |
|
111 return (x==u.x) && (y==u.y); |
|
112 }; |
|
113 |
|
114 ///Testing inequality |
|
115 bool operator!=(xy u){ |
|
116 return (x!=u.x) || (y!=u.y); |
|
117 }; |
|
118 |
|
119 }; |
|
120 |
|
121 ///Reading a plainvector from a stream |
|
122 template<typename T> |
|
123 inline |
|
124 std::istream& operator>>(std::istream &is, xy<T> &z) |
|
125 { |
|
126 |
|
127 is >> z.x >> z.y; |
|
128 return is; |
|
129 } |
|
130 |
|
131 ///Outputting a plainvector to a stream |
|
132 template<typename T> |
|
133 inline |
|
134 std::ostream& operator<<(std::ostream &os, xy<T> z) |
|
135 { |
|
136 os << "(" << z.x << ", " << z.y << ")"; |
|
137 return os; |
|
138 } |
|
139 |
|
140 |
|
141 /// A class to calculate or store the bounding box of plainvectors. |
|
142 |
|
143 /// A class to calculate or store the bounding box of plainvectors. |
|
144 /// |
|
145 ///\author Attila Bernath |
|
146 template<typename T> |
|
147 class BoundingBox { |
|
148 xy<T> bottom_left, top_right; |
|
149 bool _empty; |
|
150 public: |
|
151 |
|
152 ///Default constructor: an empty bounding box |
|
153 BoundingBox() { _empty = true; } |
|
154 |
|
155 ///Constructing the instance from one point |
|
156 BoundingBox(xy<T> a) { bottom_left=top_right=a; _empty = false; } |
|
157 |
|
158 ///Is there any point added |
|
159 bool empty() const { |
|
160 return _empty; |
|
161 } |
|
162 |
|
163 ///Gives back the bottom left corner (if the bounding box is empty, then the return value is not defined) |
|
164 xy<T> bottomLeft() const { |
|
165 return bottom_left; |
|
166 }; |
|
167 |
|
168 ///Gives back the top right corner (if the bounding box is empty, then the return value is not defined) |
|
169 xy<T> topRight() const { |
|
170 return top_right; |
|
171 }; |
|
172 |
|
173 ///Checks whether a point is inside a bounding box |
|
174 bool inside(const xy<T>& u){ |
|
175 if (_empty) |
|
176 return false; |
|
177 else{ |
|
178 return ((u.x-bottom_left.x)*(top_right.x-u.x) >= 0 && |
|
179 (u.y-bottom_left.y)*(top_right.y-u.y) >= 0 ); |
|
180 } |
|
181 } |
|
182 |
|
183 ///Increments a bounding box with a point |
|
184 BoundingBox& operator +=(const xy<T>& u){ |
|
185 if (_empty){ |
|
186 bottom_left=top_right=u; |
|
187 _empty = false; |
|
188 } |
|
189 else{ |
|
190 if (bottom_left.x > u.x) bottom_left.x = u.x; |
|
191 if (bottom_left.y > u.y) bottom_left.y = u.y; |
|
192 if (top_right.x < u.x) top_right.x = u.x; |
|
193 if (top_right.y < u.y) top_right.y = u.y; |
|
194 } |
|
195 return *this; |
|
196 }; |
|
197 |
|
198 ///Sums a bounding box and a point |
|
199 BoundingBox operator +(const xy<T>& u){ |
|
200 BoundingBox b = *this; |
|
201 return b += u; |
|
202 }; |
|
203 |
|
204 ///Increments a bounding box with an other bounding box |
|
205 BoundingBox& operator +=(const BoundingBox &u){ |
|
206 if ( !u.empty() ){ |
|
207 *this += u.bottomLeft(); |
|
208 *this += u.topRight(); |
|
209 } |
|
210 return *this; |
|
211 }; |
|
212 |
|
213 ///Sums two bounding boxes |
|
214 BoundingBox operator +(const BoundingBox& u){ |
|
215 BoundingBox b = *this; |
|
216 return b += u; |
|
217 }; |
|
218 |
|
219 };//class Boundingbox |
|
220 |
|
221 |
|
222 /// @} |
|
223 |
|
224 |
|
225 } //namespace hugo |
|
226 |
|
227 #endif //HUGO_XY_H |
|