1 // Copyright (C) 2002-2007 Nikolaus Gebhardt
2 // This file is part of the "Irrlicht Engine".
3 // For conditions of distribution and use, see copyright notice in irrlicht.h
5 #ifndef __IRR_RECT_H_INCLUDED__
6 #define __IRR_RECT_H_INCLUDED__
9 #include "dimension2d.h"
10 #include "position2d.h"
17 //! Rectangle template.
18 /** Mostly used by 2D GUI elements and for 2D drawing methods.
19 It has 2 positions instead of position and dimension and a fast
20 method for collision detection with other rectangles and points.
27 rect() : UpperLeftCorner(0,0), LowerRightCorner(0,0) {}
29 rect(T x
, T y
, T x2
, T y2
)
30 : UpperLeftCorner(x
,y
), LowerRightCorner(x2
,y2
) {}
32 rect(const position2d
<T
>& upperLeft
, const position2d
<T
>& lowerRight
)
33 : UpperLeftCorner(upperLeft
), LowerRightCorner(lowerRight
) {}
35 rect(const position2d
<T
>& pos
, const dimension2d
<T
>& size
)
36 : UpperLeftCorner(pos
), LowerRightCorner(pos
.X
+ size
.Width
, pos
.Y
+ size
.Height
) {}
39 rect
<T
> operator+(const position2d
<T
>& pos
) const
45 rect
<T
>& operator+=(const position2d
<T
>& pos
)
47 UpperLeftCorner
+= pos
;
48 LowerRightCorner
+= pos
;
52 rect
<T
> operator-(const position2d
<T
>& pos
) const
58 rect
<T
>& operator-=(const position2d
<T
>& pos
)
60 UpperLeftCorner
-= pos
;
61 LowerRightCorner
-= pos
;
65 bool operator==(const rect
<T
>& other
) const
67 return (UpperLeftCorner
== other
.UpperLeftCorner
&&
68 LowerRightCorner
== other
.LowerRightCorner
);
72 bool operator!=(const rect
<T
>& other
) const
74 return (UpperLeftCorner
!= other
.UpperLeftCorner
||
75 LowerRightCorner
!= other
.LowerRightCorner
);
78 // compares size of rectangles
79 bool operator<(const rect
<T
>& other
) const
81 return getArea() < other
.getArea();
84 //! Returns size of rectangle
87 return getWidth() * getHeight();
90 //! Returns if a 2d point is within this rectangle.
91 //! \param pos: Position to test if it lies within this rectangle.
92 //! \return Returns true if the position is within the rectangle, false if not.
93 bool isPointInside(const position2d
<T
>& pos
) const
95 return (UpperLeftCorner
.X
<= pos
.X
&&
96 UpperLeftCorner
.Y
<= pos
.Y
&&
97 LowerRightCorner
.X
>= pos
.X
&&
98 LowerRightCorner
.Y
>= pos
.Y
);
101 //! Returns if the rectangle collides with another rectangle.
102 bool isRectCollided(const rect
<T
>& other
) const
104 return (LowerRightCorner
.Y
> other
.UpperLeftCorner
.Y
&&
105 UpperLeftCorner
.Y
< other
.LowerRightCorner
.Y
&&
106 LowerRightCorner
.X
> other
.UpperLeftCorner
.X
&&
107 UpperLeftCorner
.X
< other
.LowerRightCorner
.X
);
110 //! Clips this rectangle with another one.
111 void clipAgainst(const rect
<T
>& other
)
113 if (other
.LowerRightCorner
.X
< LowerRightCorner
.X
)
114 LowerRightCorner
.X
= other
.LowerRightCorner
.X
;
115 if (other
.LowerRightCorner
.Y
< LowerRightCorner
.Y
)
116 LowerRightCorner
.Y
= other
.LowerRightCorner
.Y
;
118 if (other
.UpperLeftCorner
.X
> UpperLeftCorner
.X
)
119 UpperLeftCorner
.X
= other
.UpperLeftCorner
.X
;
120 if (other
.UpperLeftCorner
.Y
> UpperLeftCorner
.Y
)
121 UpperLeftCorner
.Y
= other
.UpperLeftCorner
.Y
;
123 // correct possible invalid rect resulting from clipping
124 if (UpperLeftCorner
.Y
> LowerRightCorner
.Y
)
125 UpperLeftCorner
.Y
= LowerRightCorner
.Y
;
126 if (UpperLeftCorner
.X
> LowerRightCorner
.X
)
127 UpperLeftCorner
.X
= LowerRightCorner
.X
;
130 //! Moves this rectangle to fit inside another one.
131 //! \return: returns true on success, false if not possible
132 bool constrainTo(const rect
<T
>& other
)
134 if (other
.getWidth() < getWidth() || other
.getHeight() < getHeight())
137 T diff
= other
.LowerRightCorner
.X
- LowerRightCorner
.X
;
140 LowerRightCorner
.X
+= diff
;
141 UpperLeftCorner
.X
+= diff
;
144 diff
= other
.LowerRightCorner
.Y
- LowerRightCorner
.Y
;
147 LowerRightCorner
.Y
+= diff
;
148 UpperLeftCorner
.Y
+= diff
;
151 diff
= UpperLeftCorner
.X
- other
.UpperLeftCorner
.X
;
154 UpperLeftCorner
.X
-= diff
;
155 LowerRightCorner
.X
-= diff
;
158 diff
= UpperLeftCorner
.Y
- other
.UpperLeftCorner
.Y
;
161 UpperLeftCorner
.Y
-= diff
;
162 LowerRightCorner
.Y
-= diff
;
168 //! Returns width of rectangle.
171 return LowerRightCorner
.X
- UpperLeftCorner
.X
;
174 //! Returns height of rectangle.
177 return LowerRightCorner
.Y
- UpperLeftCorner
.Y
;
180 //! If the lower right corner of the rect is smaller then the
181 //! upper left, the points are swapped.
184 if (LowerRightCorner
.X
< UpperLeftCorner
.X
)
186 T t
= LowerRightCorner
.X
;
187 LowerRightCorner
.X
= UpperLeftCorner
.X
;
188 UpperLeftCorner
.X
= t
;
191 if (LowerRightCorner
.Y
< UpperLeftCorner
.Y
)
193 T t
= LowerRightCorner
.Y
;
194 LowerRightCorner
.Y
= UpperLeftCorner
.Y
;
195 UpperLeftCorner
.Y
= t
;
199 //! Returns if the rect is valid to draw. It could be invalid
200 //! if the UpperLeftCorner is lower or more right than the
201 //! LowerRightCorner, or if any dimension is 0.
204 return ((LowerRightCorner
.X
>= UpperLeftCorner
.X
) &&
205 (LowerRightCorner
.Y
>= UpperLeftCorner
.Y
));
208 //! Returns the center of the rectangle
209 position2d
<T
> getCenter() const
211 return position2d
<T
>((UpperLeftCorner
.X
+ LowerRightCorner
.X
) / 2,
212 (UpperLeftCorner
.Y
+ LowerRightCorner
.Y
) / 2);
215 //! Returns the dimensions of the rectangle
216 dimension2d
<T
> getSize() const
218 return dimension2d
<T
>(getWidth(), getHeight());
222 //! Adds a point to the rectangle, causing it to grow bigger,
223 //! if point is outside of the box
224 //! \param p: Point to add into the box.
225 void addInternalPoint(const position2d
<T
>& p
)
227 addInternalPoint(p
.X
, p
.Y
);
230 //! Adds a point to the bounding rectangle, causing it to grow bigger,
231 //! if point is outside of the box.
232 //! \param x: X Coordinate of the point to add to this box.
233 //! \param y: Y Coordinate of the point to add to this box.
234 void addInternalPoint(T x
, T y
)
236 if (x
>LowerRightCorner
.X
)
237 LowerRightCorner
.X
= x
;
238 if (y
>LowerRightCorner
.Y
)
239 LowerRightCorner
.Y
= y
;
241 if (x
<UpperLeftCorner
.X
)
242 UpperLeftCorner
.X
= x
;
243 if (y
<UpperLeftCorner
.Y
)
244 UpperLeftCorner
.Y
= y
;
248 position2d
<T
> UpperLeftCorner
;
249 position2d
<T
> LowerRightCorner
;
253 } // end namespace core
254 } // end namespace irr