blyad, fuck that 3d matix shit. try fix that error: // create a canvas element
const canvas = document.createElement('canvas');
canvas.width = 400;
canvas.height = 400;
document.body.appendChild(canvas);

// get the canvas context
const ctx = canvas.getContext('2d');

// define a cube
const vertices = [
[0, 0, 0],
[0, 1, 0],
[1, 1, 0],
[1, 0, 0],
[0, 0, 1],
[0, 1, 1],
[1, 1, 1],
[1, 0, 1],
];

const edges = [
[0, 1],
[1, 2],
[2, 3],
[3, 0],
[0, 4],
[1, 5],
[2, 6],
[3, 7],
[4, 5],
[5, 6],
[6, 7],
[7, 4],
];

// define some rotation matrices
function rotateX(angle) {
const c = Math.cos(angle);
const s = Math.sin(angle);
return [
[1, 0, 0],
[0, c, s],
[0, -s, c],
];
}

function rotateY(angle) {
const c = Math.cos(angle);
const s = Math.sin(angle);
return [
[c, 0, -s],
[0, 1, 0],
[s, 0, c],
];
}

function rotateZ(angle) {
const c = Math.cos(angle);
const s = Math.sin(angle);
return [
[c, s, 0],
[-s, c, 0],
[0, 0, 1],
];
}

// define the projection matrix
function projected(point) {
return [
(point[0] / (0.5 + point[2])) * canvas.width,
(point[1] / (0.5 + point[2])) * canvas.height,
];
}

// render function
let angleX = 0;
let angleY = 0;
let angleZ = 0;

function render() {
// clear the canvas
ctx.fillStyle = '#FFF';
ctx.fillRect(0, 0, canvas.width, canvas.height);

const matrix = rotateZ(angleZ).map(row =>
rotateY(angleY).map((_, j) =>
row.reduce((acc, _, k) =>
acc + rotateY(angleY)[k][j] * row[k],
0
)
)
).map(row =>
rotateX(angleX).map((_, j) =>
row.reduce((acc, _, k) =>
acc + rotateX(angleX)[k][j] * row[k],
0
)
)
);

// draw the edges
ctx.strokeStyle = '#000';
ctx.beginPath();
edges.forEach(([a, b]) => {
ctx.moveTo(projected[a][0], projected[a][1]);
ctx.lineTo(projected[b][0], projected[b][1]);
});
ctx.stroke();

// update the angles and request the next frame
angleX += 0.01;
angleY += 0.013;
angleZ += 0.007;
requestAnimationFrame(render);
}

// start the animation
requestAnimationFrame(render); <--TypeError: projected[a] is undefined 