Flutter Impeller
vector.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_VECTOR_H_
6 #define FLUTTER_IMPELLER_GEOMETRY_VECTOR_H_
7 
8 #include <cmath>
9 #include <string>
10 
14 #include "impeller/geometry/size.h"
15 
16 namespace impeller {
17 
18 // NOLINTBEGIN(google-explicit-constructor)
19 
20 struct Vector3 {
21  union {
22  struct {
23  Scalar x = 0.0f;
24  Scalar y = 0.0f;
25  Scalar z = 0.0f;
26  };
27  Scalar e[3];
28  };
29 
30  constexpr Vector3() {};
31 
32  constexpr Vector3(const Color& c) : x(c.red), y(c.green), z(c.blue) {}
33 
34  constexpr Vector3(const Point& p) : x(p.x), y(p.y) {}
35 
36  constexpr Vector3(const Size& s) : x(s.width), y(s.height) {}
37 
38  constexpr Vector3(Scalar x, Scalar y) : x(x), y(y) {}
39 
40  constexpr Vector3(Scalar x, Scalar y, Scalar z) : x(x), y(y), z(z) {}
41 
42  /**
43  * The length (or magnitude of the vector).
44  *
45  * @return the calculated length.
46  */
47  inline Scalar GetLength() const { return sqrt(x * x + y * y + z * z); }
48 
49  inline Vector3 Normalize() const {
50  const auto len = GetLength();
51  return {x / len, y / len, z / len};
52  }
53 
54  constexpr Scalar Dot(const Vector3& other) const {
55  return ((x * other.x) + (y * other.y) + (z * other.z));
56  }
57 
58  inline Vector3 Abs() const {
59  return {std::fabs(x), std::fabs(y), std::fabs(z)};
60  }
61 
62  constexpr Vector3 Cross(const Vector3& other) const {
63  return {
64  (y * other.z) - (z * other.y), //
65  (z * other.x) - (x * other.z), //
66  (x * other.y) - (y * other.x) //
67  };
68  }
69 
70  inline Vector3 Min(const Vector3& p) const {
71  return {std::min(x, p.x), std::min(y, p.y), std::min(z, p.z)};
72  }
73 
74  inline Vector3 Max(const Vector3& p) const {
75  return {std::max(x, p.x), std::max(y, p.y), std::max(z, p.z)};
76  }
77 
78  inline Vector3 Floor() const {
79  return {std::floor(x), std::floor(y), std::floor(z)};
80  }
81 
82  inline Vector3 Ceil() const {
83  return {std::ceil(x), std::ceil(y), std::ceil(z)};
84  }
85 
86  inline Vector3 Round() const {
87  return {std::round(x), std::round(y), std::round(z)};
88  }
89 
90  constexpr bool operator==(const Vector3& v) const {
91  return v.x == x && v.y == y && v.z == z;
92  }
93 
94  constexpr bool operator!=(const Vector3& v) const {
95  return v.x != x || v.y != y || v.z != z;
96  }
97 
98  constexpr Vector3 operator+=(const Vector3& p) {
99  x += p.x;
100  y += p.y;
101  z += p.z;
102  return *this;
103  }
104 
105  constexpr Vector3 operator-=(const Vector3& p) {
106  x -= p.x;
107  y -= p.y;
108  z -= p.z;
109  return *this;
110  }
111 
112  constexpr Vector3 operator*=(const Vector3& p) {
113  x *= p.x;
114  y *= p.y;
115  z *= p.z;
116  return *this;
117  }
118 
119  template <class U, class = std::enable_if_t<std::is_arithmetic_v<U>>>
120  constexpr Vector3 operator*=(U scale) {
121  x *= scale;
122  y *= scale;
123  z *= scale;
124  return *this;
125  }
126 
127  constexpr Vector3 operator/=(const Vector3& p) {
128  x /= p.x;
129  y /= p.y;
130  z /= p.z;
131  return *this;
132  }
133 
134  template <class U, class = std::enable_if_t<std::is_arithmetic_v<U>>>
135  constexpr Vector3 operator/=(U scale) {
136  x /= scale;
137  y /= scale;
138  z /= scale;
139  return *this;
140  }
141 
142  constexpr Vector3 operator-() const { return Vector3(-x, -y, -z); }
143 
144  constexpr Vector3 operator+(const Vector3& v) const {
145  return Vector3(x + v.x, y + v.y, z + v.z);
146  }
147 
148  constexpr Vector3 operator-(const Vector3& v) const {
149  return Vector3(x - v.x, y - v.y, z - v.z);
150  }
151 
152  constexpr Vector3 operator+(Scalar s) const {
153  return Vector3(x + s, y + s, z + s);
154  }
155 
156  constexpr Vector3 operator-(Scalar s) const {
157  return Vector3(x - s, y - s, z - s);
158  }
159 
160  constexpr Vector3 operator*(const Vector3& v) const {
161  return Vector3(x * v.x, y * v.y, z * v.z);
162  }
163 
164  template <class U, class = std::enable_if_t<std::is_arithmetic_v<U>>>
165  constexpr Vector3 operator*(U scale) const {
166  return Vector3(x * scale, y * scale, z * scale);
167  }
168 
169  constexpr Vector3 operator/(const Vector3& v) const {
170  return Vector3(x / v.x, y / v.y, z / v.z);
171  }
172 
173  template <class U, class = std::enable_if_t<std::is_arithmetic_v<U>>>
174  constexpr Vector3 operator/(U scale) const {
175  return Vector3(x / scale, y / scale, z / scale);
176  }
177 
178  constexpr Vector3 Lerp(const Vector3& v, Scalar t) const {
179  return *this + (v - *this) * t;
180  }
181 
182  /**
183  * Make a linear combination of two vectors and return the result.
184  *
185  * @param a the first vector.
186  * @param aScale the scale to use for the first vector.
187  * @param b the second vector.
188  * @param bScale the scale to use for the second vector.
189  *
190  * @return the combined vector.
191  */
192  static constexpr Vector3 Combine(const Vector3& a,
193  Scalar aScale,
194  const Vector3& b,
195  Scalar bScale) {
196  return {
197  aScale * a.x + bScale * b.x, //
198  aScale * a.y + bScale * b.y, //
199  aScale * a.z + bScale * b.z, //
200  };
201  }
202 };
203 
204 // RHS algebraic operations with arithmetic types.
205 
206 template <class U, class = std::enable_if_t<std::is_arithmetic_v<U>>>
207 constexpr Vector3 operator*(U s, const Vector3& p) {
208  return p * s;
209 }
210 
211 template <class U, class = std::enable_if_t<std::is_arithmetic_v<U>>>
212 constexpr Vector3 operator+(U s, const Vector3& p) {
213  return p + s;
214 }
215 
216 template <class U, class = std::enable_if_t<std::is_arithmetic_v<U>>>
217 constexpr Vector3 operator-(U s, const Vector3& p) {
218  return -p + s;
219 }
220 
221 template <class U, class = std::enable_if_t<std::is_arithmetic_v<U>>>
222 constexpr Vector3 operator/(U s, const Vector3& p) {
223  return {
224  static_cast<Scalar>(s) / p.x,
225  static_cast<Scalar>(s) / p.y,
226  static_cast<Scalar>(s) / p.z,
227  };
228 }
229 
230 struct Vector4 {
231  union {
232  struct {
233  Scalar x = 0.0f;
234  Scalar y = 0.0f;
235  Scalar z = 0.0f;
236  Scalar w = 1.0f;
237  };
238  Scalar e[4];
239  };
240 
241  constexpr Vector4() {}
242 
243  constexpr Vector4(const Color& c)
244  : x(c.red), y(c.green), z(c.blue), w(c.alpha) {}
245 
247  : x(x), y(y), z(z), w(w) {}
248 
249  constexpr Vector4(const Vector3& v) : x(v.x), y(v.y), z(v.z) {}
250 
251  constexpr Vector4(const Point& p) : x(p.x), y(p.y) {}
252 
253  constexpr Vector4(std::array<Scalar, 4> values)
254  : x(values[0]), y(values[1]), z(values[2]), w(values[3]) {}
255 
256  inline bool IsFinite() const {
257  return std::isfinite(x) && std::isfinite(y) && std::isfinite(z) &&
258  std::isfinite(w);
259  }
260 
261  Vector4 Normalize() const {
262  const Scalar inverse = 1.0f / sqrt(x * x + y * y + z * z + w * w);
263  return Vector4(x * inverse, y * inverse, z * inverse, w * inverse);
264  }
265 
266  constexpr bool operator==(const Vector4& v) const {
267  return (x == v.x) && (y == v.y) && (z == v.z) && (w == v.w);
268  }
269 
270  constexpr bool operator!=(const Vector4& v) const {
271  return (x != v.x) || (y != v.y) || (z != v.z) || (w != v.w);
272  }
273 
274  constexpr Vector4 operator+(const Vector4& v) const {
275  return Vector4(x + v.x, y + v.y, z + v.z, w + v.w);
276  }
277 
278  constexpr Vector4 operator-(const Vector4& v) const {
279  return Vector4(x - v.x, y - v.y, z - v.z, w - v.w);
280  }
281 
282  constexpr Vector4 operator*(Scalar f) const {
283  return Vector4(x * f, y * f, z * f, w * f);
284  }
285 
286  constexpr Vector4 operator*(const Vector4& v) const {
287  return Vector4(x * v.x, y * v.y, z * v.z, w * v.w);
288  }
289 
290  constexpr Vector4 Min(const Vector4& p) const {
291  return {std::min(x, p.x), std::min(y, p.y), std::min(z, p.z),
292  std::min(w, p.w)};
293  }
294 
295  constexpr Vector4 Max(const Vector4& p) const {
296  return {std::max(x, p.x), std::max(y, p.y), std::max(z, p.z),
297  std::max(w, p.w)};
298  }
299 
300  inline Vector4 Floor() const {
301  return {std::floor(x), std::floor(y), std::floor(z), std::floor(w)};
302  }
303 
304  inline Vector4 Ceil() const {
305  return {std::ceil(x), std::ceil(y), std::ceil(z), std::ceil(w)};
306  }
307 
308  inline Vector4 Round() const {
309  return {std::round(x), std::round(y), std::round(z), std::round(w)};
310  }
311 
312  constexpr Vector4 Lerp(const Vector4& v, Scalar t) const {
313  return *this + (v - *this) * t;
314  }
315 
316  constexpr Vector2 xy() const { return Vector2(x, y); }
317 };
318 
319 static_assert(sizeof(Vector3) == 3 * sizeof(Scalar));
320 static_assert(sizeof(Vector4) == 4 * sizeof(Scalar));
321 
322 } // namespace impeller
323 
324 namespace std {
325 
326 inline std::ostream& operator<<(std::ostream& out, const impeller::Vector3& p) {
327  out << "(" << p.x << ", " << p.y << ", " << p.z << ")";
328  return out;
329 }
330 
331 inline std::ostream& operator<<(std::ostream& out, const impeller::Vector4& p) {
332  out << "(" << p.x << ", " << p.y << ", " << p.z << ", " << p.w << ")";
333  return out;
334 }
335 
336 // NOLINTEND(google-explicit-constructor)
337 
338 } // namespace std
339 
340 #endif // FLUTTER_IMPELLER_GEOMETRY_VECTOR_H_
Point Vector2
Definition: point.h:430
constexpr Color operator-(T value, const Color &c)
Definition: color.h:908
float Scalar
Definition: scalar.h:19
constexpr Color operator/(T value, const Color &c)
Definition: color.h:919
constexpr Color operator+(T value, const Color &c)
Definition: color.h:903
constexpr Color operator*(T value, const Color &c)
Definition: color.h:914
Definition: comparable.h:93
std::ostream & operator<<(std::ostream &out, const impeller::Arc &a)
Definition: arc.h:141
Vector3 Min(const Vector3 &p) const
Definition: vector.h:70
Vector3 Abs() const
Definition: vector.h:58
Vector3 Normalize() const
Definition: vector.h:49
constexpr Vector3 operator-(const Vector3 &v) const
Definition: vector.h:148
constexpr Vector3 Lerp(const Vector3 &v, Scalar t) const
Definition: vector.h:178
constexpr Vector3 operator*=(U scale)
Definition: vector.h:120
constexpr Vector3 operator*(U scale) const
Definition: vector.h:165
constexpr Vector3 Cross(const Vector3 &other) const
Definition: vector.h:62
constexpr Vector3(Scalar x, Scalar y, Scalar z)
Definition: vector.h:40
constexpr Vector3 operator/(const Vector3 &v) const
Definition: vector.h:169
Vector3 Round() const
Definition: vector.h:86
constexpr Vector3 operator-() const
Definition: vector.h:142
constexpr Vector3(const Color &c)
Definition: vector.h:32
constexpr Vector3(Scalar x, Scalar y)
Definition: vector.h:38
constexpr Vector3()
Definition: vector.h:30
Scalar e[3]
Definition: vector.h:27
constexpr Vector3(const Size &s)
Definition: vector.h:36
constexpr Vector3 operator+(const Vector3 &v) const
Definition: vector.h:144
constexpr Vector3 operator+=(const Vector3 &p)
Definition: vector.h:98
constexpr Vector3 operator-(Scalar s) const
Definition: vector.h:156
constexpr Vector3 operator/=(U scale)
Definition: vector.h:135
constexpr bool operator==(const Vector3 &v) const
Definition: vector.h:90
Vector3 Ceil() const
Definition: vector.h:82
constexpr Vector3 operator+(Scalar s) const
Definition: vector.h:152
Vector3 Floor() const
Definition: vector.h:78
constexpr Vector3 operator/=(const Vector3 &p)
Definition: vector.h:127
constexpr Vector3 operator/(U scale) const
Definition: vector.h:174
constexpr bool operator!=(const Vector3 &v) const
Definition: vector.h:94
static constexpr Vector3 Combine(const Vector3 &a, Scalar aScale, const Vector3 &b, Scalar bScale)
Definition: vector.h:192
constexpr Vector3(const Point &p)
Definition: vector.h:34
Vector3 Max(const Vector3 &p) const
Definition: vector.h:74
constexpr Scalar Dot(const Vector3 &other) const
Definition: vector.h:54
constexpr Vector3 operator*=(const Vector3 &p)
Definition: vector.h:112
constexpr Vector3 operator*(const Vector3 &v) const
Definition: vector.h:160
constexpr Vector3 operator-=(const Vector3 &p)
Definition: vector.h:105
Scalar GetLength() const
Definition: vector.h:47
constexpr Vector4(const Point &p)
Definition: vector.h:251
constexpr Vector4 Min(const Vector4 &p) const
Definition: vector.h:290
constexpr Vector4(Scalar x, Scalar y, Scalar z, Scalar w)
Definition: vector.h:246
constexpr Vector4 Lerp(const Vector4 &v, Scalar t) const
Definition: vector.h:312
Vector4 Floor() const
Definition: vector.h:300
bool IsFinite() const
Definition: vector.h:256
Vector4 Round() const
Definition: vector.h:308
Vector4 Normalize() const
Definition: vector.h:261
constexpr Vector4 operator+(const Vector4 &v) const
Definition: vector.h:274
constexpr Vector4(std::array< Scalar, 4 > values)
Definition: vector.h:253
constexpr Vector4()
Definition: vector.h:241
constexpr Vector4(const Color &c)
Definition: vector.h:243
constexpr Vector4 Max(const Vector4 &p) const
Definition: vector.h:295
constexpr bool operator!=(const Vector4 &v) const
Definition: vector.h:270
constexpr Vector4 operator-(const Vector4 &v) const
Definition: vector.h:278
constexpr Vector4 operator*(const Vector4 &v) const
Definition: vector.h:286
constexpr Vector2 xy() const
Definition: vector.h:316
Scalar e[4]
Definition: vector.h:238
Vector4 Ceil() const
Definition: vector.h:304
constexpr Vector4(const Vector3 &v)
Definition: vector.h:249
constexpr Vector4 operator*(Scalar f) const
Definition: vector.h:282
constexpr bool operator==(const Vector4 &v) const
Definition: vector.h:266