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::rectangle class.
28 * \author Julien Jorge
32/*----------------------------------------------------------------------------*/
37claw::math::rectangle<T>::rectangle()
40} // rectangle::rectangle() [constructor]
42/*----------------------------------------------------------------------------*/
44 * \brief Copy constructor.
45 * \param that Rectangle to copy from.
49claw::math::rectangle<T>::rectangle( const rectangle<U>& that )
50 : position(that.position), width(that.width), height(that.height)
53} // rectangle::rectangle() [copy constructor]
55/*----------------------------------------------------------------------------*/
57 * \brief Constructor from a box.
58 * \param that The box to copy from.
62claw::math::rectangle<T>::rectangle( const box_2d<U>& that )
63 : position(that.left(), that.top()), width(that.width()),
67} // rectangle::rectangle() [copy constructor]
69/*----------------------------------------------------------------------------*/
71 * \brief Constructor with initialization.
72 * \param _x Rectangle's X-coordinate.
73 * \param _y Rectangle's Y-coordinate.
74 * \param _width Rectangle's width.
75 * \param _height Rectangle's height.
78claw::math::rectangle<T>::rectangle
79( const value_type& _x, const value_type& _y,
80 const value_type& _width, const value_type& _height )
81 : position(_x, _y), width(_width), height(_height)
84} // rectangle::rectangle() [constructor with values]
86/*----------------------------------------------------------------------------*/
88 * \brief Constructor with initialization.
89 * \param pos The position of the rectangle.
90 * \param _width Rectangle's width.
91 * \param _height Rectangle's height.
95claw::math::rectangle<T>::rectangle
96( const coordinate_2d<U>& pos, const value_type& _width,
97 const value_type& _height )
98 : position(pos), width(_width), height(_height)
101} // rectangle::rectangle() [constructor from position and size]
103/*----------------------------------------------------------------------------*/
105 * \brief Constructor with initialization.
106 * \param pos The position of the rectangle.
107 * \param size The size of the rectangle.
111claw::math::rectangle<T>::rectangle
112( const coordinate_2d<U>& pos, const coordinate_2d<U>& size )
113 : position(pos), width(size.x), height(size.y)
116} // rectangle::rectangle() [constructor from position and size]
118/*----------------------------------------------------------------------------*/
120 * \brief Get a copy of the rectangle by converting its members to a given type.
122 * Consider the following code:
124 * <tt> rectangle<float> a;
128 * rectangle<int> b(a); </tt>
130 * The copy constructor will be called, and your compiler should print some
131 * warnings in your console. These warnings have a meaning, so we don't want to
132 * make them disapear by adding explicit type conversion inside the rectangle
133 * class nor adding a cast operator that will be used silently by the compiler.
135 * If you really want to convert the type, this method will explicitly cast the
140claw::math::rectangle<U> claw::math::rectangle<T>::cast_value_type_to() const
142 return claw::math::rectangle<U>
143 ( position.template cast_value_type_to<U>(), (U)width, (U)height );
144} // rectangle::cast_value_type_to()
146/*----------------------------------------------------------------------------*/
148 * \brief Tell if this rectangle equals an other rectangle.
149 * \param that The rectangle to compare to.
152bool claw::math::rectangle<T>::operator==( const self_type& that ) const
154 return (position == that.position) && (width == that.width)
155 && (height == that.height);
156} // rectangle::operator==()
158/*----------------------------------------------------------------------------*/
160 * \brief Tell if this rectangle equals an other rectangle.
161 * \param that The rectangle to compare to.
164bool claw::math::rectangle<T>::operator!=( const self_type& that ) const
166 return !(*this == that);
167} // rectangle::operator!=()
169/*----------------------------------------------------------------------------*/
171 * \brief Calculate the rectangle's area.
174typename claw::math::rectangle<T>::value_type
175claw::math::rectangle<T>::area() const
177 return width * height;
178} // rectangle::area()
180/*----------------------------------------------------------------------------*/
182 * \brief Tell if a point is in a rectangle.
183 * \param p The supposed included point.
187claw::math::rectangle<T>::includes( const coordinate_2d<value_type>& p ) const
189 return (position.x <= p.x) && (right() >= p.x)
190 && (position.y <= p.y) && (bottom() >= p.y);
191} // rectangle::includes()
193/*----------------------------------------------------------------------------*/
195 * \brief Tell if a rectangle is in a rectangle.
196 * \param r The supposed included rectangle.
199bool claw::math::rectangle<T>::includes( const self_type& r ) const
201 box_2d<value_type> his_box(r);
203 return includes(his_box.first_point) && includes(his_box.second_point);
204} // rectangle::includes() [rectangle]
206/*----------------------------------------------------------------------------*/
208 * \brief Tell if there is an intersection of two rectangles.
209 * \param r The supposed intersecting rectangle.
212bool claw::math::rectangle<T>::intersects( const self_type& r ) const
214 return (right() >= r.position.x)
215 && (r.right() >= position.x)
216 && (bottom() >= r.position.y)
217 && (r.bottom() >= position.y);
218} // rectangle::intersects()
220/*----------------------------------------------------------------------------*/
222 * \brief Intersection of two rectangles.
223 * \param r The supposed intersecting rectangle.
226claw::math::rectangle<T>
227claw::math::rectangle<T>::intersection( const self_type& r ) const
233 x_intersection(r, result);
234 y_intersection(r, result);
238} // rectangle::intersection()
240/*----------------------------------------------------------------------------*/
242 * \brief Get the smallest rectangle bounding both this rectangle and another
244 * \param r The other rectangle.
247claw::math::rectangle<T>
248claw::math::rectangle<T>::join( const self_type& r ) const
250 const T result_left = std::min( left(), r.left() );
251 const T result_top = std::min( top(), r.top() );
252 const T result_bottom = std::max( bottom(), r.bottom() );
253 const T result_right = std::max( right(), r.right() );
256 ( result_left, result_top, result_right - result_left,
257 result_bottom - result_top );
258} // rectangle::join()
260/*----------------------------------------------------------------------------*/
262 * \brief set new position and size to the rectangle.
263 * \param new_x New x-coordinate.
264 * \param new_y New y-coordinate.
265 * \param new_width New width.
266 * \param new_height New height.
269void claw::math::rectangle<T>::set
270( const value_type& new_x, const value_type& new_y,
271 const value_type& new_width, const value_type& new_height )
279/*----------------------------------------------------------------------------*/
281 * \brief Get the x-coordinate of the left edge.
284typename claw::math::rectangle<T>::value_type
285claw::math::rectangle<T>::left() const
288} // rectangle::left()
290/*----------------------------------------------------------------------------*/
292 * \brief Get the x-coordinate of the right edge.
295typename claw::math::rectangle<T>::value_type
296claw::math::rectangle<T>::right() const
298 return position.x + width;
299} // rectangle::right()
301/*----------------------------------------------------------------------------*/
303 * \brief Get the y-coordinate of the bottom edge.
306typename claw::math::rectangle<T>::value_type
307claw::math::rectangle<T>::bottom() const
309 return position.y + height;
310} // rectangle::bottom()
312/*----------------------------------------------------------------------------*/
314 * \brief Get the y-coordinate of the top edge.
317typename claw::math::rectangle<T>::value_type
318claw::math::rectangle<T>::top() const
323/*----------------------------------------------------------------------------*/
325 * \brief Get the size of the rectangle.
328claw::math::coordinate_2d< typename claw::math::rectangle<T>::value_type >
329claw::math::rectangle<T>::size() const
331 return claw::math::coordinate_2d<value_type>(width, height);
332} // rectangle::size()
334/*----------------------------------------------------------------------------*/
336 * \brief X-intersection of two rectangles.
337 * \pre There is an intersection between this and r.
338 * \post result's x and width fields are filled.
341void claw::math::rectangle<T>::x_intersection
342( const self_type& r, self_type& result ) const
344 if (position.x <= r.position.x)
346 result.position.x = r.position.x;
348 if (right() >= r.right())
349 result.width = r.width;
351 result.width = right() - r.position.x;
354 r.x_intersection(*this, result);
356} // rectangle::x_intersection()
358/*----------------------------------------------------------------------------*/
360 * \brief Y-intersection of two rectangles.
361 * \pre There is an intersection between this and r.
362 * \post result's y and height fields are filled.
365void claw::math::rectangle<T>::y_intersection
366( const self_type& r, self_type& result ) const
368 if (position.y <= r.position.y)
370 result.position.y = r.position.y;
372 if (bottom() >= r.bottom())
373 result.height = r.height;
375 result.height = bottom() - r.position.y;
378 r.y_intersection(*this, result);
380} // rectangle::y_intersection()