IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)

FAQ mathématiques pour les jeux

FAQ mathématiques pour les jeuxConsultez toutes les FAQ

Nombre d'auteurs : 7, nombre de questions : 82, dernière mise à jour : 15 juin 2021 

 
OuvrirSommaireTrigonométrieTrigonométrie Bases

La trigonométrie est la branche des mathématiques qui étudie les relations entre les longueurs des côtés des triangles et leurs angles, et, par extension, les fonctions trigonométriques (sinus, cosinus et leurs dérivés : tangente, cotangente, sécante, cosécante).

La trigonométrie est très souvent utilisée dans des domaines très variés. Par exemple, elle est très utile dans l'optique (pour les microscopes, par exemple) ou la physique newtonienne (lois des mouvements…), ou pour la triangulation, qui permet de localiser un point en mesurant les angles formés avec d'autres points de référence.

Créé le 16 septembre 2010  par Thibaut Cuvelier

Il existe deux mesures principales de l'angle : le degré et le radian. Il existe aussi le quadrant, la mesure d'angle d'un angle droit. Un cercle décrit un angle de 360°, de 4q et de Image non disponible.

° est le symbole du degré, q celui du quadrant, et rad celui du radian.

Un radian est la mesure de l'angle dont la mesure de l'arc interceptant un cercle vaut le rayon de ce cercle.
Un quadrant est le quart de l'angle formé par un cercle.
Un degré est le 360e de l'angle formé par un cercle.

Ceci permet d'écrire les égalités suivantes :

Image non disponible
Image non disponible
Image non disponible

Ces égalités permettent de facilement convertir une mesure d'angle des degrés en radians et inversement. Voici de telles fonctions avec leurs notations mathématiques.

Image non disponible
Image non disponible

Et voici son implémentation en C99, compatible C++.

 
Sélectionnez
#define PI 3.141592653589793

inline
long double deg2rad (float deg)
{
    return deg / (180 / PI);
}

inline
long double rad2deg (float rad)
{
    return rad * (180 / PI);
}

Il existe encore d'autres mesures d'angle, mais elles sont nettement moins utilisées : le grade, le mil, la révolution (ou rotation), le degré binaire, le radian binaire (bradian), l'angle horaire, le gradient…

Créé le 16 septembre 2010  par Thibaut Cuvelier
Le cercle trigonométrique, ou cercle unité
Le cercle trigonométrique, ou cercle unité

Le cercle trigonométrique est le cercle dont le centre est le centre du repère et de rayon 1. C'est pourquoi il est aussi appelé cercle unité : chacun de ses points se situe à une unité du centre du repère. Ces points ont des abscisses et des ordonnées un peu particulières : elles correspondent au sinus et au cosinus de l'angle orienté formé par l'axe des abscisses et la droite passant par ce point et le centre du repère.

Voici les équations paramétriques de ce cercle :

Image non disponible
Image non disponible

On utilise généralement le sens trigonométrique pour parcourir ce cercle : il est opposé au sens horloger. On parle aussi exceptionnellement du sens senestre (par opposition à dextre).

Créé le 16 septembre 2010  par Thibaut Cuvelier

Angles complémentaires Deux angles sont complémentaires si la somme de leurs mesures d'angle équivaut la mesure d'un angle droit.

Angles opposés Deux angles sont opposés si leurs mesures d'angle sont opposées.

Angles supplémentaires Deux angles sont supplémentaires si la somme de leurs mesures d'angle équivaut la mesure d'un angle plat.

Angles antisupplémentaires Deux angles sont antisupplémentaires si l'un équivaut l'autre à la mesure d'un angle plat près.

En effet, lors d'un travail en radians,

Image non disponible
Image non disponible

De même,

Image non disponible
Image non disponible
Image non disponible
Image non disponible
Image non disponible
Image non disponible
Créé le 16 septembre 2010  par Thibaut Cuvelier

