xxxxxxxxxx
164
// based on Khan Academy Tutorial; Dan Shiffman/Coding train; objects added by Erim Keresteci; arbitrary point rotation added by Max Larsson
const objs = []; // an empty array to store all JS object
let shape = []; // an empty array to store all the cubes
let cameraPosition = {
x: 0,
y: 0,
z: 0,
};
function setup() {
createCanvas(500, 500);
// generating the two cuboid and defining them // (x, y, z, h, d, w)
}
function draw() {
// using angles for our sin and cos calc instead of radians
angleMode(DEGREES);
background(220);
// translate (0, 0) to center of canvas
translate(200, 200);
// need to intitialize; rename initCube to drawCube
// draw each cube here
for (var i = 0; i < objs.length; i++) {
shape[i].drawCube();
}
text("Framerate: " + frameRate(), -150, -150);
}
function mouseClicked() {
// creates a new cube when mouse is pressed
// adds each object to objs array
shape.push(new cuboid(mouseX - 200, mouseY - 200, 200, 10, 10, 10));
}
function mouseDragged() {
// uses the past mouse X and Y to understand the direction of the mouse movement and then do a X and Y rotate
// control rotation here
// syntax for the rotate functions
// rotate(angle, a, b, c)
// a, b, c are hypothetical points in XYZ space
for (i = 0; i < objs.length; i++) {
objs[i].rotateX3D(pmouseY - mouseY, 20, 20, 20);
objs[i].rotateY3D(pmouseY - mouseY, 20, 20, 20);
objs[i].rotateZ3D(pmouseY - mouseY, 20, 20, 20);
}
}
class cuboid {
// intializes the object with a number of parameter for identifying the nodes and edges
constructor(x, y, z, w, h, d) {
this.x = x;
this.y = y;
this.z = z;
this.w = w;
this.h = h;
this.d = d;
this.nodes = [
[this.x, this.y, this.z],
[this.x, this.y, this.z + this.d],
[this.x, this.y + this.h, this.z],
[this.x, this.y + this.h, this.z + this.d],
[this.x + this.w, this.y, this.z],
[this.x + this.w, this.y, this.z + this.d],
[this.x + this.w, this.y + this.h, this.z],
[this.x + this.w, this.y + this.h, this.z + this.d],
];
this.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],
];
// don't need to sore "shape" info
this.shape = { nodes: this.nodes, edges: this.edges };
this.nodeSize = 8;
this.nodeColor = color(40, 168, 107);
this.edgeColor = color(34, 68, 204);
objs.push(this);
}
// uses theta and the transformation matrix to calculate new Xs and Ys
// lines 58 and 59 updated with c and b to allow for rotation around arbitrary point
rotateX3D(theta, a, b, c) {
let sinTheta = sin(theta);
let cosTheta = cos(theta);
for (let n = 0; n < this.nodes.length; n++) {
let node = this.nodes[n];
let y = node[1];
let z = node[2];
node[2] = c + (z - c) * cosTheta + (y - b) * sinTheta;
node[1] = b + (y - b) * cosTheta - (z - c) * sinTheta;
}
}
// rotating on Y axis, convert Zs and Xs into new Xs and Ys
rotateY3D(theta, a, b, c) {
let sinTheta = sin(theta);
let cosTheta = cos(theta);
for (let n = 0; n < this.nodes.length; n++) {
let node = this.nodes[n];
let x = node[0];
let z = node[2];
node[0] = a + (x - a) * cosTheta + (z - c) * sinTheta;
node[2] = c + (z - c) * cosTheta - (x - a) * sinTheta;
}
}
// rotating on Z axis, convert Xs and Ys into new Xs and Ys
rotateZ3D(theta, a, b, c) {
let sinTheta = sin(theta);
let cosTheta = cos(theta);
for (let n = 0; n < this.nodes.length; n++) {
let node = this.nodes[n];
let x = node[0];
let y = node[1];
node[0] = a + (x - a) * cosTheta - (y - b) * sinTheta;
node[1] = b + (y - b) * cosTheta + (x - a) * sinTheta;
}
}
// update method name; this method draws lines on the canvas based on new Xs and Ys
drawCube() {
this.nodes = [
[this.x, this.y, this.z],
[this.x, this.y, this.z + this.d],
[this.x, this.y + this.h, this.z],
[this.x, this.y + this.h, this.z + this.d],
[this.x + this.w, this.y, this.z],
[this.x + this.w, this.y, this.z + this.d],
[this.x + this.w, this.y + this.h, this.z],
[this.x + this.w, this.y + this.h, this.z + this.d],
];
stroke(this.edgeColor);
for (let e = 0; e < this.edges.length; e++) {
let n0 = this.edges[e][0];
let n1 = this.edges[e][1];
let node0 = this.nodes[n0];
let node1 = this.nodes[n1];
line(node0[0], node0[1], node1[0], node1[1]);
}
// draws circles where the nodes are
fill(this.nodeColor);
noStroke();
for (let n = 0; n < this.nodes.length; n++) {
let node = this.nodes[n];
ellipse(node[0], node[1], this.nodeSize, this.nodeSize);
}
}
}