I programmed a hypercube in javascript using p5.js and works fine, but I would like to know how to rotate this hypercube in X axis using matrix rotations. I know that we can do this using standard functions in p5.js like rotateX (in the line 84), but I would like to do this using matrix rotations and isn't working.
Here's the code:
var points = [];
var distance = 2; //distance in w axis
var angle = 0;
//4D vector
class vector4D {
constructor(x, y, z, w) {
this.x = x;
this.y = y;
this.z = z;
this.w = w;
}
}
var rotatedVector = new vector4D();
var projectedVector = new vector4D();
//All points of a hypercube.
points[0] = new vector4D([-1], [-1], [-1], [1]);
points[1] = new vector4D([1], [-1], [-1], [1]);
points[2] = new vector4D([1], [1], [-1], [1]);
points[3] = new vector4D([-1], [1], [-1], [1]);
points[4] = new vector4D([-1], [-1], [1], [1]);
points[5] = new vector4D([1], [-1], [1], [1]);
points[6] = new vector4D([1], [1], [1], [1]);
points[7] = new vector4D([-1], [1], [1], [1]);
points[8] = new vector4D([-1], [-1], [-1], [-1]);
points[9] = new vector4D([1], [-1], [-1], [-1]);
points[10] = new vector4D([1], [1], [-1], [-1]);
points[11] = new vector4D([-1], [1], [-1], [-1]);
points[12] = new vector4D([-1], [-1], [1], [-1]);
points[13] = new vector4D([1], [-1], [1], [-1]);
points[14] = new vector4D([1], [1], [1], [-1]);
points[15] = new vector4D([-1], [1], [1], [-1]);
function setup() {
createCanvas(600, 400, WEBGL);
}
//Multiply a 4x4 or 3x3 matrix with a vector
function multiply(a, b, size) {
var vector = new vector4D();
if (size == 4) {
vector.x =
a[0][0] * b.x + a[0][1] * b.y + a[0][2] * b.z + a[0][3] * b.w;
vector.y =
a[1][0] * b.x + a[1][1] * b.y + a[1][2] * b.z + a[1][3] * b.w;
vector.z =
a[2][0] * b.x + a[2][1] * b.y + a[2][2] * b.z + a[2][3] * b.w;
vector.w =
a[3][0] * b.x + a[3][1] * b.y + a[3][2] * b.z + a[3][3] * b.w;
} else {
vector.x = a[0][0] * b.x + a[0][1] * b.y + a[0][2] * b.z;
vector.y = a[1][0] * b.x + a[1][1] * b.y + a[1][2] * b.z;
vector.z = a[2][0] * b.x + a[2][1] * b.y + a[2][2] * b.z;
vector.w = 1;
}
return vector;
}
//Connect all points of a hypercube
function connectDots(i, j, j2, projected) {
line(
projected[j + i].x,
projected[j + i].y,
projected[j + i].z,
projected[j2 + i].x,
projected[j2 + i].y,
projected[j2 + i].z
);
}
function draw() {
background("blue");
translate(0, 0);
stroke(255);
<!-- rotateX(-PI / 2); -->
strokeWeight(1);
//X, Y and Z are not used, but I put here to test rotations in all these axis
var rotationMatrixX = [
[1, 0, 0],
[0, cos(angle), -sin(angle)],
[0, sin(angle), cos(angle)],
];
var rotationMatrixY = [
[cos(angle), 0, sin(angle)],
[0, 1, 0],
[-sin(angle), 0, cos(angle)],
];
var rotationMatrixZ = [
[cos(angle), -sin(angle), 0],
[sin(angle), cos(angle), 0],
[0, 0, 1],
];
var rotationMatrixXY = [
[cos(angle), -sin(angle), 0, 0],
[sin(angle), cos(angle), 0, 0],
[0, 0, 1, 0],
[0, 0, 0, 1],
];
var rotationMatrixZW = [
[1, 0, 0, 0],
[0, 1, 0, 0],
[0, 0, cos(angle), -sin(angle)],
[0, 0, sin(angle), cos(angle)],
];
//All points rotated and projected to connect
var projected = [16];
for (i in points) {
rotatedVector = multiply(
rotationMatrixXY,
points[i],
rotationMatrixXY.length
);
rotatedVector = multiply(
rotationMatrixZW,
rotatedVector,
rotationMatrixZW.length
);
//w perspective
var w = 2 / (distance - rotatedVector.w);
var projectionMatrix = [
[w, 0, 0, 0],
[0, w, 0, 0],
[0, 0, w, 0],
];
projectedVector = multiply(
projectionMatrix,
rotatedVector,
projectionMatrix.length
);
projectedVector.x *= 25;
projectedVector.y *= 25;
projectedVector.z *= 25;
projected[i] = projectedVector;
point(projectedVector.x, projectedVector.y, projectedVector.z);
}
//Connecting all dots
for (i = 0; i < 8; i++) {
if (i < 4) {
connectDots(0, i, i + 4, projected);
connectDots(0, i, i + 8, projected);
connectDots(0, i, (i + 1) % 4, projected);
connectDots(0, i + 4, ((i + 1) % 4) + 4, projected);
connectDots(8, i, i + 4, projected);
connectDots(8, i, (i + 1) % 4, projected);
connectDots(8, i + 4, ((i + 1) % 4) + 4, projected);
}
connectDots(0, i, i + 8, projected);
}
angle += 0.025;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.6.0/p5.js"></script>