<script src="https://cdn.jsdelivr.net/npm/p5@1.9.0/lib/p5.js"></script>
body {margin:0px; padding:0px; overflow: hidden}
const points = [
  [-100, -100, -100, -100], [100, -100, -100, -100], [-100, 100, -100, -100], [100, 100, -100, -100],
  [-100, -100, 100, -100], [100, -100, 100, -100], [-100, 100, 100, -100], [100, 100, 100, -100],
  [-100, -100, -100, 100], [100, -100, -100, 100], [-100, 100, -100, 100], [100, 100, -100, 100],
  [-100, -100, 100, 100], [100, -100, 100, 100], [-100, 100, 100, 100], [100, 100, 100, 100]
];

const lines = [
  [0, 1], [0, 2], [0, 4], [0, 8], 
  [1, 3], [1, 5], [1, 9], 
  [2, 3], [2, 6], [2, 10],
  [3, 7], [3, 11], 
  [4, 5], [4, 6], [4, 12], 
  [5, 7], [5, 13], 
  [6, 7], [6, 14], 
  [7, 15],
  [8, 9], [8, 10], [8, 12],
  [9, 11], [9, 13],
  [10, 11], [10, 14],
  [11, 15],
  [12, 13], [12, 14],
  [13, 15],
  [14, 15]
];

let rotation = 0;

function setup() {
  createCanvas(windowWidth, windowHeight);
}

function draw() {
  clear();
  background(240, 240, 30);
  
  const deltaTimeInSeconds = deltaTime / 1000;
  rotation += radians(15) * deltaTimeInSeconds;
  
  const rotatedPoints = points.map(p => {
    return rotateBoxPoint(p, rotation);
  });
  
  push();
  translate(width * 0.5, height * 0.5);
  
  for (const l of lines) {
    const point1 = project(rotatedPoints[l[0]]); 
    const point2 = project(rotatedPoints[l[1]]);
    drawLine(point1, point2);
  }
  
  for (const point of rotatedPoints) {
    const projected = project(point); 
    drawPoint(projected);
    drawLabel(projected[0], projected[1], `${round(point[0])}, ${round(point[1])}, ${round(point[2])}, ${round(point[3])}`);
  }
  pop();
}

function project(point3D) {
  const distance = 500;
  const scale = distance / (distance + point3D[2]);
  const x2D = point3D[0] * scale;
  const y2D = point3D[1] * scale;
  return [x2D, y2D];
}

function drawPoint(point2D) {
  fill(0);
  noStroke();
  circle(point2D[0], point2D[1], 10);
}

function drawLine(point1, point2) {
  stroke(0);
  line(point1[0], point1[1], point2[0], point2[1]);
}

function rotate2D(point2D, angle) {
  const x = cos(angle) * point2D[0] - sin(angle) * point2D[1];
  const y = sin(angle) * point2D[0] + cos(angle) * point2D[1];
  return [x, y];
}

function rotateOnPlane(point, angle, axisA, axisB) {
  const rotated = rotate2D([point[axisA], point[axisB]], angle);
  const newPoint = point.slice();
  newPoint[axisA] = rotated[0];
  newPoint[axisB] = rotated[1];
  return newPoint;
}

function rotateBoxPoint(point, angle) {
  let newPoint = point.slice();
  newPoint = rotateOnPlane(newPoint, angle, 0, 3);
  newPoint = rotateOnPlane(newPoint, angle * 1.5, 1, 3);
  newPoint = rotateOnPlane(newPoint, angle * 2.0, 2, 3);
  return newPoint;
}

function drawLabel(x, y, label, align = CENTER) {
  push();
  strokeWeight(0);
  textFont("monospace");
  textSize(14);
  textAlign(align);
  if (align == LEFT) {x += 6;}
  if (align == RIGHT) {x -= 6;}
  text(label, x, y);
  pop();
}
Run Pen

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.