Calculer la norme, la normale et le milieu d’un segment

Dans cet article on va parler de comment calculer simplement la norme, la normale et le milieu d’un segment en 2 dimensions. L’intérêt est multiple, mais en ce moment, ces trois calculs me servent à afficher les normales des murs des secteurs dans l’éditeur de mon moteur de musée virtuel. Je m’en suis servit en partie dans Demiurge, en 3D, sauf pour la normale qui nécessite l’utilisation d’un produit en croix pour les surfaces (cross product en anglais).

Le milieu d’un segment

Commençons par le milieu d’un segment qui ne nécessite pas les deux autres pour être calculé. En 2D, pour calculer simplement le milieu d’un segment, il suffit tout d’abord de ramener le segment à son vecteur directeur, ici non normalisé, comme on la vue dans l’article sur le calcul du sens d’un segment. L’équation est simple, je le rappelle ici :

Vecteur = (xB - xA, yB - yA)

Ce vecteur, contrairement, au segment (sauf cas particulier) a sa position aux coordonnées (0, 0) et donc les coordonnées de la pointe du vecteur correspondent logiquement à la soustraction du deuxième point du segment par le premier point. Il s’agit d’une simplification du segment qui permet de lui faire toutes sortes de choses et notamment trouver le milieu, mais aussi sa normale. Mais, on verra après pour la normale 🙂

Pour trouver le milieu du segment, il reste deux étapes toutes simple. La première consiste à diviser par 2 les coordonnées du vecteur non normalisé. Ainsi, on obtient la moitié du vecteur. Puis, la deuxième et dernière étape consiste à ramener le vecteur à sa place en l’additionnant avec le premier point du segment.

DemiVecteur = (Vecteur.x / 2, Vecteur.y / 2)
Milieu = (xA + DemiVecteur.x, xB + DemiVecteur.y)

La norme du segment

La norme d’un segment est la distance entre le premier et le deuxième point qui le constitue. C’est à dire, pour faire simple, sa longueur. Peu importe que votre segment se trouve sur une grille de pixels, et donc soumis à un repère, il s’agit là de la longueur que vous obtiendriez si vous aviez une règle est mesureriez le segment 🙂

La formule de la norme est un peu plus compliqué et gourmand en ressources pour un ordinateur que ce qu’on a fait précédemment. Heureusement pour nous, elle a au moins le mérite de tenir sur une seule ligne :p

Norme = √(Vecteur.x²+Vecteur.y²)

Je le réécris différemment pour plus de lisibilité et de compréhension.

Norme = RacineCarrée( Carré(Vecteur.x) + Carré(Vecteur.y) )

J’ai utilisé ici le vecteur de tout à l’heure. En effet, on ne calcule pas directement la norme d’un segment, mais celui de son vecteur non normalisé. Et si depuis tout à l’heure je n’ai pas normalisé mon vecteur, c’est précisément parce que normaliser signifie qu’on le ramène à une norme de 1, hors nous voulons mesurer notre segment, ce serait donc absurde 🙂

Avec une norme on peut faire le calcul du milieu du segment d’une façon différente que la méthode précédente, mais aussi faire d’autres choses comme calculer la trajectoire d’un projectile par exemple. Cependant, pour y arriver, il va normaliser le vecteur. Je vais vous expliquer comment en même temps que le calcul de la normale d’un segment ou d’une droite 🙂

Normaliser un segment et calculer sa normale

Comme je l’ai dit tout à l’heure, normaliser un vecteur, c’est mettre sa norme à 1. Et pour faire cela, rien de plus simple 🙂

Normalisé = (Vecteur.x / norme, Vecteur.y / norme)

Voilà, c’est fait 😀 Il suffisait tout simplement de diviser les coordonnées du vecteur précédemment obtenu. C’est assez logique, puisque la norme est la longueur du vecteur de départ. Et c’est pour cette raison qu’un vecteur normalisé est très utile pour une trajectoire de projectile par exemple, puisque entre le moment où un personnage fait feu et un instant T, le projectile aura parcouru une certaine distance. Ainsi, connaître son vecteur directeur permet de simplement le multiplier par la distance parcouru pour trouver les coordonnées du projectile :p Si vous voulez par exemple, afficher un objet se déplaçant suivant un vecteur, vous pouvez associer une distance pour chaque quantum de temps (fraction du temps) et additionner ces distances à chaque instant pour ensuite le multiplier par le vecteur. A chaque quantum de temps, votre ordinateur affichera votre objet aux bonnes coordonnées et vous le verrez se déplacer sur votre trajectoire. Ajoutez à ceci, un vecteur de gravité, qui irait toujours vers le bas, soit ceci (0, y), et vous aurez la base d’un jeu de missile, sniper ou d’archer, et une part non négligeable d’un Worms x)

Bon, je vous raconte tout ça, mais il me reste un truc à vous expliquer. C’est le calcul de la normale au segment, ou plus tôt au vecteur. La normale d’un vecteur est un vecteur perpendiculaire au premier. Là encore, en 2 dimensions, trouver la normale d’un vecteur est simplicime. Voici la formule :

Normale =(-Normalisé.y, Normalisé.x)

Et voilà, hihihihi 😀 Tout simplement, la coordonnées X de la normale est égale à la coordonnées Y en négatif du vecteur directeur, et la coordonnées Y de la normale est égale à la coordonnées X du vecteur directeur. Ni plus, ni moins 🙂 Il n’y a donc pas réellement de calcules à faire, mais juste des assignations de valeurs.

C’est lorsqu’on fait des tests sur un papier ou à l’écran, qu’on comprend l’utilité de calculer le sens d’un segment comme je l’ai proposé en premier article de la série sur l’algorithmie. En effet, si vous placez les points de votre segment dans un ordre ou dans un autre, vous changerez nécessairement l’ordre de ces derniers dans les opérations précédemment expliqué ici. Ainsi, votre normale ne sera pas dans le même sens non plus. Pour un ligne horizontale par exemple, la normale sera soit vers le haut, soit vers le bas, selon l’ordre dans lequel vous avez entré vos deux points du segment. Cette propriété peut provoquer des erreurs d’affichages, de physique dans un moteur physique, mais aussi, bien exploitée, permettre de déterminer l’intérieur et l’extérieur d’un monde comme dans mon moteur de musée 🙂

Bonus : Dessiner une normale au milieu d’un segment

TimidouvegMuseum_2017-07-26Je vous mets un petit algorithme qui utilise tout ce qui est au-dessus pour dessiner la normale d’un segment.

DessinerSegment(xA, yA, xB, yB);
Vecteur(xB-xA, yB-yA);
Norme = RacineCarré(Carré(Vecteur.x) + Carré(Vecteur.y));
Normalisé = (Vecteur.x/Norme, Vecteur.y/Norme);
Normale = (-Normalisé.y, Normalisé.x);
Milieu = (xA+Vecteur.x/2, yA+Vecteur.y/2);
DessinerNormale(Milieu.x, Milieu.y, Milieu.x+Normale.x, Milieu.y+Normale.y);

Si les unités de votre dessin sont les pixels, la normale ne fera qu’un seule pixel et dans certains cas, il ne pourra pas s’afficher. Vous pouvez donc multiplier ses coordonnées par un nombre raisonnable pour bien voir la ligne s’afficher et apprécier la perpendiculaire a votre segment 🙂

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *