Imported more code from the old engine.
[peakengine.git] / engine / include / support / rect.h
blobd145132ffa9dda3f69323ab84c82aca8135324c8
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__
8 #include "irrTypes.h"
9 #include "dimension2d.h"
10 #include "position2d.h"
12 namespace irr
14 namespace core
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 template <class T>
23 class rect
25 public:
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
41 rect<T> ret(*this);
42 return ret+=pos;
45 rect<T>& operator+=(const position2d<T>& pos)
47 UpperLeftCorner += pos;
48 LowerRightCorner += pos;
49 return *this;
52 rect<T> operator-(const position2d<T>& pos) const
54 rect<T> ret(*this);
55 return ret-=pos;
58 rect<T>& operator-=(const position2d<T>& pos)
60 UpperLeftCorner -= pos;
61 LowerRightCorner -= pos;
62 return *this;
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
85 T getArea() const
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())
135 return false;
137 T diff = other.LowerRightCorner.X - LowerRightCorner.X;
138 if (diff < 0)
140 LowerRightCorner.X += diff;
141 UpperLeftCorner.X += diff;
144 diff = other.LowerRightCorner.Y - LowerRightCorner.Y;
145 if (diff < 0)
147 LowerRightCorner.Y += diff;
148 UpperLeftCorner.Y += diff;
151 diff = UpperLeftCorner.X - other.UpperLeftCorner.X;
152 if (diff < 0)
154 UpperLeftCorner.X -= diff;
155 LowerRightCorner.X -= diff;
158 diff = UpperLeftCorner.Y - other.UpperLeftCorner.Y;
159 if (diff < 0)
161 UpperLeftCorner.Y -= diff;
162 LowerRightCorner.Y -= diff;
165 return true;
168 //! Returns width of rectangle.
169 T getWidth() const
171 return LowerRightCorner.X - UpperLeftCorner.X;
174 //! Returns height of rectangle.
175 T getHeight() const
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.
182 void repair()
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.
202 bool isValid() const
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
256 #endif