Note pour les utilisateurs d'Internet Explorer
Cette page affiche des formules mathématiques en utilisant un script MathML.
Si vous lisez ceci avec Internet Explorer, je vous recommande d'accepter l'exécution de ce script quand IE vous le
demande.
Qu'est-ce qu'un vecteur ?
Un vecteur est un objet géométrique qui définit une longueur et une direction.
En géométrie il est communément représenté par une flèche. Mais en programmation on le représentera par ses
coordonnées.
Le but de cet article est de commencer à écrire une classe vecteur. Et on ajoutera des fonctions à cette classe
dans plusieurs autres articles.
Maintenant imaginons qu'on a 2 points A et B.
On peut tracer un vecteur
allant de A à B.
Remarquez la petite flèche au-dessus du "V" c'est une notation mathématique qui dit que c'est un vecteur.
Naturellement dans le code on ne pourra pas ajouter cet élément graphique...
Si le plan est muni d'un repère, on peut définir les coordonnées du vecteur comme la différence entre les
coordonnées du point de destination et celles du point d'origine.
Ca veut dire que les coordonnées de notre vecteur sont (x
B-x
A, y
B-y
A).
Mais les mathématiciens préfèrent souvent les écrire verticalement
.
Maintenant oubliez les points.
Les coordonnées
du vecteur ne sont que 2 nombres qui représentent sa longueur et son orientation.
Ce vecteur n'a pas besoin de commencer au point A. Vous pouvez le déplacer partout dans le plan ça restera le même
vecteur tant qu'il aura la même longueur et la même direction.
Et c'est ici qu'on va commencer à écrire notre classe. Elle contiendra simplement les 2 coordonnées de notre
vecteur.
class Vec2f
{
public:
Vec2f(const float _x = 0.0, const float _y = 0.0);
float x, y;
};
Vec2f::Vec2f(const float _x, const float _y)
{
x = _x;
y = _y;
}
Je l'ai appelée Vec2f parce qu'elle a 2 coordonnées. Le "f" nous dit que ce sont des float.
Eventuellement on pourrait plus tard vouloir écrire une classe avec des coordonnées entières ou des doubles.
Mais les points sont aussi des vecteurs
Cette classe contient 2 coordonnées, comme les coordonnées d'un point.
Alors ça pourrait être pratique si on pouvait l'utiliser pour stocker un point.
Mais est-ce que ça aurait un sens ?
En fait, les coordonnées d'un point peuvent être vues comme les coordonnées d'un vecteur qui va de l'origine du plan
au point.
Souvenez-vous qu'on a défini les coordonnées d'un vecteur comme la différence des coordonnées de ses extrémités.
Dans notre cas on a
.
Comme les coordonnées de O sont (0, 0), les coordonnées du point et du vecteur sont les mêmes.
Ce fait va beaucoup nous aider quand on parlera des transformations géométriques.
Supposons qu'on a 2 vecteurs
et
.
Pour obtenir les coordonnées du vecteur somme, vous additionnez simplement les coordonnée des 2 vecteurs.
Donc
.
Graphiquement, vous pouvez voir ça comme si vous déplaciez le vecteur
au bout du vecteur
.
Le vecteur somme peut être tracé en partant de l'origine de
et en s'arrêtant à la fin de
.
Maintenant on peut ajouter l'addition à notre classe en surchargeant l'opérateur addition.
Vec2f Vec2f::operator+(const Vec2f& a)
{
Vec2f result;
result.x = x + a.x;
result.y = y + a.y;
return result;
}
Et on peut aussi écrire l'opérateur +=.
Vec2f& Vec2f::operator+=(const Vec2f& a)
{
x += a.x;
y += a.y;
return *this;
}
De cette façon on peut additionner des vecteurs comme on le ferait avec de simples nombres. Par exemple:
Vec2f v1(1.0, 2.0);
Vec2f v2(3.0, 4.0);
Vec2f v3;
v3 = v1 + v2;
L'opposé d'un vecteur est un vecteur dont les coordonnées sont l'opposé des celles du vecteur d'origine.
Graphiquement il ressemble au vecteur d'origine, mais il va dans l'autre sens.
On va définir ça avec l'opérateur unaire moins.
Vec2f Vec2f::operator-()
{
Vec2f result;
result.x = -x;
result.y = -y;
return result;
}
On peut l'utiliser comme ça:
v2 = -v1;
Soustraire le vecteur
du vecteur
est la même chose que d'ajouter son opposé.
Maintenant on peut définir l'opérateur moins binaire et l'opérateur -=.
Vec2f Vec2f::operator-(const Vec2f& a)
{
Vec2f result;
result.x = x - a.x;
result.y = y - a.y;
return result;
}
Vec2f& Vec2f::operator-=(const Vec2f& a)
{
x -= a.x;
y -= a.y;
return *this;
}
Le module d'un vecteur est sa longueur (on l'appelle aussi parfois sa "norme").
Avec ce vecteur:
En appliquant le théorème de Pythagore, on a:
Et en prenant la racine carrée:
On va ajouter les 2 formules à notre classe car parfois on préférera utiliser la valeur au carré pour éviter une
coûteuse fonction racine carrée.
Note: on utilise le mot "mag" pour magnitude en anglais.
float Vec2f::squaredMag()
{
return x * x + y * y;
}
float Vec2f::mag()
{
return sqrt(squaredMag());
}
L'argument d'un vecteur est l'angle entre ce vecteur et l'axe horizontal.
D'après les formules trigonométriques on a:
Donc on peut trouver l'angle:
Dans le code on utilisera la fonction atan2 pour éviter des problèmes comme une division par 0.
float Vec2f::arg()
{
return atan2(y, x);
}
On continuera d'ajouter des fonctions à cette classe dans un futur article.
Vous pouvez télécharger le code de cet article
ici.