Retour Suite
sylvainmahe.site LE SITE de Sylvain Mahé contact@sylvainmahe.site
Article : Sylvain Mahé contact@sylvainmahe.site Les fonctions mathématiques avec Math.h La logique pure est généralement accompagnée de calculs arithmétiques pour mener à bien un projet, pour se faire le microcontrôleur est équipé d'une unité arithmétique et logique (l'ALU pour "Arithmetic Logic Unit") permettant uniquement d'effectuer des opérations simples, telles les additions, soustractions, multiplications, et divisions (en virgule flottante si besoin) : En effet l'unité arithmétique et logique des microcontrôleurs mis en œuvre dans mes automates programmables ne permettent pas d'effectuer des opérations arithmétiques autres que les calculs élémentaires énoncés ci-dessus (additions, soustractions, multiplications, et divisions), comprendre que des opérations plus complexes comme par exemple sinus ou cosinus ne sont pas câblés en interne dans le circuit intégré (comme c'est le cas dans la plupart des microcontrôleurs). C'est pourquoi ces opérations mathématiques plus lourdes prenants un certain nombre d'instructions de base (additions, soustractions, etc...), il est plus aisé de les écrire et les conditionner dans une classe dédiée de sorte de pouvoir les appeler facilement en un minimum de lignes de programmation, c'est ce que permet Math.h. Descriptif des fonctions de Math.h : - floor : arrondit un nombre décimal à l'entier inférieur.
- round : arrondit un nombre décimal à l'entier le plus proche.
- ceil : arrondit un nombre décimal à l'entier supérieur.
- curve : créé des interpolations linéaires ou exponentielles de courbes.
- wurve : créé des interpolations linéaires ou exponentielles dissymétriques de courbes.
- range : cadre une valeur dans un intervalle.
- center : calcule la moyenne de deux valeurs.
- pow : calcule la puissance d'un nombre.
- sqrt : calcule la racine carrée d'un nombre.
- fact : calcule la factorielle d'un nombre.
- sin : trouve le sinus d'un angle.
- cos : trouve le cosinus d'un angle.
- tan : trouve la tangente d'un angle.
- arcsin : trouve l'angle à partir d'un sinus.
- arccos : trouve l'angle à partir d'un cosinus.
- arctan : trouve l'angle à partir d'une tangente.
Si vos applications requièrent des fonctions mathématiques qui ne sont pas présentes dans la classe Math.h, libre à vous d'en ajouter si besoin ! Arrondir des nombres décimaux : Des calculs complexes en virgule flottante (float), comprenez en nombre décimaux, sont parfois nécessaires afin de conserver la précision tout au long des opérations arithmétiques. Mais la finalité de ces opérations se retrouveront souvent dans un but de faire fonctionner des systèmes prenant en entrée uniquement des nombres entiers. Il est donc nécessaire d'arrondir le résultat en toute fin du calcul. Exemple pour arrondir un nombre décimal à l'entier inférieur : #include <Math.h> int main() { Math::floor (14.6); //la fonction retourne la valeur 14 return 0; } Dans l'exemple ci-dessus, la fonction statique floor est appelée, elle prend en paramètre 14.6, le nombre décimal à arrondir à l'entier inférieur, et retourne (dans ce cas de figure) le nombre entier 14. Exemple pour arrondir un nombre décimal à l'entier le plus proche : #include <Math.h> int main() { Math::round (23.7); //la fonction retourne la valeur 24 return 0; } Dans cet exemple la fonction statique round est appelée, elle prend en paramètre 23.7, le nombre décimal à arrondir à l'entier le plus proche, et retourne le nombre entier 24. Exemple pour arrondir un nombre décimal à l'entier supérieur : #include <Math.h> int main() { Math::ceil (5.12); //la fonction retourne la valeur 6 return 0; } Ici la fonction statique ceil est appelée, elle prend en paramètre 5.12, le nombre décimal à arrondir à l'entier supérieur, et retourne le nombre entier 6. Créer des interpolations de courbes : Il est très simple avec les fonctions de courbes que je propose de changer des valeurs d'échelle, d'interpoler des courbes vers d'autres valeurs, tout en ajoutant de l'exponentiel afin d'adoucir ou de rendre plus vif l'évolution des courbes ainsi créées. Il est également possible de créer des interpolations dissymétriques autour d'un centre arbitraire, mettant en jeu de part et d'autre deux types d'interpolations différentes (linéaires et exponentielles positives et négatives). Exemple pour créer une interpolation linéaire d'une courbe : #include <Math.h> int main() { Math::curve (-25, 50, 100, 1, 10, 0); //la fonction retourne la valeur 6.4 return 0; } Dans l'exemple ci-dessus, la fonction statique curve est appelée prenant plusieurs paramètres :
- Le 1er paramètre -25 est le point initial de la courbe.
- Le 2ème paramètre 50 est le point courant de la courbe.
- Le 3ème paramètre 100 est le point final de la courbe.
- Le 4ème paramètre 1 est le point initial de l'interpolation souhaitée.
- Le 5ème paramètre 10 est le point final de l'interpolation souhaitée.
- Le 6ème paramètre 0 défini le type d'interpolation (0 = linéaire) à partir du point initial vers le point final.
Le résultat du calcul est 6.4. Exemple pour créer une interpolation exponentielle d'une courbe : #include <Math.h> int main() { Math::curve (-25, 50, 100, 1, 10, 40); //la fonction retourne la valeur 1.318 (valeur arrondie) return 0; } L'exemple est identique au précédent, sauf le 6ème paramètre 40 (différent de 0 donc non-linéaire) qui permet une interpolation exponentielle positive, plus ce nombre est élevé, plus l'exponentielle est prononcée. Un nombre négatif produit une exponentielle négative, c'est-à-dire non pas une interpolation exponentielle qui évolue doucement proche du point initial de la courbe, mais plutôt évoluant rapidement proche du point initial pour terminer plus douce à l'approche du point final. Le résultat du calcul est maintenant 1.318 (valeur arrondie). Exemple pour créer une interpolation linéaire dissymétrique d'une courbe : #include <Math.h> int main() { Math::wurve (0, 50, 70, 0, 9, 10, 0, 0); //la fonction retourne la valeur 9.429 (valeur arrondie) return 0; } Dans l'exemple ci-dessus la fonction statique wurve est appelée, voici le détail des paramètres (similaires à la fonction statique curve) :
- Le 1er paramètre 0 est le point initial de la courbe.
- Le 2ème paramètre 50 est le point courant de la courbe.
- Le 3ème paramètre 70 est le point final de la courbe.
- Le 4ème paramètre 0 est le point initial de l'interpolation souhaitée.
- Le 5ème paramètre 9 est le point central de l'interpolation souhaitée.
- Le 6ème paramètre 10 est le point final de l'interpolation souhaitée.
- Le 7ème paramètre 0 défini le type d'interpolation (0 = linéaire) à partir du point central vers le point initial.
- Le 8ème paramètre 0 défini le type d'interpolation (0 = linéaire) à partir du point central vers le point final.
Le résultat du calcul est 9.429 (valeur arrondie). Exemple pour créer une interpolation double exponentielle centrée d'une courbe : #include <Math.h> int main() { Math::wurve (0, 473, 1023, 1000, 1500, 2000, 20, 20); //la fonction retourne la valeur 1498.045 (valeur arrondie) return 0; } Ci-dessus la fonction statique wurve prend en entrée la valeur d'un potentiomètre pouvant varier de 0 à 1023, c'est la courbe à interpoler, les valeurs d'interpolations vont de 1000 à 2000 en passant par un centre à 1500, ce centre sert à créer une double exponentielle centrée sur 1500 ayant des valeurs de 20 (non-linéaire) de part et d'autre de ce point central (ou neutre). Le résultat du calcul est 1498.045 (valeur arrondie). Cette simple expression pourrait servir à transposer un ordre analogique via un potentiomètre (0 à 1023) vers un signal PWM (pouvant varier de 1000 à 2000 microsecondes) dans le but d'asservir un servo-moteur. Beaucoup de mes projets utilisent les fonctions de courbes, car elles permettent de transposer facilement des valeurs d'un domaine vers un autre, sans pour autant compliquer la programmation (une ligne de programme est utilisé soit un seul appel de fonction et quelques paramètres). Cadrer une valeur dans un intervalle : Il peut être utile de solliciter une fonction dédiée lorsque nous souhaitons qu'une valeur ne sorte pas d'un certain intervalle, sans être obligé de rajouter les conditions logiques nécessaires à cette fonctionnalité dans notre programme (si inférieur ou égal à, si supérieur ou égal à, etc...), ce qui permet de diminuer le nombre d'instructions visibles et d'augmenter la lisibilité du code source. Exemple pour cadrer une valeur dans un intervalle : #include <Math.h> #include <Random.h> int main() { Random::seed (32); while (true) { Math::range (-10, Random::integer (-20, 53), 10); //la fonction retourne une valeur qui ne sortira jamais de l'intervalle -10 à 10 } return 0; } Dans l'exemple ci-dessus, un nombre aléatoire est généré, celui-ci peut prendre des valeurs de -20 à 53. La fonction statique range dans ce cas limite l'intervalle que peut prendre ce nombre dans un cadre -10 à 10. Calculer la moyenne de deux valeurs : De même que la fonction présentée ci-dessus, une fonction pour trouver la moyenne de deux nombres (ou centre) semble facultative, néanmoins elle reste bien pratique ! Exemple pour calculer la moyenne de deux valeurs : #include <Math.h> int main() { Math::center (125, 85.3); //la fonction retourne la valeur 105.15 return 0; } Les nombres 125 et 85.3 peuvent être permutés indifféremment, la moyenne de ces deux nombres est 105.15. Calculer la puissance d'un nombre : La fonction statique pow ("power" pour puissance) retourne le résultat de la multiplication d'un nombre avec lui-même entré en paramètre via un exposant (ce nombre et cet exposant peuvent être positifs, nuls, ou négatifs). Exemple pour calculer la puissance d'un nombre : #include <Math.h> int main() { Math::pow (5, 4); //la fonction retourne la valeur 625 return 0; } Ici le nombre 5 représente le nombre à multiplier avec lui-même, 4 est l'exposant, soit le calcul 5 x 5 x 5 x 5 = 625. Calculer la racine carrée d'un nombre : La fonction statique sqrt ("square root" pour racine carrée) retourne le nombre qui, multiplié par lui-même, donne le nombre entré en paramètre. Exemple pour calculer la racine carrée d'un nombre : #include <Math.h> int main() { Math::sqrt (25); //la fonction retourne la valeur 5 return 0; } Ci-dessus le nombre 25 est le résultat du nombre 5 multiplié par lui-même (5 x 5 = 25), la fonction retourne donc le nombre 5. Calculer la factorielle d'un nombre : La factorielle d'un nombre est le produit des nombres entiers strictement positifs inférieurs ou égaux à ce nombre. Cet algèbre permet d'effectuer des approches du nombre Pi, de faire converger des équations pour obtenir le sinus, le cosinus, etc... Exemple pour calculer la factorielle d'un nombre : #include <Math.h> int main() { Math::fact (7); //la fonction retourne la valeur 5040 return 0; } Dans l'exemple ci-dessus la factorielle du nombre 7 entré en paramètre donne le résultat 5040, car 1 x 2 x 3 x 4 x 5 x 6 x 7 = 5040. Par convention la factorielle du nombre 0 est 1. Les fonctions sinus, cosinus, et tangente : Les fonctions trigonométriques élémentaires comme sinus, cosinus, ou encore tangente s'avèrent utiles dans le domaine des automates programmables afin d'obtenir la position angulaire d'un robot, calculer la trajectoire d'un objet à l'aide d'un gyroscope, etc... Attention, mes fonctions trigonométriques sin (sinus), cos (cosinus), et tan (tangente) prennent en entrée un angle en degrés (et non pas en radians). Exemple pour calculer le sinus d'un angle : #include <Math.h> int main() { Math::sin (30); //la fonction retourne la valeur 0.5 return 0; } Dans cet exemple le sinus de l'angle 30 degrés est 0.5. Exemple pour calculer le cosinus d'un angle : #include <Math.h> int main() { Math::cos (45); //la fonction retourne la valeur 0.707 (valeur arrondie) return 0; } Dans l'exemple ci-dessus, le cosinus de l'angle 45 degrés est 0.707 (valeur arrondie). Exemple pour calculer la tangente d'un angle : #include <Math.h> int main() { Math::tan (45); //la fonction retourne la valeur 1 return 0; } Ci-dessus la tangente de l'angle 45 degrés est 1. Les fonctions réciproques arc sinus, arc cosinus, et arc tangente : En complément des fonctions de sinus, cosinus, et tangente, il est fort utile de disposer de fonction réciproques comme arc sinus, arc cosinus, et arc tangente. Attention, mes fonctions trigonométriques arcsin (arc sinus), arccos (arc cosinus), et arctan (arc tangente) retournent en sortie un angle en degrés (et non pas en radians). Exemple pour trouver l'angle à partir d'un sinus : #include <Math.h> int main() { Math::arcsin (0.5); //la fonction retourne la valeur 30 return 0; } Dans l'exemple ci-dessus, un sinus de 0.5 correspond à un angle de 30 degrés. Exemple pour trouver l'angle à partir d'un cosinus : #include <Math.h> int main() { Math::arccos (0.707); //la fonction retourne la valeur 45 (valeur arrondie) return 0; } Avec la fonction statique arccos, on trouve qu'un cosinus de 0.707 correspond à un angle de 45 degrés (valeur arrondie). Exemple pour trouver l'angle à partir d'une tangente : #include <Math.h> int main() { Math::arctan (1); //la fonction retourne la valeur 45 return 0; } Une tangente de 1 correspond à un angle de 45 degrés. La classe Math.h simplifie grandement la mise en œuvre de nombreuses applications, vous pouvez combiner les fonctions entres-elles et obtenir des résultats étonnants de complexité ! Récapitulatif des fonctions de cette classe : static signed long floor (const float VALUE); static signed long round (const float VALUE); static signed long ceil (const float VALUE); static float curve (const float POSITION_START, const float POSITION_CURRENT, const float POSITION_END, const float INTERPOLATION_START, const float INTERPOLATION_END, const float CURVE); static float wurve (const float POSITION_START, const float POSITION_CURRENT, const float POSITION_END, const float INTERPOLATION_START, const float INTERPOLATION_CENTER, const float INTERPOLATION_END, const float CURVE_START, const float CURVE_END); static float range (const float RANGE_START, const float VALUE_CURRENT, const float RANGE_END); static float center (const float VALUE_START, const float VALUE_END); static float pow (const float NUMBER, const unsigned long EXPONENT); static float sqrt (const float SQUARED); static unsigned long long fact (const unsigned long INTEGER); static float sin (const float ANGLE); static float cos (const float ANGLE); static float tan (const float ANGLE); static float arcsin (const float SINUS); static float arccos (const float COSINUS); static float arctan (const float TANGENT);