Formatted API
[platform/core/uifw/dali-core.git] / dali / public-api / math / vector2.h
1 #ifndef DALI_VECTOR_2_H
2 #define DALI_VECTOR_2_H
3
4 /*
5  * Copyright (c) 2020 Samsung Electronics Co., Ltd.
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  * http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  */
20
21 // EXTERNAL INCLUDES
22 #include <cstdint> // uint32_t
23 #include <iosfwd>
24
25 // INTERNAL INCLUDES
26 #include <dali/public-api/common/dali-common.h>
27 #include <dali/public-api/common/type-traits.h>
28
29 namespace Dali
30 {
31 class Uint16Pair;
32
33 /**
34  * @addtogroup dali_core_math
35  * @{
36  */
37
38 struct Vector3;
39 struct Vector4;
40
41 /**
42  * @brief A two dimensional vector.
43  * @SINCE_1_0.0
44  */
45 struct DALI_CORE_API Vector2
46 {
47   // (x width) and (y height) must be consecutive in memory.
48   // No other data must be added before (x width) member.
49   // No virtual methods must be added to this struct.
50
51 public:
52   /**
53    * @brief Constructor.
54    * @SINCE_1_0.0
55    */
56   Vector2()
57   : x(0.0f),
58     y(0.0f)
59   {
60   }
61
62   /**
63    * @brief Constructor.
64    *
65    * @SINCE_1_0.0
66    * @param[in] x x or width component
67    * @param[in] y y or height component
68    */
69   explicit constexpr Vector2(float x, float y)
70   : x(x),
71     y(y)
72   {
73   }
74
75   /**
76    * @brief Conversion constructor from an array of two floats.
77    *
78    * @SINCE_1_0.0
79    * @param[in] array Array of xy
80    */
81   explicit Vector2(const float* array)
82   : x(array[0]),
83     y(array[1])
84   {
85   }
86
87   /**
88    * @brief Constructor.
89    *
90    * @SINCE_1_0.0
91    * @param[in] vec3 Vector3 to create this vector from
92    */
93   explicit Vector2(const Vector3& vec3);
94
95   /**
96    * @brief Constructor.
97    *
98    * @SINCE_1_0.0
99    * @param[in] vec4 Vector4 to create this vector from
100    */
101   explicit Vector2(const Vector4& vec4);
102
103   /**
104    * @brief Conversion constructor from a Uint16Pair.
105    *
106    * @SINCE_1_9.21
107    *
108    * @param[in] pair The Uint16Pair to create this vector from
109    */
110   Vector2(const Uint16Pair& pair);
111
112   // Constants
113
114   static const Vector2 ONE;            ///< (1.0f,1.0f)
115   static const Vector2 XAXIS;          ///< Vector representing the X axis
116   static const Vector2 YAXIS;          ///< Vector representing the Y axis
117   static const Vector2 NEGATIVE_XAXIS; ///< Vector representing the negative X axis
118   static const Vector2 NEGATIVE_YAXIS; ///< Vector representing the negative Y axis
119   static const Vector2 ZERO;           ///< (0.0f, 0.0f)
120
121   // API
122
123   /**
124    * @brief Assignment operator.
125    *
126    * @SINCE_1_0.0
127    * @param[in] array Array of floats
128    * @return Itself
129    */
130   Vector2& operator=(const float* array)
131   {
132     x = array[0];
133     y = array[1];
134
135     return *this;
136   }
137
138   /**
139    * @brief Assignment operator.
140    *
141    * @SINCE_1_0.0
142    * @param[in] rhs Vector to assign
143    * @return Itself
144    */
145   Vector2& operator=(const Vector3& rhs);
146
147   /**
148    * @brief Assignment operator.
149    *
150    * @SINCE_1_0.0
151    * @param[in] rhs Vector to assign
152    * @return Itself
153    */
154   Vector2& operator=(const Vector4& rhs);
155
156   /**
157    * @brief Addition operator.
158    *
159    * @SINCE_1_0.0
160    * @param[in] rhs Vector to add
161    * @return A vector containing the result of the addition
162    */
163   Vector2 operator+(const Vector2& rhs) const
164   {
165     Vector2 temp(*this);
166
167     return temp += rhs;
168   }
169
170   /**
171    * @brief Addition assignment operator.
172    *
173    * @SINCE_1_0.0
174    * @param[in] rhs Vector to add
175    * @return Itself
176    */
177   Vector2& operator+=(const Vector2& rhs)
178   {
179     x += rhs.x;
180     y += rhs.y;
181
182     return *this;
183   }
184
185   /**
186    * @brief Subtraction operator.
187    *
188    * @SINCE_1_0.0
189    * @param[in] rhs The vector to subtract
190    * @return A vector containing the result of the subtraction
191    */
192   Vector2 operator-(const Vector2& rhs) const
193   {
194     Vector2 temp(*this);
195
196     return temp -= rhs;
197   }
198
199   /**
200    * @brief Subtraction assignment operator.
201    *
202    * @SINCE_1_0.0
203    * @param[in] rhs The vector to subtract
204    * @return Itself
205    */
206   Vector2& operator-=(const Vector2& rhs)
207   {
208     x -= rhs.x;
209     y -= rhs.y;
210
211     return *this;
212   }
213
214   /**
215    * @brief Multiplication operator.
216    *
217    * @SINCE_1_0.0
218    * @param[in] rhs The vector to multiply
219    * @return A vector containing the result of the multiplication
220    */
221   Vector2 operator*(const Vector2& rhs) const
222   {
223     return Vector2(x * rhs.x, y * rhs.y);
224   }
225
226   /**
227    * @brief Multiplication operator.
228    *
229    * @SINCE_1_0.0
230    * @param[in] rhs The float value to scale the vector
231    * @return A vector containing the result of the scaling
232    */
233   Vector2 operator*(float rhs) const
234   {
235     return Vector2(x * rhs, y * rhs);
236   }
237
238   /**
239    * @brief Multiplication assignment operator.
240    *
241    * @SINCE_1_0.0
242    * @param[in] rhs The vector to multiply
243    * @return Itself
244    */
245   Vector2& operator*=(const Vector2& rhs)
246   {
247     x *= rhs.x;
248     y *= rhs.y;
249
250     return *this;
251   }
252
253   /**
254    * @brief Multiplication assignment operator.
255    *
256    * @SINCE_1_0.0
257    * @param[in] rhs The float value to scale the vector
258    * @return Itself
259    */
260   Vector2& operator*=(float rhs)
261   {
262     x *= rhs;
263     y *= rhs;
264
265     return *this;
266   }
267
268   /**
269    * @brief Division operator.
270    *
271    * @SINCE_1_0.0
272    * @param[in] rhs The vector to divide
273    * @return A vector containing the result of the division
274    */
275   Vector2 operator/(const Vector2& rhs) const
276   {
277     return Vector2(x / rhs.x, y / rhs.y);
278   }
279
280   /**
281    * @brief Division operator.
282    *
283    * @SINCE_1_0.0
284    * @param[in] rhs The float value to scale the vector by
285    * @return A vector containing the result of the scaling
286    */
287   Vector2 operator/(float rhs) const
288   {
289     return Vector2(x / rhs, y / rhs);
290   }
291
292   /**
293    * @brief Division assignment operator.
294    *
295    * @SINCE_1_0.0
296    * @param[in] rhs The vector to divide
297    * @return Itself
298    */
299   Vector2& operator/=(const Vector2& rhs)
300   {
301     x /= rhs.x;
302     y /= rhs.y;
303
304     return *this;
305   }
306
307   /**
308    * @brief Division assignment operator.
309    *
310    * @SINCE_1_0.0
311    * @param[in] rhs The float value to scale the vector by
312    * @return Itself
313    */
314   Vector2& operator/=(float rhs)
315   {
316     x /= rhs;
317     y /= rhs;
318
319     return *this;
320   }
321
322   /**
323    * @brief Unary negation operator.
324    *
325    * @SINCE_1_0.0
326    * @return A vector containing the negation
327    */
328   Vector2 operator-() const
329   {
330     Vector2 temp(-x, -y);
331
332     return temp;
333   }
334
335   /**
336    * @brief Equality operator.
337    *
338    * Utilizes appropriate machine epsilon values.
339    *
340    * @SINCE_1_0.0
341    * @param[in] rhs The vector to test against
342    * @return true if the vectors are equal
343    */
344   bool operator==(const Vector2& rhs) const;
345
346   /**
347    * @brief Inequality operator.
348    *
349    * Utilizes appropriate machine epsilon values.
350    *
351    * @SINCE_1_0.0
352    * @param[in] rhs The vector to test against
353    * @return true if the vectors are not equal
354    */
355   bool operator!=(const Vector2& rhs) const
356   {
357     return !(*this == rhs);
358   }
359
360   /**
361    * @brief Const array subscript operator overload.
362    *
363    * Asserts if index is out of range. Should be 0 or 1.
364    * @SINCE_1_0.0
365    * @param[in] index Subscript index
366    * @return The float at the given index
367    */
368   const float& operator[](const uint32_t index) const
369   {
370     DALI_ASSERT_ALWAYS(index < 2 && "Vector element index out of bounds");
371
372     return AsFloat()[index];
373   }
374
375   /**
376    * @brief Mutable array subscript operator overload.
377    *
378    * Asserts if index is out of range. Should be 0 or 1.
379    * @SINCE_1_0.0
380    * @param[in] index Subscript index
381    * @return The float at the given index
382    */
383   float& operator[](const uint32_t index)
384   {
385     DALI_ASSERT_ALWAYS(index < 2 && "Vector element index out of bounds");
386
387     return AsFloat()[index];
388   }
389
390   /**
391    * @brief Returns the length of the vector.
392    *
393    * @SINCE_1_0.0
394    * @return The length of the vector
395    */
396   float Length() const;
397
398   /**
399    * @brief Returns the length of the vector squared.
400    *
401    * This is more efficient than Length() for threshold
402    * testing as it avoids the use of a square root.
403    * @SINCE_1_0.0
404    * @return The length of the vector squared
405    */
406   float LengthSquared() const;
407
408   /**
409    * @brief Sets the vector to be unit length, whilst maintaining its direction.
410    *
411    * @SINCE_1_0.0
412    */
413   void Normalize();
414
415   /**
416     * @brief Clamps the vector between minimum and maximum vectors.
417     *
418     * @SINCE_1_0.0
419     * @param[in] min The minimum vector
420     * @param[in] max The maximum vector
421    */
422   void Clamp(const Vector2& min, const Vector2& max);
423
424   /**
425    * @brief Returns the contents of the vector as an array of 2 floats.
426    *
427    * The order of the values in this array are as follows:
428    * 0: x (or width)
429    * 1: y (or height)
430    * @SINCE_1_0.0
431    * @return The vector contents as an array of 2 floats
432    * @note inlined for performance reasons (generates less code than a function call)
433    */
434   const float* AsFloat() const
435   {
436     return &x;
437   }
438
439   /**
440    * @brief Returns the contents of the vector as an array of 2 floats.
441    *
442    * The order of the values in this array are as follows:
443    * 0: x (or width)
444    * 1: y (or height)
445    * @SINCE_1_0.0
446    * @return The vector contents as an array of 2 floats
447    * @note inlined for performance reasons (generates less code than a function call)
448    */
449   float* AsFloat()
450   {
451     return &x;
452   }
453
454 public:
455   Vector2(const Vector2&) = default;            ///< Default copy constructor
456   Vector2(Vector2&&)      = default;            ///< Default move constructor
457   Vector2& operator=(const Vector2&) = default; ///< Default copy assignment operator
458   Vector2& operator=(Vector2&&) = default;      ///< Default move assignment operator
459
460 public: // Data
461   // NOTE
462   // (x width) and (y height) must be consecutive in memory.
463   // No other data must be added before (x width) member.
464   // No virtual methods must be added to this struct.
465   union
466   {
467     float x;     ///< x component
468     float width; ///< width
469   };
470
471   union
472   {
473     float y;      ///< y component
474     float height; ///< height
475   };
476 };
477
478 /**
479  * @brief Size is an alias of Dali::Vector2.
480  * @SINCE_1_0.0
481  */
482 using Size = Vector2;
483
484 /**
485  * @brief Print a Vector2.
486  *
487  * @SINCE_1_0.0
488  * @param[in] o The output stream operator
489  * @param[in] vector The vector to print
490  * @return The output stream operator
491  */
492 DALI_CORE_API std::ostream& operator<<(std::ostream& o, const Vector2& vector);
493
494 /**
495  * @brief Returns a vector with components set to the minimum of the corresponding component in a and b.
496  *
497  * If a=0,1 and b=1,0 returns a vector of 0,0.
498  * @SINCE_1_0.0
499  * @param[in] a A vector
500  * @param[in] b A vector
501  * @return A vector containing the minimum of each component from a and b
502  */
503 inline Vector2 Min(const Vector2& a, const Vector2& b)
504 {
505   return Vector2(a.x < b.x ? a.x : b.x, a.y < b.y ? a.y : b.y);
506 }
507
508 /**
509  * @brief Returns a vector with components set to the maximum of the corresponding component in a and b.
510  *
511  * If a=0,1 and b=1,0 returns a vector of 1,1.
512  * @SINCE_1_0.0
513  * @param[in] a A vector
514  * @param[in] b A vector
515  * @return A vector containing the maximum of each component from a and b
516  */
517 inline Vector2 Max(const Vector2& a, const Vector2& b)
518 {
519   return Vector2(a.x > b.x ? a.x : b.x, a.y > b.y ? a.y : b.y);
520 }
521
522 /**
523  * @brief Clamps each of vector v's components between minimum and maximum values.
524  *
525  * @SINCE_1_0.0
526  * @param[in] v A vector
527  * @param[in] min The minimum value
528  * @param[in] max The maximum value
529  * @return A vector containing the clamped components of v
530  */
531 DALI_CORE_API Vector2 Clamp(const Vector2& v, const float& min, const float& max);
532
533 // Allow Vector2 to be treated as a POD type
534 template<>
535 struct TypeTraits<Vector2> : public BasicTypes<Vector2>
536 {
537   enum
538   {
539     IS_TRIVIAL_TYPE = true
540   };
541 };
542
543 /**
544  * @}
545  */
546 } // namespace Dali
547
548 #endif // DALI_VECTOR_2_H