MAV'RIC
|
00001 /******************************************************************************* 00002 * Copyright (c) 2009-2016, MAV'RIC Development Team 00003 * All rights reserved. 00004 * 00005 * Redistribution and use in source and binary forms, with or without 00006 * modification, are permitted provided that the following conditions are met: 00007 * 00008 * 1. Redistributions of source code must retain the above copyright notice, 00009 * this list of conditions and the following disclaimer. 00010 * 00011 * 2. Redistributions in binary form must reproduce the above copyright notice, 00012 * this list of conditions and the following disclaimer in the documentation 00013 * and/or other materials provided with the distribution. 00014 * 00015 * 3. Neither the name of the copyright holder nor the names of its contributors 00016 * may be used to endorse or promote products derived from this software without 00017 * specific prior written permission. 00018 * 00019 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 00020 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00021 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 00022 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 00023 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 00024 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 00025 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 00026 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 00027 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 00028 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 00029 * POSSIBILITY OF SUCH DAMAGE. 00030 ******************************************************************************/ 00031 00032 /******************************************************************************* 00033 * \file maths.h 00034 * 00035 * \author MAV'RIC Team 00036 * \author Felix Schill 00037 * \author Geraud L'Eplattenier 00038 * 00039 * \brief Useful math functions 00040 * 00041 ******************************************************************************/ 00042 00043 00044 #ifndef MATHS_H 00045 #define MATHS_H 00046 00047 #ifdef __cplusplus 00048 extern "C" 00049 { 00050 #endif 00051 00052 #include <stdint.h> 00053 #include <math.h> 00054 00055 #define PI 3.141592653589793f ///< Declaration of PI for math computation 00056 00057 00061 #define MATH_DEG_TO_RAD (PI/180.0f) 00062 00063 00067 #define MATH_RAD_TO_DEG (180.0f/PI) 00068 00069 00076 #define SQR(in) \ 00077 ((in)*(in)) 00078 00079 00086 float static inline maths_deg_to_rad(float i) 00087 { 00088 return MATH_DEG_TO_RAD * i; 00089 } 00090 00091 00098 float static inline maths_rad_to_deg(float i) 00099 { 00100 return MATH_RAD_TO_DEG * i; 00101 } 00102 00103 00111 float static inline maths_calc_smaller_angle(float angle) 00112 { 00113 float out; 00114 00115 if (angle > 0.0f) 00116 { 00117 out = fmod(angle + PI, 2.0f * PI) - PI; 00118 } 00119 else 00120 { 00121 out = fmod(angle - PI, 2.0f * PI) + PI; 00122 } 00123 00124 return out; 00125 } 00126 00127 00137 float static inline maths_fast_inv_sqrt(float number) 00138 { 00139 union 00140 { 00141 float f; 00142 int32_t l; 00143 } i; 00144 00145 float x, y; 00146 const float f = 1.5f; 00147 00148 x = number * 0.5f; 00149 i.f = number; 00150 i.l = 0x5f3759df - (i.l >> 1); 00151 y = i.f; 00152 y = y * (f - (x * y * y)); 00153 return y; 00154 } 00155 00156 00164 float static inline maths_fast_sqrt(float number) 00165 { 00166 union 00167 { 00168 float f; 00169 int32_t l; 00170 } i; 00171 00172 float x, y; 00173 const float f = 1.5f; 00174 00175 x = number * 0.5f; 00176 i.f = number; 00177 i.l = 0x5f3759df - (i.l >> 1); 00178 y = i.f; 00179 y = y * (f - (x * y * y)); 00180 y = y * (f - (x * y * y)); // repeat newton iteration for more accuracy 00181 return number * y; 00182 } 00183 00184 00192 float static inline maths_fast_sqrt_1(float input) 00193 { 00194 if (input < 0) 00195 { 00196 return 0.0f; 00197 } 00198 00199 float result = 1.0f; 00200 00201 result = 0.5f * (result + (input / result)); 00202 result = 0.5f * (result + (input / result)); 00203 00204 return result; 00205 } 00206 00207 00215 static inline float maths_f_abs(const float a) 00216 { 00217 if (a >= 0.0f) 00218 { 00219 return a; 00220 } 00221 else 00222 { 00223 return -a; 00224 } 00225 } 00226 00227 00236 static inline float maths_f_min(const float a, const float b) 00237 { 00238 if (a <= b) 00239 { 00240 return a; 00241 } 00242 else 00243 { 00244 return b; 00245 } 00246 } 00247 00248 00257 static inline float maths_f_max(const float a, const float b) 00258 { 00259 if (a >= b) 00260 { 00261 return a; 00262 } 00263 else 00264 { 00265 return b; 00266 } 00267 } 00268 00269 00280 static float inline maths_clip(float input_value, float clip_value) 00281 { 00282 if (input_value > clip_value) return clip_value; 00283 if (input_value < -clip_value) return -clip_value; 00284 return input_value; 00285 } 00286 00287 00296 static float inline maths_soft_zone(float x, float soft_zone_width) 00297 { 00298 if (soft_zone_width < 0.0000001f) 00299 { 00300 return x; 00301 } 00302 else 00303 { 00304 return x * x * x / (SQR(soft_zone_width) + SQR(x)); 00305 } 00306 }; 00307 00308 00315 static float inline maths_sigmoid(float x) 00316 { 00317 return (x / maths_fast_sqrt(1 + SQR(x))); 00318 }; 00319 00320 00327 static float inline maths_center_window_2(float x) 00328 { 00329 return 1.0f / (1 + SQR(x)); 00330 } 00331 00332 00339 static float inline maths_center_window_4(float x) 00340 { 00341 return 1.0f / (1 + SQR(SQR(x))); 00342 } 00343 00344 00356 static float inline maths_median_filter_3x(float a, float b, float c) 00357 { 00358 float middle; 00359 00360 if ((a <= b) && (a <= c)) 00361 { 00362 middle = (b <= c) ? b : c; 00363 } 00364 else if ((b <= a) && (b <= c)) 00365 { 00366 middle = (a <= c) ? a : c; 00367 } 00368 else 00369 { 00370 middle = (a <= b) ? a : b; 00371 } 00372 00373 return middle; 00374 } 00375 00376 00390 static inline float maths_interpolate(float x, float x1, float x2, float y1, float y2) 00391 { 00392 if (x1 == x2) 00393 { 00394 return y1; 00395 } 00396 else 00397 { 00398 float y = y1 + (y2 - y1) * (x - x1) / (x2 - x1); 00399 return y; 00400 } 00401 } 00402 00403 00404 static inline int8_t maths_sign(float x) 00405 { 00406 if (x >= 0.0f) 00407 { 00408 return 1.0f; 00409 } 00410 else 00411 { 00412 return -1.0f; 00413 } 00414 } 00415 00416 00417 #ifdef __cplusplus 00418 } 00419 #endif 00420 00421 #endif /* MATHS_H */