Mir
rectangle.h
Go to the documentation of this file.
1 /*
2  * Copyright © 2021 Canonical Ltd.
3  *
4  * This program is free software: you can redistribute it and/or modify it
5  * under the terms of the GNU Lesser General Public License version 2 or 3,
6  * as published by the Free Software Foundation.
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  * GNU Lesser General Public License for more details.
12  *
13  * You should have received a copy of the GNU Lesser General Public License
14  * along with this program. If not, see <http://www.gnu.org/licenses/>.
15  */
16 
17 #ifndef MIR_GEOMETRY_RECTANGLE_H_
18 #define MIR_GEOMETRY_RECTANGLE_H_
19 
20 #include "forward.h"
21 #include "point.h"
22 #include "size.h"
23 #include "displacement.h"
24 
25 #include <ostream>
26 
27 namespace mir
28 {
29 namespace geometry
30 {
31 namespace generic
32 {
33 template<typename T>
34 struct Rectangle
35 {
36  constexpr Rectangle() = default;
37 
38  constexpr Rectangle(Point<T> const& top_left, Size<T> const& size)
39  : top_left{top_left}, size{size}
40  {
41  }
42 
43  /**
44  * The bottom right boundary point of the rectangle.
45  *
46  * Note that the returned point is *not* included in the rectangle
47  * area, that is, the rectangle is represented as [top_left,bottom_right).
48  */
49  Point<T> bottom_right() const
50  {
51  return top_left + as_displacement(size);
52  }
53 
54  Point<T> top_right() const
55  {
56  return top_left + as_delta(size.width);
57  }
58 
59  Point<T> bottom_left() const
60  {
61  return top_left + as_delta(size.height);
62  }
63 
64  bool contains(Point<T> const& p) const
65  {
66  if (size.width == decltype(size.width){} || size.height == decltype(size.height){})
67  return false;
68 
69  auto br = bottom_right();
70  return p.x >= left() && p.x < br.x &&
71  p.y >= top() && p.y < br.y;
72  }
73 
74  /**
75  * Test if the rectangle contains another.
76  *
77  * Note that an empty rectangle can still contain other empty rectangles,
78  * which are treated as points or lines of thickness zero.
79  */
80  bool contains(Rectangle<T> const& r) const
81  {
82  return r.left() >= left() &&
83  r.left() + as_delta(r.size.width) <= left() + as_delta(size.width) &&
84  r.top() >= top() &&
85  r.top() + as_delta(r.size.height) <= top() + as_delta(size.height);
86  }
87 
88  bool overlaps(Rectangle<T> const& r) const
89  {
90  bool disjoint = r.left() >= right()
91  || r.right() <= left()
92  || r.top() >= bottom()
93  || r.bottom() <= top()
94  || size.width == decltype(size.width){}
95  || size.height == decltype(size.height){}
96  || r.size.width == decltype(r.size.width){}
97  || r.size.height == decltype(r.size.height){};
98  return !disjoint;
99  }
100 
101  X<T> left() const { return top_left.x; }
102  X<T> right() const { return bottom_right().x; }
103  Y<T> top() const { return top_left.y; }
104  Y<T> bottom() const { return bottom_right().y; }
105 
106  Point<T> top_left;
107  Size<T> size;
108 };
109 
110 template<typename T>
111 Rectangle<T> intersection_of(Rectangle<T> const& a, Rectangle<T> const& b)
112 {
113  auto const max_left = std::max(a.left(), b.left());
114  auto const min_right = std::min(a.right(), b.right());
115  auto const max_top = std::max(a.top(), b.top());
116  auto const min_bottom = std::min(a.bottom(), b.bottom());
117 
118  if (max_left < min_right && max_top < min_bottom)
119  return {{max_left, max_top},
120  {(min_right - max_left).as_value(),
121  (min_bottom - max_top).as_value()}};
122  else
123  return {};
124 }
125 
126 template<typename T>
127 inline constexpr bool operator == (Rectangle<T> const& lhs, Rectangle<T> const& rhs)
128 {
129  return lhs.top_left == rhs.top_left && lhs.size == rhs.size;
130 }
131 
132 template<typename T>
133 inline constexpr bool operator != (Rectangle<T> const& lhs, Rectangle<T> const& rhs)
134 {
135  return lhs.top_left != rhs.top_left || lhs.size != rhs.size;
136 }
137 
138 template<typename T>
139 std::ostream& operator<<(std::ostream& out, Rectangle<T> const& value)
140 {
141  out << '(' << value.top_left << ", " << value.size << ')';
142  return out;
143 }
144 }
145 }
146 }
147 
148 #endif // MIR_GEOMETRY_RECTANGLE_H_

Copyright © 2012-2022 Canonical Ltd.
Generated on Thu Sep 8 12:37:23 UTC 2022
This documentation is licensed under the GPL version 2 or 3.