Merge "move constants to unnamed namespace to prevent compiler&linker from treating...
[platform/core/uifw/dali-core.git] / dali / public-api / math / math-utils.cpp
1 /*
2  * Copyright (c) 2014 Samsung Electronics Co., Ltd.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */
17
18 // CLASS HEADER
19 #include <dali/public-api/math/math-utils.h>
20
21 // EXTERNAL INCLUDES
22 #include <math.h>
23
24 // INTERNAL INCLUDES
25 #include <dali/public-api/common/constants.h>
26
27
28 namespace Dali
29 {
30
31 unsigned int NextPowerOfTwo(unsigned int i)
32 {
33   DALI_ASSERT_DEBUG(i <= 1U << (sizeof(unsigned) * 8 - 1) && "Return type cannot represent the next power of two greater than the argument.");
34   if(i==0)
35   {
36     return 1;
37   }
38
39   i--;
40   i |= i >> 1;
41   i |= i >> 2;
42   i |= i >> 4;
43   i |= i >> 8;
44   i |= i >> 16;
45   i++;
46   return i;
47 }
48
49 bool IsPowerOfTwo(unsigned int i)
50 {
51   return (i != 0) && ((i & (i - 1)) == 0);
52 }
53
54 float GetRangedEpsilon(float a, float b)
55 {
56   float abs_f = std::max(fabsf(a), fabsf(b));
57   int abs_i = (int) abs_f;
58
59   float epsilon = Math::MACHINE_EPSILON_10000;
60   if (abs_f < 0.1f)
61   {
62     return Math::MACHINE_EPSILON_0;
63   }
64   else if (abs_i < 2)
65   {
66     return Math::MACHINE_EPSILON_1;
67   }
68   else if (abs_i < 20)
69   {
70     return Math::MACHINE_EPSILON_10;
71   }
72   else if (abs_i < 200)
73   {
74     return Math::MACHINE_EPSILON_100;
75   }
76   else if (abs_i < 2000)
77   {
78     return Math::MACHINE_EPSILON_1000;
79   }
80   return epsilon;
81 }
82
83 // TODO: Change this to use #pragma GCC diagnostic push / pop when the compiler is updated to 4.6.0+
84 #pragma GCC diagnostic ignored "-Wfloat-equal"
85 bool EqualsZero( float value )
86 {
87   return value == 0.0f;
88 }
89 #pragma GCC diagnostic error "-Wfloat-equal"
90
91 bool Equals( float a, float b )
92 {
93   return ( fabsf( a - b ) <= GetRangedEpsilon( a, b ) );
94 }
95
96 bool Equals( float a, float b, float epsilon )
97 {
98   return ( fabsf( a - b ) <= epsilon );
99 }
100
101 float Round(float value, int pos)
102 {
103   float temp;
104   temp = value * powf( 10, pos );
105   temp = floorf( temp + 0.5 );
106   temp *= powf( 10, -pos );
107   return temp;
108 }
109
110 float WrapInDomain(float x, float start, float end)
111 {
112   float domain = end - start;
113   x -= start;
114
115   if(fabsf(domain) > Math::MACHINE_EPSILON_1)
116   {
117     return start + (x - floorf(x / domain) * domain);
118   }
119
120   return start;
121 }
122
123 float ShortestDistanceInDomain(float a, float b, float start, float end)
124 {
125   //  (a-start + end-b)
126   float size = end-start;
127   float vect = b-a;
128
129   if(vect > 0)
130   {
131     // +ve vector, let's try perspective 1 domain to the right,
132     // and see if closer.
133     float aRight = a+size;
134     if( aRight-b < vect )
135     {
136       return b-aRight;
137     }
138   }
139   else
140   {
141     // -ve vector, let's try perspective 1 domain to the left,
142     // and see if closer.
143     float aLeft = a-size;
144     if( aLeft-b > vect )
145     {
146       return b-aLeft;
147     }
148   }
149
150   return vect;
151 }
152
153 } // namespace Dali