Scroom  0.14
point.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 <cmath>
11 #include <ostream>
12 
13 #include <boost/operators.hpp>
14 
15 #include <gdk/gdk.h>
16 
17 #include <scroom/rounding.hh>
18 
19 namespace Scroom::Utils
20 {
21 
22  template <typename T>
23  class Point
24  : public boost::addable<Point<T>>
25  , public boost::subtractable<Point<T>>
26  , public boost::multipliable2<Point<T>, T>
27  , public boost::dividable2<Point<T>, T>
28  {
29  public:
30  using value_type = T;
31 
32  Point() = default;
33 
34  explicit Point(value_type xy)
35  : Point(xy, xy)
36  {
37  }
38 
40  : x(x_)
41  , y(y_)
42  {
43  }
44 
45  template <typename U>
46  explicit Point(Point<U> other)
47  : x(other.x)
48  , y(other.y)
49  {
50  }
51 
52  explicit Point(const GdkPoint& other)
53  : x(other.x)
54  , y(other.y)
55  {
56  }
57 
58  bool operator==(const Point<value_type>& other) const { return x == other.x && y == other.y; }
59  bool operator!=(const Point<value_type>& other) const { return !(*this == other); }
60 
62  {
63  x += other.x;
64  y += other.y;
65  return *this;
66  }
67 
68  Point<value_type>& operator-=(const Point<value_type>& other) { return *this += -other; }
69 
71  {
72  x *= other;
73  y *= other;
74  return *this;
75  }
76 
78  {
79  x *= other.x;
80  y *= other.y;
81  return *this;
82  }
83 
85  {
86  x /= other;
87  y /= other;
88  return *this;
89  }
90 
92  {
93  x /= other.x;
94  y /= other.y;
95  return *this;
96  }
97 
99 
100  [[nodiscard]] double magnitude() const { return sqrt(x * x + y * y); }
101 
102  template <typename U>
103  [[nodiscard]] Point<U> to() const
104  {
105  return {static_cast<U>(x), static_cast<U>(y)};
106  }
107 
108  [[nodiscard]] GdkPoint toGdkPoint() const { return {static_cast<int>(x), static_cast<int>(y)}; }
109 
110  public:
113  };
114 
115  template <typename T>
117  {
118  return Point<T>(x, y);
119  }
120 
121  template <typename T>
123  {
124  return Point<T>(c, c);
125  }
126 
127  template <typename T>
128  std::ostream& operator<<(std::ostream& os, const Point<T>& p)
129  {
130  return os << '(' << p.x << ',' << p.y << ')';
131  }
132 
133  template <typename T, typename U>
135  {
136  using R = typename std::common_type<T, U>::type;
137 
138  Point<R> result(left);
139  result -= Point<R>(right);
140  return result;
141  }
142 
143  template <typename T, typename U>
145  {
146  using R = typename std::common_type<T, U>::type;
147 
148  Point<R> result(left);
149  result += Point<R>(right);
150  return result;
151  }
152 
153  template <typename T, typename U>
155  {
156  using R = typename std::common_type<T, U>::type;
157 
158  Point<R> result(left);
159  result *= Point<R>(right);
160  return result;
161  }
162 
163  template <typename T, typename U>
165  {
166  using R = typename std::common_type<T, U>::type;
167 
168  Point<R> result(left);
169  result /= Point<R>(right);
170  return result;
171  }
172 
173  template <typename T, typename U>
175  {
176  return make_point(left, left) / right;
177  }
178 
179  template <typename T, typename U>
181  {
182  return left / make_point(right, right);
183  }
184 
185  template <typename T>
187  {
189  return {rounded_divide_by(value.x, factor), rounded_divide_by(value.y, factor)};
190  }
191 
192  template <typename T>
194  {
196  return {ceiled_divide_by(value.x, factor), ceiled_divide_by(value.y, factor)};
197  }
198 
199  template <typename T>
201  {
203  return {floored_divide_by(value.x, factor), floored_divide_by(value.y, factor)};
204  }
205 
206  template <typename T>
208  {
210  return {rounded_divide_by(value.x, factor.x), rounded_divide_by(value.y, factor.y)};
211  }
212 
213  template <typename T>
215  {
217  return {ceiled_divide_by(value.x, factor.x), ceiled_divide_by(value.y, factor.y)};
218  }
219 
220  template <typename T>
222  {
224  return {floored_divide_by(value.x, factor.x), floored_divide_by(value.y, factor.y)};
225  }
226 
227  template <typename T>
229  {
230  using std::ceil;
231  return {ceil(p.x), ceil(p.y)};
232  }
233 
234 } // namespace Scroom::Utils
Scroom::Utils::Point::operator/=
Point< value_type > & operator/=(value_type other)
Definition: point.hh:84
Scroom::Utils::operator+
Point< typename std::common_type< T, U >::type > operator+(Point< T > left, Point< U > right)
Definition: point.hh:144
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::Point::operator*=
Point< value_type > & operator*=(const Point< value_type > &other)
Definition: point.hh:77
Scroom::Utils::Point::operator*=
Point< value_type > & operator*=(value_type other)
Definition: point.hh:70
Scroom::Utils::Point::magnitude
double magnitude() const
Definition: point.hh:100
Scroom::Utils::Point::operator+=
Point< value_type > & operator+=(const Point< value_type > &other)
Definition: point.hh:61
Scroom::Utils::Point::operator-=
Point< value_type > & operator-=(const Point< value_type > &other)
Definition: point.hh:68
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::Point::Point
Point(value_type x_, value_type y_)
Definition: point.hh:39
Scroom::Utils::Point::operator/=
Point< value_type > & operator/=(const Point< value_type > &other)
Definition: point.hh:91
Scroom::Utils::ceil
Point< T > ceil(Point< T > p)
Definition: point.hh:228
Scroom::Utils::Point::to
Point< U > to() const
Definition: point.hh:103
Scroom::Utils::rounded_divide_by
Point< T > rounded_divide_by(Point< T > value, Point< T > factor)
Definition: point.hh:207
Scroom::Utils::Point::operator!=
bool operator!=(const Point< value_type > &other) const
Definition: point.hh:59
Scroom::Utils::ceiled_divide_by
Point< T > ceiled_divide_by(Point< T > value, T factor)
Definition: point.hh:193
Scroom::Utils::Point::Point
Point(Point< U > other)
Definition: point.hh:46
Scroom::Utils::floored_divide_by
Point< T > floored_divide_by(Point< T > value, Point< T > factor)
Definition: point.hh:221
Scroom::Utils::Point::Point
Point(const GdkPoint &other)
Definition: point.hh:52
Scroom::Utils::floored_divide_by
Point< T > floored_divide_by(Point< T > value, T factor)
Definition: point.hh:200
Scroom::Utils::Point::Point
Point(value_type xy)
Definition: point.hh:34
Scroom::Utils::Point< int >::value_type
int value_type
Definition: point.hh:30
Scroom::Utils::rounded_divide_by
Point< T > rounded_divide_by(Point< T > value, T factor)
Definition: point.hh:186
Scroom::Utils::Point::operator==
bool operator==(const Point< value_type > &other) const
Definition: point.hh:58
Scroom::Utils::Point::toGdkPoint
GdkPoint toGdkPoint() const
Definition: point.hh:108
Scroom::Utils::Point::operator-
Point< value_type > operator-() const
Definition: point.hh:98
Scroom::Utils::ceiled_divide_by
Point< T > ceiled_divide_by(Point< T > value, Point< T > factor)
Definition: point.hh:214
Scroom::Utils::operator*
Point< typename std::common_type< T, U >::type > operator*(Point< T > left, Point< U > right)
Definition: point.hh:154
Scroom::Utils::operator<<
std::ostream & operator<<(std::ostream &os, const Segment< T > &s)
Definition: linearsegment.hh:235
Scroom::Utils::Point::y
value_type y
Definition: point.hh:112
Scroom::Utils::Point::Point
Point()=default
Scroom::Utils::operator/
Point< typename std::common_type< T, U >::type > operator/(Point< T > left, Point< U > right)
Definition: point.hh:164
rounding.hh
Scroom::Utils::Point
Definition: point.hh:23