1
// Copyright (C) 2002-2011 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.
22
Coordinates are (0,0) for top-left corner, and increasing to the right
30
//! Default constructor creating empty rectangle at (0,0)
31
rect() : UpperLeftCorner(0,0), LowerRightCorner(0,0) {}
33
//! Constructor with two corners
34
rect(T x, T y, T x2, T y2)
35
: UpperLeftCorner(x,y), LowerRightCorner(x2,y2) {}
37
//! Constructor with two corners
38
rect(const position2d<T>& upperLeft, const position2d<T>& lowerRight)
39
: UpperLeftCorner(upperLeft), LowerRightCorner(lowerRight) {}
41
//! Constructor with upper left corner and dimension
43
rect(const position2d<T>& pos, const dimension2d<U>& size)
44
: UpperLeftCorner(pos), LowerRightCorner(pos.X + size.Width, pos.Y + size.Height) {}
46
//! move right by given numbers
47
rect<T> operator+(const position2d<T>& pos) const
53
//! move right by given numbers
54
rect<T>& operator+=(const position2d<T>& pos)
56
UpperLeftCorner += pos;
57
LowerRightCorner += pos;
61
//! move left by given numbers
62
rect<T> operator-(const position2d<T>& pos) const
68
//! move left by given numbers
69
rect<T>& operator-=(const position2d<T>& pos)
71
UpperLeftCorner -= pos;
72
LowerRightCorner -= pos;
77
bool operator==(const rect<T>& other) const
79
return (UpperLeftCorner == other.UpperLeftCorner &&
80
LowerRightCorner == other.LowerRightCorner);
83
//! inequality operator
84
bool operator!=(const rect<T>& other) const
86
return (UpperLeftCorner != other.UpperLeftCorner ||
87
LowerRightCorner != other.LowerRightCorner);
90
//! compares size of rectangles
91
bool operator<(const rect<T>& other) const
93
return getArea() < other.getArea();
96
//! Returns size of rectangle
99
return getWidth() * getHeight();
102
//! Returns if a 2d point is within this rectangle.
103
/** \param pos Position to test if it lies within this rectangle.
104
\return True if the position is within the rectangle, false if not. */
105
bool isPointInside(const position2d<T>& pos) const
107
return (UpperLeftCorner.X <= pos.X &&
108
UpperLeftCorner.Y <= pos.Y &&
109
LowerRightCorner.X >= pos.X &&
110
LowerRightCorner.Y >= pos.Y);
113
//! Check if the rectangle collides with another rectangle.
114
/** \param other Rectangle to test collision with
115
\return True if the rectangles collide. */
116
bool isRectCollided(const rect<T>& other) const
118
return (LowerRightCorner.Y > other.UpperLeftCorner.Y &&
119
UpperLeftCorner.Y < other.LowerRightCorner.Y &&
120
LowerRightCorner.X > other.UpperLeftCorner.X &&
121
UpperLeftCorner.X < other.LowerRightCorner.X);
124
//! Clips this rectangle with another one.
125
/** \param other Rectangle to clip with */
126
void clipAgainst(const rect<T>& other)
128
if (other.LowerRightCorner.X < LowerRightCorner.X)
129
LowerRightCorner.X = other.LowerRightCorner.X;
130
if (other.LowerRightCorner.Y < LowerRightCorner.Y)
131
LowerRightCorner.Y = other.LowerRightCorner.Y;
133
if (other.UpperLeftCorner.X > UpperLeftCorner.X)
134
UpperLeftCorner.X = other.UpperLeftCorner.X;
135
if (other.UpperLeftCorner.Y > UpperLeftCorner.Y)
136
UpperLeftCorner.Y = other.UpperLeftCorner.Y;
138
// correct possible invalid rect resulting from clipping
139
if (UpperLeftCorner.Y > LowerRightCorner.Y)
140
UpperLeftCorner.Y = LowerRightCorner.Y;
141
if (UpperLeftCorner.X > LowerRightCorner.X)
142
UpperLeftCorner.X = LowerRightCorner.X;
145
//! Moves this rectangle to fit inside another one.
146
/** \return True on success, false if not possible */
147
bool constrainTo(const rect<T>& other)
149
if (other.getWidth() < getWidth() || other.getHeight() < getHeight())
152
T diff = other.LowerRightCorner.X - LowerRightCorner.X;
155
LowerRightCorner.X += diff;
156
UpperLeftCorner.X += diff;
159
diff = other.LowerRightCorner.Y - LowerRightCorner.Y;
162
LowerRightCorner.Y += diff;
163
UpperLeftCorner.Y += diff;
166
diff = UpperLeftCorner.X - other.UpperLeftCorner.X;
169
UpperLeftCorner.X -= diff;
170
LowerRightCorner.X -= diff;
173
diff = UpperLeftCorner.Y - other.UpperLeftCorner.Y;
176
UpperLeftCorner.Y -= diff;
177
LowerRightCorner.Y -= diff;
183
//! Get width of rectangle.
186
return LowerRightCorner.X - UpperLeftCorner.X;
189
//! Get height of rectangle.
192
return LowerRightCorner.Y - UpperLeftCorner.Y;
195
//! If the lower right corner of the rect is smaller then the upper left, the points are swapped.
198
if (LowerRightCorner.X < UpperLeftCorner.X)
200
T t = LowerRightCorner.X;
201
LowerRightCorner.X = UpperLeftCorner.X;
202
UpperLeftCorner.X = t;
205
if (LowerRightCorner.Y < UpperLeftCorner.Y)
207
T t = LowerRightCorner.Y;
208
LowerRightCorner.Y = UpperLeftCorner.Y;
209
UpperLeftCorner.Y = t;
213
//! Returns if the rect is valid to draw.
214
/** It would be invalid if the UpperLeftCorner is lower or more
215
right than the LowerRightCorner. */
218
return ((LowerRightCorner.X >= UpperLeftCorner.X) &&
219
(LowerRightCorner.Y >= UpperLeftCorner.Y));
222
//! Get the center of the rectangle
223
position2d<T> getCenter() const
225
return position2d<T>(
226
(UpperLeftCorner.X + LowerRightCorner.X) / 2,
227
(UpperLeftCorner.Y + LowerRightCorner.Y) / 2);
230
//! Get the dimensions of the rectangle
231
dimension2d<T> getSize() const
233
return dimension2d<T>(getWidth(), getHeight());
237
//! Adds a point to the rectangle
238
/** Causes the rectangle to grow bigger if point is outside of
240
\param p Point to add to the box. */
241
void addInternalPoint(const position2d<T>& p)
243
addInternalPoint(p.X, p.Y);
246
//! Adds a point to the bounding rectangle
247
/** Causes the rectangle to grow bigger if point is outside of
249
\param x X-Coordinate of the point to add to this box.
250
\param y Y-Coordinate of the point to add to this box. */
251
void addInternalPoint(T x, T y)
253
if (x>LowerRightCorner.X)
254
LowerRightCorner.X = x;
255
if (y>LowerRightCorner.Y)
256
LowerRightCorner.Y = y;
258
if (x<UpperLeftCorner.X)
259
UpperLeftCorner.X = x;
260
if (y<UpperLeftCorner.Y)
261
UpperLeftCorner.Y = y;
264
//! Upper left corner
265
position2d<T> UpperLeftCorner;
266
//! Lower right corner
267
position2d<T> LowerRightCorner;
270
//! Rectangle with float values
271
typedef rect<f32> rectf;
272
//! Rectangle with int values
273
typedef rect<s32> recti;
275
} // end namespace core
276
} // end namespace irr