00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #if !defined(_XRB_RECT_HPP_)
00013 #define _XRB_RECT_HPP_
00014
00015 #include "xrb.hpp"
00016
00017 #include "xrb_simpletransform2.hpp"
00018 #include "xrb_vector.hpp"
00019
00020 namespace Xrb
00021 {
00022
00043 template <typename T>
00044 class Rect
00045 {
00046 public:
00047
00049 Vector<T, 2> m_bottom_left;
00051 Vector<T, 2> m_top_right;
00052
00056 inline Rect ()
00057 {
00058 }
00059 inline Rect (Vector<T, 2> const &size)
00060 {
00061 m_bottom_left = Vector<T, 2>::ms_zero;
00062 m_top_right = size;
00063 }
00064 inline Rect (T left, T bottom, T right, T top)
00065 {
00066 m_bottom_left[Dim::X] = left;
00067 m_bottom_left[Dim::Y] = bottom;
00068 m_top_right[Dim::X] = right;
00069 m_top_right[Dim::Y] = top;
00070 }
00071 inline Rect (Vector<T, 2> const &bottom_left,
00072 Vector<T, 2> const &top_right)
00073 {
00074 m_bottom_left = bottom_left;
00075 m_top_right = top_right;
00076 }
00077 inline Rect (Rect<T> const &source)
00078 {
00079 m_bottom_left = source.m_bottom_left;
00080 m_top_right = source.m_top_right;
00081 }
00082 inline ~Rect ()
00083 {
00084 }
00085
00086
00087
00088
00089
00090 inline void operator = (Vector<T, 2> const &size)
00091 {
00092 m_bottom_left = Vector<T, 2>::ms_zero;
00093 m_top_right = size;
00094 }
00095 inline void operator = (Rect<T> const &source)
00096 {
00097 m_bottom_left = source.m_bottom_left;
00098 m_top_right = source.m_top_right;
00099 }
00100
00101 inline bool operator == (Rect<T> const &operand)
00102 {
00103 return m_bottom_left == operand.m_bottom_left &&
00104 m_top_right == operand.m_top_right;
00105 }
00106 inline bool operator != (Rect<T> const &operand)
00107 {
00108 return m_bottom_left != operand.m_bottom_left ||
00109 m_top_right != operand.m_top_right;
00110 }
00111
00112 inline void operator |= (Rect<T> const &operand)
00113 {
00114 EncompassPoint(operand.TopLeft());
00115 EncompassPoint(operand.BottomRight());
00116 }
00117 inline void operator &= (Rect<T> const &operand)
00118 {
00119 m_bottom_left[Dim::X] =
00120 Max(m_bottom_left[Dim::X], operand.m_bottom_left[Dim::X]);
00121 m_bottom_left[Dim::Y] =
00122 Max(m_bottom_left[Dim::Y], operand.m_bottom_left[Dim::Y]);
00123 m_top_right[Dim::X] = Min(m_top_right[Dim::X], operand.m_top_right[Dim::X]);
00124 m_top_right[Dim::Y] = Min(m_top_right[Dim::Y], operand.m_top_right[Dim::Y]);
00125 if (m_bottom_left[Dim::X] > m_top_right[Dim::X])
00126 m_bottom_left[Dim::X] = m_top_right[Dim::X];
00127 if (m_bottom_left[Dim::Y] > m_top_right[Dim::Y])
00128 m_bottom_left[Dim::Y] = m_top_right[Dim::Y];
00129 }
00130
00131 inline void operator += (Vector<T, 2> const &operand)
00132 {
00133 m_bottom_left += operand;
00134 m_top_right += operand;
00135 }
00136 inline void operator -= (Vector<T, 2> const &operand)
00137 {
00138 m_bottom_left -= operand;
00139 m_top_right -= operand;
00140 }
00141 inline void operator *= (SimpleTransform2<T> const &transform)
00142 {
00143 m_bottom_left *= transform;
00144 m_top_right *= transform;
00145 }
00146
00147
00148
00149
00150
00151 inline Vector<T, 2> TopLeft () const
00152 {
00153 return Vector<T, 2>(m_bottom_left[Dim::X], m_top_right[Dim::Y]);
00154 }
00155 inline Vector<T, 2> const &TopRight () const
00156 {
00157 return m_top_right;
00158 }
00159 inline Vector<T, 2> const &BottomLeft () const
00160 {
00161 return m_bottom_left;
00162 }
00163 inline Vector<T, 2> BottomRight () const
00164 {
00165 return Vector<T, 2>(m_top_right[Dim::X], m_bottom_left[Dim::Y]);
00166 }
00167
00168 inline T Top () const
00169 {
00170 return m_top_right[Dim::Y];
00171 }
00172 inline T Left () const
00173 {
00174 return m_bottom_left[Dim::X];
00175 }
00176 inline T Bottom () const
00177 {
00178 return m_bottom_left[Dim::Y];
00179 }
00180 inline T Right () const
00181 {
00182 return m_top_right[Dim::X];
00183 }
00184
00185 inline Vector<T, 2> Center () const
00186 {
00187 return (m_bottom_left + m_top_right) / static_cast<T>(2);
00188 }
00189
00190 inline Vector<T, 2> Size () const
00191 {
00192 return m_top_right - m_bottom_left;
00193 }
00194 inline T Width () const
00195 {
00196 return Right() - Left();
00197 }
00198 inline T Height () const
00199 {
00200 return Top() - Bottom();
00201 }
00202
00203 Rect<T> Grown (Vector<T, 2> const &vector_to_grow_by) const
00204 {
00205 Rect<T> retval;
00206 retval.m_bottom_left = m_bottom_left - vector_to_grow_by;
00207 retval.m_top_right = m_top_right + vector_to_grow_by;
00208 return retval;
00209 }
00210
00211 inline bool IsValid () const
00212 {
00213 return m_bottom_left[Dim::X] <= m_top_right[Dim::X] &&
00214 m_bottom_left[Dim::Y] <= m_top_right[Dim::Y];
00215 }
00216 inline bool HasPositiveArea () const
00217 {
00218 return m_bottom_left[Dim::X] < m_top_right[Dim::X] &&
00219 m_bottom_left[Dim::Y] < m_top_right[Dim::Y];
00220 }
00221 inline bool IsPointInside (Vector<T, 2> const &point) const
00222 {
00223 return m_bottom_left[Dim::X] <= point[Dim::X] &&
00224 point[Dim::X] < m_top_right[Dim::X] &&
00225 m_bottom_left[Dim::Y] <= point[Dim::Y] &&
00226 point[Dim::Y] < m_top_right[Dim::Y];
00227 }
00228
00229 template <typename U>
00230 inline Rect<U> StaticCast () const
00231 {
00232 Rect<U> retval;
00233 retval.SetBottomLeft(m_bottom_left.StaticCast<U>());
00234 retval.SetTopRight(m_top_right.StaticCast<U>());
00235 return retval;
00236 }
00237
00238
00239
00240
00241
00242 inline void SetTopLeft (Vector<T, 2> const &top_left)
00243 {
00244 m_bottom_left[Dim::X] = top_left[Dim::X];
00245 m_top_right[Dim::Y] = top_left[Dim::Y];
00246 }
00247 inline void SetTopRight (Vector<T, 2> const &top_right)
00248 {
00249 m_top_right = top_right;
00250 }
00251 inline void SetBottomLeft (Vector<T, 2> const &bottom_left)
00252 {
00253 m_bottom_left = bottom_left;
00254 }
00255 inline void SetBottomRight (Vector<T, 2> const &bottom_right)
00256 {
00257 m_top_right[Dim::X] = bottom_right[Dim::X];
00258 m_bottom_left[Dim::Y] = bottom_right[Dim::Y];
00259 }
00260
00261 inline void SetTop (T top)
00262 {
00263 m_top_right[Dim::Y] = top;
00264 }
00265 inline void SetLeft (T left)
00266 {
00267 m_bottom_left[Dim::X] = left;
00268 }
00269 inline void SetBottom (T bottom)
00270 {
00271 m_bottom_left[Dim::Y] = bottom;
00272 }
00273 inline void SetRight (T right)
00274 {
00275 m_top_right[Dim::X] = right;
00276 }
00277
00278 inline void SetCenter (Vector<T, 2> const ¢er)
00279 {
00280 operator-=(Center());
00281 operator+=(center);
00282 }
00283
00284 inline void SetSize (Vector<T, 2> const &size)
00285 {
00286 m_top_right = m_bottom_left + size;
00287 }
00288 inline void SetSize (Uint32 component, T size)
00289 {
00290 ASSERT1(component < 2);
00291 m_top_right[component] = m_bottom_left[component] + size;
00292 }
00293 inline void SetWidth (T const width)
00294 {
00295 m_top_right[Dim::X] = m_bottom_left[Dim::X] + width;
00296 }
00297 inline void SetHeight (T const height)
00298 {
00299 m_top_right[Dim::Y] = m_bottom_left[Dim::Y] + height;
00300 }
00301
00302 template <typename U>
00303 inline void StaticCastAssign (Rect<U> const &source)
00304 {
00305 m_bottom_left = source.BottomLeft().StaticCast<T>();
00306 m_top_right = source.TopRight().StaticCast<T>();
00307 }
00308
00309
00310
00311
00312
00313 void EncompassPoint (Vector<T, 2> const &point)
00314 {
00315 if (point[Dim::X] < m_bottom_left[Dim::X])
00316 m_bottom_left[Dim::X] = point[Dim::X];
00317 else if (point[Dim::X] > m_top_right[Dim::X])
00318 m_top_right[Dim::X] = point[Dim::X];
00319
00320 if (point[Dim::Y] < m_bottom_left[Dim::Y])
00321 m_bottom_left[Dim::Y] = point[Dim::Y];
00322 else if (point[Dim::Y] > m_top_right[Dim::Y])
00323 m_top_right[Dim::Y] = point[Dim::Y];
00324 }
00325
00326 void Flip ()
00327 {
00328 T temp;
00329
00330 temp = m_bottom_left[Dim::X];
00331 m_bottom_left[Dim::X] = m_top_right[Dim::X];
00332 m_top_right[Dim::X] = temp;
00333
00334 temp = m_bottom_left[Dim::Y];
00335 m_bottom_left[Dim::Y] = m_top_right[Dim::Y];
00336 m_top_right[Dim::Y] = temp;
00337 }
00338 void Flip (Dim::Component const component)
00339 {
00340 ASSERT1(component <= Dim::Y);
00341
00342 T temp = m_bottom_left[component];
00343 m_bottom_left[component] = m_top_right[component];
00344 m_top_right[component] = temp;
00345 }
00346
00347 void Fprint (FILE *const fptr,
00348 char const *const component_printf_format,
00349 bool const show_size_instead_of_top_right = true,
00350 bool const add_newline = true) const
00351 {
00352 fprintf(fptr, "Rect : left/bottom = (");
00353 fprintf(fptr, component_printf_format, BottomLeft()[Dim::X]);
00354 fprintf(fptr, ", ");
00355 fprintf(fptr, component_printf_format, BottomLeft()[Dim::Y]);
00356 fprintf(fptr,
00357 "), %s/%s = (",
00358 show_size_instead_of_top_right ? "width" : "right",
00359 show_size_instead_of_top_right ? "height" : "top");
00360 fprintf(fptr,
00361 component_printf_format,
00362 show_size_instead_of_top_right ?
00363 Size()[Dim::X] :
00364 TopRight()[Dim::X]);
00365 fprintf(fptr, ", ");
00366 fprintf(fptr,
00367 component_printf_format,
00368 show_size_instead_of_top_right ?
00369 Size()[Dim::Y] :
00370 TopRight()[Dim::Y]);
00371 fprintf(fptr, ")%c", add_newline ? '\n' : '\0');
00372 }
00373
00374 void Grow (Vector<T, 2> const &vector_to_grow_by)
00375 {
00376 m_bottom_left -= vector_to_grow_by;
00377 m_top_right += vector_to_grow_by;
00378 }
00379 };
00380
00381 template <typename T>
00382 inline Rect<T> operator | (
00383 Rect<T> const &left_operand,
00384 Rect<T> const &right_operand)
00385 {
00386 Rect<T> retval(left_operand);
00387 retval |= right_operand;
00388 return retval;
00389 }
00390
00391 template <typename T>
00392 inline Rect<T> operator & (
00393 Rect<T> const &left_operand,
00394 Rect<T> const &right_operand)
00395 {
00396 Rect<T> retval(left_operand);
00397 retval &= right_operand;
00398 return retval;
00399 }
00400
00401 template <typename T>
00402 inline Rect<T> operator + (
00403 Rect<T> const &left_operand,
00404 Vector<T, 2> const &right_operand)
00405 {
00406 Rect<T> retval(left_operand);
00407 retval += right_operand;
00408 return retval;
00409 }
00410
00411 template <typename T>
00412 inline Rect<T> operator - (
00413 Rect<T> const &left_operand,
00414 Vector<T, 2> const &right_operand)
00415 {
00416 Rect<T> retval(left_operand);
00417 retval -= right_operand;
00418 return retval;
00419 }
00420
00421 template <typename T>
00422 inline Rect<T> operator * (
00423 SimpleTransform2<T> const &left_operand,
00424 Rect<T> const &right_operand)
00425 {
00426 Rect<T> retval(right_operand);
00427 retval *= left_operand;
00428 return retval;
00429 }
00430
00431
00432
00433
00434
00435
00436
00439 typedef Rect<Float> FloatRect;
00442 typedef Rect<Sint32> Sint32Rect;
00443
00444 void Fprint (
00445 FILE *fptr,
00446 FloatRect const &rect,
00447 bool const show_size_instead_of_top_right = true,
00448 bool add_newline = true);
00449
00450 void Fprint (
00451 FILE *fptr,
00452 Sint32Rect const &rect,
00453 bool const show_size_instead_of_top_right = true,
00454 bool add_newline = true);
00455
00456 }
00457
00458 #endif // !defined(_XRB_RECT_HPP_)