Colobot
func.h
Go to the documentation of this file.
1 /*
2  * This file is part of the Colobot: Gold Edition source code
3  * Copyright (C) 2001-2016, Daniel Roux, EPSITEC SA & TerranovaTeam
4  * http://epsitec.ch; http://colobot.info; http://github.com/colobot
5  *
6  * This program is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation, either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14  * See the GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program. If not, see http://gnu.org/licenses
18  */
19 
25 #pragma once
26 
27 
28 #include "math/const.h"
29 
30 
31 #include <cmath>
32 #include <cstdlib>
33 
34 
35 // Math module namespace
36 namespace Math
37 {
38 
39 
41 inline bool IsEqual(float a, float b, float tolerance = Math::TOLERANCE)
42 {
43  return fabs(a - b) < tolerance;
44 }
45 
47 inline bool IsZero(float a, float tolerance = Math::TOLERANCE)
48 {
49  return Math::IsEqual(a, 0.0f, tolerance);
50 }
51 
53 inline float Min(float a, float b)
54 {
55  if ( a <= b ) return a;
56  else return b;
57 }
58 
59 inline float Min(float a, float b, float c)
60 {
61  return Min( Min(a, b), c );
62 }
63 
64 inline float Min(float a, float b, float c, float d)
65 {
66  return Math::Min( Math::Min(a, b), Math::Min(c, d) );
67 }
68 
69 inline float Min(float a, float b, float c, float d, float e)
70 {
71  return Math::Min( Math::Min(a, b), Math::Min(c, d), e );
72 }
73 
75 inline float Max(float a, float b)
76 {
77  if ( a >= b ) return a;
78  else return b;
79 }
80 
81 inline float Max(float a, float b, float c)
82 {
83  return Math::Max( Math::Max(a, b), c );
84 }
85 
86 inline float Max(float a, float b, float c, float d)
87 {
88  return Math::Max( Math::Max(a, b), Math::Max(c, d) );
89 }
90 
91 inline float Max(float a, float b, float c, float d, float e)
92 {
93  return Math::Max( Math::Max(a, b), Math::Max(c, d), e );
94 }
95 
97 template<typename T>
98 inline T Clamp(T value, T min, T max)
99 {
100  if (value < min) return min;
101  else if (value > max) return max;
102  else return value;
103 }
104 
106 inline float Norm(float a)
107 {
108  if ( a < 0.0f ) return 0.0f;
109  if ( a > 1.0f ) return 1.0f;
110  return a;
111 }
112 
114 inline void Swap(int &a, int &b)
115 {
116  int c = a;
117  a = b;
118  b = c;
119 }
120 
122 inline void Swap(float &a, float &b)
123 {
124  float c = a;
125  a = b;
126  b = c;
127 }
128 
130 
132 inline float Mod(float a, float m)
133 {
134  return a - ( static_cast<int>(a / m) ) * m;
135 }
136 
138 inline float Rand()
139 {
140  return static_cast<float>(rand()) / static_cast<float>(RAND_MAX);
141 }
142 
144 inline bool IsPowerOfTwo(unsigned int x)
145 {
146  return x && !(x & (x - 1));
147 }
148 
150 inline int NextPowerOfTwo(int x)
151 {
152  double logbase2 = log(static_cast<float>(x)) / Math::LOG_2;
153  return static_cast<int>(pow(2, ceil(logbase2)) + 0.5);
154 }
155 
156 
158 inline float NormAngle(float angle)
159 {
160  angle = Math::Mod(angle, PI*2.0f);
161  if ( angle < 0.0f )
162  return PI*2.0f + angle;
163 
164  return angle;
165 }
166 
168 inline bool TestAngle(float angle, float min, float max)
169 {
170  angle = Math::NormAngle(angle);
171  min = Math::NormAngle(min);
172  max = Math::NormAngle(max);
173 
174  if ( min > max )
175  return ( angle <= max || angle >= min );
176 
177  return ( angle >= min && angle <= max );
178 }
179 
181 inline float PropAngle(float a, float b, float p)
182 {
183  float aa = a * DEG_TO_RAD;
184  float bb = b * DEG_TO_RAD;
185 
186  return aa + p * (bb - aa);
187 }
188 
190 
191 inline float Direction(float a, float g)
192 {
193  a = Math::NormAngle(a);
194  g = Math::NormAngle(g);
195 
196  if ( a < g )
197  {
198  if ( a+PI*2.0f-g < g-a ) a += PI*2.0f;
199  }
200  else
201  {
202  if ( g+PI*2.0f-a < a-g ) g += PI*2.0f;
203  }
204 
205  return g-a;
206 }
207 
209 
217 inline float Neutral(float value, float dead)
218 {
219  if ( fabs(value) <= dead )
220  {
221  return 0.0f;
222  }
223  else
224  {
225  if ( value > 0.0f ) return (value-dead)/(1.0f-dead);
226  else return (value+dead)/(1.0f-dead);
227  }
228 }
229 
231 
232 inline float Smooth(float actual, float hope, float time)
233 {
234  float future = actual + (hope-actual)*time;
235 
236  if ( hope > actual )
237  {
238  if ( future > hope ) future = hope;
239  }
240  if ( hope < actual )
241  {
242  if ( future < hope ) future = hope;
243  }
244 
245  return future;
246 }
247 
249 
262 inline float Bounce(float progress, float middle = 0.3f, float bounce = 0.4f)
263 {
264  if ( progress < middle )
265  {
266  progress = progress/middle; // 0..1
267  return 0.5f+sinf(progress*PI-PI/2.0f)/2.0f;
268  }
269  else
270  {
271  progress = (progress-middle)/(1.0f-middle); // 0..1
272  return (1.0f-bounce/2.0f)+sinf((0.5f+progress*2.0f)*PI)*(bounce/2.0f);
273  }
274 }
275 
276 
277 } // namespace Math
278 
bool TestAngle(float angle, float min, float max)
Test if a angle is between two terminals.
Definition: func.h:168
const float DEG_TO_RAD
Degrees to radians multiplier.
Definition: const.h:51
const float TOLERANCE
Tolerance level – minimum accepted float value.
Definition: const.h:37
bool IsZero(float a, float tolerance=Math::TOLERANCE)
Compares a to zero within tolerance.
Definition: func.h:47
float Max(float a, float b)
Maximum.
Definition: func.h:75
float NormAngle(float angle)
Returns a normalized angle, that is in other words between 0 and 2 * PI.
Definition: func.h:158
float Direction(float a, float g)
Calculates the angle to rotate the angle a to the angle g.
Definition: func.h:191
float Mod(float a, float m)
Returns the modulo of a floating point number.
Definition: func.h:132
float Smooth(float actual, float hope, float time)
Gently advances a desired value from its current value.
Definition: func.h:232
const float PI
PI.
Definition: const.h:48
float Norm(float a)
Returns the normalized value (0 .. 1)
Definition: func.h:106
bool IsPowerOfTwo(unsigned int x)
Returns whether x is an even power of 2.
Definition: func.h:144
float Rand()
Returns a random value between 0 and 1.
Definition: func.h:138
bool IsEqual(float a, float b, float tolerance=Math::TOLERANCE)
Compares a and b within tolerance.
Definition: func.h:41
Namespace for (new) math code.
Definition: device.h:39
float Bounce(float progress, float middle=0.3f, float bounce=0.4f)
Bounces any movement.
Definition: func.h:262
const float LOG_2
Natural logarithm of 2.
Definition: const.h:56
void Swap(int &a, int &b)
Swaps two integers.
Definition: func.h:114
float Min(float a, float b)
Minimum.
Definition: func.h:53
T Clamp(T value, T min, T max)
Clamps the value to a range specified by min and max.
Definition: func.h:98
Constants used in math functions.
float Neutral(float value, float dead)
Managing the dead zone of a joystick.
Definition: func.h:217
int NextPowerOfTwo(int x)
Returns the next nearest power of two to x.
Definition: func.h:150
float PropAngle(float a, float b, float p)
Calculates a value (radians) proportional between a and b (degrees)
Definition: func.h:181