Bonjour ! Dans la leçon précédente, nous avons fait une distinction cruciale entre les coordonnées locales (relatives à un parent) et mondiales (relatives à la scène). Vous savez maintenant comment obtenir la position absolue de n'importe quel objet dans votre univers 3D avec getWorldPosition().
Introduction
Aujourd'hui, nous allons mettre cette connaissance en pratique. L'objectif de cette leçon est d'apprendre à calculer la distance et la direction entre deux points dans l'espace 3D. C'est une compétence fondamentale qui ouvre la porte à d'innombrables interactions : faire en sorte qu'un personnage regarde un objet, simuler une force d'attraction, vérifier si un objet est à portée d'un autre, afficher des mesures dans un configurateur de produit, etc.
Nous allons d'abord comprendre les concepts mathématiques sous-jacents (les vecteurs) de manière très intuitive, puis nous verrons comment les manipuler facilement avec les outils fournis par Three.js.
1. Qu'est-ce qu'un Vecteur ?
Avant de calculer quoi que ce soit, nous devons nous familiariser avec notre outil principal : le vecteur. En 3D, un vecteur est plus qu'une simple coordonnée (x, y, z). Il représente une quantité qui possède une magnitude (une longueur ou une intensité) et une direction.

Vous avez déjà beaucoup utilisé les vecteurs sans forcément y mettre ce nom, notamment via object.position qui est un Vector3. Il représente le déplacement depuis l'origine de son parent pour atteindre la position de l'objet.
Pour une introduction conceptuelle, l'article suivant explique très bien ce qu'est un vecteur et comment sa longueur (ou "norme") est calculée.
Du code au réel — Week 1 : Vecteur et ce bon vieux Newton
L'article 'Du code au réel' de Vincent Largillet offre une excellente introduction à la notion de vecteur. Concentrez-vous sur la première partie pour bien saisir le concept.
Lisez la section intitulée '— Vecteur'. Elle explique ce qu'est un vecteur et comment sa longueur est calculée en 2D avec le théorème de Pythagore. Le principe est exactement le même en 3D, on ajoute simplement la coordonnée z : longueur = √(x² + y² + z²).
2. Calculer la Direction entre deux Points
Imaginons que nous avons deux objets dans notre scène, A et B. Nous connaissons leur position dans le monde. Comment trouver la direction pour aller de A vers B ?
La réponse est simple : on soustrait la position du point de départ (A) de la position du point d'arrivée (B).
Direction de A vers B = Position(B) - Position(A)

