Colobot
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Pages
func.h
Go to the documentation of this file.
1 // * This file is part of the COLOBOT source code
2 // * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch
3 // * Copyright (C) 2012, Polish Portal of Colobot (PPC)
4 // *
5 // * This program is free software: you can redistribute it and/or modify
6 // * it under the terms of the GNU General Public License as published by
7 // * the Free Software Foundation, either version 3 of the License, or
8 // * (at your option) any later version.
9 // *
10 // * This program is distributed in the hope that it will be useful,
11 // * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // * GNU General Public License for more details.
14 // *
15 // * You should have received a copy of the GNU General Public License
16 // * along with this program. If not, see http://www.gnu.org/licenses/.
17 
23 #pragma once
24 
25 
26 #include "math/const.h"
27 
28 
29 #include <cmath>
30 #include <cstdlib>
31 
32 
33 // Math module namespace
34 namespace Math {
35 
36 
38 inline bool IsEqual(float a, float b, float tolerance = Math::TOLERANCE)
39 {
40  return fabs(a - b) < tolerance;
41 }
42 
44 inline bool IsZero(float a, float tolerance = Math::TOLERANCE)
45 {
46  return Math::IsEqual(a, 0.0f, tolerance);
47 }
48 
50 inline float Min(float a, float b)
51 {
52  if ( a <= b ) return a;
53  else return b;
54 }
55 
56 inline float Min(float a, float b, float c)
57 {
58  return Min( Min(a, b), c );
59 }
60 
61 inline float Min(float a, float b, float c, float d)
62 {
63  return Math::Min( Math::Min(a, b), Math::Min(c, d) );
64 }
65 
66 inline float Min(float a, float b, float c, float d, float e)
67 {
68  return Math::Min( Math::Min(a, b), Math::Min(c, d), e );
69 }
70 
72 inline float Max(float a, float b)
73 {
74  if ( a >= b ) return a;
75  else return b;
76 }
77 
78 inline float Max(float a, float b, float c)
79 {
80  return Math::Max( Math::Max(a, b), c );
81 }
82 
83 inline float Max(float a, float b, float c, float d)
84 {
85  return Math::Max( Math::Max(a, b), Math::Max(c, d) );
86 }
87 
88 inline float Max(float a, float b, float c, float d, float e)
89 {
90  return Math::Max( Math::Max(a, b), Math::Max(c, d), e );
91 }
92 
94 inline float Norm(float a)
95 {
96  if ( a < 0.0f ) return 0.0f;
97  if ( a > 1.0f ) return 1.0f;
98  return a;
99 }
100 
102 inline void Swap(int &a, int &b)
103 {
104  int c = a;
105  a = b;
106  b = c;
107 }
108 
110 inline void Swap(float &a, float &b)
111 {
112  float c = a;
113  a = b;
114  b = c;
115 }
116 
118 
120 inline float Mod(float a, float m)
121 {
122  return a - ( static_cast<int>(a / m) ) * m;
123 }
124 
126 inline float Rand()
127 {
128  return static_cast<float>(rand()) / static_cast<float>(RAND_MAX);
129 }
130 
132 inline bool IsPowerOfTwo(unsigned int x)
133 {
134  return x && !(x & (x - 1));
135 }
136 
138 inline int NextPowerOfTwo(int x)
139 {
140  double logbase2 = log(static_cast<float>(x)) / Math::LOG_2;
141  return static_cast<int>(pow(2, ceil(logbase2)) + 0.5);
142 }
143 
144 
146 inline float NormAngle(float angle)
147 {
148  angle = Math::Mod(angle, PI*2.0f);
149  if ( angle < 0.0f )
150  return PI*2.0f + angle;
151 
152  return angle;
153 }
154 
156 inline bool TestAngle(float angle, float min, float max)
157 {
158  angle = Math::NormAngle(angle);
159  min = Math::NormAngle(min);
160  max = Math::NormAngle(max);
161 
162  if ( min > max )
163  return ( angle <= max || angle >= min );
164 
165  return ( angle >= min && angle <= max );
166 }
167 
169 inline float PropAngle(int a, int b, float p)
170 {
171  float aa = static_cast<float>(a) * DEG_TO_RAD;
172  float bb = static_cast<float>(b) * DEG_TO_RAD;
173 
174  return aa + p * (bb - aa);
175 }
176 
178 
179 inline float Direction(float a, float g)
180 {
181  a = Math::NormAngle(a);
182  g = Math::NormAngle(g);
183 
184  if ( a < g )
185  {
186  if ( a+PI*2.0f-g < g-a ) a += PI*2.0f;
187  }
188  else
189  {
190  if ( g+PI*2.0f-a < a-g ) g += PI*2.0f;
191  }
192 
193  return g-a;
194 }
195 
197 
205 inline float Neutral(float value, float dead)
206 {
207  if ( fabs(value) <= dead )
208  {
209  return 0.0f;
210  }
211  else
212  {
213  if ( value > 0.0f ) return (value-dead)/(1.0f-dead);
214  else return (value+dead)/(1.0f-dead);
215  }
216 }
217 
219 
220 inline float Smooth(float actual, float hope, float time)
221 {
222  float future = actual + (hope-actual)*time;
223 
224  if ( hope > actual )
225  {
226  if ( future > hope ) future = hope;
227  }
228  if ( hope < actual )
229  {
230  if ( future < hope ) future = hope;
231  }
232 
233  return future;
234 }
235 
237 
250 inline float Bounce(float progress, float middle = 0.3f, float bounce = 0.4f)
251 {
252  if ( progress < middle )
253  {
254  progress = progress/middle; // 0..1
255  return 0.5f+sinf(progress*PI-PI/2.0f)/2.0f;
256  }
257  else
258  {
259  progress = (progress-middle)/(1.0f-middle); // 0..1
260  return (1.0f-bounce/2.0f)+sinf((0.5f+progress*2.0f)*PI)*(bounce/2.0f);
261  }
262 }
263 
264 
265 } // namespace Math
266