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

Ако си зад уеб филтър, моля, увери се, че домейните *. kastatic.org и *. kasandbox.org са разрешени.

Основно съдържание

Генериране на 3D форми

И така, имаме куб, но какво трябва да направим, ако искаме да променим положението или размера? Или ако искаме правоъгълен паралелепипед или много паралелепипеди? В нашия текущ код ще трябва да променим възлите един по един, което ще ни бъде неудобно. Това, което бихме искали, е прост метод за създаване на правоъгълен паралелепипед с определена позиция и размери. С други думи искаме функция, която да поставя позицията и измеренията в масив от възли и масив от ръбове.

Дефиниране на правоъгълен паралелепипед

Правоъгълният паралелепипед има три размера: широчина, височина и дълбочина:
Той също има място в 3D пространството, което ни дава шест параметъра. Има няколко начина, по които бихме могли да определим позицията на куба: бихме могли да дефинираме неговия център или един негов ъгъл. Първият начин е вероятно по-често срещан, но си мисля, че последният е по-лесен за използване.
Нашата функция трябва да върне и масива с възлите, и този с ръбовете. Един начин да върнем две променливи е да пакетираме променливите в обект с ключ за възли и ключ за ръбове. Обърни внимание, че можеш да използваш произволен низ за име на променливата; според мен е просто по-лесно да използвам същата дума.
// Създай паралелепипед с връх точка (x, y, z)
// с широчина w, височина h и дълбочина d.
var createCuboid = function(x, y, z, w, h, d) {
  var nodes = [];
  var edges = [];
  var shape = { 'nodes': nodes, 'edges': edges };
  return shape;
};
Ако използвахме тази функция за създаване на правоъгълен паралелепипед, щяхме да достъпим първия възел така :
var object = createCuboid(0, 0, 0, 100, 160, 50);
var node0 = shape.nodes[0];
Това ще зададе node0 на първата стойност в масива nodes. В момента, обаче, няма стойности в масивите с възли и ръбове .
Дефинираме възлите като всяка комбинация от позиция с или без съответното измерение. Ръбовете се дефинират както преди (само че вместо да дефинирам всеки ръб по отделно, дефинирам всички наведнъж). Имай предвид, че тази функция ти позволява да зададеш отрицателните измерения за паралелепипеда.
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};
};
Можем след това да създадем паралелепипед с широчина 100, височина 160, дълбочина 50 и един възел в началната точка ето така:
var shape = createCuboid(0, 0, 0, 100, 160, 50);
Тъй като предният ни код реферира глобалните променливи nodes и edges , трябва да съхраним свойствата на нашия обект в тези глобални променливи:
var nodes = shape.nodes; var edges = shape.edges;
Можеш да видиш целия код по-долу.

Работа с множество фигури

Mожем да създадем форми с различни размери, но ако искаме да имаме повече от една? Когато ни трябва променлив брой неща, масив ще ни свърши работа, така че нека създадем масив от форми.
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];
Сега трябва да променим функциите за показване и ротация, така че да работят с масив от обекти. Да започнем, като вкараме кода за показване на ръбовете във for цикъл, който обхожда всички фигури:
// Да нарисуваме ръбовете
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]);
  }
}
И подобен цикъл за показване на възлите:
// Да нарисуваме възлите
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);
  }
}
Можем да добавим подобен for цикъл към всяка от функциите за въртене, но мисля, че ще е по-гъвкаво да подадем масив от точки на всяка функция – така можем да завъртим формите независимо една от друга. Например функцията rotateZ3D() ще изглежда така:
var rotateZ3D = function(theta, nodes) { ... };
Така, когато използваме мишката за да завъртим, ще трябва да обхождаме формите и да извикаме функцията за всяка една:
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);
  }
};
Увери се, че премахна всички други извиквания на функциите за ротация, които не подават никакви възли. Можеш да видите целия код по-долу.

Искаш ли да се присъединиш към разговора?

Все още няма публикации.
Разбираш ли английски? Натисни тук, за да видиш още дискусии в английския сайт на Кан Академия.