Объект перемещается за пределы экрана, когда я пытаюсь вращаться вокруг оси и центра

#javascript #graphics #rotation #transformation

Вопрос:

Я пытаюсь повернуть куб вокруг его собственной оси 3, а также заставить его вращаться вокруг центра экрана. По отдельности оба этих преобразования работают, но когда я запускаю их вместе, куб медленно перемещается за пределы экрана.

 
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);
    }
 

Я пробовал читать об аффинных преобразованиях и комбинировать их, но у меня возникли проблемы с переводом теории в этот код. Любая помощь будет признательна.