Woldmap images for earthtux
[supertux.git] / src / math / rectf.hpp
1 //  SuperTux
2 //  Copyright (C) 2006 Matthias Braun <matze@braunis.de>
3 //
4 //  This program is free software: you can redistribute it and/or modify
5 //  it under the terms of the GNU General Public License as published by
6 //  the Free Software Foundation, either version 3 of the License, or
7 //  (at your option) any later version.
8 //
9 //  This program is distributed in the hope that it will be useful,
10 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
11 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 //  GNU General Public License for more details.
13 //
14 //  You should have received a copy of the GNU General Public License
15 //  along with this program.  If not, see <http://www.gnu.org/licenses/>.
16
17 #ifndef HEADER_SUPERTUX_MATH_RECTF_HPP
18 #define HEADER_SUPERTUX_MATH_RECTF_HPP
19
20 #include <assert.h>
21
22 #include "math/sizef.hpp"
23 #include "math/vector.hpp"
24 #include "object/anchor_point.hpp"
25
26 class Sizef;
27
28 /** This class represents a rectangle.
29  * (Implementation Note) We're using upper left and lower right point instead of
30  * upper left and width/height here, because that makes the collision detection
31  * a little bit more efficient.
32  */
33 class Rectf
34 {
35 public:
36   Rectf() :
37     p1(),
38     p2()
39   { }
40
41   Rectf(const Vector& np1, const Vector& np2) :
42     p1(np1), p2(np2)
43   {
44   }
45
46   Rectf(float x1, float y1, float x2, float y2) :
47     p1(x1, y1), p2(x2, y2)
48   {
49     assert(p1.x <= p2.x && p1.y <= p2.y);
50   }
51
52   Rectf(const Vector& p1_, const Sizef& size);
53
54   float get_left() const
55   { return p1.x; }
56
57   float get_right() const
58   { return p2.x; }
59
60   float get_top() const
61   { return p1.y; }
62
63   float get_bottom() const
64   { return p2.y; }
65
66   float get_width() const
67   { return p2.x - p1.x; }
68
69   float get_height() const
70   { return p2.y - p1.y; }
71
72   Vector get_middle() const
73   { return Vector((p1.x+p2.x)/2, (p1.y+p2.y)/2); }
74
75   void set_pos(const Vector& v)
76   {
77     move(v-p1);
78   }
79
80   void set_height(float height)
81   {
82     p2.y = p1.y + height;
83   }
84   void set_width(float width)
85   {
86     p2.x = p1.x + width;
87   }
88   void set_size(float width, float height)
89   {
90     set_width(width);
91     set_height(height);
92   }
93   Sizef get_size() const
94   {
95     return Sizef(get_width(), get_height());
96   }
97
98   void move(const Vector& v)
99   {
100     p1 += v;
101     p2 += v;
102   }
103
104   bool contains(const Vector& v) const
105   {
106     return v.x >= p1.x && v.y >= p1.y && v.x < p2.x && v.y < p2.y;
107   }
108   bool contains(const Rectf& other) const
109   {
110     if(p1.x >= other.p2.x || other.p1.x >= p2.x)
111       return false;
112     if(p1.y >= other.p2.y || other.p1.y >= p2.y)
113       return false;
114
115     return true;
116   }
117
118   float distance (const Vector& other, AnchorPoint ap = ANCHOR_MIDDLE) const
119   {
120     Vector v = get_anchor_pos (*this, ap);
121     return ((v - other).norm ());
122   }
123
124   float distance (const Rectf& other, AnchorPoint ap = ANCHOR_MIDDLE) const
125   {
126     Vector v1 = get_anchor_pos (*this, ap);
127     Vector v2 = get_anchor_pos (other, ap);
128
129     return ((v1 - v2).norm ());
130   }
131
132   Rectf grown(float border) const
133   {
134     return Rectf(p1.x - border, p1.y - border,
135                  p2.x + border, p2.y + border);
136   }
137
138   // leave these two public to save the headaches of set/get functions for such
139   // simple things :)
140
141   /// upper left edge
142   Vector p1;
143   /// lower right edge
144   Vector p2;
145 };
146
147 #endif
148
149 /* EOF */