Merge "Follow the include-order coding conventions" into tizen
[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) 2014 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 <iosfwd>
23
24 // INTERNAL INCLUDES
25 #include <dali/public-api/common/dali-common.h>
26
27 namespace Dali
28 {
29
30 struct Vector3;
31 struct Vector4;
32
33 /**
34  * @brief A two dimensional vector.
35  */
36 struct DALI_IMPORT_API Vector2
37 {
38 // (x width) and (y height) must be consecutive in memory.
39 // No other data must be added before (x width) member.
40 // No virtual methods must be added to this struct.
41
42 public:
43
44   /**
45    * @brief Constructor.
46    */
47   Vector2()
48   : x(0.0f),
49     y(0.0f)
50   {
51   }
52
53   /**
54    * @brief Constructor.
55    *
56    * @param[in] x x or width component
57    * @param[in] y y or height component
58    */
59   explicit Vector2(float x, float y)
60   : x(x), y(y)
61   {
62   }
63
64   /**
65    * @brief Conversion constructor from an array of two floats.
66    *
67    * @param [in] array of xy
68    */
69   explicit Vector2(const float* array)
70   : x(array[0]),
71     y(array[1])
72   {
73   }
74
75   /**
76    * @brief Constructor.
77    *
78    * @param [in] vec3 Vector3 to create this vector from
79    */
80   explicit Vector2(const Vector3& vec3);
81
82   /**
83    * @brief Constructor.
84    *
85    * @param [in] vec4 Vector4 to create this vector from
86    */
87   explicit Vector2(const Vector4& vec4);
88
89 // Constants
90
91   static const Vector2 ONE;               ///< (1.0f,1.0f)
92   static const Vector2 XAXIS;             ///< Vector representing the X axis
93   static const Vector2 YAXIS;             ///< Vector representing the Y axis
94   static const Vector2 NEGATIVE_XAXIS;    ///< Vector representing the negative X axis
95   static const Vector2 NEGATIVE_YAXIS;    ///< Vector representing the negative Y axis
96   static const Vector2 ZERO;              ///< (0.0f, 0.0f)
97
98 // API
99
100   /**
101    * @brief Assignment operator.
102    *
103    * @param[in] array of floats
104    * @return itself
105    */
106   Vector2& operator=(const float* array)
107   {
108     x = array[0];
109     y = array[1];
110
111     return *this;
112   }
113
114   /**
115    * @brief Assignment operator.
116    *
117    * @param[in] rhs vector to assign.
118    * @return itself
119    */
120   Vector2& operator=(const Vector3& rhs);
121
122   /**
123    * @brief Assignment operator.
124    *
125    * @param[in] rhs vector to assign.
126    * @return itself
127    */
128   Vector2& operator=(const Vector4& rhs);
129
130   /**
131    * @brief Addition operator.
132    *
133    * @param[in] rhs vector to add.
134    * @return A vector containing the result of the addition
135    */
136   Vector2 operator+(const Vector2& rhs) const
137   {
138     Vector2 temp(*this);
139
140     return temp += rhs;
141   }
142
143   /**
144    * @brief Addition assignment operator.
145    *
146    * @param[in] rhs vector to add.
147    * @return itself
148    */
149   Vector2& operator+=(const Vector2& rhs)
150   {
151     x += rhs.x;
152     y += rhs.y;
153
154     return *this;
155   }
156
157   /**
158    * @brief Subtraction operator.
159    *
160    * @param[in] rhs  the vector to subtract
161    * @return A vector containing the result of the subtraction
162    */
163   Vector2 operator-(const Vector2& rhs) const
164   {
165     Vector2 temp(*this);
166
167     return temp -= rhs;
168   }
169
170   /**
171    * @brief Subtraction assignment operator.
172    *
173    * @param[in] rhs the vector to subtract
174    * @return itself
175    */
176   Vector2& operator-=(const Vector2& rhs)
177   {
178     x -= rhs.x;
179     y -= rhs.y;
180
181     return *this;
182   }
183
184   /**
185    * @brief Multiplication operator.
186    *
187    * @param[in] rhs the vector to multiply
188    * @return A vector containing the result of the multiplication
189    */
190   Vector2 operator*(const Vector2& rhs) const
191   {
192     return Vector2(x * rhs.x, y * rhs.y);
193   }
194
195   /**
196    * @brief Multiplication operator.
197    *
198    * @param[in] rhs the float value to scale the vector
199    * @return A vector containing the result of the scaling
200    */
201   Vector2 operator*(float rhs) const
202   {
203     return Vector2(x * rhs, y * rhs);
204   }
205
206   /**
207    * @brief Multiplication assignment operator.
208    *
209    * @param[in] rhs the vector to multiply
210    * @return itself
211    */
212   Vector2& operator*=(const Vector2& rhs)
213   {
214     x *= rhs.x;
215     y *= rhs.y;
216
217     return *this;
218   }
219
220   /**
221    * @brief Multiplication assignment operator.
222    *
223    * @param[in] rhs the float value to scale the vector
224    * @return itself
225    */
226   Vector2& operator*=(float rhs)
227   {
228     x *= rhs;
229     y *= rhs;
230
231     return *this;
232   }
233
234   /**
235    * @brief Division operator.
236    *
237    * @param[in] rhs the vector to divide
238    * @return A vector containing the result of the division
239    */
240   Vector2 operator/(const Vector2& rhs) const
241   {
242     return Vector2(x / rhs.x, y / rhs.y);
243   }
244
245   /**
246    * @brief Division operator.
247    *
248    * @param[in] rhs The float value to scale the vector by
249    * @return A vector containing the result of the scaling
250    */
251   Vector2 operator/(float rhs) const
252   {
253     return Vector2(x / rhs, y / rhs);
254   }
255
256
257   /**
258    * @brief Division assignment operator.
259    *
260    * @param[in] rhs the vector to divide
261    * @return itself
262    */
263   Vector2& operator/=(const Vector2& rhs)
264   {
265     x /= rhs.x;
266     y /= rhs.y;
267
268     return *this;
269   }
270
271   /**
272    * @brief Division assignment operator.
273    *
274    * @param[in] rhs the float value to scale the vector by
275    * @return itself
276    */
277   Vector2& operator/=(float rhs)
278   {
279     x /= rhs;
280     y /= rhs;
281
282     return *this;
283   }
284
285   /**
286    * @brief Unary negation operator.
287    *
288    * @return A vector containg the negation
289    */
290   Vector2 operator-() const
291   {
292     Vector2 temp(-x, -y);
293
294     return temp;
295   }
296
297   /**
298    * @brief Equality operator.
299    *
300    * utilises appropriate machine epsilon values;
301    *
302    * @param[in] rhs The vector to test against
303    * @return true if the vectors are equal
304    */
305   bool operator==(const Vector2& rhs) const;
306
307   /**
308    * @brief Inequality operator.
309    *
310    * utilises appropriate machine epsilon values;
311    *
312    * @param[in] rhs The vector to test against
313    * @return true if the vectors are not equal
314    */
315   bool operator!=(const Vector2& rhs) const
316   {
317     return !(*this == rhs);
318   }
319
320   /**
321    * @brief Const array subscript operator overload.
322    *
323    * Asserts if index is out of range. Should be 0 or 1
324    * @param[in] index Subscript
325    * @return    The float at the given index
326    */
327   const float& operator[](const unsigned int index) const
328   {
329     DALI_ASSERT_ALWAYS( index < 2 && "Vector element index out of bounds" );
330
331     return AsFloat()[index];
332   }
333
334   /**
335    * @brief Mutable array subscript operator overload.
336    *
337    * Asserts if index is out of range. Should be 0 or 1
338    * @param[in] index Subscript index
339    * @return    The float at the given index.
340    */
341   float& operator[](const unsigned int index)
342   {
343     DALI_ASSERT_ALWAYS( index < 2 && "Vector element index out of bounds" );
344
345     return AsFloat()[index];
346   }
347
348   /**
349    * @brief Returns the length of the vector.
350    *
351    * @return the length of the vector
352    */
353   float Length() const;
354
355   /**
356    * @brief Returns the length of the vector squared.
357    *
358    * This is more efficient than Length() for threshold
359    * testing as it avoids the use of a square root.
360    * @return the length of the vector squared.
361    */
362   float LengthSquared() const;
363
364   /**
365    * @brief Sets the vector to be unit length, whilst maintaining its direction.
366    *
367    */
368   void Normalize();
369
370   /**
371     * @brief Clamps the vector between minimum and maximum vectors.
372     *
373     * @param [in] min the minimum vector
374     * @param [in] max the maximum vector
375    */
376   void Clamp( const Vector2& min, const Vector2& max );
377
378   /**
379    * @brief Returns the contents of the vector as an array of 2 floats.
380    *
381    * The order of the values in this array are as follows:
382    * 0: x (or width)
383    * 1: y (or height)
384    * @note inlined for performance reasons (generates less code than a function call)
385    * @return the vector contents as an array of 2 floats.
386    */
387   const float* AsFloat() const {return &x;}
388
389   /**
390    * @brief Returns the contents of the vector as an array of 2 floats.
391    *
392    * The order of the values in this array are as follows:
393    * 0: x (or width)
394    * 1: y (or height)
395    * @note inlined for performance reasons (generates less code than a function call)
396    * @return the vector contents as an array of 2 floats.
397    */
398   float* AsFloat() {return &x;}
399
400 public: // Data
401
402   // NOTE
403   // (x width) and (y height) must be consecutive in memory.
404   // No other data must be added before (x width) member.
405   // No virtual methods must be added to this struct.
406   union
407   {
408     float x;     ///< x component
409     float width; ///< width
410   };
411
412   union
413   {
414     float y;      ///< y component
415     float height; ///< height
416   };
417
418 };
419
420 /**
421  * @brief Size is an alias of Dali::Vector2
422  */
423 typedef Vector2 Size;
424
425 /**
426  * @brief Print a Vector2.
427  *
428  * @param [in] o The output stream operator.
429  * @param [in] vector The vector to print.
430  * @return The output stream operator.
431  */
432 DALI_IMPORT_API std::ostream& operator<< (std::ostream& o, const Vector2& vector);
433
434 /**
435  * @brief Returns a vector with components set to the minimum of the corresponding component in a and b.
436  *
437  * If a=0,1 and b=1,0  returns a vector of 0,0.
438  * @param [in] a     a vector
439  * @param [in] b     a vector
440  * @return      a vector containing the minimum of each component from a and b
441  */
442 inline Vector2 Min( const Vector2& a, const Vector2& b )
443 {
444   return Vector2( a.x < b.x ? a.x : b.x , a.y < b.y ? a.y : b.y );
445 }
446
447 /**
448  * @brief Returns a vector with components set to the maximum of the corresponding component in a and b.
449  *
450  * If a=0,1 and b=1,0  returns a vector of 1,1
451  * @param [in] a     a vector
452  * @param [in] b     a vector
453  * @return      a vector containing the maximum of each component from a and b
454  */
455 inline Vector2 Max( const Vector2& a, const Vector2& b )
456 {
457   return Vector2( a.x > b.x ? a.x : b.x , a.y > b.y ? a.y : b.y );
458 }
459
460 /**
461  * @brief Clamps each of vector v's components between minimum and maximum values.
462  *
463  * @param [in] v     a vector
464  * @param [in] min the minimum value
465  * @param [in] max the maximum value
466  * @return     a vector containing the clamped components of v
467  */
468 DALI_IMPORT_API Vector2 Clamp( const Vector2& v, const float& min, const float& max );
469
470 /**
471  * @brief Fits source size inside the target size maintaining aspect ratio.
472  *
473  * @pre source width and height > 0
474  * @param [in] target size
475  * @param [in] source size
476  * @return target scaled inside source
477  */
478 DALI_IMPORT_API Size FitInside( const Size& target, const Size& source );
479
480 /**
481  * @brief Fits or scales to fill.
482  *
483  * a) If target width and height are non-zero
484  *    Fits source size into target aspect ratio
485  *    If source is bigger, simply returns target.
486  *    Does not scale larger than source
487  * b) If target width or height is zero
488  *    maintains the aspect ratio of source (as target has no aspect ratio)
489  *    returns target width and scaled height or target height and scaled width
490  * This algorithm is usefull when you want for example a square thumbnail of a rectangular image data
491  * @param [in] target size
492  * @param [in] source size
493  * @return target scaled inside source
494  */
495 DALI_IMPORT_API Size FitScaleToFill( const Size& target, const Size& source );
496
497 /**
498  * @brief Shrinks source size inside the target size maintaining aspect ratio of source.
499  *
500  * If source is smaller than target it returns source.
501  * @pre source width and height > 0
502  * @param [in] target size
503  * @param [in] source size
504  * @return target scaled inside source
505  */
506 DALI_IMPORT_API Size ShrinkInside( const Size& target, const Size& source );
507
508 } // namespace Dali
509
510 #endif // __DALI_VECTOR_2_H__