Skip to main content

Welcome to a Grasp lesson

Create a free account to keep studying and create your own study path.

Lesson 12

`Vector3` : Positions, échelles et directions

Recommended resources

Bonjour ! Dans la leçon précédente, nous avons rendu notre scène interactive en ajoutant des OrbitControls, nous donnant la liberté d'explorer notre création sous tous les angles. C'est une excellente première étape vers l'interactivité.

Introduction

Jusqu'à présent, pour positionner nos objets, nous avons utilisé des valeurs un peu "magiques", comme camera.position.z = 5. Mais comment déplacer un objet précisément dans une direction donnée ? Comment connaître la distance entre deux objets ? Ou comment déformer un cube pour en faire un parallélépipède ?

L'objectif de cette leçon est de vous donner les outils mathématiques de base pour répondre à ces questions. Vous allez apprendre à utiliser la classe Vector3 pour représenter et manipuler des positions, des échelles et des directions. Le Vector3 est l'un des objets les plus fondamentaux de Three.js. Le maîtriser est essentiel pour passer de scènes statiques à des mondes dynamiques et interactifs.

À la fin de cette leçon, vous serez capable de contrôler précisément la position et la taille de vos objets et de comprendre les bases du mouvement dans un espace 3D.


1. Qu'est-ce qu'un Vector3 ?

En termes simples, un Vector3 est un objet qui stocke trois nombres : x, y, et z. Vous l'avez déjà rencontré sans forcément y prêter attention : les propriétés camera.position, cube.position et cube.rotation sont toutes des Vector3 (ou une classe similaire, Euler, qui se comporte de manière très proche pour la rotation).

Un Vector3 est un véritable couteau suisse et peut représenter trois concepts distincts :

  1. Une Position : C'est son utilisation la plus intuitive. Un Vector3 peut représenter un point unique dans l'espace 3D. Par exemple, (2, 3, 1) est un point situé à 2 unités sur l'axe X, 3 sur l'axe Y et 1 sur l'axe Z.
  2. Une Échelle (Scale) : Il peut représenter un facteur d'agrandissement ou de réduction sur chaque axe. Par exemple, une échelle de (2, 1, 1) rendra un objet deux fois plus large (sur X) mais gardera sa hauteur et sa profondeur d'origine.
  3. Une Direction : C'est un concept un peu plus abstrait. Un Vector3 peut représenter une direction et une magnitude (longueur). Par exemple, le vecteur (0, 1, 0) représente une direction purement "vers le haut" le long de l'axe Y.

Explorons ces trois usages en pratique.


2. Utiliser Vector3 pour la Position

Chaque objet que vous ajoutez à la scène (Object3D) possède une propriété .position qui est un Vector3. Pour positionner un objet, le moyen le plus simple est d'utiliser la méthode .set().

// Créons notre cube comme d'habitude
const geometry = new THREE.BoxGeometry(1, 1, 1);
const material = new THREE.MeshBasicMaterial({ color: 0x0095dd });
const cube = new THREE.Mesh(geometry, material);
scene.add(cube);

// Plaçons le cube à des coordonnées précises
cube.position.set(2, 0, -3); // x=2, y=0, z=-3

Vous pouvez également créer un vecteur séparément et copier ses valeurs, ce qui peut être utile pour réutiliser des positions.

const targetPosition = new THREE.Vector3(2, 0, -3);
cube.position.copy(targetPosition);

L'article ci-dessous, bien que traitant d'un projet de panorama, montre un exemple très clair de création d'un Vector3 pour définir la position d'un marqueur dans une scène.

Tutoriel vidéo three.js & JavaScript : Panorama 360

Cet article de Grafikart utilise un Vector3 pour placer un élément dans un monde 3D. Concentrez-vous sur la manière dont une nouvelle instance de Vector3 est créée et utilisée pour définir une position.

Repérez la ligne let point = new THREE.Vector3(14, 1.9, -47). C'est un exemple parfait de la création d'un vecteur pour stocker des coordonnées de position.


3. Utiliser Vector3 pour l'Échelle

De la même manière, chaque Object3D a une propriété .scale, qui est un Vector3. Par défaut, sa valeur est (1, 1, 1), ce qui signifie que l'objet a sa taille d'origine.

Pour déformer un objet, il suffit de modifier les valeurs de son vecteur d'échelle.

// Agrandit le cube pour qu'il soit 2x plus large,
// 0.5x moins haut, et 1.5x plus profond.
cube.scale.set(2, 0.5, 1.5);
Demonstration of 3D Object Scaling with X, Y, Z Values
Cette image illustre parfaitement comment la modification des valeurs x, y et z du vecteur `.scale` affecte la forme d'un objet. Le cube du milieu a une échelle de (1, 1, 1), celui de gauche est réduit uniformément (0.5, 0.5, 0.5), et celui de droite est déformé de manière non uniforme (1, 0.5, 2).

4. Utiliser Vector3 pour la Direction

