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-2014, Daniel Roux, EPSITEC SA & TerranovaTeam
4  * http://epsiteс.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 
40 inline bool IsEqual(float a, float b, float tolerance = Math::TOLERANCE)
41 {
42  return fabs(a - b) < tolerance;
43 }
44 
46 inline bool IsZero(float a, float tolerance = Math::TOLERANCE)
47 {
48  return Math::IsEqual(a, 0.0f, tolerance);
49 }
50 
52 inline float Min(float a, float b)
53 {
54  if ( a <= b ) return a;
55  else return b;
56 }
57 
58 inline float Min(float a, float b, float c)
59 {
60  return Min( Min(a, b), c );
61 }
62 
63 inline float Min(float a, float b, float c, float d)
64 {
65  return Math::Min( Math::Min(a, b), Math::Min(c, d) );
66 }
67 
68 inline float Min(float a, float b, float c, float d, float e)
69 {
70  return Math::Min( Math::Min(a, b), Math::Min(c, d), e );
71 }
72 
74 inline float Max(float a, float b)
75 {
76  if ( a >= b ) return a;
77  else return b;
78 }
79 
80 inline float Max(float a, float b, float c)
81 {
82  return Math::Max( Math::Max(a, b), c );
83 }
84 
85 inline float Max(float a, float b, float c, float d)
86 {
87  return Math::Max( Math::Max(a, b), Math::Max(c, d) );
88 }
89 
90 inline float Max(float a, float b, float c, float d, float e)
91 {
92  return Math::Max( Math::Max(a, b), Math::Max(c, d), e );
93 }
94 
96 inline float Norm(float a)
97 {
98  if ( a < 0.0f ) return 0.0f;
99  if ( a > 1.0f ) return 1.0f;
100  return a;
101 }
102 
104 inline void Swap(int &a, int &b)
105 {
106  int c = a;
107  a = b;
108  b = c;
109 }
110 
112 inline void Swap(float &a, float &b)
113 {
114  float c = a;
115  a = b;
116  b = c;
117 }
118 
120 
122 inline float Mod(float a, float m)
123 {
124  return a - ( static_cast<int>(a / m) ) * m;
125 }
126 
128 inline float Rand()
129 {
130  return static_cast<float>(rand()) / static_cast<float>(RAND_MAX);
131 }
132 
134 inline bool IsPowerOfTwo(unsigned int x)
135 {
136  return x && !(x & (x - 1));
137 }
138 
140 inline int NextPowerOfTwo(int x)
141 {
142  double logbase2 = log(static_cast<float>(x)) / Math::LOG_2;
143  return static_cast<int>(pow(2, ceil(logbase2)) + 0.5);
144 }
145 
146 
148 inline float NormAngle(float angle)
149 {
150  angle = Math::Mod(angle, PI*2.0f);
151  if ( angle < 0.0f )
152  return PI*2.0f + angle;
153 
154  return angle;
155 }
156 
158 inline bool TestAngle(float angle, float min, float max)
159 {
160  angle = Math::NormAngle(angle);
161  min = Math::NormAngle(min);
162  max = Math::NormAngle(max);
163 
164  if ( min > max )
165  return ( angle <= max || angle >= min );
166 
167  return ( angle >= min && angle <= max );
168 }
169 
171 inline float PropAngle(int a, int b, float p)
172 {
173  float aa = static_cast<float>(a) * DEG_TO_RAD;
174  float bb = static_cast<float>(b) * DEG_TO_RAD;
175 
176  return aa + p * (bb - aa);
177 }
178 
180 
181 inline float Direction(float a, float g)
182 {
183  a = Math::NormAngle(a);
184  g = Math::NormAngle(g);
185 
186  if ( a < g )
187  {
188  if ( a+PI*2.0f-g < g-a ) a += PI*2.0f;
189  }
190  else
191  {
192  if ( g+PI*2.0f-a < a-g ) g += PI*2.0f;
193  }
194 
195  return g-a;
196 }
197 
199 
207 inline float Neutral(float value, float dead)
208 {
209  if ( fabs(value) <= dead )
210  {
211  return 0.0f;
212  }
213  else
214  {
215  if ( value > 0.0f ) return (value-dead)/(1.0f-dead);
216  else return (value+dead)/(1.0f-dead);
217  }
218 }
219 
221 
222 inline float Smooth(float actual, float hope, float time)
223 {
224  float future = actual + (hope-actual)*time;
225 
226  if ( hope > actual )
227  {
228  if ( future > hope ) future = hope;
229  }
230  if ( hope < actual )
231  {
232  if ( future < hope ) future = hope;
233  }
234 
235  return future;
236 }
237 
239 
252 inline float Bounce(float progress, float middle = 0.3f, float bounce = 0.4f)
253 {
254  if ( progress < middle )
255  {
256  progress = progress/middle; // 0..1
257  return 0.5f+sinf(progress*PI-PI/2.0f)/2.0f;
258  }
259  else
260  {
261  progress = (progress-middle)/(1.0f-middle); // 0..1
262  return (1.0f-bounce/2.0f)+sinf((0.5f+progress*2.0f)*PI)*(bounce/2.0f);
263  }
264 }
265 
266 
267 } // namespace Math
268 
bool TestAngle(float angle, float min, float max)
Test if a angle is between two terminals.
Definition: func.h:158
const float DEG_TO_RAD
Degrees to radians multiplier.
Definition: const.h:50
const float TOLERANCE
Tolerance level – minimum accepted float value.
Definition: const.h:36
bool IsZero(float a, float tolerance=Math::TOLERANCE)
Compares a to zero within tolerance.
Definition: func.h:46
float Max(float a, float b)
Maximum.
Definition: func.h:74
float NormAngle(float angle)
Returns a normalized angle, that is in other words between 0 and 2 * PI.
Definition: func.h:148
float Direction(float a, float g)
Calculates the angle to rotate the angle a to the angle g.
Definition: func.h:181
float Mod(float a, float m)
Returns the modulo of a floating point number.
Definition: func.h:122
float Smooth(float actual, float hope, float time)
Gently advances a desired value from its current value.
Definition: func.h:222
const float PI
PI.
Definition: const.h:47
float Norm(float a)
Returns the normalized value (0 .. 1)
Definition: func.h:96
bool IsPowerOfTwo(unsigned int x)
Returns whether x is an even power of 2.
Definition: func.h:134
float Rand()
Returns a random value between 0 and 1.
Definition: func.h:128
bool IsEqual(float a, float b, float tolerance=Math::TOLERANCE)
Compares a and b within tolerance.
Definition: func.h:40
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:252
const float LOG_2
Natural logarithm of 2.
Definition: const.h:55
void Swap(int &a, int &b)
Swaps two integers.
Definition: func.h:104
float Min(float a, float b)
Minimum.
Definition: func.h:52
Constants used in math functions.
float Neutral(float value, float dead)
Managing the dead zone of a joystick.
Definition: func.h:207
int NextPowerOfTwo(int x)
Returns the next nearest power of two to x.
Definition: func.h:140
float PropAngle(int a, int b, float p)
Calculates a value (radians) proportional between a and b (degrees)
Definition: func.h:171