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