En Three.js, cela se traduit par une soustraction de Vector3. Si positionA et positionB sont deux THREE.Vector3, le code serait :
const directionVector = new THREE.Vector3();
directionVector.subVectors(positionB, positionA);
Le directionVector contient maintenant les composantes (x, y, z) du "trajet" à effectuer pour aller de A à B.
3. Calculer la Distance
Maintenant que nous avons ce "vecteur direction", comment connaître la distance entre A et B ? C'est tout simplement la longueur (ou la norme, ou la magnitude) de ce vecteur.
Comme vu dans l'article précédent, Three.js s'occupe pour nous du calcul de la racine carrée de la somme des carrés.
Pour obtenir la liste des opérations possibles sur les vecteurs, vous pouvez consulter cette documentation de référence. Elle est très utile et vous servira souvent.
threejs-fundamentals | Skills Market
Cette ressource est une sorte de "cheat sheet" pour Three.js. La section sur Vector3 liste toutes les méthodes utiles que nous allons employer.
Repérez la section 'Math Utilities' puis 'Vector3'. Parcourez rapidement les méthodes listées. Attardez-vous sur sub(), length() et distanceTo(). Nous allons les utiliser tout de suite.
Vous avez deux manières de calculer la distance :
-
La méthode en deux étapes (conceptuelle) :
- Calculer le vecteur direction :
directionVector.subVectors(positionA, positionB); - Calculer sa longueur :
const distance = directionVector.length();
- Calculer le vecteur direction :
-
La méthode directe (plus simple et optimisée) :
- Utiliser la méthode
distanceTo()qui fait tout en une seule fois :const distance = positionA.distanceTo(positionB);
- Utiliser la méthode
Les deux approches donnent exactement le même résultat. La deuxième est généralement préférable pour simplement connaître la distance. La première est utile si vous avez aussi besoin du vecteur direction pour autre chose.
4. Obtenir une Direction "Pure" : La Normalisation
Parfois, la distance ne nous intéresse pas. Nous voulons juste savoir dans quelle direction regarder ou se déplacer, quelle que soit la distance. Pour cela, nous utilisons un vecteur unitaire (unit vector), c'est-à-dire un vecteur dont la longueur est exactement 1.
Le processus pour transformer un vecteur quelconque en vecteur unitaire s'appelle la normalisation.
Un vecteur (en bleu) est réduit à une longueur de 1 tout en conservant sa direction et son sens. C'est un vecteur normalisé (en rouge).
En Three.js, c'est très simple. Une fois que vous avez votre vecteur direction, il suffit d'appeler la méthode .normalize().
// On part du vecteur calculé précédemment
const directionVector = new THREE.Vector3().subVectors(positionB, positionA);
// On le normalise
directionVector.normalize();
// Maintenant, directionVector.length() renverra 1 (ou une valeur très proche)
// Mais il pointe toujours dans la même direction !
Ce vecteur normalisé est extrêmement utile pour appliquer une vitesse constante. Par exemple, pour déplacer l'objet A vers l'objet B, vous pouvez, à chaque image, ajouter ce vecteur direction normalisé multiplié par une petite vitesse.
5. Exercice Pratique : Attraction et Visualisation
Mettons tout cela en pratique. Nous allons créer une scène avec deux sphères. Une sphère "cible" (B) sera fixe, et une sphère "chasseuse" (A) se déplacera vers elle. Nous afficherons la distance en temps réel et visualiserons la direction avec une flèche.
-
Préparez votre scène de base (scène, caméra, renderer, boucle
animate). -
Créez les deux sphères et une flèche :
// Création des objets
const sphereAGeometry = new THREE.SphereGeometry(0.5, 32, 16);
const sphereAMaterial = new THREE.MeshBasicMaterial({ color: 0x0000ff }); // Bleu
const sphereA = new THREE.Mesh(sphereAGeometry, sphereAMaterial);
sphereA.position.set(-5, 0, 0);
scene.add(sphereA);
const sphereBGeometry = new THREE.SphereGeometry(0.5, 32, 16);
const sphereBMaterial = new THREE.MeshBasicMaterial({ color: 0xff0000 }); // Rouge
const sphereB = new THREE.Mesh(sphereBGeometry, sphereBMaterial);
sphereB.position.set(5, 0, 0);
scene.add(sphereB);
// Création de l'aide visuelle pour la direction (la flèche)
// On initialise la direction, la longueur sera calculée dynamiquement
const direction = new THREE.Vector3();
const arrowHelper = new THREE.ArrowHelper(
direction.normalize(), // Le vecteur direction (doit être normalisé)
sphereA.position, // Le point de départ
1, // Longueur de la flèche
0xffff00 // Couleur jaune
);
scene.add(arrowHelper);
- Dans votre boucle
animate(), ajoutez la logique :
// Déclarez cette variable hors de la boucle pour la performance
const speed = 0.05;
function animate() {
requestAnimationFrame(animate);
// --- 1. Calculer la distance ---
const distance = sphereA.position.distanceTo(sphereB.position);
console.log("Distance: ", distance.toFixed(2));
// --- 2. Calculer le vecteur direction ---
// La direction pour aller de A vers B est B - A
direction.subVectors(sphereB.position, sphereA.position);
// --- 3. Mettre à jour la flèche visuelle ---
arrowHelper.setDirection(direction.clone().normalize()); // On utilise un clone pour ne pas modifier l'original
arrowHelper.setLength(distance); // La flèche va de A à B
// --- 4. Déplacer la sphère A vers la sphère B ---
// On arrête le mouvement si on est très proche pour éviter les tremblements
if (distance > 1) { // 1 car c'est la somme des rayons des deux sphères (0.5 + 0.5)
// On normalise le vecteur direction pour avoir une vitesse constante
direction.normalize();
// On déplace sphereA en ajoutant la direction multipliée par la vitesse
sphereA.position.add(direction.multiplyScalar(speed));
}
renderer.render(scene, camera);
}
animate();
Lancez ce code. Vous devriez voir la sphère bleue se diriger vers la sphère rouge à une vitesse constante. La flèche jaune matérialise le "chemin" entre les deux, et la console de votre navigateur affiche la distance qui diminue à chaque image.
Conclusion
Félicitations ! Vous venez d'acquérir une des compétences les plus importantes en 3D. Vous ne voyez plus seulement des objets dans l'espace, mais vous pouvez quantifier les relations spatiales qui existent entre eux.
Points clés à retenir :
- La direction d'un point A vers un point B est un vecteur obtenu par la soustraction :
positionB - positionA. - La distance entre A et B est la longueur (ou
length()) de ce vecteur. La méthodepositionA.distanceTo(positionB)est un raccourci pratique. - Normaliser un vecteur (
.normalize()) le transforme en vecteur unitaire (longueur de 1), ce qui permet de représenter une direction pure, indépendante de la distance. - Ces opérations sont au cœur de l'interactivité en 3D : IA simple, visée, effets physiques, etc.
Aperçu de la prochaine leçon :
Nous avons maintenant une excellente maîtrise de la manipulation des objets dans l'espace 3D : les placer, les grouper, et mesurer les distances/directions entre eux. Notre scène est fonctionnelle, mais visuellement un peu simple. Dans le prochain module, nous allons nous concentrer sur l'apparence de nos objets en explorant la grande variété de géométries et de matériaux que Three.js a à offrir.