Flutter Engine Uber Docs
Docs for the entire Flutter Engine repo.
 
Loading...
Searching...
No Matches
point.h File Reference
#include <algorithm>
#include <cmath>
#include <cstdint>
#include <ostream>
#include <string>
#include <type_traits>
#include "fml/logging.h"
#include "impeller/geometry/scalar.h"
#include "impeller/geometry/size.h"
#include "impeller/geometry/type_traits.h"

Go to the source code of this file.

Classes

struct  impeller::TPoint< T >
 

Namespaces

namespace  impeller
 
namespace  std
 

Macros

#define ONLY_ON_FLOAT_M(Modifiers, Return)
 
#define ONLY_ON_FLOAT(Return)   DL_ONLY_ON_FLOAT_M(, Return)
 

Typedefs

using impeller::Point = TPoint< Scalar >
 
using impeller::IPoint = TPoint< int64_t >
 
using impeller::IPoint32 = TPoint< int32_t >
 
using impeller::UintPoint32 = TPoint< uint32_t >
 
using impeller::Vector2 = Point
 
using impeller::Quad = std::array< Point, 4 >
 

Functions

template<class F , class I , class = MixedOp<F, I>>
constexpr TPoint< F > impeller::operator+ (const TPoint< F > &p1, const TPoint< I > &p2)
 
template<class F , class I , class = MixedOp<F, I>>
constexpr TPoint< F > impeller::operator+ (const TPoint< I > &p1, const TPoint< F > &p2)
 
template<class F , class I , class = MixedOp<F, I>>
constexpr TPoint< F > impeller::operator- (const TPoint< F > &p1, const TPoint< I > &p2)
 
template<class F , class I , class = MixedOp<F, I>>
constexpr TPoint< F > impeller::operator- (const TPoint< I > &p1, const TPoint< F > &p2)
 
template<class F , class I , class = MixedOp<F, I>>
constexpr TPoint< F > impeller::operator* (const TPoint< F > &p1, const TPoint< I > &p2)
 
template<class F , class I , class = MixedOp<F, I>>
constexpr TPoint< F > impeller::operator* (const TPoint< I > &p1, const TPoint< F > &p2)
 
template<class F , class I , class = MixedOp<F, I>>
constexpr TPoint< F > impeller::operator/ (const TPoint< F > &p1, const TPoint< I > &p2)
 
template<class F , class I , class = MixedOp<F, I>>
constexpr TPoint< F > impeller::operator/ (const TPoint< I > &p1, const TPoint< F > &p2)
 
template<class T , class U , class = std::enable_if_t<std::is_arithmetic_v<U>>>
constexpr TPoint< T > impeller::operator* (U s, const TPoint< T > &p)
 
template<class T , class U , class = std::enable_if_t<std::is_arithmetic_v<U>>>
constexpr TPoint< T > impeller::operator/ (U s, const TPoint< T > &p)
 
template<class T , class U >
constexpr TPoint< T > impeller::operator+ (const TSize< U > &s, const TPoint< T > &p)
 
template<class T , class U >
constexpr TPoint< T > impeller::operator- (const TSize< U > &s, const TPoint< T > &p)
 
template<class T , class U >
constexpr TPoint< T > impeller::operator* (const TSize< U > &s, const TPoint< T > &p)
 
template<class T , class U >
constexpr TPoint< T > impeller::operator/ (const TSize< U > &s, const TPoint< T > &p)
 
template<class T >
constexpr TPoint< T > impeller::operator- (const TPoint< T > &p, T v)
 
template<class T >
std::ostream & std::operator<< (std::ostream &out, const impeller::TPoint< T > &p)
 

Variables

static constexpr impeller::Vector2 impeller::kQuadrantAxes [4]
 

Macro Definition Documentation

◆ ONLY_ON_FLOAT

#define ONLY_ON_FLOAT (   Return)    DL_ONLY_ON_FLOAT_M(, Return)

Definition at line 25 of file point.h.

◆ ONLY_ON_FLOAT_M

#define ONLY_ON_FLOAT_M (   Modifiers,
  Return 
)
Value:
template <typename U = T> \
Modifiers std::enable_if_t<std::is_floating_point_v<U>, Return>

Definition at line 22 of file point.h.