Représenter une direction est crucial pour les animations et les rotations. Une direction est simplement un vecteur pointant de l'origine (0,0,0) vers un point (x,y,z).

  • (1, 0, 0) est la direction de l'axe X positif.
  • (0, 1, 0) est la direction de l'axe Y positif ("vers le haut").
  • (0, 0, -1) est la direction de l'axe Z négatif ("vers l'avant" dans la configuration par défaut de Three.js).

Une application très courante est de définir un axe de rotation personnalisé. L'article suivant, qui anime le système Terre-Lune, utilise un Vector3 pour spécifier l'axe de rotation de la Terre.

Animer le système Terre-Lune en HTML et JavaScript (2/2)

Cet article de La voie du dév explique comment animer la rotation de la Terre. Il contient un exemple parfait d'utilisation d'un Vector3 pour définir une direction (l'axe de rotation).

Dans le bloc de code de la section 'Implémentation dans JavaScript', trouvez la ligne contenant earth.rotateOnAxis(new Vector3(0, 1, 0), ...). Cela montre comment un Vector3 est utilisé pour indiquer que la rotation doit se faire autour de l'axe Y.

La méthode rotateOnAxis(axis, angle) prend en premier argument un Vector3 qui définit l'axe autour duquel la rotation doit s'effectuer. L'utilisation de new Vector3(0, 1, 0) indique que la Terre doit tourner autour de son axe vertical.


5. Manipulations de base des vecteurs

La vraie puissance des vecteurs vient des méthodes qui permettent de les combiner et de les manipuler. Voici quelques-unes des plus utiles :

  • Calculer une distance : .distanceTo(vector)
    Cette méthode est extrêmement pratique pour connaître la distance entre deux points.

    const distance = camera.position.distanceTo(cube.position);
    console.log(`La distance au cube est de : ${distance} unités.`);
    
  • Additionner des vecteurs : .add(vector)
    Additionner deux vecteurs est utile pour appliquer un déplacement. Si vous ajoutez un petit vecteur de direction à la position d'un objet à chaque image, l'objet se déplacera.

    // Dans la boucle d'animation
    const direction = new THREE.Vector3(0, 0.01, 0); // Un petit mouvement vers le haut
    cube.position.add(direction); // Déplace le cube vers le haut à chaque frame
    
  • Multiplier par un scalaire : .multiplyScalar(number)
    Cette méthode modifie la longueur (magnitude) d'un vecteur sans changer sa direction. C'est parfait pour contrôler la vitesse d'un mouvement.

    // Un vecteur pointant vers le haut à droite
    const direction = new THREE.Vector3(1, 1, 0);
    
    // Pour que le mouvement soit cohérent, on normalise d'abord le vecteur.
    // La normalisation ajuste le vecteur pour que sa longueur soit de 1.
    direction.normalize(); 
    
    const speed = 5;
    const movement = direction.multiplyScalar(speed); // Maintenant, `movement` est un vecteur de longueur 5 dans la bonne direction.
    

    Le premier article de Grafikart que nous avons vu utilise cette technique avec la ligne sprite.position.copy(point.position.clone().normalize().multiplyScalar(30)). C'est un schéma très courant : prendre une direction, la normaliser pour obtenir une direction "pure" (longueur de 1), puis la multiplier par la distance ou la vitesse souhaitée.


Exercice pratique

Mettons ces concepts en application. Repartez de votre code existant (avec la scène, le cube et les OrbitControls).

  1. Redimensionnez le cube principal pour qu'il soit deux fois plus large que haut (scale.x = 2, scale.y = 0.5).
  2. Créez un deuxième cube, plus petit (échelle de 0.5 sur tous les axes), de couleur rouge (0xff0000).
  3. Placez ce cube rouge à 4 unités à droite du cube principal (sur l'axe X positif).
  4. Dans votre boucle d'animation animate(), faites en sorte que le cube rouge monte lentement le long de l'axe Y.
  5. Toujours dans la boucle d'animation, utilisez console.log() pour afficher en continu la distance entre la caméra et le cube rouge.

Astuce : Pour le mouvement, vous devrez créer un Vector3 représentant une petite translation vers le haut et l'ajouter à la position du cube rouge à chaque image.


Conclusion

Vous venez de faire vos premiers pas avec l'outil mathématique le plus essentiel de la 3D. En maîtrisant le Vector3, vous débloquez la capacité de manipuler l'espace de manière programmatique.

Points clés à retenir :

  • Le Vector3 est un objet contenant des coordonnées x, y, z.
  • Il sert principalement à définir une position (.position), une échelle (.scale) ou une direction.
  • Des méthodes comme .set(), .distanceTo(), .add() et .multiplyScalar() permettent d'effectuer des opérations spatiales courantes de manière simple et lisible.

Aperçu de la prochaine leçon :
Nous savons maintenant positionner et déplacer des objets individuels. Mais comment gérer des ensembles d'objets complexes, comme une voiture avec ses quatre roues qui doivent tourner ensemble ? Tenter de calculer la position de chaque roue individuellement serait un cauchemar. Dans la prochaine leçon, nous découvrirons comment organiser des objets en hiérarchies logiques à l'aide de Group, une technique puissante pour que les objets enfants héritent des transformations de leurs parents.