supertux
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 #include <iosfwd>
22 
23 #include "math/anchor_point.hpp"
24 #include "math/sizef.hpp"
25 #include "math/vector.hpp"
26 
27 class Rect;
28 
29 class Rectf final
30 {
31 public:
32  static Rectf from_center(const Vector& center, const Sizef& size)
33  {
34  return Rectf(center.x - size.width / 2.0f,
35  center.y - size.height / 2.0f,
36  center.x + size.width / 2.0f,
37  center.y + size.height / 2.0f);
38  }
39 
40 public:
41  Rectf() :
42  m_p1(),
43  m_size()
44  { }
45 
46  Rectf(const Rectf& rhs) = default;
47  Rectf& operator=(const Rectf& rhs) = default;
48 
49  Rectf(const Vector& np1, const Vector& np2) :
50  m_p1(np1), m_size(np2.x - np1.x, np2.y - np1.y)
51  {
52  }
53 
54  Rectf(float x1, float y1, float x2, float y2) :
55  m_p1(x1, y1), m_size(x2 - x1, y2 - y1)
56  {
57  assert(m_size.width >= 0 &&
58  m_size.height >= 0);
59  }
60 
61  Rectf(const Vector& p1, const Sizef& size) :
62  m_p1(p1),
63  m_size(size)
64  {
65  }
66 
67  Rectf(const Rect& rect);
68 
69  bool operator==(const Rectf& other) const
70  {
71  return (m_p1 == other.m_p1 &&
72  m_size == other.m_size);
73  }
74 
75  // This is a temporary hack to pass x/y to ReaderMapping
76  float& get_left() { return m_p1.x; }
77  float& get_top() { return m_p1.y; }
78 
79  float get_left() const { return m_p1.x; }
80  float get_right() const { return m_p1.x + m_size.width; }
81  float get_top() const { return m_p1.y; }
82  float get_bottom() const { return m_p1.y + m_size.height; }
83 
84  float get_width() const { return m_size.width; }
85  float get_height() const { return m_size.height; }
86 
87  void set_left(float v) { m_size.width -= v - m_p1.x; m_p1.x = v; }
88  void set_right(float v) { m_size.width += v - get_right(); }
89 
90  void set_top(float v) { m_size.height -= v - m_p1.y; m_p1.y = v; }
91  void set_bottom(float v) { m_size.height += v - get_bottom(); }
92 
93  Vector get_middle() const { return Vector(m_p1.x + m_size.width / 2.0f,
94  m_p1.y + m_size.height / 2.0f); }
95 
96  void set_pos(const Vector& v) { m_p1 = v; }
97 
98  void set_width(float width) { m_size.width = width; }
99  void set_height(float height) { m_size.height = height; }
100  void set_size(float width, float height) { m_size = Sizef(width, height); }
101  Sizef get_size() const { return m_size; }
102 
103  void move(const Vector& v) { m_p1 += v; }
104  Rectf moved(const Vector& v) const { return Rectf(m_p1 + v, m_size); }
105 
106  bool contains(const Vector& v) const {
107  return v.x >= m_p1.x && v.y >= m_p1.y && v.x < get_right() && v.y < get_bottom();
108  }
109 
110  bool contains(const Rectf& other) const
111  {
112  // FIXME: This is overlaps(), not contains()!
113  if (m_p1.x >= other.get_right() || other.get_left() >= get_right())
114  return false;
115  if (m_p1.y >= other.get_bottom() || other.get_top() >= get_bottom())
116  return false;
117 
118  return true;
119  }
120 
121  float distance (const Vector& other, AnchorPoint ap = ANCHOR_MIDDLE) const
122  {
123  Vector v = get_anchor_pos (*this, ap);
124  return ((v - other).norm ());
125  }
126 
127  float distance (const Rectf& other, AnchorPoint ap = ANCHOR_MIDDLE) const
128  {
129  Vector v1 = get_anchor_pos(*this, ap);
130  Vector v2 = get_anchor_pos(other, ap);
131 
132  return ((v1 - v2).norm ());
133  }
134 
135  Rectf grown(float border) const
136  {
137  return Rectf(m_p1.x - border, m_p1.y - border,
138  get_right() + border, get_bottom() + border);
139  }
140 
141  // leave these two public to save the headaches of set/get functions for such
142  // simple things :)
143 
144  Vector p1() const { return m_p1; }
145  Vector p2() const { return Vector(m_p1.x + m_size.width, m_p1.y + m_size.height); }
146 
147  void set_p1(const Vector& p) {
148  m_size = Sizef(m_size.width + (m_p1.x - p.x),
149  m_size.height + (m_p1.y - p.y));
150  m_p1 = p;
151  }
152  void set_p2(const Vector& p) {
153  m_size = Sizef(p.x - m_p1.x,
154  p.y - m_p1.y);
155  }
156 
157 private:
159  Vector m_p1;
160  Sizef m_size;
161 };
162 
163 std::ostream& operator<<(std::ostream& out, const Rectf& rect);
164 
165 #endif
166 
167 /* EOF */
Simple two dimensional vector.
Definition: vector.hpp:24
Definition: rect.hpp:30
Definition: rectf.hpp:29
Definition: sizef.hpp:26