Claw 1.7.3
rectangle.tpp
1/*
2 CLAW - a C++ Library Absolutely Wonderful
3
4 CLAW is a free library without any particular aim but being useful to
5 anyone.
6
7 Copyright (C) 2005-2011 Julien Jorge
8
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.
13
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.
18
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
22
23 contact: julien.jorge@gamned.org
24*/
25/**
26 * \file rectangle.tpp
27 * \brief Implementation of claw::math::rectangle class.
28 * \author Julien Jorge
29 */
30#include <algorithm>
31
32/*----------------------------------------------------------------------------*/
33/**
34 * \brief Constructor.
35 */
36template<class T>
37claw::math::rectangle<T>::rectangle()
38{
39
40} // rectangle::rectangle() [constructor]
41
42/*----------------------------------------------------------------------------*/
43/**
44 * \brief Copy constructor.
45 * \param that Rectangle to copy from.
46 */
47template<class T>
48template<class U>
49claw::math::rectangle<T>::rectangle( const rectangle<U>& that )
50 : position(that.position), width(that.width), height(that.height)
51{
52
53} // rectangle::rectangle() [copy constructor]
54
55/*----------------------------------------------------------------------------*/
56/**
57 * \brief Constructor from a box.
58 * \param that The box to copy from.
59 */
60template<class T>
61template<class U>
62claw::math::rectangle<T>::rectangle( const box_2d<U>& that )
63 : position(that.left(), that.top()), width(that.width()),
64 height(that.height())
65{
66
67} // rectangle::rectangle() [copy constructor]
68
69/*----------------------------------------------------------------------------*/
70/**
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.
76 */
77template<class T>
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)
82{
83
84} // rectangle::rectangle() [constructor with values]
85
86/*----------------------------------------------------------------------------*/
87/**
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.
92 */
93template<class T>
94template<typename U>
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)
99{
100
101} // rectangle::rectangle() [constructor from position and size]
102
103/*----------------------------------------------------------------------------*/
104/**
105 * \brief Constructor with initialization.
106 * \param pos The position of the rectangle.
107 * \param size The size of the rectangle.
108 */
109template<class T>
110template<typename U>
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)
114{
115
116} // rectangle::rectangle() [constructor from position and size]
117
118/*----------------------------------------------------------------------------*/
119/**
120 * \brief Get a copy of the rectangle by converting its members to a given type.
121 *
122 * Consider the following code:
123 *
124 * <tt> rectangle<float> a;
125 *
126 * ...
127 *
128 * rectangle<int> b(a); </tt>
129 *
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.
134 *
135 * If you really want to convert the type, this method will explicitly cast the
136 * member variables.
137 */
138template<class T>
139template<typename U>
140claw::math::rectangle<U> claw::math::rectangle<T>::cast_value_type_to() const
141{
142 return claw::math::rectangle<U>
143 ( position.template cast_value_type_to<U>(), (U)width, (U)height );
144} // rectangle::cast_value_type_to()
145
146/*----------------------------------------------------------------------------*/
147/**
148 * \brief Tell if this rectangle equals an other rectangle.
149 * \param that The rectangle to compare to.
150 */
151template<class T>
152bool claw::math::rectangle<T>::operator==( const self_type& that ) const
153{
154 return (position == that.position) && (width == that.width)
155 && (height == that.height);
156} // rectangle::operator==()
157
158/*----------------------------------------------------------------------------*/
159/**
160 * \brief Tell if this rectangle equals an other rectangle.
161 * \param that The rectangle to compare to.
162 */
163template<class T>
164bool claw::math::rectangle<T>::operator!=( const self_type& that ) const
165{
166 return !(*this == that);
167} // rectangle::operator!=()
168
169/*----------------------------------------------------------------------------*/
170/**
171 * \brief Calculate the rectangle's area.
172 */
173template<class T>
174typename claw::math::rectangle<T>::value_type
175claw::math::rectangle<T>::area() const
176{
177 return width * height;
178} // rectangle::area()
179
180/*----------------------------------------------------------------------------*/
181/**
182 * \brief Tell if a point is in a rectangle.
183 * \param p The supposed included point.
184 */
185template<class T>
186bool
187claw::math::rectangle<T>::includes( const coordinate_2d<value_type>& p ) const
188{
189 return (position.x <= p.x) && (right() >= p.x)
190 && (position.y <= p.y) && (bottom() >= p.y);
191} // rectangle::includes()
192
193/*----------------------------------------------------------------------------*/
194/**
195 * \brief Tell if a rectangle is in a rectangle.
196 * \param r The supposed included rectangle.
197 */
198template<class T>
199bool claw::math::rectangle<T>::includes( const self_type& r ) const
200{
201 box_2d<value_type> his_box(r);
202
203 return includes(his_box.first_point) && includes(his_box.second_point);
204} // rectangle::includes() [rectangle]
205
206/*----------------------------------------------------------------------------*/
207/**
208 * \brief Tell if there is an intersection of two rectangles.
209 * \param r The supposed intersecting rectangle.
210 */
211template<class T>
212bool claw::math::rectangle<T>::intersects( const self_type& r ) const
213{
214 return (right() >= r.position.x)
215 && (r.right() >= position.x)
216 && (bottom() >= r.position.y)
217 && (r.bottom() >= position.y);
218} // rectangle::intersects()
219
220/*----------------------------------------------------------------------------*/
221/**
222 * \brief Intersection of two rectangles.
223 * \param r The supposed intersecting rectangle.
224 */
225template<class T>
226claw::math::rectangle<T>
227claw::math::rectangle<T>::intersection( const self_type& r ) const
228{
229 self_type result;
230
231 if ( intersects(r) )
232 {
233 x_intersection(r, result);
234 y_intersection(r, result);
235 }
236
237 return result;
238} // rectangle::intersection()
239
240/*----------------------------------------------------------------------------*/
241/**
242 * \brief Get the smallest rectangle bounding both this rectangle and another
243 * one.
244 * \param r The other rectangle.
245 */
246template<class T>
247claw::math::rectangle<T>
248claw::math::rectangle<T>::join( const self_type& r ) const
249{
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() );
254
255 return self_type
256 ( result_left, result_top, result_right - result_left,
257 result_bottom - result_top );
258} // rectangle::join()
259
260/*----------------------------------------------------------------------------*/
261/**
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.
267 */
268template<class T>
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 )
272{
273 position.x = new_x;
274 position.y = new_y;
275 width = new_width;
276 height = new_height;
277} // rectangle::set()
278
279/*----------------------------------------------------------------------------*/
280/**
281 * \brief Get the x-coordinate of the left edge.
282 */
283template<class T>
284typename claw::math::rectangle<T>::value_type
285claw::math::rectangle<T>::left() const
286{
287 return position.x;
288} // rectangle::left()
289
290/*----------------------------------------------------------------------------*/
291/**
292 * \brief Get the x-coordinate of the right edge.
293 */
294template<class T>
295typename claw::math::rectangle<T>::value_type
296claw::math::rectangle<T>::right() const
297{
298 return position.x + width;
299} // rectangle::right()
300
301/*----------------------------------------------------------------------------*/
302/**
303 * \brief Get the y-coordinate of the bottom edge.
304 */
305template<class T>
306typename claw::math::rectangle<T>::value_type
307claw::math::rectangle<T>::bottom() const
308{
309 return position.y + height;
310} // rectangle::bottom()
311
312/*----------------------------------------------------------------------------*/
313/**
314 * \brief Get the y-coordinate of the top edge.
315 */
316template<class T>
317typename claw::math::rectangle<T>::value_type
318claw::math::rectangle<T>::top() const
319{
320 return position.y;
321} // rectangle::top()
322
323/*----------------------------------------------------------------------------*/
324/**
325 * \brief Get the size of the rectangle.
326 */
327template<class T>
328claw::math::coordinate_2d< typename claw::math::rectangle<T>::value_type >
329claw::math::rectangle<T>::size() const
330{
331 return claw::math::coordinate_2d<value_type>(width, height);
332} // rectangle::size()
333
334/*----------------------------------------------------------------------------*/
335/**
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.
339 */
340template<class T>
341void claw::math::rectangle<T>::x_intersection
342( const self_type& r, self_type& result ) const
343{
344 if (position.x <= r.position.x)
345 {
346 result.position.x = r.position.x;
347
348 if (right() >= r.right())
349 result.width = r.width;
350 else
351 result.width = right() - r.position.x;
352 }
353 else
354 r.x_intersection(*this, result);
355
356} // rectangle::x_intersection()
357
358/*----------------------------------------------------------------------------*/
359/**
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.
363 */
364template<class T>
365void claw::math::rectangle<T>::y_intersection
366( const self_type& r, self_type& result ) const
367{
368 if (position.y <= r.position.y)
369 {
370 result.position.y = r.position.y;
371
372 if (bottom() >= r.bottom())
373 result.height = r.height;
374 else
375 result.height = bottom() - r.position.y;
376 }
377 else
378 r.y_intersection(*this, result);
379
380} // rectangle::y_intersection()