Scroom  0.14
rectangle.hh
Go to the documentation of this file.
1 /*
2  * Scroom - Generic viewer for 2D data
3  * Copyright (C) 2009-2022 Kees-Jan Dijkzeul
4  *
5  * SPDX-License-Identifier: LGPL-2.1
6  */
7 
8 #pragma once
9 
10 #include <ostream>
11 
12 #include <boost/operators.hpp>
13 
14 #include <scroom/gtk-helpers.hh>
15 #include <scroom/linearsegment.hh>
16 #include <scroom/point.hh>
17 
18 namespace Scroom::Utils
19 {
20 
21  template <typename T>
22  class Rectangle
23  : public boost::addable2<Rectangle<T>, Point<T>>
24  , public boost::subtractable2<Rectangle<T>, Point<T>>
25  , public boost::multipliable2<Rectangle<T>, T>
26  , public boost::multipliable2<Rectangle<T>, Point<T>>
27  , public boost::dividable2<Rectangle<T>, T>
28  , public boost::dividable2<Rectangle<T>, Point<T>>
29  {
30  public:
31  using value_type = T;
32  using xy_type = Point<T>;
33 
34  Rectangle() = default;
35 
37  : horizontally(x_, width_)
38  , vertically(y_, height_)
39  {
40  }
41 
42  Rectangle(const Segment<value_type>& horizontally_, const Segment<value_type>& vertically_)
43  : horizontally(horizontally_)
44  , vertically(vertically_)
45  {
46  }
47 
48  explicit Rectangle(const cairo_rectangle_int_t& rect)
49  : horizontally(rect.x, rect.width)
50  , vertically(rect.y, rect.height)
51  {
52  }
53 
55  template <bool T_is_int = std::is_same<int, typename std::remove_cv<T>::type>::value>
56  explicit Rectangle(typename std::enable_if<!T_is_int, Rectangle<int> const&>::type rect)
58  , vertically(rect.getVertically())
59  {
60  }
61 
62  [[nodiscard]] cairo_rectangle_int_t toGdkRectangle() const
63  {
65  }
66 
67  [[nodiscard]] Rectangle moveTo(xy_type const& other) const { return moveTo(other.x, other.y); }
68 
69  [[nodiscard]] Rectangle moveTo(value_type const& x, value_type const& y) const
70  {
72  }
73 
74  [[nodiscard]] bool contains(xy_type const& other) const
75  {
76  return horizontally.contains(other.x) && vertically.contains(other.y);
77  }
78 
79  [[nodiscard]] bool contains(const Rectangle& other) const
80  {
82  }
83 
84  [[nodiscard]] bool intersects(const Rectangle& other) const
85  {
87  }
88 
90  {
93  }
94 
95  [[nodiscard]] Rectangle intersection(const Rectangle& other) const
96  {
98  }
99 
100  template <typename U>
102  {
103  using R = typename std::common_type<T, U>::type;
104 
105  return Rectangle<R>(*this).intersection(Rectangle<R>(other));
106  }
107 
108  [[nodiscard]] value_type getTop() const { return vertically.getStart(); }
109 
110  [[nodiscard]] value_type getLeft() const { return horizontally.getStart(); }
111 
112  [[nodiscard]] value_type getBottom() const { return vertically.getEnd(); }
113 
114  [[nodiscard]] value_type getRight() const { return horizontally.getEnd(); }
115 
120 
121  [[nodiscard]] value_type getWidth() const { return horizontally.getSize(); }
122 
123  [[nodiscard]] value_type getHeight() const { return vertically.getSize(); }
124 
125  [[nodiscard]] value_type x() const { return getLeft(); }
126 
127  [[nodiscard]] value_type y() const { return getTop(); }
128 
129  [[nodiscard]] value_type width() const { return getWidth(); }
130 
131  [[nodiscard]] value_type height() const { return getHeight(); }
132 
133  [[nodiscard]] xy_type getTopLeft() const { return xy_type(horizontally.getStart(), vertically.getStart()); }
134 
135  [[nodiscard]] xy_type getTopRight() const { return xy_type(horizontally.getEnd(), vertically.getStart()); }
136 
137  [[nodiscard]] xy_type getBottomLeft() const { return xy_type(horizontally.getStart(), vertically.getEnd()); }
138 
139  [[nodiscard]] xy_type getBottomRight() const { return xy_type(horizontally.getEnd(), vertically.getEnd()); }
140 
141  [[nodiscard]] bool isEmpty() const { return horizontally.isEmpty() || vertically.isEmpty(); }
142 
143  [[nodiscard]] Rectangle<value_type> leftOf(value_type v) const
144  {
146  }
147 
148  [[nodiscard]] Rectangle<value_type> rightOf(value_type v) const
149  {
151  }
152 
153  [[nodiscard]] Rectangle<value_type> above(value_type v) const
154  {
156  }
157 
158  [[nodiscard]] Rectangle<value_type> below(value_type v) const
159  {
161  }
162 
163  [[nodiscard]] Rectangle<value_type> leftOf(Rectangle<value_type> const& r) const
164  {
165  if(r.isEmpty())
166  {
167  return r;
168  }
169 
171  }
172 
174  {
175  if(r.isEmpty())
176  {
177  return r;
178  }
179 
181  }
182 
183  [[nodiscard]] Rectangle<value_type> above(Rectangle<value_type> const& r) const
184  {
185  if(r.isEmpty())
186  {
187  return r;
188  }
189 
191  }
192 
193  [[nodiscard]] Rectangle<value_type> below(Rectangle<value_type> const& r) const
194  {
195  if(r.isEmpty())
196  {
197  return r;
198  }
199 
201  }
202 
203  bool operator==(const Rectangle& other) const
204  {
205  if(isEmpty() != other.isEmpty())
206  {
207  return false;
208  }
209 
210  if(isEmpty())
211  {
212  return true;
213  }
214 
215  return horizontally == other.horizontally && vertically == other.vertically;
216  }
217 
218  bool operator!=(const Rectangle& other) const { return !(*this == other); }
219 
221  {
222  horizontally += other.x;
223  vertically += other.y;
224  return *this;
225  }
226 
227  Rectangle<value_type>& operator-=(xy_type const& other) { return *this += -other; }
228 
230  {
231  horizontally *= other;
232  vertically *= other;
233  return *this;
234  }
235 
237  {
238  horizontally *= other.x;
239  vertically *= other.y;
240  return *this;
241  }
242 
244  {
245  horizontally /= other;
246  vertically /= other;
247  return *this;
248  }
249 
251  {
252  horizontally /= other.x;
253  vertically /= other.y;
254  return *this;
255  }
256 
257  [[nodiscard]] const Segment<value_type>& getHorizontally() const { return horizontally; }
258 
259  [[nodiscard]] const Segment<value_type>& getVertically() const { return vertically; }
260 
261  void setSize(xy_type const& s)
262  {
264  vertically.setSize(s.y);
265  }
266 
267  [[nodiscard]] xy_type getSize() const { return xy_type(horizontally.getSize(), vertically.getSize()); }
268 
269  template <typename U>
270  [[nodiscard]] Rectangle<U> to() const
271  {
272  return {
273  horizontally.template to<U>(),
274  vertically.template to<U>(),
275  };
276  }
277 
278  private:
281  };
282 
283  template <typename T>
284  Rectangle<T> make_rect(T x, T y, T width, T height)
285  {
286  return Rectangle<T>(x, y, width, height);
287  }
288 
289  template <typename T>
291  {
292  return Rectangle<T>(position.x, position.y, size.x, size.y);
293  }
294 
295  template <typename T>
297  {
298  return Rectangle<T>(make_segment_from_start_end(start.x, end.x), make_segment_from_start_end(start.y, end.y));
299  }
300 
301  template <typename T>
302  std::ostream& operator<<(std::ostream& os, const Rectangle<T>& r)
303  {
304  os << '<' << r.getLeft() << ',' << r.getTop() << ',' << r.getWidth() << ',' << r.getHeight() << '>';
305 
306  return os;
307  }
308 
309  inline std::ostream& operator<<(std::ostream& os, const cairo_rectangle_int_t& r) { return os << Rectangle<double>(r); }
310 
311  template <typename T, typename U>
313  {
315  result *= static_cast<typename std::common_type<T, U>::type>(right);
316  return result;
317  }
318 
319  template <typename T, typename U>
321  {
322  return right * left;
323  }
324 
325  inline Rectangle<double> operator*(cairo_rectangle_int_t const& r, Point<double> const& p) { return Rectangle<double>(r) * p; }
326 
327  inline Rectangle<double> operator*(Point<double> const& p, cairo_rectangle_int_t const& r) { return Rectangle<double>(r) * p; }
328 
329  template <typename T, typename U>
331  {
332  using R = typename std::common_type<T, U>::type;
333 
334  return Rectangle<R>(left) - Point<R>(right);
335  }
336 
338  {
339  return {
342  };
343  }
344 
346  {
349  }
350 
351  template <typename T>
353  {
355  }
356 
357 
358 } // namespace Scroom::Utils
Scroom::Utils::Rectangle::isEmpty
bool isEmpty() const
Definition: rectangle.hh:141
Scroom::Utils::Rectangle::setSize
void setSize(xy_type const &s)
Definition: rectangle.hh:261
Scroom::Utils::Rectangle::getTopLeft
xy_type getTopLeft() const
Definition: rectangle.hh:133
Scroom::Utils::Rectangle::x
value_type x() const
Definition: rectangle.hh:125
Scroom::Utils::Rectangle::xy_type
Point< T > xy_type
Definition: rectangle.hh:32
Scroom::Utils
Definition: assertions.hh:14
Scroom::Utils::operator-
Point< typename std::common_type< T, U >::type > operator-(Point< T > left, Point< U > right)
Definition: point.hh:134
Scroom::Utils::Rectangle::above
Rectangle< value_type > above(Rectangle< value_type > const &r) const
Definition: rectangle.hh:183
Scroom::Utils::Rectangle::rightOf
Rectangle< value_type > rightOf(value_type v) const
Definition: rectangle.hh:148
Scroom::Utils::Rectangle::width
value_type width() const
Definition: rectangle.hh:129
Scroom::Utils::Rectangle::operator/=
Rectangle< value_type > & operator/=(value_type other)
Definition: rectangle.hh:243
Scroom::Utils::Rectangle::getVertically
const Segment< value_type > & getVertically() const
Definition: rectangle.hh:259
Scroom::Utils::Rectangle::intersection
Rectangle< typename std::common_type< T, U >::type > intersection(const Rectangle< U > &other) const
Definition: rectangle.hh:101
Scroom::Utils::Rectangle::operator-=
Rectangle< value_type > & operator-=(xy_type const &other)
Definition: rectangle.hh:227
point.hh
Scroom::Utils::Rectangle::below
Rectangle< value_type > below(Rectangle< value_type > const &r) const
Definition: rectangle.hh:193
Scroom::Utils::Rectangle::vertically
Segment< value_type > vertically
Definition: rectangle.hh:280
Scroom::Utils::Rectangle::setRight
void setRight(value_type v)
Definition: rectangle.hh:119
Scroom::Utils::Rectangle::Rectangle
Rectangle(value_type x_, value_type y_, value_type width_, value_type height_)
Definition: rectangle.hh:36
Scroom::Utils::roundCorners
Rectangle< double > roundCorners(Rectangle< double > r)
Definition: rectangle.hh:345
Scroom::Utils::Rectangle::getBottom
value_type getBottom() const
Definition: rectangle.hh:112
Scroom::Utils::Rectangle::getBottomLeft
xy_type getBottomLeft() const
Definition: rectangle.hh:137
Scroom::Utils::Rectangle::operator/=
Rectangle< value_type > & operator/=(xy_type const &other)
Definition: rectangle.hh:250
Scroom::Utils::Segment::contains
bool contains(value_type p) const
Definition: linearsegment.hh:77
Scroom::Utils::Rectangle::to
Rectangle< U > to() const
Definition: rectangle.hh:270
Scroom::Utils::Rectangle::intersection
Rectangle intersection(const Rectangle &other) const
Definition: rectangle.hh:95
Scroom::Utils::Rectangle::operator==
bool operator==(const Rectangle &other) const
Definition: rectangle.hh:203
Scroom::Utils::Rectangle::Rectangle
Rectangle(const Segment< value_type > &horizontally_, const Segment< value_type > &vertically_)
Definition: rectangle.hh:42
Scroom::Utils::make_rect
Rectangle< T > make_rect(T x, T y, T width, T height)
Definition: rectangle.hh:284
Scroom::Utils::Rectangle::getHeight
value_type getHeight() const
Definition: rectangle.hh:123
Scroom::Utils::Point::x
value_type x
Definition: point.hh:111
Scroom::Utils::make_point
Point< T > make_point(T x, T y)
Definition: point.hh:116
Scroom::Utils::Segment::getEnd
value_type getEnd() const
Definition: linearsegment.hh:135
Scroom::Utils::make_segment_from_start_end
Segment< T > make_segment_from_start_end(T start, T end)
Definition: linearsegment.hh:229
Scroom::Utils::Rectangle::operator*=
Rectangle< value_type > & operator*=(xy_type const &other)
Definition: rectangle.hh:236
Scroom::Utils::Rectangle::intersects
bool intersects(const Rectangle &other) const
Definition: rectangle.hh:84
Scroom::Utils::Rectangle::moveTo
Rectangle moveTo(value_type const &x, value_type const &y) const
Definition: rectangle.hh:69
Scroom::Utils::Rectangle::operator!=
bool operator!=(const Rectangle &other) const
Definition: rectangle.hh:218
Scroom::Utils::Rectangle::Rectangle
Rectangle(const cairo_rectangle_int_t &rect)
Definition: rectangle.hh:48
Scroom::Utils::Rectangle::setLeft
void setLeft(value_type v)
Definition: rectangle.hh:117
Scroom::Utils::Rectangle::leftOf
Rectangle< value_type > leftOf(Rectangle< value_type > const &r) const
Definition: rectangle.hh:163
Scroom::Utils::Segment::setSize
void setSize(value_type n)
Definition: linearsegment.hh:191
Scroom::Utils::Rectangle::moveTo
Rectangle moveTo(xy_type const &other) const
Definition: rectangle.hh:67
Scroom::Utils::Rectangle< int >::value_type
int value_type
Definition: rectangle.hh:31
Scroom::Utils::Rectangle::getBottomRight
xy_type getBottomRight() const
Definition: rectangle.hh:139
Scroom::Utils::Rectangle::contains
bool contains(const Rectangle &other) const
Definition: rectangle.hh:79
Scroom::Utils::Rectangle::below
Rectangle< value_type > below(value_type v) const
Definition: rectangle.hh:158
Scroom::Utils::Rectangle::getSize
xy_type getSize() const
Definition: rectangle.hh:267
Scroom::Utils::Rectangle::getWidth
value_type getWidth() const
Definition: rectangle.hh:121
Scroom::Utils::Segment::intersects
bool intersects(const Segment< value_type > &other) const
Definition: linearsegment.hh:84
Scroom::Utils::Rectangle::Rectangle
Rectangle()=default
Scroom::Utils::Rectangle::getRight
value_type getRight() const
Definition: rectangle.hh:114
round_to_multiple_of
T round_to_multiple_of(T value, T factor)
Definition: rounding.hh:32
Scroom::Utils::Rectangle::setTop
void setTop(value_type v)
Definition: rectangle.hh:116
Scroom::Utils::make_rect_from_start_end
Rectangle< T > make_rect_from_start_end(Point< T > start, Point< T > end)
Definition: rectangle.hh:296
Scroom::Utils::Rectangle::Rectangle
Rectangle(typename std::enable_if<!T_is_int, Rectangle< int > const & >::type rect)
Definition: rectangle.hh:56
Scroom::Utils::Rectangle::horizontally
Segment< value_type > horizontally
Definition: rectangle.hh:279
Scroom::Utils::Rectangle::getLeft
value_type getLeft() const
Definition: rectangle.hh:110
Scroom::Utils::Rectangle::contains
bool contains(xy_type const &other) const
Definition: rectangle.hh:74
Scroom::Utils::Segment< value_type >
Scroom::Utils::Rectangle::getTopRight
xy_type getTopRight() const
Definition: rectangle.hh:135
Scroom::Utils::Segment::reduceSizeToMultipleOf
void reduceSizeToMultipleOf(value_type m)
Definition: linearsegment.hh:89
Scroom::Utils::Rectangle::getHorizontally
const Segment< value_type > & getHorizontally() const
Definition: rectangle.hh:257
Scroom::Utils::Rectangle::height
value_type height() const
Definition: rectangle.hh:131
gtk-helpers.hh
Scroom::Utils::Rectangle::above
Rectangle< value_type > above(value_type v) const
Definition: rectangle.hh:153
Scroom::Utils::Rectangle::toGdkRectangle
cairo_rectangle_int_t toGdkRectangle() const
Definition: rectangle.hh:62
Scroom::Utils::Segment::moveTo
Segment moveTo(value_type p) const
Definition: linearsegment.hh:75
Scroom::Utils::Segment::intersection
Segment< value_type > intersection(const Segment< value_type > &other) const
Definition: linearsegment.hh:91
Scroom::Utils::Segment::setEnd
void setEnd(value_type n)
Definition: linearsegment.hh:192
Scroom::Utils::Rectangle::y
value_type y() const
Definition: rectangle.hh:127
Scroom::Utils::Rectangle::operator*=
Rectangle< value_type > & operator*=(value_type other)
Definition: rectangle.hh:229
Scroom::Utils::center
T center(Segment< T > s)
Definition: linearsegment.hh:246
Scroom::Utils::operator*
Point< typename std::common_type< T, U >::type > operator*(Point< T > left, Point< U > right)
Definition: point.hh:154
Scroom::Utils::Segment::getStart
value_type getStart() const
Definition: linearsegment.hh:133
linearsegment.hh
Scroom::Utils::Rectangle::setBottom
void setBottom(value_type v)
Definition: rectangle.hh:118
Scroom::Utils::Rectangle::rightOf
Rectangle< value_type > rightOf(Rectangle< value_type > const &r) const
Definition: rectangle.hh:173
Scroom::Utils::Rectangle
Definition: rectangle.hh:22
Scroom::Utils::operator<<
std::ostream & operator<<(std::ostream &os, const Segment< T > &s)
Definition: linearsegment.hh:235
Scroom::Utils::roundOutward
Segment< double > roundOutward(Segment< double > s)
Definition: linearsegment.hh:240
Scroom::GtkHelpers::createCairoIntRectangle
cairo_rectangle_int_t createCairoIntRectangle(int x, int y, int width, int height)
Definition: gtk-helpers.hh:71
Scroom::Utils::Segment::isEmpty
bool isEmpty() const
Definition: linearsegment.hh:139
Scroom::Utils::Rectangle::getTop
value_type getTop() const
Definition: rectangle.hh:108
Scroom::Utils::Rectangle::leftOf
Rectangle< value_type > leftOf(value_type v) const
Definition: rectangle.hh:143
Scroom::Utils::Segment::getSize
value_type getSize() const
Definition: linearsegment.hh:137
Scroom::Utils::Point::y
value_type y
Definition: point.hh:112
Scroom::Utils::Rectangle::operator+=
Rectangle< value_type > & operator+=(xy_type const &other)
Definition: rectangle.hh:220
Scroom::Utils::Segment::before
Segment< value_type > before(value_type v) const
Definition: linearsegment.hh:107
Scroom::Utils::Rectangle::reduceSizeToMultipleOf
void reduceSizeToMultipleOf(value_type size)
Definition: rectangle.hh:89
Scroom::Utils::Segment::after
Segment< value_type > after(value_type v) const
Definition: linearsegment.hh:120
Scroom::Utils::Point< int >
Scroom::Utils::Segment::setStart
void setStart(value_type n)
Definition: linearsegment.hh:185