| 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
15 #include "impeller/geometry/scalar.h"
16 #include "impeller/geometry/size.h"
17 #include "impeller/geometry/type_traits.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
327 using Point = TPoint<Scalar>;
328 using IPoint = TPoint<int64_t>;
329 using IPoint32 = TPoint<int32_t>;
330 using UintPoint32 = TPoint<uint32_t>;
331 using Vector2 = Point;
332 using Quad = std::array<Point, 4>;
333
334 #undef ONLY_ON_FLOAT
335 #undef ONLY_ON_FLOAT_M
336
337 } // namespace impeller
338
339 namespace std {
340
341 template <class T>
342 inline std::ostream& operator<<(std::ostream& out,
343 const impeller::TPoint<T>& p) {
344 out << "(" << p.x << ", " << p.y << ")";
345 return out;
346 }
347
348 } // namespace std
349
350 #endif // FLUTTER_IMPELLER_GEOMETRY_POINT_H_
impeller
Definition: allocation.cc:12
impeller::operator-
constexpr Color operator-(T value, const Color &c)
Definition: color.h:902
impeller::Scalar
float Scalar
Definition: scalar.h:18
impeller::operator/
constexpr Color operator/(T value, const Color &c)
Definition: color.h:913
impeller::operator+
constexpr Color operator+(T value, const Color &c)
Definition: color.h:897
impeller::Point
TPoint< Scalar > Point
Definition: point.h:327
impeller::operator*
constexpr Color operator*(T value, const Color &c)
Definition: color.h:908
impeller::Quad
std::array< Point, 4 > Quad
Definition: point.h:332
std
Definition: comparable.h:95
std::operator<<
std::ostream & operator<<(std::ostream &out, const impeller::Color &c)
Definition: color.h:926
ONLY_ON_FLOAT_M
#define ONLY_ON_FLOAT_M(Modifiers, Return)
Definition: point.h:21
scalar.h
size.h
scale
const Scalar scale
Definition: stroke_path_geometry.cc:316
impeller::Radians
Definition: scalar.h:43
impeller::Radians::radians
Scalar radians
Definition: scalar.h:44
impeller::TPoint
Definition: point.h:27
impeller::TPoint::Abs
constexpr TPoint Abs() const
Definition: point.h:216
impeller::TPoint::Round
static constexpr TPoint Round(const TPoint< U > &other)
Definition: point.h:49
impeller::TPoint::Max
constexpr TPoint Max(const TPoint &p) const
Definition: point.h:190
impeller::TPoint::operator/=
TPoint operator/=(U scale)
Definition: point.h:126
impeller::TPoint::operator-=
TPoint operator-=(const TSize< U > &s)
Definition: point.h:84
impeller::TPoint::GetLength
constexpr Type GetLength() const
Definition: point.h:206
impeller::TPoint::operator/
constexpr TPoint operator/(const TSize< U > &s) const
Definition: point.h:176
impeller::TPoint::Ceil
constexpr TPoint Ceil() const
Definition: point.h:196
impeller::TPoint::operator!=
constexpr bool operator!=(const TPoint &p) const
Definition: point.h:58
impeller::TPoint::MakeXY
static constexpr TPoint< Type > MakeXY(Type x, Type y)
Definition: point.h:46
impeller::TPoint::TPoint
constexpr TPoint(Type x, Type y)
Definition: point.h:44
impeller::TPoint::Normalize
constexpr TPoint Normalize() const
Definition: point.h:208
impeller::TPoint::Cross
constexpr Type Cross(const TPoint &p) const
Definition: point.h:218
impeller::TPoint::IsZero
constexpr bool IsZero() const
Definition: point.h:240
impeller::TPoint::GetLengthSquared
constexpr Type GetLengthSquared() const
Definition: point.h:204
impeller::TPoint::GetDistance
constexpr Type GetDistance(const TPoint &p) const
Definition: point.h:200
impeller::TPoint::Lerp
constexpr TPoint Lerp(const TPoint &p, Scalar t) const
Definition: point.h:236
impeller::TPoint::operator+=
TPoint operator+=(const TSize< U > &s)
Definition: point.h:70
impeller::TPoint::operator-
constexpr TPoint operator-(const TPoint &p) const
Definition: point.h:143
impeller::TPoint::operator/
constexpr TPoint operator/(U d) const
Definition: point.h:167
impeller::TPoint::Type
T Type
Definition: point.h:28
impeller::TPoint::Floor
constexpr TPoint Floor() const
Definition: point.h:194
impeller::TPoint::operator*
constexpr TPoint operator*(const TSize< U > &s) const
Definition: point.h:162
impeller::TPoint::TPoint
constexpr TPoint()=default
impeller::TPoint::operator==
constexpr bool operator==(const TPoint &p) const
Definition: point.h:54
impeller::TPoint::operator/
constexpr TPoint operator/(const TPoint &p) const
Definition: point.h:171
impeller::TPoint::operator+
constexpr TPoint operator+(const TSize< U > &s) const
Definition: point.h:139
impeller::TPoint::operator/=
TPoint operator/=(const TPoint< U > &p)
Definition: point.h:112
impeller::TPoint::Round
constexpr TPoint Round() const
Definition: point.h:198
impeller::TPoint::IsFinite
IsFinite() const
Definition: point.h:243
impeller::TPoint::operator+=
TPoint operator+=(const TPoint< U > &p)
Definition: point.h:63
impeller::TPoint::TPoint
constexpr TPoint(const TPoint< U > &other)
Definition: point.h:36
impeller::TPoint::operator-
constexpr TPoint operator-(const TSize< U > &s) const
Definition: point.h:148
impeller::TPoint::Rotate
constexpr TPoint Rotate(const Radians &angle) const
Definition: point.h:226
impeller::TPoint::operator+
constexpr TPoint operator+(const TPoint &p) const
Definition: point.h:134
impeller::TPoint::y
Type y
Definition: point.h:31
impeller::TPoint::x
Type x
Definition: point.h:30
impeller::TPoint::operator*=
TPoint operator*=(const TPoint< U > &p)
Definition: point.h:91
impeller::TPoint::Reflect
constexpr TPoint Reflect(const TPoint &axis) const
Definition: point.h:222
impeller::TPoint::Min
constexpr TPoint Min(const TPoint &p) const
Definition: point.h:186
impeller::TPoint::operator/=
TPoint operator/=(const TSize< U > &s)
Definition: point.h:119
impeller::TPoint::operator-=
TPoint operator-=(const TPoint< U > &p)
Definition: point.h:77
impeller::TPoint::operator-
constexpr TPoint operator-() const
Definition: point.h:132
impeller::TPoint::TPoint
constexpr TPoint(const TSize< U > &other)
Definition: point.h:40
impeller::TPoint::operator*=
TPoint operator*=(U scale)
Definition: point.h:105
impeller::TPoint::Dot
constexpr Type Dot(const TPoint &p) const
Definition: point.h:220
impeller::TPoint::GetDistanceSquared
constexpr Type GetDistanceSquared(const TPoint &p) const
Definition: point.h:180
impeller::TPoint::AngleTo
constexpr Radians AngleTo(const TPoint &p) const
Definition: point.h:232
impeller::TPoint::operator*=
TPoint operator*=(const TSize< U > &s)
Definition: point.h:98
impeller::TPoint::operator*
constexpr TPoint operator*(const TPoint &p) const
Definition: point.h:157
impeller::TPoint::operator*
constexpr TPoint operator*(U scale) const
Definition: point.h:153
impeller::TSize
Definition: size.h:25
impeller::TSize::height
Type height
Definition: size.h:29
impeller::TSize::width
Type width
Definition: size.h:28
type_traits.h