Główna zawartość
Programowanie
Tworzenie brył w trzech wymiarach
Mamy więc sześcian, ale co zrobić, jeżeli chcemy zmienić jego położenie lub rozmiar? Albo jeżeli chcemy stworzyć prostopadłościan, lub wiele prostopadłościanów? Z naszym aktualnym kodem musielibyśmy zmienić każdy węzeł pojedynczo, co nie jest zbyt wygodne. To, czego potrzebujemy to prosta metoda na stworzenie sześcianu z konkretną pozycją i wymiarami. Innymi słowy chcemy stworzyć funkcję, która przerabia lokalizację i wymiary w tablicę lub węzły i tablicę krawędzi.
Tworzenie prostopadłościanu
Prostopadłościan ma trzy wymiary: szerokość, wysokość i głębokość:
Ma również swoje miejsce w przestrzeni trójwymiarowej, co daje nam w sumie sześć parametrów. Jest kilka sposobów, w jakie możemy zdefiniować położenie bryły: możemy określić jej środek, albo jeden z rogów. Pierwsza z tych opcji jest bardziej popularna, ale ta druga jest łatwiejsza w użyciu.
Nasza funkcja musi zwracać zarówno tablicę węzłów, jak i krawędzi. Jedną ze sposobów aby zwrócić dwie zmienne to spakować je do obiektu, z osobnym odniesieniem do
węzłów
i osobnym do krawędzi
. Pamiętaj, że możesz nazwać zmienną w dowolny sposób, dla mnie po prostu łatwiej jest użyć tego samego słowa.// Stwórz prostopadłościan z wierzchołkiem w (x, y, z)
// z szerokością w, wysokością h, i głębokością d.
var createCuboid = function(x, y, z, w, h, d) {
var nodes = [];
var edges = [];
var shape = { 'nodes': nodes, 'edges': edges };
return shape;
};
Jeżeli użylibyśmy tej funkcji do stworzenia prostopadłościanu, odniesiemy się do pierwszego węzła w sposób następujący:
var shape = createCuboid(0, 0, 0, 100, 160, 50);
var node0 = shape.nodes[0];
Ustawi to wartość
node0
na pierwszą wartość w tablicy nodes
. Jednak w tej chwili nie ma żadnych wartości w tablicach węzłów lub krawędzi.Określamy węzły jako kombinację wszystkich pozycji z lub bez odpowiedniego wymiaru. Krawędzie są definiowane w taki sam sposób, jak były definiowane wcześniej(tyle, że zamiast definiować każdy z nich osobno, deklarujemy je wszystkie na raz). Zauważ, że ta funkcja pozwala wam na określanie wymiarów ujemnych dla prostopadłościanu.
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};
};
Możemy teraz stworzyć prostopadłościan o szerokości 100, wysokości 160, głębokości 50 i jednym węzłem w środku układu za pomocą następującej komendy:
var shape = createCuboid(0, 0, 0, 100, 160, 50);
Z racji, że nasz poprzedni kod odnosi się do globalnych zmiennych
nodes
i edges
, musimy przechowywać cechy naszego obiektu w tych zmiennych:var nodes = shape.nodes; var edges = shape.edges;
Możecie zobaczyć skończony kod poniżej.
Praca z wieloma kształtami
Możemy stworzyć kształty o różnych wymiarach, ale co, jeżeli chcemy więcej niż jeden? Za każdym razem, gdy chcemy zmienną liczbę rzeczy, tablica to dobre wyjście - stwórzmy więc tablicę kształtów.
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];
Teraz musimy zmienić funkcje display i rotate tak, aby współpracowały z tablicą obiektów. Zacznijmy od umieszczenia kodu wyświetlającego krawędzie w pętli, która iteruje po wszystkich kształtach:
// Rysowanie krawędzi
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]);
}
}
Oraz podobna pętla do wyświetlania węzłów:
// Rysuj węzły
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);
}
}
Możemy dodać podobną pętlę do każdej funkcji obracającej, ale bardziej elastycznym sposobem jest przekazanie tablicy krawędzi do każdej funkcji - dzięki temu możemy obracać każdym kształtem niezależnie od innych. Dla przykładu, funkcja rotateZ3D() będzie wyglądać tak:
var rotateZ3D = function(theta, nodes) { ... };
Teraz gdy używamy myszki do obracania, musimy w pętli przejrzeć wszystkie kształty i wywołać funkcję dla każdego z nich:
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);
}
};
Upewnijcie się, że usunęliście wszystkie inne wywołania metody obracającej, które nie przekazują węzłów. Gotowy kod możecie zobaczyć poniżej.
Chcesz dołączyć do dyskusji?
- Dlaczego w tym temacie nie ma żadnych wyzwań ani projektów ?(3 głosy)
- Aktualnie w tym dziale nie dodano jeszcze żadnych wyzwań/Projektów. Prawdopodobnie zostaną dodane już niedługo.(2 głosy)