Un nombre trigonométrique est le résultat d'une fonction trigonométrique (sinus, cosinus, tangente, cotangente…). Par exemple :

Image non disponible
Image non disponible

Un nombre trigonométrique peut être calculé assez exactement par une machine, ou bien être approché grâce au cercle trigonométrique.

Dans la figure suivante, on a tracé un angle. Pour en trouver le sinus, il suffit de tracer la parallèle à l'axe des cosinus passant par le point de contact entre la demi-droite bornant l'angle et le cercle trigonométrique et de mesurer la distance entre l'axe des cosinus et cette droite.

Approximation d'un nombre trigonométrique
Approximation d'un nombre trigonométrique
Créé le 16 septembre 2010  par Thibaut Cuvelier

Il faut plusieurs relations entre les différents nombres trigonométriques afin de pouvoir les exprimer les uns par rapport aux autres.

Image non disponible
Image non disponible
Image non disponible
Image non disponible
Image non disponible
Image non disponible

Avec ces quelques relations, vous pouvez sans problème trouver tous les nombres trigonométriques de l'angle dont vous avez un nombre trigonométrique.

La relation fondamentale exprimée en fonction du cosinus pour obtenir facilement le sinus :

Image non disponible

La relation fondamentale exprimée en fonction du sinus pour obtenir facilement le cosinus :

Image non disponible

La définition de la tangente en fonction du cosinus :

Image non disponible

La définition de la cotangente en fonction du sinus :

Image non disponible
Créé le 16 septembre 2010  par Thibaut Cuvelier

Premièrement, quels sont les angles remarquables ?
En degrés : 0°, 30°, 45°, 60°, 90°.
En radians : Image non disponible, Image non disponible, Image non disponible, Image non disponible, Image non disponible.

Qu'ont-ils de particulier ? Il est possible de démontrer leurs cosinus et sinus, pour obtenir une fraction (ir)rationnelle assez simple.

 

Image non disponible

Image non disponible

Image non disponible

Image non disponible

Image non disponible

Sinus

Image non disponible

Image non disponible

Image non disponible

Image non disponible

Image non disponible

Cosinus

Image non disponible

Image non disponible

Image non disponible

Image non disponible

Image non disponible

Créé le 16 septembre 2010  par Thibaut Cuvelier

Une des manières les plus simples est d'utiliser les séries entières. Les voici.

Image non disponible
Image non disponible

Plus on développe la série, plus le résultat devient précis, mais lent à calculer.

Voici une implémentation du calcul du sinus par cette méthode en C99, compatible C++.

Sinus
Cacher/Afficher le codeSélectionnez

Et voici son pendant pour le cosinus par cette méthode en C99, compatible C++.

Cosinus
Cacher/Afficher le codeSélectionnez

Ces implémentations ne sont pas prévues pour être rapides, il s'agit juste de montrer comment faire. Un certain nombre d'optimisations peuvent être envisagées.

Créé le 16 septembre 2010  par Thibaut Cuvelier

Cet algorithme recherche les coordonnées de l'intersection de l'angle avec le cercle trigonométrique. Il procède avec un vecteur v_0 = ( 0 ; 1 ), qu'il fait tourner pour qu'il atteigne l'angle recherché.

À chaque itération, on calcule la multiplication du vecteur v_i avec une matrice de transformation, R_i

R_i=\begin{pmatrix}\cos\gamma_i&-\sin\gamma_i\\\sin\gamma_i&\cos\gamma _i\end{pmatrix}

En mettant le facteur \cos{\gamma} en évidence, on obtient :

v_{i+1}=R_iv_i=\cos\gamma_i\begin{pmatrix}1&-\sigma_i\tan\gamma_i\\\sigma_i\tan\gamma_i&1\end{pmatrix}                         \begin{pmatrix}x_i\\y_i\end{pmatrix}

