I am trying to rotate a cube around its own 3 axis, as well as make it orbit the centre of the screen. Individually both of these transformations work, but when I run them together, the cube slowly translates off screen.
function loop(timeNow) {
//calculate time difference
timeDelta = timeNow - timeLast;
timeLast = timeNow;
// background
ctx.fillRect(0, 0, w, h);
// c is the centre of the cube
// rotate along z axis
let angle = timeDelta * 0.001 * SPEED_Z * Math.PI * 2;
for (let v of vertices) {
let dx = v.x - c.x;
let dy = v.y - c.y;
let x = dx * Math.cos(angle) - dy * Math.sin(angle);
let y = dx * Math.sin(angle) + dy * Math.cos(angle);
v.x = x + c.x;
v.y = y + c.y;
}
// rotate along x axis
angle = timeDelta * 0.001 * SPEED_X * Math.PI * 2;
for (let v of vertices) {
let dz = v.z - c.z;
let dy = v.y - c.y;
let z = dy * Math.sin(angle) + dz * Math.cos(angle);
let y = dy * Math.cos(angle) - dz * Math.sin(angle);
v.z = z + c.z;
v.y = y + c.y;
}
// rotate along y axis
angle = timeDelta * 0.001 * SPEED_Y * Math.PI * 2;
for (let v of vertices) {
let dz = v.z - c.z;
let dx = v.x - c.x;
let z = dz * Math.cos(angle) - dx * Math.sin(angle);
let x = dz * Math.sin(angle) + dx * Math.cos(angle);
v.z = z + c.z;
v.x = x + c.x;
}
// centre is the centre of the page
// rotating around the centre of the page
let theta = Math.PI * 2 * timeDelta * 0.001 * 0.5;
for (let v of vertices) {
let dx = v.x - centre.x;
let dy = v.y - centre.y;
let x = dx * Math.cos(theta) - dy * Math.sin(theta);
let y = dx * Math.sin(theta) + dy * Math.cos(theta);
v.x = centre.x + x;
v.y = centre.y + y;
}
// draw each edge
for (let edge of edges) {
ctx.beginPath();
ctx.moveTo(vertices[edge[0]].x, vertices[edge[0]].y);
ctx.lineTo(vertices[edge[1]].x, vertices[edge[1]].y);
ctx.stroke();
}
// call next frame
requestAnimationFrame(loop);
}
I have tried reading up on affine transformations and combining them, but I'm having trouble translating the theory into this code. Any help would be appreciated.