2 CLAW - a C++ Library Absolutely Wonderful
4 CLAW is a free library without any particular aim but being useful to
7 Copyright (C) 2005-2011 Julien Jorge
9 This library is free software; you can redistribute it and/or
10 modify it under the terms of the GNU Lesser General Public
11 License as published by the Free Software Foundation; either
12 version 2.1 of the License, or (at your option) any later version.
14 This library is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 Lesser General Public License for more details.
19 You should have received a copy of the GNU Lesser General Public
20 License along with this library; if not, write to the Free Software
21 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
23 contact: julien.jorge@gamned.org
27 * \brief Implementation of claw::math::box_2d class.
28 * \author Julien Jorge
30#include <claw/rectangle.hpp>
31#include <claw/assert.hpp>
33/*----------------------------------------------------------------------------*/
38claw::math::box_2d<T>::box_2d()
41} // box_2d::box_2d() [constructor]
43/*----------------------------------------------------------------------------*/
45 * \brief Copy constructor.
46 * \param that Box to copy from.
49claw::math::box_2d<T>::box_2d( const self_type& that )
50 : first_point(that.first_point), second_point(that.second_point)
53} // box_2d::box_2d() [copy constructor]
55/*----------------------------------------------------------------------------*/
57 * \brief Constructor from a rectangle.
58 * \param that Rectangle to copy from.
61claw::math::box_2d<T>::box_2d( const rectangle<value_type>& that )
62 : first_point(that.position),
63 second_point(that.right(), that.bottom())
66} // box_2d::box_2d() [constructor from rectangle]
68/*----------------------------------------------------------------------------*/
70 * \brief Constructor from two points.
71 * \param p1 The first point.
72 * \param p2 The second point.
75claw::math::box_2d<T>::box_2d( const point_type& p1, const point_type& p2 )
76 : first_point(p1), second_point(p2)
79} // box_2d::box_2d() [constructor from coordinates]
81/*----------------------------------------------------------------------------*/
83 * \brief Constructor with initialization.
84 * \param x1 X-coordinate of the first point.
85 * \param y1 Y-coordinate of the first point.
86 * \param x2 X-coordinate of the second point.
87 * \param y2 Y-coordinate of the second point.
90claw::math::box_2d<T>::box_2d( const value_type& x1, const value_type& y1,
91 const value_type& x2, const value_type& y2 )
92 : first_point(x1, y1), second_point(x2, y2)
95} // box_2d::box_2d() [constructor with values]
97/*----------------------------------------------------------------------------*/
99 * \brief Set the coordinates of the two points.
100 * \param x1 X-coordinate of the first point.
101 * \param y1 Y-coordinate of the first point.
102 * \param x2 X-coordinate of the second point.
103 * \param y2 Y-coordinate of the second point.
106void claw::math::box_2d<T>::set
107( const value_type& x1, const value_type& y1, const value_type& x2,
108 const value_type& y2 )
110 first_point.set(x1, y1);
111 second_point.set(x2, y2);
114/*----------------------------------------------------------------------------*/
116 * \brief Get a copy of the box by converting its members to a given type.
118 * Consider the following code:
120 * <tt> box_2d<float> a;
124 * box_2d<int> b(a); </tt>
126 * The copy constructor will be called, and your compiler should print some
127 * warnings in your console. These warnings have a meaning, so we don't wan't to
128 * make them disapear by adding explicit type conversion inside the box_2d
129 * class nor adding a cast operator that will be used silently by the compiler.
131 * If you really want to convert the type, this method will explicitly cast the
136claw::math::box_2d<U> claw::math::box_2d<T>::cast_value_type_to() const
138 return claw::math::box_2d<U>
139 ( first_point.template cast_value_type_to<U>(),
140 second_point.template cast_value_type_to<U>() );
141} // box_2d::cast_value_type_to()
143/*----------------------------------------------------------------------------*/
145 * \brief Calculate the box's area.
148typename claw::math::box_2d<T>::value_type claw::math::box_2d<T>::area() const
150 return width() * height();
153/*----------------------------------------------------------------------------*/
155 * \brief Tell if a point is in a box.
156 * \param p The supposed included point.
160claw::math::box_2d<T>::includes( const coordinate_2d<value_type>& p ) const
162 return (left() <= p.x) && (right() >= p.x)
163 && (bottom() <= p.y) && (top() >= p.y);
164} // box_2d::includes()
166/*----------------------------------------------------------------------------*/
168 * \brief Tell if a box_2d is in a box_2d.
169 * \param r The supposed included box_2d.
172bool claw::math::box_2d<T>::includes( const self_type& r ) const
174 return includes(r.first_point) && includes(r.second_point);
175} // box_2d::includes()
177/*----------------------------------------------------------------------------*/
179 * \brief Tell if there is an intersection of two boxes.
180 * \param r The supposed intersecting box.
183bool claw::math::box_2d<T>::intersects( const self_type& r ) const
185 return (right() >= r.left()) && (r.right() >= left())
186 && (top() >= r.bottom()) && (r.top() >= bottom());
187} // box_2d::intersects()
189/*----------------------------------------------------------------------------*/
191 * \brief Intersection of two box_2ds.
192 * \param r The supposed intersecting box_2d.
196claw::math::box_2d<T>::intersection( const self_type& r ) const
198 CLAW_PRECOND( intersects(r) );
204 x_intersection(r, result);
205 y_intersection(r, result);
209} // box_2d::intersection()
211/*----------------------------------------------------------------------------*/
213 * \brief Join two box_2ds.
214 * \param r The box to join with.
215 * \returns a box containing \a *this and \a r.
218claw::math::box_2d<T> claw::math::box_2d<T>::join( const self_type& r ) const
221 ( std::min(r.left(), left()), std::min(r.bottom(), bottom()),
222 std::max(r.right(), right()), std::max(r.top(), top()) );
225/*----------------------------------------------------------------------------*/
227 * \brief Tell if the box has a dimension equal to zero.
230bool claw::math::box_2d<T>::empty() const
232 return (width() == 0) || (height() == 0);
235/*----------------------------------------------------------------------------*/
237 * \brief Get the y-coordinate of the top edge.
240typename claw::math::box_2d<T>::value_type claw::math::box_2d<T>::top() const
242 return (first_point.y > second_point.y) ? first_point.y : second_point.y;
245/*----------------------------------------------------------------------------*/
247 * \brief Get the y-coordinate of the bottom edge.
250typename claw::math::box_2d<T>::value_type claw::math::box_2d<T>::bottom() const
252 return (first_point.y < second_point.y) ? first_point.y : second_point.y;
255/*----------------------------------------------------------------------------*/
257 * \brief Get the x-coordinate of the left edge.
260typename claw::math::box_2d<T>::value_type claw::math::box_2d<T>::left() const
262 return (first_point.x < second_point.x) ? first_point.x : second_point.x;
265/*----------------------------------------------------------------------------*/
267 * \brief Get the x-coordinate of the right edge.
270typename claw::math::box_2d<T>::value_type claw::math::box_2d<T>::right() const
272 return (first_point.x > second_point.x) ? first_point.x : second_point.x;
275/*----------------------------------------------------------------------------*/
277 * \brief Get the coordinate of the top-left corner.
280typename claw::math::box_2d<T>::point_type
281claw::math::box_2d<T>::top_left() const
283 return point_type(left(), top());
284} // box_2d::top_left()
286/*----------------------------------------------------------------------------*/
288 * \brief Get the coordinate of the top-right corner.
291typename claw::math::box_2d<T>::point_type
292claw::math::box_2d<T>::top_right() const
294 return point_type(right(), top());
295} // box_2d::top_right()
297/*----------------------------------------------------------------------------*/
299 * \brief Get the coordinate of the bottom-left corner.
302typename claw::math::box_2d<T>::point_type
303claw::math::box_2d<T>::bottom_left() const
305 return point_type(left(), bottom());
306} // box_2d::bottom_left()
308/*----------------------------------------------------------------------------*/
310 * \brief Get the coordinate of the bottom-right corner.
313typename claw::math::box_2d<T>::point_type
314claw::math::box_2d<T>::bottom_right() const
316 return point_type(right(), bottom());
317} // box_2d::bottom_right()
319/*----------------------------------------------------------------------------*/
321 * \brief Move the top edge at a given position.
322 * \param p The position.
325void claw::math::box_2d<T>::top( const value_type& p )
330/*----------------------------------------------------------------------------*/
332 * \brief Move the bottom edge at a given position.
333 * \param p The position.
336void claw::math::box_2d<T>::bottom( const value_type& p )
338 shift_y(p - bottom());
341/*----------------------------------------------------------------------------*/
343 * \brief Move the left edge at a given position.
344 * \param p The position.
347void claw::math::box_2d<T>::left( const value_type& p )
352/*----------------------------------------------------------------------------*/
354 * \brief Move the right edge at a given position.
355 * \param p The position.
358void claw::math::box_2d<T>::right( const value_type& p )
360 shift_x(p - right());
363/*----------------------------------------------------------------------------*/
365 * \brief Move the top-left corner at a given position.
366 * \param p The position.
370claw::math::box_2d<T>::top_left( const coordinate_2d<value_type>& p )
374} // box_2d::top_left()
376/*----------------------------------------------------------------------------*/
378 * \brief Move the top-right corner at a given position.
379 * \param p The position.
383claw::math::box_2d<T>::top_right( const coordinate_2d<value_type>& p )
387} // box_2d::top_right()
389/*----------------------------------------------------------------------------*/
391 * \brief Move the bottom-left corner at a given position.
392 * \param p The position.
396claw::math::box_2d<T>::bottom_left( const coordinate_2d<value_type>& p )
400} // box_2d::bottom_left()
402/*----------------------------------------------------------------------------*/
404 * \brief Move the bottom-right corner at a given position.
405 * \param p The position.
408void claw::math::box_2d<T>::bottom_right
409( const coordinate_2d<value_type>& p )
413} // box_2d::bottom_right()
415/*----------------------------------------------------------------------------*/
417 * \brief Shift the position of the box on the x-axis.
418 * \param d The movement length.
421void claw::math::box_2d<T>::shift_x( const value_type& d )
425} // box_2d::shift_x()
427/*----------------------------------------------------------------------------*/
429 * \brief Shift the position of the box on the y-axis.
430 * \param d The movement length.
433void claw::math::box_2d<T>::shift_y( const value_type& d )
437} // box_2d::shift_y()
439/*----------------------------------------------------------------------------*/
441 * \brief Get the size of the box_2d.
444claw::math::coordinate_2d< typename claw::math::box_2d<T>::value_type >
445claw::math::box_2d<T>::size() const
447 return claw::math::coordinate_2d<value_type>(width(), height());
450/*----------------------------------------------------------------------------*/
452 * \brief Equality operator
453 * \param that Box to compare to.
456bool claw::math::box_2d<T>::operator==(const self_type& that) const
458 return (left() == that.left()) && (right() == that.right())
459 && (top() == that.top()) && (bottom() == that.bottom());
460} // box_2d::operator==()
462/*----------------------------------------------------------------------------*/
464 * \brief Difference operator.
465 * \param that Box to compare to.
468bool claw::math::box_2d<T>::operator!=(const self_type& that) const
470 return !( *this == that );
471} // box_2d::operator!=()
473/*----------------------------------------------------------------------------*/
475 * \brief Translation.
476 * \param vect The vector to add to points.
480claw::math::box_2d<T>::operator+(const point_type& vect) const
482 return self_type( first_point + vect, second_point + vect );
483} // box_2d::operator+()
485/*----------------------------------------------------------------------------*/
487 * \brief Translation.
488 * \param vect The vector to substract to points.
492claw::math::box_2d<T>::operator-(const point_type& vect) const
494 return self_type( first_point - vect, second_point - vect );
495} // box_2d::operator-()
497/*----------------------------------------------------------------------------*/
499 * \brief Translation.
500 * \param vect The vector to add to points.
503claw::math::box_2d<T>&
504claw::math::box_2d<T>::operator+=(const point_type& vect)
507 second_point += vect;
508} // box_2d::operator+=()
510/*----------------------------------------------------------------------------*/
512 * \brief Translation.
513 * \param vect The vector to substract to points.
516claw::math::box_2d<T>&
517claw::math::box_2d<T>::operator-=(const point_type& vect)
520 second_point -= vect;
521} // box_2d::operator-=()
523/*----------------------------------------------------------------------------*/
525 * \brief Return box' width.
528typename claw::math::box_2d<T>::value_type
529claw::math::box_2d<T>::width() const
531 if (first_point.x > second_point.x)
532 return first_point.x - second_point.x;
534 return second_point.x - first_point.x;
537/*----------------------------------------------------------------------------*/
539 * \brief Return box' height.
542typename claw::math::box_2d<T>::value_type
543claw::math::box_2d<T>::height() const
545 if (first_point.y > second_point.y)
546 return first_point.y - second_point.y;
548 return second_point.y - first_point.y;
551/*----------------------------------------------------------------------------*/
553 * \brief X-intersection of two box_2ds.
554 * \pre There is an intersection between this and r.
555 * \post result's x and width fields are filled.
558void claw::math::box_2d<T>::x_intersection
559( const self_type& r, self_type& result ) const
561 result.first_point.x = std::max(left(), r.left());
562 result.second_point.x = std::min(right(), r.right());
563} // box_2d::x_intersection()
565/*----------------------------------------------------------------------------*/
567 * \brief Y-intersection of two box_2ds.
568 * \pre There is an intersection between this and r.
569 * \post result's y and height fields are filled.
572void claw::math::box_2d<T>::y_intersection
573( const self_type& r, self_type& result ) const
575 result.first_point.y = std::max(bottom(), r.bottom());
576 result.second_point.y = std::min(top(), r.top());
577} // box_2d::y_intersection()