Le facteur \sigma_i peut valoir -1 ou +1 en fonction du sens de rotation. Si on restreint les valeurs de Image non disponible afin que \tan{\gamma} soit égal à 2^{-i}, alors la multiplication par le facteur tangente devient une multiplication par une puissance de 2. D'où :

v_{i+1}=\cos(\arctan(2^{-i}))\\begin{pmatrix}x_i-\sigma_i2^{-i}y_i\\x_i\sigma_i2^{-i}+y_i\end{pmatrix}

Le facteur \cos(\arctan(2^{-i})) peut être ignoré pendant l'itération, et factorisé en un seul coefficient multiplicatif final. Ici, n représente le nombre d'itérations.

\cos{\arctan{2^{-i}}}=\prod_{i=0}^{n-1}\cos{\arctan{2^{-i}}}=\prod_{i=0}^{n-1}\frac{1}{\sqrt{1+2^{-2i}}}

La limite de ce produit lorsque n tend vers l'infini est de 0,607 252 94.

Après suffisamment d'itérations, l'angle formé par le vecteur et l'axe des cosinus se rapprochera de l'angle dont on recherche les sinus et cosinus.

La dernière étape consiste à déterminer à chaque itération le sens de rotation : trigonométrique (antihoraire) ou horaire. Ce résultat influence la valeur de \sigma_i.

Tout simplement, on soustrait la mesure de l'angle \beta_{n+1} à la mesure de l'angle désiré. Si le résultat est positif, on tourne dans le sens horloger. S'il est négatif, on tourne dans le sens trigonométrique. Cette étape peut être déclarée dichotomique.

\beta_{i+1} = \beta_i - \sigma_i \gamma_i
\quad \gamma_i = \arctan 2^{-i}

Voici maintenant l'implémentation de cet algorithme en C99, compatible C++.

CORDIC
Cacher/Afficher le codeSélectionnez
Créé le 16 septembre 2010  par Thibaut Cuvelier

Une look up table (ou LUT) est un tableau statique à chargement dynamique. Dit autrement, il s'agit d'une sorte de tableau qui est construit dynamiquement (typiquement au lancement du programme, quand il affiche son splash screen) dont l'accès aux données se fait comme s'il était stocké dans le binaire.

Une LUT sert principalement à accélérer le calcul de valeurs de fonctions prenant un certain temps à calculer, surtout quand on en a besoin très souvent (par exemple, une application devant calculer des milliers de cosinus par seconde pourra en profiter, ils seront déjà calculés, il suffira d'aller les lire).

Son fonctionnement est très simple : il s'agit tout d'abord d'un conteneur un peu spécial. Il stocke des valeurs d'une fonction pour un paramètre précis, ce paramètre servant d'indice au tableau (pour l'implémentation, on utilise généralement un vecteur). Seulement, ces indices sont forcément entiers alors que les paramètres, surtout en trigonométrie, ne sont que très rarement entiers. Il faut donc un peu tricher à cet endroit pour transformer ces flottants en entiers (un exemple est disponible ci-dessous).

Une implémentation très basique d'une LUT pour la fonction cosinus
Sélectionnez
#include <vector>
#include <cmath>
 
using namespace std;
 
class lut
{
private: 
    vector<float> m_lut; 
    float m_min; 
    float m_max; 
    float m_precision; 
public: 
    lut() {}
    ~lut() {}
    
    // L'intervalle dans lequel on devra calculer les valeurs prises par la fonction
    void setInterval (float min, float max)
    {
        this->m_min = min; 
        this->m_max = max; 
    }
    
    // Donne la précision, la différence entre les paramètres de deux valeurs stockées
    void setPrecision (float p)
    {
        this->m_precision = p; 
    }
    
