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

Ha webszűrőt használsz, győződj meg róla, hogy a *.kastatic.org és a *.kasandbox.org nincsenek blokkolva.

Fő tartalom

3D alakzatok generálása

Most már van egy kockánk, de mi történne, ha meg szeretnénk változtatni a helyzetét vagy a méretét? Vagy ha téglatestet vagy téglatesteket szeretnénk? A mostani kódunkkal a csúcsokat egyesével meg kellene változtatni, ami valljuk be, hogy elég kellemetlen lenne. Szeretnénk egy egyszerű metódust, ami egy téglatestet készít a megadott helyre, adott méretekkel. Más szóval egy olyan függvényt szeretnénk, ami a helyzetet és a méreteket leképezi csomópontok és élek tömbjére.

Téglatest definiálása

A téglatesteknek három dimenziójuk van: szélességük (angolul width), magasságuk (angolul height) és mélységük (angolul depth):
Emellett a 3D térben van még helyzetük is, ez összesen hat paramétert jelent. Számos módon megadhatjuk egy téglatest helyzetét: megadhatjuk a közepét vagy valamelyik sarkát. Az előbbi valószínűleg a leggyakoribb, de úgy gondolom, hogy az utóbbit egyszerűbb használni.
A függvényünknek a csúcsok és élek tömbjét is vissza kell adnia. Egyik módja a két változóval való visszatérésnek, hogy a változókat egy objektumba csomagoljuk, ahol az egyik kulcs (a nodes) lesz a csúcsoké, a másik kulcs (az edges) az éleké.
// Téglatest az (x, y, z) pontban
// w szélességgel, h magassággal és d mélységgel.
var createCuboid = function(x, y, z, w, h, d) {
   var nodes = [];
   var edges = [];
   var shape = { 'nodes': nodes, 'edges': edges };
   return shape;
};
Ha ezt a függvényt használjuk a téglatest létrehozásához, akkor így tudjuk elérni az első csúcsot:
var shape = createCuboid(0, 0, 0, 100, 160, 50);
var node0 = shape.nodes[0];
Ez beállítja a node0-t a nodes tömb első értékének. Jelenleg viszont nincsen még semmilyen érték tárolva a nodes és edges tömbökben.
A csúcsokat úgy definiáljuk, mint a helyzetek valamennyi lehetséges kombinációja a hozzátartozó dimenzióval vagy anélkül. Az éleket úgy definiáljuk, ahogy korábban is (kivéve azt, hogy nem egyenként definiáljuk őket, hanem egyszerre). Érdemes megjegyezni, hogy ez a függvény negatív kiterjedés használatát is lehetővé teszi.
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};
};
Most már létrehozhatjuk a téglatestet 100 szélességgel, 160 magassággal, és 50 mélységgel az origóban:
var shape = createCuboid(0, 0, 0, 100, 160, 50);
Mivel az előző kód a nodes és edges globális változókra hivatkozott, el kell tárolnunk az objektumunk tulajdonságait ezekben a globális változókban:
var nodes = shape.nodes; var edges = shape.edges;
Alább láthatod a teljes kódot.

Dolgozzunk több alakzattal!

Készíthetünk alakzatokat különböző dimenziókkal, de hogyan kezelhetjük, ha egynél több alakzatunk van? Mindig hasznos tömböt használni olyankor, ha változó számú dolgunk van, ezért készítsünk is az alakzatoknak egy tömböt!
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];
Most meg kell változtatnunk a megjelenítő és az elforgató függvényt, hogy objektumtömbön működjön. Kezdjük azzal, hogy a megjelenítő kódot egy for ciklusban helyezzük el, ami végighalad az összes alakzaton:
// Élek kirajzolása
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]);
   }
}
És egy hasonló for ciklus a csúcsok megjelenítéséhez:
// Csúcsok kirajzolása
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);
   }
}
Hozzáadhatnánk egy hasonló for ciklust minden elforgató függvényhez, de szerintem rugalmasabb, ha minden függvénynek a csomópontok (csúcsok) tömbjét adjuk át – így az alakzatokat egymástól függetlenül is forgathatjuk. Például a rotateZ3D() függvény ilyen lenne:
var rotateZ3D = function(theta, nodes) { ... };
Így most, mikor az egérrel forgatjuk, végig kell haladnunk a ciklussal az alakzatokon, és meg kell hívnunk a függvényt minden egyes alakzatra.
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);
   }
};
Figyelj rá, hogy minden olyat hívást törölj az elforgató függvényekből, ami nem ad át egyetlen csomópontot sem. Alább láthatod a teljes kódot.

Szeretnél részt venni a beszélgetésben?

Még nincs hozzászólás.
Tudsz angolul? Kattints ide, ha meg szeretnéd nézni, milyen beszélgetések folynak a Khan Academy angol nyelvű oldalán.