If you're seeing this message, it means we're having trouble loading external resources on our website.

Si vous avez un filtre web, veuillez vous assurer que les domaines *. kastatic.org et *. kasandbox.org sont autorisés.

Contenu principal

Générer des formes 3D

Bien, nous avons maintenant un cube. Et si nous voulions modifier sa position ou sa taille ? Ou, si nous voulions un ou plusieurs parallélépipèdes rectangles ? Avec notre code actuel, nous aurions à modifier les nœuds un par un, ce qui seraient vraiment ennuyeux. Ce que nous voulons est une méthode simple pour créer un parallélépipède rectangle, avec position et dimensions. En d'autres mots, nous souhaiterions une fonction qui enregistrerait une position et des dimensions dans des tableaux de nœuds et d'arêtes.

Définir un parallélépipède rectangle

Un parallélépipède rectangle a trois dimensions : largeur, hauteur et profondeur :
Il possède également des coordonnées dans l'espace 3D (x, y, z), ce qui fait six paramètres. il existe deux façons de définir le positionnement du cube : nous pouvons utiliser son centre ou nous pouvons définir les coordonnées d'un coin. La première méthode est probablement celle qui est la plus commune, mais je pense que la deuxième est plus facile à utiliser.
Il faut que notre fonction retourne, et le tableau de nœuds, et le tableau d'arêtes. Un moyen de retourner deux variables est d'utiliser un objet pour les stocker, avec une clef pour nodes et une clef pour edges. Remarquez que vous pouvez utiliser n'importe quelle chaîne de caractères pour vous référer aux variables. J'ai juste trouvé plus facile d'utiliser les mêmes mots.
// Création d'un parallélépipède rectangle avec un sommet en (x, y, z),
// une largeur w, une hauteur h, et une profondeur d.
var createCuboid = function(x, y, z, w, h, d) {
   var nodes = [];
   var edges = [];`
   var shape = { 'nodes': nodes, 'edges': edges };
   return shape;
};
Si nous utilisions cette fonction pour créer un parallélépipède rectangle, nous accèderions au premier nœud comme ceci :
var object = createCuboid(0, 0, 0, 100, 160, 50);
var node0 = shape.nodes[0];
Cela va affecter la première valeur du tableau nodes à node0. Pour l'instant, cependant, il n'y a pas de valeurs dans les tableaux de nœuds et d'arêtes.
Nous définissons les nœuds en calculant toutes les combinaisons possibles de coordonnées, additionnées ou non, des dimensions correspondantes. Les arêtes sont définies de la même façon qu'avant (sauf que plutôt que de définir chaque arête l'une après l'autre, je les définis toutes en même temps). Remarquez que cette fonction vous permet de spécifier des dimensions négatives pour le parallélépipède rectangle.
var createCuboid = function(x, y, z, w, h, d) {
   var nodes = [[x, y, z ], [x, y, z+d], [x, y+h, z ], [x, y+h, z+d], [x+w, y, z ], [x+w, y, z+d], [x+w, y+h, z ], [x+w, y+h, z+d]];

   var edges = [[0, 1], [1, 3], [3, 2], [2, 0], [4, 5], [5, 7], [7, 6], [6, 4], [0, 4], [1, 5], [2, 6], [3, 7]];

   return { 'nodes': nodes, 'edges': edges};
};
Nous pouvons maintenant créer un parallélépipède rectangle de largeur 100, de hauteur 160, et de profondeur 50, avec un sommet à l'origine, comme ceci :
var shape = createCuboid(0, 0, 0, 100, 160, 50);
Étant donné que notre code précédent référence des variables globales nodes et edges, il nous faut enregistrer nos propriétés d'objet dans ces variables globales :
var nodes = shape.nodes; var edges = shape.edges;
Vous pouvez regarder le code complet ci-dessous.

Travailler avec plusieurs formes

Nous pouvons créer des formes avec des dimensions différentes. Et si nous en voulions plus d'une ? À chaque fois qu'on souhaite un nombre variable de choses, il faut penser aux tableaux. Créons un tableau de formes.
var shape1 = createCuboid(-120, -20, -20, 240, 40, 40);
var shape2 = createCuboid(-120, -50, -30, -20, 100, 60);
var shape3 = createCuboid( 120, -50, -30, 20, 100, 60);
var shapes = [shape1, shape2, shape3];
Maintenant, il nous faut modifier l'affichage et les fonctions de rotation pour que cela fonctionne avec un tableau d'objets. Commençons par envelopper le code qui affiche les arêtes dans une boucle for parcourant toutes les formes :
// Draw edges
stroke(edgeColor);
for (var shapeNum = 0; shapeNum < shapes.length; shapeNum++) {
    var nodes = shapes[shapeNum].nodes;
    var edges = shapes[shapeNum].edges;
    for (var e = 0; e < edges.length; e++) {
        var n0 = edges[e][0];
        var n1 = edges[e][1];
        var node0 = nodes[n0];
        var node1 = nodes[n1];
    line(node0[0], node0[1], node1[0], node1[1]);
    }
}
Et une boucle for similaire pour afficher les nœuds :
// Draw nodes
fill(nodeColor);
noStroke();
for (var shapeNum = 0; shapeNum < shapes.length; shapeNum++) {
    var nodes = shapes[shapeNum].nodes;
    for (var n = 0; n < nodes.length; n++) {
       var node = nodes[n]; ellipse(node[0], node[1], nodeSize, nodeSize);
    }
}
Nous pouvons ajouter une boucle for similaire pour chacune des fonctions de rotation, mais je pense qu'il est plus flexible de passer les tableaux de nœuds à chaque fonction (de cette façon, on peut faire pivoter les formes indépendamment les unes des autres). Par exemple, la fonction rotateZ3D() donnerait :
var rotateZ3D = function(theta, nodes) { ... };
Maintenant, quand on utilise la souris pour faire pivoter, on doit boucler sur les formes et appeler la fonction sur chacune :
mouseDragged = function() {
    var dx = mouseX - pmouseX;
    var dy = mouseY - pmouseY;
    for (var shapeNum = 0; shapeNum < shapes.length; shapeNum++) {
        var nodes = shapes[shapeNum].nodes;
        rotateY3D(dx, nodes);
        rotateX3D(dy, nodes);
    }
};
Veillez à supprimer tous les autres appels aux fonctions de rotation qui ne passent aucun nœud en argument. Vous pouvez consulter le code complet ci-dessous :

Vous souhaitez rejoindre la discussion ?

Vous comprenez l'anglais ? Cliquez ici pour participer à d'autres discussions sur Khan Academy en anglais.