28 {
29 using Type = T;
30
31 Type x = {};
32 Type y = {};
33
34 constexpr TPoint() = default;
35
36 template <class U>
37 explicit constexpr TPoint(const TPoint<U>& other)
38 : TPoint(static_cast<Type>(other.x), static_cast<Type>(other.y)) {}
39
40 template <class U>
41 explicit constexpr TPoint(const TSize<U>& other)
42 : TPoint(static_cast<Type>(other.width),
43 static_cast<Type>(other.height)) {}
44
45 constexpr TPoint(Type x, Type y) : x(x), y(y) {}
46
47 static constexpr TPoint<Type> MakeXY(Type x, Type y) { return {x, y}; }
48
49 template <class U>
50 static constexpr TPoint Round(const TPoint<U>& other) {
51 return TPoint{static_cast<Type>(std::round(other.x)),
52 static_cast<Type>(std::round(other.y))};
53 }
54
55 constexpr bool operator==(const TPoint& p) const {
56 return p.x == x && p.y == y;
57 }
58
59 constexpr bool operator!=(const TPoint& p) const {
60 return p.x != x || p.y != y;
61 }
62
63 template <class U>
64 inline TPoint operator+=(const TPoint<U>& p) {
65 x += static_cast<Type>(p.x);
66 y += static_cast<Type>(p.y);
67 return *this;
68 }
69
70 template <class U>
71 inline TPoint operator+=(const TSize<U>& s) {
72 x += static_cast<Type>(s.width);
73 y += static_cast<Type>(s.height);
74 return *this;
75 }
76
77 template <class U>
78 inline TPoint operator-=(const TPoint<U>& p) {
79 x -= static_cast<Type>(p.x);
80 y -= static_cast<Type>(p.y);
81 return *this;
82 }
83
84 template <class U>
85 inline TPoint operator-=(const TSize<U>& s) {
86 x -= static_cast<Type>(s.width);
87 y -= static_cast<Type>(s.height);
88 return *this;
89 }
90
91 template <class U>
92 inline TPoint operator*=(const TPoint<U>& p) {
93 x *= static_cast<Type>(p.x);
94 y *= static_cast<Type>(p.y);
95 return *this;
96 }
97
98 template <class U>
99 inline TPoint operator*=(const TSize<U>& s) {
100 x *= static_cast<Type>(s.width);
101 y *= static_cast<Type>(s.height);
102 return *this;
103 }
104
105 template <class U, class = std::enable_if_t<std::is_arithmetic_v<U>>>
106 inline TPoint operator*=(U scale) {
107 x *= static_cast<Type>(scale);
108 y *= static_cast<Type>(scale);
109 return *this;
110 }
111
112 template <class U>
113 inline TPoint operator/=(const TPoint<U>& p) {
114 x /= static_cast<Type>(p.x);
115 y /= static_cast<Type>(p.y);
116 return *this;
117 }
118
119 template <class U>
120 inline TPoint operator/=(const TSize<U>& s) {
121 x /= static_cast<Type>(s.width);
122 y /= static_cast<Type>(s.height);
123 return *this;
124 }
125
126 template <class U, class = std::enable_if_t<std::is_arithmetic_v<U>>>
127 inline TPoint operator/=(U scale) {
128 x /= static_cast<Type>(scale);
129 y /= static_cast<Type>(scale);
130 return *this;
131 }
132
133 constexpr TPoint operator-() const { return {-x, -y}; }
134
135 constexpr TPoint operator+(const TPoint& p) const {
136 return {x + p.x, y + p.y};
137 }
138
139 template <class U>
140 constexpr TPoint operator+(const TSize<U>& s) const {
141 return {x + static_cast<Type>(s.width), y + static_cast<Type>(s.height)};
142 }
143
144 constexpr TPoint operator-(const TPoint& p) const {
145 return {x - p.x, y - p.y};
146 }
147
148 template <class U>
149 constexpr TPoint operator-(const TSize<U>& s) const {
150 return {x - static_cast<Type>(s.width), y - static_cast<Type>(s.height)};
151 }
152
153 template <class U, class = std::enable_if_t<std::is_arithmetic_v<U>>>
154 constexpr TPoint operator*(U scale) const {
155 return {static_cast<Type>(x * scale), static_cast<Type>(y * scale)};
156 }
157
158 constexpr TPoint operator*(const TPoint& p) const {
159 return {x * p.x, y * p.y};
160 }
161
162 template <class U>
163 constexpr TPoint operator*(const TSize<U>& s) const {
164 return {x * static_cast<Type>(s.width), y * static_cast<Type>(s.height)};
165 }
166
167 template <class U, class = std::enable_if_t<std::is_arithmetic_v<U>>>
168 constexpr TPoint operator/(U d) const {
169 return {static_cast<Type>(x / d), static_cast<Type>(y / d)};
170 }
171
172 constexpr TPoint operator/(const TPoint& p) const {
173 return {x / p.x, y / p.y};
174 }
175
176 template <class U>
177 constexpr TPoint operator/(const TSize<U>& s) const {
178 return {x / static_cast<Type>(s.width), y / static_cast<Type>(s.height)};
179 }
180
181 constexpr Type GetDistanceSquared(const TPoint& p) const {
182 double dx = p.x - x;
183 double dy = p.y - y;
184 return dx * dx + dy * dy;
185 }
186
187 constexpr TPoint Min(const TPoint& p) const {
188 return {std::min<Type>(x, p.x), std::min<Type>(y, p.y)};
189 }
190
191 constexpr TPoint Max(const TPoint& p) const {
192 return {std::max<Type>(x, p.x), std::max<Type>(y, p.y)};
193 }
194
195 constexpr TPoint Floor() const { return {std::floor(x), std::floor(y)}; }
196
197 constexpr TPoint Ceil() const { return {std::ceil(x), std::ceil(y)}; }
198
199 constexpr TPoint Round() const { return {std::round(x), std::round(y)}; }
200
201 constexpr Type GetDistance(const TPoint& p) const {
202 return sqrt(GetDistanceSquared(p));
203 }
204
205 constexpr Type GetLengthSquared() const {
206 return static_cast<double>(x) * x + static_cast<double>(y) * y;
207 }
208
209 constexpr Type GetLength() const { return std::sqrt(GetLengthSquared()); }
210
211 /// Returns the distance (squared) from this point to the closest point on
212 /// the line segment p0 -> p1.
213 ///
214 /// If the projection of this point onto the line defined by the two points
215 /// is between them, the distance (squared) to that point is returned.
216 /// Otherwise, we return the distance (squared) to the endpoint that is
217 /// closer to the projected point.
218 Type GetDistanceToSegmentSquared(TPoint p0, TPoint p1) const {
219 // Compute relative vectors to one endpoint of the segment (p0)
220 TPoint u = p1 - p0;
221 TPoint v = *this - p0;
222
223 // Compute the projection of (this point) onto p0->p1.
224 Scalar dot = u.Dot(v);
225 if (dot <= 0) {
226 // The projection lands outside the segment on the p0 side.
227 // The result is the (square of the) distance to p0 (length of v).
228 return v.GetLengthSquared();
229 }
230
231 // The dot product is the product of the length of the two vectors
232 // ||u|| and ||v|| and the cosine of the angle between them. The length
233 // of the v vector times the cosine is the same as the length of
234 // the projection of the v vector onto the u vector (consider a right
235 // triangle [(0,0), v, v_projected], the length of v multipled by the
236 // cosine is the length of v_projected).
237 //
238 // Thus the dot product is also the product of the u vector and the
239 // projected shadow of the v vector onto the u vector.
240 //
241 // So, if the dot product is larger than the square of the length of
242 // the u vector, then the v vector was projected onto the line beyond
243 // the end of the u vector and so we can use the distance formula to
244 // that endpoint as our result.
245 Scalar uLengthSquared = u.GetLengthSquared();
246 if (dot >= uLengthSquared) {
247 // The projection lands outside the segment on the p1 side.
248 // The result is the (square of the) distance to p1.
249 return GetDistanceSquared(p1);
250 }
251
252 // We must now compute the distance from this point to its projection
253 // on to the segment.
254 //
255 // We compute the cross product of the two vectors u and v which
256 // gives us the area of the parallelogram [(0,0), u, u+v, v]. That
257 // parallelogram area is also the product of the length of one of its
258 // sides and the height perpendicular to that side. We have the length
259 // of one side which is the length of the segment itself (squared) as
260 // uLengthSquared, so if we divide the parallelogram area (squared)
261 // by uLengthSquared then we will get its height (squared) relative to u.
262 //
263 // That height is also the distance from this point to the line segment.
264 Scalar cross = u.Cross(v);
265 // The cross product may currently be signed, but we will square it later.
266
267 // To get our height (squared), we want to compute:
268 // result^2 == h^2 == (cross * cross / uLengthSquared)
269 //
270 // We reorder the equation slightly to avoid infinities:
271 return (cross / uLengthSquared) * cross;
272 }
273
274 /// Returns the distance from this point to the closest point on the line
275 /// segment p0 -> p1.
276 ///
277 /// If the projection of this point onto the line defined by the two points
278 /// is between them, the distance to that point is returned. Otherwise,
279 /// we return the distance to the endpoint that is closer to the projected
280 /// point.
281 constexpr Type GetDistanceToSegment(TPoint p0, TPoint p1) const {
282 return std::sqrt(GetDistanceToSegmentSquared(p0, p1));
283 }
284
285 constexpr TPoint Normalize() const {
286 const auto length = GetLength();
287 if (length == 0) {
288 return {1, 0};
289 }
290 return {x / length, y / length};
291 }
292
293 constexpr TPoint Abs() const { return {std::fabs(x), std::fabs(y)}; }
294
295 constexpr Type Cross(const TPoint& p) const { return (x * p.y) - (y * p.x); }
296
297 /// Return the cross product representing the sign (turning direction) and
298 /// magnitude (sin of the angle) of the angle from p1 to p2 as viewed from
299 /// p0.
300 ///
301 /// Equivalent to ((p1 - p0).Cross(p2 - p0)).
302 static constexpr Type Cross(const TPoint& p0,
303 const TPoint& p1,
304 const TPoint& p2) {
305 return (p1 - p0).Cross(p2 - p0);
306 }
307
308 constexpr Type Dot(const TPoint& p) const { return (x * p.x) + (y * p.y); }
309
310 constexpr TPoint Reflect(const TPoint& axis) const {
311 return *this - axis * this->Dot(axis) * 2;
312 }
313
314 constexpr TPoint Rotate(const Radians& angle) const {
315 const auto cos_a = std::cosf(angle.radians);
316 const auto sin_a = std::sinf(angle.radians);
317 return {x * cos_a - y * sin_a, x * sin_a + y * cos_a};
318 }
319
320 /// Return the perpendicular vector turning to the right (Clockwise)
321 /// in the logical coordinate system where X increases to the right and Y
322 /// increases downward.
323 constexpr TPoint PerpendicularRight() const { return {-y, x}; }
324
325 /// Return the perpendicular vector turning to the left (Counterclockwise)
326 /// in the logical coordinate system where X increases to the right and Y
327 /// increases downward.
328 constexpr TPoint PerpendicularLeft() const { return {y, -x}; }
329
330 constexpr Radians AngleTo(const TPoint& p) const {
331 return Radians{std::atan2(this->Cross(p), this->Dot(p))};
332 }
333
334 constexpr TPoint Lerp(const TPoint& p, Scalar t) const {
335 return *this + (p - *this) * t;
336 }
337
338 constexpr bool IsZero() const { return x == 0 && y == 0; }
339
340 ONLY_ON_FLOAT_M(constexpr, bool)
341 IsFinite() const { return std::isfinite(x) && std::isfinite(y); }
342};
343
344// Specializations for mixed (float & integer) algebraic operations.
345
346template <class F, class I, class = MixedOp<F, I>>
347constexpr TPoint<F> operator+(const TPoint<F>& p1, const TPoint<I>& p2) {
348 return {p1.x + static_cast<F>(p2.x), p1.y + static_cast<F>(p2.y)};
349}
350
351template <class F, class I, class = MixedOp<F, I>>
352constexpr TPoint<F> operator+(const TPoint<I>& p1, const TPoint<F>& p2) {
353 return p2 + p1;
354}
355
356template <class F, class I, class = MixedOp<F, I>>
357constexpr TPoint<F> operator-(const TPoint<F>& p1, const TPoint<I>& p2) {
358 return {p1.x - static_cast<F>(p2.x), p1.y - static_cast<F>(p2.y)};
359}
360
361template <class F, class I, class = MixedOp<F, I>>
362constexpr TPoint<F> operator-(const TPoint<I>& p1, const TPoint<F>& p2) {
363 return {static_cast<F>(p1.x) - p2.x, static_cast<F>(p1.y) - p2.y};
364}
365
366template <class F, class I, class = MixedOp<F, I>>
367constexpr TPoint<F> operator*(const TPoint<F>& p1, const TPoint<I>& p2) {
368 return {p1.x * static_cast<F>(p2.x), p1.y * static_cast<F>(p2.y)};
369}
370
371template <class F, class I, class = MixedOp<F, I>>
372constexpr TPoint<F> operator*(const TPoint<I>& p1, const TPoint<F>& p2) {
373 return p2 * p1;
374}
375
376template <class F, class I, class = MixedOp<F, I>>
377constexpr TPoint<F> operator/(const TPoint<F>& p1, const TPoint<I>& p2) {
378 return {p1.x / static_cast<F>(p2.x), p1.y / static_cast<F>(p2.y)};
379}
380
381template <class F, class I, class = MixedOp<F, I>>
382constexpr TPoint<F> operator/(const TPoint<I>& p1, const TPoint<F>& p2) {
383 return {static_cast<F>(p1.x) / p2.x, static_cast<F>(p1.y) / p2.y};
384}
385
386// RHS algebraic operations with arithmetic types.
387
388template <class T, class U, class = std::enable_if_t<std::is_arithmetic_v<U>>>
389constexpr TPoint<T> operator*(U s, const TPoint<T>& p) {
390 return p * s;
391}
392
393template <class T, class U, class = std::enable_if_t<std::is_arithmetic_v<U>>>
394constexpr TPoint<T> operator/(U s, const TPoint<T>& p) {
395 return {static_cast<T>(s) / p.x, static_cast<T>(s) / p.y};
396}
397
398// RHS algebraic operations with TSize.
399
400template <class T, class U>
401constexpr TPoint<T> operator+(const TSize<U>& s, const TPoint<T>& p) {
402 return p + s;
403}
404
405template <class T, class U>
406constexpr TPoint<T> operator-(const TSize<U>& s, const TPoint<T>& p) {
407 return {static_cast<T>(s.width) - p.x, static_cast<T>(s.height) - p.y};
408}
409
410template <class T, class U>
411constexpr TPoint<T> operator*(const TSize<U>& s, const TPoint<T>& p) {
412 return p * s;
413}
414
415template <class T, class U>
416constexpr TPoint<T> operator/(const TSize<U>& s, const TPoint<T>& p) {
417 return {static_cast<T>(s.width) / p.x, static_cast<T>(s.height) / p.y};
418}
419
420template <class T>
421constexpr TPoint<T> operator-(const TPoint<T>& p, T v) {
422 return {p.x - v, p.y - v};
423}
424
425using Point = TPoint<Scalar>;
426using IPoint = TPoint<int64_t>;
427using IPoint32 = TPoint<int32_t>;
428using UintPoint32 = TPoint<uint32_t>;
429using Vector2 = Point;
430using Quad = std::array<Point, 4>;
431
432[[maybe_unused]]
433static constexpr impeller::Vector2 kQuadrantAxes[4] = {
434 {1.0f, 0.0f},
435 {0.0f, 1.0f},
436 {-1.0f, 0.0f},
437 {0.0f, -1.0f},
438};
439
440#undef ONLY_ON_FLOAT
441#undef ONLY_ON_FLOAT_M
442
443} // namespace impeller
444
445namespace std {
446
447template <class T>
448inline std::ostream& operator<<(std::ostream& out,
449 const impeller::TPoint<T>& p) {
450 out << "(" << p.x << ", " << p.y << ")";
451 return out;
452}
453
454} // namespace std
455
456#endif // FLUTTER_IMPELLER_GEOMETRY_POINT_H_
int32_t x
bool operator==(const FlutterPoint &a, const FlutterPoint &b)
auto & d
Definition main.cc:28
#define ONLY_ON_FLOAT_M(Modifiers, Return)
Definition point.h:22
size_t length
double y
bool operator!=(const T &value, const UniqueObject< T, Traits > &object)
Point Vector2
Definition point.h:429
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:425
TPoint< int32_t > IPoint32
Definition point.h:427
TPoint< int64_t > IPoint
Definition point.h:426
static constexpr impeller::Vector2 kQuadrantAxes[4]
Definition point.h:433
constexpr Color operator*(T value, const Color &c)
Definition color.h:909
TPoint< uint32_t > UintPoint32
Definition point.h:428
std::array< Point, 4 > Quad
Definition point.h:430
Definition ref_ptr.h:261
std::ostream & operator<<(std::ostream &out, const impeller::Arc &a)
Definition arc.h:141
int32_t height
int32_t width