Flutter Impeller
point.h
Go to the documentation of this file.
1 // Copyright 2013 The Flutter Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef FLUTTER_IMPELLER_GEOMETRY_POINT_H_
6 #define FLUTTER_IMPELLER_GEOMETRY_POINT_H_
7 
8 #include <algorithm>
9 #include <cmath>
10 #include <cstdint>
11 #include <ostream>
12 #include <string>
13 #include <type_traits>
14 
16 #include "impeller/geometry/size.h"
18 
19 namespace impeller {
20 
21 #define ONLY_ON_FLOAT_M(Modifiers, Return) \
22  template <typename U = T> \
23  Modifiers std::enable_if_t<std::is_floating_point_v<U>, Return>
24 #define ONLY_ON_FLOAT(Return) DL_ONLY_ON_FLOAT_M(, Return)
25 
26 template <class T>
27 struct TPoint {
28  using Type = T;
29 
30  Type x = {};
31  Type y = {};
32 
33  constexpr TPoint() = default;
34 
35  template <class U>
36  explicit constexpr TPoint(const TPoint<U>& other)
37  : TPoint(static_cast<Type>(other.x), static_cast<Type>(other.y)) {}
38 
39  template <class U>
40  explicit constexpr TPoint(const TSize<U>& other)
41  : TPoint(static_cast<Type>(other.width),
42  static_cast<Type>(other.height)) {}
43 
44  constexpr TPoint(Type x, Type y) : x(x), y(y) {}
45 
46  static constexpr TPoint<Type> MakeXY(Type x, Type y) { return {x, y}; }
47 
48  template <class U>
49  static constexpr TPoint Round(const TPoint<U>& other) {
50  return TPoint{static_cast<Type>(std::round(other.x)),
51  static_cast<Type>(std::round(other.y))};
52  }
53 
54  constexpr bool operator==(const TPoint& p) const {
55  return p.x == x && p.y == y;
56  }
57 
58  constexpr bool operator!=(const TPoint& p) const {
59  return p.x != x || p.y != y;
60  }
61 
62  template <class U>
63  inline TPoint operator+=(const TPoint<U>& p) {
64  x += static_cast<Type>(p.x);
65  y += static_cast<Type>(p.y);
66  return *this;
67  }
68 
69  template <class U>
70  inline TPoint operator+=(const TSize<U>& s) {
71  x += static_cast<Type>(s.width);
72  y += static_cast<Type>(s.height);
73  return *this;
74  }
75 
76  template <class U>
77  inline TPoint operator-=(const TPoint<U>& p) {
78  x -= static_cast<Type>(p.x);
79  y -= static_cast<Type>(p.y);
80  return *this;
81  }
82 
83  template <class U>
84  inline TPoint operator-=(const TSize<U>& s) {
85  x -= static_cast<Type>(s.width);
86  y -= static_cast<Type>(s.height);
87  return *this;
88  }
89 
90  template <class U>
91  inline TPoint operator*=(const TPoint<U>& p) {
92  x *= static_cast<Type>(p.x);
93  y *= static_cast<Type>(p.y);
94  return *this;
95  }
96 
97  template <class U>
98  inline TPoint operator*=(const TSize<U>& s) {
99  x *= static_cast<Type>(s.width);
100  y *= static_cast<Type>(s.height);
101  return *this;
102  }
103 
104  template <class U, class = std::enable_if_t<std::is_arithmetic_v<U>>>
105  inline TPoint operator*=(U scale) {
106  x *= static_cast<Type>(scale);
107  y *= static_cast<Type>(scale);
108  return *this;
109  }
110 
111  template <class U>
112  inline TPoint operator/=(const TPoint<U>& p) {
113  x /= static_cast<Type>(p.x);
114  y /= static_cast<Type>(p.y);
115  return *this;
116  }
117 
118  template <class U>
119  inline TPoint operator/=(const TSize<U>& s) {
120  x /= static_cast<Type>(s.width);
121  y /= static_cast<Type>(s.height);
122  return *this;
123  }
124 
125  template <class U, class = std::enable_if_t<std::is_arithmetic_v<U>>>
126  inline TPoint operator/=(U scale) {
127  x /= static_cast<Type>(scale);
128  y /= static_cast<Type>(scale);
129  return *this;
130  }
131 
132  constexpr TPoint operator-() const { return {-x, -y}; }
133 
134  constexpr TPoint operator+(const TPoint& p) const {
135  return {x + p.x, y + p.y};
136  }
137 
138  template <class U>
139  constexpr TPoint operator+(const TSize<U>& s) const {
140  return {x + static_cast<Type>(s.width), y + static_cast<Type>(s.height)};
141  }
142 
143  constexpr TPoint operator-(const TPoint& p) const {
144  return {x - p.x, y - p.y};
145  }
146 
147  template <class U>
148  constexpr TPoint operator-(const TSize<U>& s) const {
149  return {x - static_cast<Type>(s.width), y - static_cast<Type>(s.height)};
150  }
151 
152  template <class U, class = std::enable_if_t<std::is_arithmetic_v<U>>>
153  constexpr TPoint operator*(U scale) const {
154  return {static_cast<Type>(x * scale), static_cast<Type>(y * scale)};
155  }
156 
157  constexpr TPoint operator*(const TPoint& p) const {
158  return {x * p.x, y * p.y};
159  }
160 
161  template <class U>
162  constexpr TPoint operator*(const TSize<U>& s) const {
163  return {x * static_cast<Type>(s.width), y * static_cast<Type>(s.height)};
164  }
165 
166  template <class U, class = std::enable_if_t<std::is_arithmetic_v<U>>>
167  constexpr TPoint operator/(U d) const {
168  return {static_cast<Type>(x / d), static_cast<Type>(y / d)};
169  }
170 
171  constexpr TPoint operator/(const TPoint& p) const {
172  return {x / p.x, y / p.y};
173  }
174 
175  template <class U>
176  constexpr TPoint operator/(const TSize<U>& s) const {
177  return {x / static_cast<Type>(s.width), y / static_cast<Type>(s.height)};
178  }
179 
180  constexpr Type GetDistanceSquared(const TPoint& p) const {
181  double dx = p.x - x;
182  double dy = p.y - y;
183  return dx * dx + dy * dy;
184  }
185 
186  constexpr TPoint Min(const TPoint& p) const {
187  return {std::min<Type>(x, p.x), std::min<Type>(y, p.y)};
188  }
189 
190  constexpr TPoint Max(const TPoint& p) const {
191  return {std::max<Type>(x, p.x), std::max<Type>(y, p.y)};
192  }
193 
194  constexpr TPoint Floor() const { return {std::floor(x), std::floor(y)}; }
195 
196  constexpr TPoint Ceil() const { return {std::ceil(x), std::ceil(y)}; }
197 
198  constexpr TPoint Round() const { return {std::round(x), std::round(y)}; }
199 
200  constexpr Type GetDistance(const TPoint& p) const {
201  return sqrt(GetDistanceSquared(p));
202  }
203 
204  constexpr Type GetLengthSquared() const { return GetDistanceSquared({}); }
205 
206  constexpr Type GetLength() const { return GetDistance({}); }
207 
208  constexpr TPoint Normalize() const {
209  const auto length = GetLength();
210  if (length == 0) {
211  return {1, 0};
212  }
213  return {x / length, y / length};
214  }
215 
216  constexpr TPoint Abs() const { return {std::fabs(x), std::fabs(y)}; }
217 
218  constexpr Type Cross(const TPoint& p) const { return (x * p.y) - (y * p.x); }
219 
220  constexpr Type Dot(const TPoint& p) const { return (x * p.x) + (y * p.y); }
221 
222  constexpr TPoint Reflect(const TPoint& axis) const {
223  return *this - axis * this->Dot(axis) * 2;
224  }
225 
226  constexpr TPoint Rotate(const Radians& angle) const {
227  const auto cos_a = std::cosf(angle.radians);
228  const auto sin_a = std::sinf(angle.radians);
229  return {x * cos_a - y * sin_a, x * sin_a + y * cos_a};
230  }
231 
232  constexpr Radians AngleTo(const TPoint& p) const {
233  return Radians{std::atan2(this->Cross(p), this->Dot(p))};
234  }
235 
236  constexpr TPoint Lerp(const TPoint& p, Scalar t) const {
237  return *this + (p - *this) * t;
238  }
239 
240  constexpr bool IsZero() const { return x == 0 && y == 0; }
241 
242  ONLY_ON_FLOAT_M(constexpr, bool)
243  IsFinite() const { return std::isfinite(x) && std::isfinite(y); }
244 };
245 
246 // Specializations for mixed (float & integer) algebraic operations.
247 
248 template <class F, class I, class = MixedOp<F, I>>
249 constexpr TPoint<F> operator+(const TPoint<F>& p1, const TPoint<I>& p2) {
250  return {p1.x + static_cast<F>(p2.x), p1.y + static_cast<F>(p2.y)};
251 }
252 
253 template <class F, class I, class = MixedOp<F, I>>
254 constexpr TPoint<F> operator+(const TPoint<I>& p1, const TPoint<F>& p2) {
255  return p2 + p1;
256 }
257 
258 template <class F, class I, class = MixedOp<F, I>>
259 constexpr TPoint<F> operator-(const TPoint<F>& p1, const TPoint<I>& p2) {
260  return {p1.x - static_cast<F>(p2.x), p1.y - static_cast<F>(p2.y)};
261 }
262 
263 template <class F, class I, class = MixedOp<F, I>>
264 constexpr TPoint<F> operator-(const TPoint<I>& p1, const TPoint<F>& p2) {
265  return {static_cast<F>(p1.x) - p2.x, static_cast<F>(p1.y) - p2.y};
266 }
267 
268 template <class F, class I, class = MixedOp<F, I>>
269 constexpr TPoint<F> operator*(const TPoint<F>& p1, const TPoint<I>& p2) {
270  return {p1.x * static_cast<F>(p2.x), p1.y * static_cast<F>(p2.y)};
271 }
272 
273 template <class F, class I, class = MixedOp<F, I>>
274 constexpr TPoint<F> operator*(const TPoint<I>& p1, const TPoint<F>& p2) {
275  return p2 * p1;
276 }
277 
278 template <class F, class I, class = MixedOp<F, I>>
279 constexpr TPoint<F> operator/(const TPoint<F>& p1, const TPoint<I>& p2) {
280  return {p1.x / static_cast<F>(p2.x), p1.y / static_cast<F>(p2.y)};
281 }
282 
283 template <class F, class I, class = MixedOp<F, I>>
284 constexpr TPoint<F> operator/(const TPoint<I>& p1, const TPoint<F>& p2) {
285  return {static_cast<F>(p1.x) / p2.x, static_cast<F>(p1.y) / p2.y};
286 }
287 
288 // RHS algebraic operations with arithmetic types.
289 
290 template <class T, class U, class = std::enable_if_t<std::is_arithmetic_v<U>>>
291 constexpr TPoint<T> operator*(U s, const TPoint<T>& p) {
292  return p * s;
293 }
294 
295 template <class T, class U, class = std::enable_if_t<std::is_arithmetic_v<U>>>
296 constexpr TPoint<T> operator/(U s, const TPoint<T>& p) {
297  return {static_cast<T>(s) / p.x, static_cast<T>(s) / p.y};
298 }
299 
300 // RHS algebraic operations with TSize.
301 
302 template <class T, class U>
303 constexpr TPoint<T> operator+(const TSize<U>& s, const TPoint<T>& p) {
304  return p + s;
305 }
306 
307 template <class T, class U>
308 constexpr TPoint<T> operator-(const TSize<U>& s, const TPoint<T>& p) {
309  return {static_cast<T>(s.width) - p.x, static_cast<T>(s.height) - p.y};
310 }
311 
312 template <class T, class U>
313 constexpr TPoint<T> operator*(const TSize<U>& s, const TPoint<T>& p) {
314  return p * s;
315 }
316 
317 template <class T, class U>
318 constexpr TPoint<T> operator/(const TSize<U>& s, const TPoint<T>& p) {
319  return {static_cast<T>(s.width) / p.x, static_cast<T>(s.height) / p.y};
320 }
321 
322 template <class T>
323 constexpr TPoint<T> operator-(const TPoint<T>& p, T v) {
324  return {p.x - v, p.y - v};
325 }
326 
331 using Vector2 = Point;
332 using Quad = std::array<Point, 4>;
333 
334 [[maybe_unused]]
335 static constexpr impeller::Vector2 kQuadrantAxes[4] = {
336  {1.0f, 0.0f},
337  {0.0f, 1.0f},
338  {-1.0f, 0.0f},
339  {0.0f, -1.0f},
340 };
341 
342 #undef ONLY_ON_FLOAT
343 #undef ONLY_ON_FLOAT_M
344 
345 } // namespace impeller
346 
347 namespace std {
348 
349 template <class T>
350 inline std::ostream& operator<<(std::ostream& out,
351  const impeller::TPoint<T>& p) {
352  out << "(" << p.x << ", " << p.y << ")";
353  return out;
354 }
355 
356 } // namespace std
357 
358 #endif // FLUTTER_IMPELLER_GEOMETRY_POINT_H_
constexpr Color operator-(T value, const Color &c)
Definition: color.h:903
float Scalar
Definition: scalar.h:19
constexpr Color operator/(T value, const Color &c)
Definition: color.h:914
constexpr Color operator+(T value, const Color &c)
Definition: color.h:898
TPoint< Scalar > Point
Definition: point.h:327
static constexpr impeller::Vector2 kQuadrantAxes[4]
Definition: point.h:335
constexpr Color operator*(T value, const Color &c)
Definition: color.h:909
std::array< Point, 4 > Quad
Definition: point.h:332
Definition: comparable.h:95
std::ostream & operator<<(std::ostream &out, const impeller::Arc &a)
Definition: arc.h:141
#define ONLY_ON_FLOAT_M(Modifiers, Return)
Definition: point.h:21
Scalar radians
Definition: scalar.h:45
constexpr TPoint Abs() const
Definition: point.h:216
static constexpr TPoint Round(const TPoint< U > &other)
Definition: point.h:49
constexpr TPoint Max(const TPoint &p) const
Definition: point.h:190
TPoint operator/=(U scale)
Definition: point.h:126
TPoint operator-=(const TSize< U > &s)
Definition: point.h:84
constexpr Type GetLength() const
Definition: point.h:206
constexpr TPoint operator/(const TSize< U > &s) const
Definition: point.h:176
constexpr TPoint Ceil() const
Definition: point.h:196
constexpr bool operator!=(const TPoint &p) const
Definition: point.h:58
static constexpr TPoint< Type > MakeXY(Type x, Type y)
Definition: point.h:46
constexpr TPoint(Type x, Type y)
Definition: point.h:44
constexpr TPoint Normalize() const
Definition: point.h:208
constexpr Type Cross(const TPoint &p) const
Definition: point.h:218
constexpr bool IsZero() const
Definition: point.h:240
constexpr Type GetLengthSquared() const
Definition: point.h:204
constexpr Type GetDistance(const TPoint &p) const
Definition: point.h:200
constexpr TPoint Lerp(const TPoint &p, Scalar t) const
Definition: point.h:236
TPoint operator+=(const TSize< U > &s)
Definition: point.h:70
constexpr TPoint operator-(const TPoint &p) const
Definition: point.h:143
constexpr TPoint operator/(U d) const
Definition: point.h:167
constexpr TPoint Floor() const
Definition: point.h:194
constexpr TPoint operator*(const TSize< U > &s) const
Definition: point.h:162
constexpr TPoint()=default
constexpr bool operator==(const TPoint &p) const
Definition: point.h:54
constexpr TPoint operator/(const TPoint &p) const
Definition: point.h:171
constexpr TPoint operator+(const TSize< U > &s) const
Definition: point.h:139
TPoint operator/=(const TPoint< U > &p)
Definition: point.h:112
constexpr TPoint Round() const
Definition: point.h:198
IsFinite() const
Definition: point.h:243
TPoint operator+=(const TPoint< U > &p)
Definition: point.h:63
constexpr TPoint(const TPoint< U > &other)
Definition: point.h:36
constexpr TPoint operator-(const TSize< U > &s) const
Definition: point.h:148
constexpr TPoint Rotate(const Radians &angle) const
Definition: point.h:226
constexpr TPoint operator+(const TPoint &p) const
Definition: point.h:134
TPoint operator*=(const TPoint< U > &p)
Definition: point.h:91
constexpr TPoint Reflect(const TPoint &axis) const
Definition: point.h:222
constexpr TPoint Min(const TPoint &p) const
Definition: point.h:186
TPoint operator/=(const TSize< U > &s)
Definition: point.h:119
TPoint operator-=(const TPoint< U > &p)
Definition: point.h:77
constexpr TPoint operator-() const
Definition: point.h:132
constexpr TPoint(const TSize< U > &other)
Definition: point.h:40
TPoint operator*=(U scale)
Definition: point.h:105
constexpr Type Dot(const TPoint &p) const
Definition: point.h:220
constexpr Type GetDistanceSquared(const TPoint &p) const
Definition: point.h:180
constexpr Radians AngleTo(const TPoint &p) const
Definition: point.h:232
TPoint operator*=(const TSize< U > &s)
Definition: point.h:98
constexpr TPoint operator*(const TPoint &p) const
Definition: point.h:157
constexpr TPoint operator*(U scale) const
Definition: point.h:153
Type height
Definition: size.h:29
Type width
Definition: size.h:28