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-2015, 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 inline float Norm(float a)
98 {
99  if ( a < 0.0f ) return 0.0f;
100  if ( a > 1.0f ) return 1.0f;
101  return a;
102 }
103 
105 inline void Swap(int &a, int &b)
106 {
107  int c = a;
108  a = b;
109  b = c;
110 }
111 
113 inline void Swap(float &a, float &b)
114 {
115  float c = a;
116  a = b;
117  b = c;
118 }
119 
121 
123 inline float Mod(float a, float m)
124 {
125  return a - ( static_cast<int>(a / m) ) * m;
126 }
127 
129 inline float Rand()
130 {
131  return static_cast<float>(rand()) / static_cast<float>(RAND_MAX);
132 }
133 
135 inline bool IsPowerOfTwo(unsigned int x)
136 {
137  return x && !(x & (x - 1));
138 }
139 
141 inline int NextPowerOfTwo(int x)
142 {
143  double logbase2 = log(static_cast<float>(x)) / Math::LOG_2;
144  return static_cast<int>(pow(2, ceil(logbase2)) + 0.5);
145 }
146 
147 
149 inline float NormAngle(float angle)
150 {
151  angle = Math::Mod(angle, PI*2.0f);
152  if ( angle < 0.0f )
153  return PI*2.0f + angle;
154 
155  return angle;
156 }
157 
159 inline bool TestAngle(float angle, float min, float max)
160 {
161  angle = Math::NormAngle(angle);
162  min = Math::NormAngle(min);
163  max = Math::NormAngle(max);
164 
165  if ( min > max )
166  return ( angle <= max || angle >= min );
167 
168  return ( angle >= min && angle <= max );
169 }
170 
172 inline float PropAngle(int a, int b, float p)
173 {
174  float aa = static_cast<float>(a) * DEG_TO_RAD;
175  float bb = static_cast<float>(b) * DEG_TO_RAD;
176 
177  return aa + p * (bb - aa);
178 }
179 
181 
182 inline float Direction(float a, float g)
183 {
184  a = Math::NormAngle(a);
185  g = Math::NormAngle(g);
186 
187  if ( a < g )
188  {
189  if ( a+PI*2.0f-g < g-a ) a += PI*2.0f;
190  }
191  else
192  {
193  if ( g+PI*2.0f-a < a-g ) g += PI*2.0f;
194  }
195 
196  return g-a;
197 }
198 
200 
208 inline float Neutral(float value, float dead)
209 {
210  if ( fabs(value) <= dead )
211  {
212  return 0.0f;
213  }
214  else
215  {
216  if ( value > 0.0f ) return (value-dead)/(1.0f-dead);
217  else return (value+dead)/(1.0f-dead);
218  }
219 }
220 
222 
223 inline float Smooth(float actual, float hope, float time)
224 {
225  float future = actual + (hope-actual)*time;
226 
227  if ( hope > actual )
228  {
229  if ( future > hope ) future = hope;
230  }
231  if ( hope < actual )
232  {
233  if ( future < hope ) future = hope;
234  }
235 
236  return future;
237 }
238 
240 
253 inline float Bounce(float progress, float middle = 0.3f, float bounce = 0.4f)
254 {
255  if ( progress < middle )
256  {
257  progress = progress/middle; // 0..1
258  return 0.5f+sinf(progress*PI-PI/2.0f)/2.0f;
259  }
260  else
261  {
262  progress = (progress-middle)/(1.0f-middle); // 0..1
263  return (1.0f-bounce/2.0f)+sinf((0.5f+progress*2.0f)*PI)*(bounce/2.0f);
264  }
265 }
266 
267 
268 } // namespace Math
269 
bool TestAngle(float angle, float min, float max)
Test if a angle is between two terminals.
Definition: func.h:159
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:149
float Direction(float a, float g)
Calculates the angle to rotate the angle a to the angle g.
Definition: func.h:182
float Mod(float a, float m)
Returns the modulo of a floating point number.
Definition: func.h:123
float Smooth(float actual, float hope, float time)
Gently advances a desired value from its current value.
Definition: func.h:223
const float PI
PI.
Definition: const.h:48
float Norm(float a)
Returns the normalized value (0 .. 1)
Definition: func.h:97
bool IsPowerOfTwo(unsigned int x)
Returns whether x is an even power of 2.
Definition: func.h:135
float Rand()
Returns a random value between 0 and 1.
Definition: func.h:129
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: const.h:32
float Bounce(float progress, float middle=0.3f, float bounce=0.4f)
Bounces any movement.
Definition: func.h:253
const float LOG_2
Natural logarithm of 2.
Definition: const.h:56
void Swap(int &a, int &b)
Swaps two integers.
Definition: func.h:105
float Min(float a, float b)
Minimum.
Definition: func.h:53
Constants used in math functions.
float Neutral(float value, float dead)
Managing the dead zone of a joystick.
Definition: func.h:208
int NextPowerOfTwo(int x)
Returns the next nearest power of two to x.
Definition: func.h:141
float PropAngle(int a, int b, float p)
Calculates a value (radians) proportional between a and b (degrees)
Definition: func.h:172