    // Calcule les valeurs demandées
    void compute()
    {
        for(float x = this->m_min, int i = 0 ; x <= this->m_max ; x += this->m_precision, ++i)
        {
            this->m_lut[i] = cos(x);
        }
        // Le code est assez clair : pour toutes les valeurs entre this->m_min et this->m_max,
        // on calcule le cosinus de cette valeur et on l'inscrit dans la LUT.
        // Seulement, un vecteur n'aime pas trop les float comme indices, il faut donc tricher : 
        // 0 -> this->m_min
        // 1 -> this->m_mix + this->m_precision
        // etc.
        // Problème : il faut retransformer les valeurs demandées en indices du vecteur.
        // Cependant, cela évite de créer son propre conteneur, ce qui n'est pas le but ici.
        // Ce code est loin d'être optimal, il ne donne qu'une manière de faire, qui ne veut pas
        // être la meilleure, mais juste suffisamment simple à comprendre. 
    }
    
    float get(float x)
    {
        // On veut forcément une valeur dans l'intervalle ; sinon, cette implémentation calcule cette valeur précise, mais ne la stocke pas. 
        if ( ! (x > this->m_min && x < this->m_max) )
            return cos(x); 
            
        // La valeur 0 correspond au minimum : si x vaut ce minimum, il doit valoir 0, on ne peut pas le créer autrement.
        x -= this->m_min; 
        // Toutes les valeurs ne sont pas disponibles : on divise donc par la précision pour avoir une valeur comme ce que nous voulons. 
        x /= this->m_precision; 
        // x est toujours un flottant, on veut un entier : il suffit de perdre les décimales pour obtenir notre indice ! 
        int i = floor(x); // vous auriez pu utiliser ceil ou une autre méthode pour récupérer un entier
        
        // Maintenant, on retourne à l'utilisateur le résultat demandé. 
        return this->m_lut[i]; 
    }
};

Cette implémentation d'une LUT n'est pas forcément la meilleure possible ! Il ne s'agit que d'un exemple pour vous aider à comprendre leur principe ; en réalité, vous devriez plutôt prévoir une LUT plus réutilisable (notamment pas autant liée à une fonction, ne pas mettre en dur la fonction dont vous calculez les images), plus optimisée en fonction de vos besoins (vos indices seront peut-être exclusivement entiers, un pan entier de cette implémentation peut ainsi être évité).

L'utilisation de cette LUT
Sélectionnez
lut m_lut; 
m_lut->setInterval(0, 1.57); // de 0 à PI/2
m_lut->setPrecision(0.157); // soit PI/20
m_lut->compute();
cout << m_lut->get(0.157); // récupérée de la lut, valeur déjà calculée
cout << m_lut->get(0.158); // valeur en dehors de la lut, calculée à ce moment-là

Cet exemple de LUT peut être fortement amélioré : on pourrait, par exemple, instaurer un système d'interpolation pour les valeurs pour lesquelles rien n'est calculé. Il serait possible de coder son propre conteneur à cet effet et d'autoriser alors l'utilisation d'indices flottants, par exemple ce qui est disponible avec les tableaux CUDA normalisés (ils n'autorisent que des indices entre 0 et 1).

Utiliser une LUT n'a de sens que si vous devez obtenir très souvent le résultat d'une fonction ! S'il s'agit simplement de calculer trois cosinus sur toute la durée de vie de l'application, elle perdra beaucoup de temps à créer cette LUT et prendra beaucoup de mémoire pour la stocker pour rien. Il n'est pas non plus intéressant d'utiliser une LUT pour des opérations très simples, l'accès à un élément ayant un coût non négligeable pour ce genre d'opérations.

Créé le 16 septembre 2010  par Thibaut Cuvelier

Les sources présentées sur cette page sont libres de droits et vous pouvez les utiliser à votre convenance. Par contre, la page de présentation constitue une œuvre intellectuelle protégée par les droits d'auteur. Copyright © 2005-2014 Developpez LLC et al. Aucune reproduction, même partielle, ne peut être faite de ce site ni de l'ensemble de son contenu : textes, documents, images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.