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  std::string ToString() const;
204 };
205 
206 // RHS algebraic operations with arithmetic types.
207 
208 template <class U, class = std::enable_if_t<std::is_arithmetic_v<U>>>
209 constexpr Vector3 operator*(U s, const Vector3& p) {
210  return p * s;
211 }
212 
213 template <class U, class = std::enable_if_t<std::is_arithmetic_v<U>>>
214 constexpr Vector3 operator+(U s, const Vector3& p) {
215  return p + s;
216 }
217 
218 template <class U, class = std::enable_if_t<std::is_arithmetic_v<U>>>
219 constexpr Vector3 operator-(U s, const Vector3& p) {
220  return -p + s;
221 }
222 
223 template <class U, class = std::enable_if_t<std::is_arithmetic_v<U>>>
224 constexpr Vector3 operator/(U s, const Vector3& p) {
225  return {
226  static_cast<Scalar>(s) / p.x,
227  static_cast<Scalar>(s) / p.y,
228  static_cast<Scalar>(s) / p.z,
229  };
230 }
231 
232 struct Vector4 {
233  union {
234  struct {
235  Scalar x = 0.0f;
236  Scalar y = 0.0f;
237  Scalar z = 0.0f;
238  Scalar w = 1.0f;
239  };
240  Scalar e[4];
241  };
242 
243  constexpr Vector4() {}
244 
245  constexpr Vector4(const Color& c)
246  : x(c.red), y(c.green), z(c.blue), w(c.alpha) {}
247 
249  : x(x), y(y), z(z), w(w) {}
250 
251  constexpr Vector4(const Vector3& v) : x(v.x), y(v.y), z(v.z) {}
252 
253  constexpr Vector4(const Point& p) : x(p.x), y(p.y) {}
254 
255  constexpr Vector4(std::array<Scalar, 4> values)
256  : x(values[0]), y(values[1]), z(values[2]), w(values[3]) {}
257 
258  inline bool IsFinite() const {
259  return std::isfinite(x) && std::isfinite(y) && std::isfinite(z) &&
260  std::isfinite(w);
261  }
262 
263  Vector4 Normalize() const {
264  const Scalar inverse = 1.0f / sqrt(x * x + y * y + z * z + w * w);
265  return Vector4(x * inverse, y * inverse, z * inverse, w * inverse);
266  }
267 
268  constexpr bool operator==(const Vector4& v) const {
269  return (x == v.x) && (y == v.y) && (z == v.z) && (w == v.w);
270  }
271 
272  constexpr bool operator!=(const Vector4& v) const {
273  return (x != v.x) || (y != v.y) || (z != v.z) || (w != v.w);
274  }
275 
276  constexpr Vector4 operator+(const Vector4& v) const {
277  return Vector4(x + v.x, y + v.y, z + v.z, w + v.w);
278  }
279 
280  constexpr Vector4 operator-(const Vector4& v) const {
281  return Vector4(x - v.x, y - v.y, z - v.z, w - v.w);
282  }
283 
284  constexpr Vector4 operator*(Scalar f) const {
285  return Vector4(x * f, y * f, z * f, w * f);
286  }
287 
288  constexpr Vector4 operator*(const Vector4& v) const {
289  return Vector4(x * v.x, y * v.y, z * v.z, w * v.w);
290  }
291 
292  constexpr Vector4 Min(const Vector4& p) const {
293  return {std::min(x, p.x), std::min(y, p.y), std::min(z, p.z),
294  std::min(w, p.w)};
295  }
296 
297  constexpr Vector4 Max(const Vector4& p) const {
298  return {std::max(x, p.x), std::max(y, p.y), std::max(z, p.z),
299  std::max(w, p.w)};
300  }
301 
302  inline Vector4 Floor() const {
303  return {std::floor(x), std::floor(y), std::floor(z), std::floor(w)};
304  }
305 
306  inline Vector4 Ceil() const {
307  return {std::ceil(x), std::ceil(y), std::ceil(z), std::ceil(w)};
308  }
309 
310  inline Vector4 Round() const {
311  return {std::round(x), std::round(y), std::round(z), std::round(w)};
312  }
313 
314  constexpr Vector4 Lerp(const Vector4& v, Scalar t) const {
315  return *this + (v - *this) * t;
316  }
317 
318  constexpr Vector2 xy() const { return Vector2(x, y); }
319 
320  std::string ToString() const;
321 };
322 
323 static_assert(sizeof(Vector3) == 3 * sizeof(Scalar));
324 static_assert(sizeof(Vector4) == 4 * sizeof(Scalar));
325 
326 } // namespace impeller
327 
328 namespace std {
329 
330 inline std::ostream& operator<<(std::ostream& out, const impeller::Vector3& p) {
331  out << "(" << p.x << ", " << p.y << ", " << p.z << ")";
332  return out;
333 }
334 
335 inline std::ostream& operator<<(std::ostream& out, const impeller::Vector4& p) {
336  out << "(" << p.x << ", " << p.y << ", " << p.z << ", " << p.w << ")";
337  return out;
338 }
339 
340 // NOLINTEND(google-explicit-constructor)
341 
342 } // namespace std
343 
344 #endif // FLUTTER_IMPELLER_GEOMETRY_VECTOR_H_
Point Vector2
Definition: point.h:331
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
constexpr Color operator*(T value, const Color &c)
Definition: color.h:909
Definition: comparable.h:95
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
std::string ToString() const
Definition: vector.cc:10
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:253
constexpr Vector4 Min(const Vector4 &p) const
Definition: vector.h:292
constexpr Vector4(Scalar x, Scalar y, Scalar z, Scalar w)
Definition: vector.h:248
constexpr Vector4 Lerp(const Vector4 &v, Scalar t) const
Definition: vector.h:314
Vector4 Floor() const
Definition: vector.h:302
bool IsFinite() const
Definition: vector.h:258
Vector4 Round() const
Definition: vector.h:310
Vector4 Normalize() const
Definition: vector.h:263
constexpr Vector4 operator+(const Vector4 &v) const
Definition: vector.h:276
std::string ToString() const
Definition: vector.cc:16
constexpr Vector4(std::array< Scalar, 4 > values)
Definition: vector.h:255
constexpr Vector4()
Definition: vector.h:243
constexpr Vector4(const Color &c)
Definition: vector.h:245
constexpr Vector4 Max(const Vector4 &p) const
Definition: vector.h:297
constexpr bool operator!=(const Vector4 &v) const
Definition: vector.h:272
constexpr Vector4 operator-(const Vector4 &v) const
Definition: vector.h:280
constexpr Vector4 operator*(const Vector4 &v) const
Definition: vector.h:288
constexpr Vector2 xy() const
Definition: vector.h:318
Scalar e[4]
Definition: vector.h:240
Vector4 Ceil() const
Definition: vector.h:306
constexpr Vector4(const Vector3 &v)
Definition: vector.h:251
constexpr Vector4 operator*(Scalar f) const
Definition: vector.h:284
constexpr bool operator==(const Vector4 &v) const
Definition: vector.h:268