вращения 3д куба относительно центра декартовой системы

С помощью проецирование квадрата на плоскость я получил 3д куб. Моя задача крутить его относительно центра и относительно оси z. С помощью функции rotatePoint(x,y,z,fi) я изменяю координать заданой точки. Где fi это тот кут, на сколько градусов я изменяю положение точки. И у меня на данном этапе все работает. Дело состоит в том, что 'по умолчанию' точка изменяет положение, но только относительно верхнего левого угла. Что бы изменять положение относительно заданой точки, нужно сначала переместить точку на вектор [-tx,-ty,-tz], дальше покрутить её, а потом снова переместить только уже о вектор [tx,ty,tz]. В закоментированых частях кода я пытался это сделать, но при попытках изменять положение точки она убегала куда то в угол и вращение уже не работало. Сейчас при изменениях кута в input куб вроде хорошо вращается но относительно левого верхнего угла. Как мне правильно сделать перемещение точки до и после вращения?

function randInt(min, max) {
            return Math.floor(Math.random() * (max - min + 1) ) + min;
        }

        function randomColor() {
            return "rgb(" + randInt(0,255) + "," + randInt(0,255) + "," + randInt(0,255) + ")";
        }

        function ctg(x) { 
            return 1 / Math.tan(x); 
        }

        function draw() {
            let canvas = document.getElementById("canvas");
            let context = canvas.getContext("2d");

            let canvasWidth = 300;
            canvas.width = canvas.height = canvasWidth;

            function drawUW() {
                context.lineWidth = 0.1;
                context.beginPath();
                context.moveTo(0,canvas.height/2);
                context.lineTo(canvas.width,canvas.height/2);
                context.moveTo(canvas.width/2,0);
                context.lineTo(canvas.width/2,canvas.height);
                context.stroke();
            }

            function updateCanvas() {
                context.clearRect(0,0,canvas.width,canvas.height);
                drawUW();
            }
            
            let x = 50, y = 50, z = 50;
            let d = 100;

            let x0 = canvas.width/2;
            let y0 = canvas.height/2;
            let x1 = x0+x;
            let y1 = y0;
            let x2 = x0;
            let y2 = y0-y;
            let x3 = x0+x;
            let y3 = y0-y;
            // x' = xd/(z+d)
            // y' = yd/(z+d)
            let x0p=x0*d/(z+d);
            let y0p=y0*d/(z+d);
            let x1p=x1*d/(z+d);
            let y1p=y1*d/(z+d);
            let x2p=x2*d/(z+d);
            let y2p=y2*d/(z+d);
            let x3p=x3*d/(z+d);
            let y3p=y3*d/(z+d);


            function getWalls() {
                wall01 = [[x0,x2,x3,x1],[y0,y2,y3,y1]];
                wall02 = [[x0p,x2p,x2,x0],[y0p,y2p,y2,y0]];
                wall03 = [[x0p,x2p,x3p,x1p],[y0p,y2p,y3p,y1p]];
                wall04 = [[x1p,x3p,x3,x1],[y1p,y3p,y3,y1]];
                wall05 = [[x2,x2p,x3p,x3],[y2,y2p,y3p,y3]];
                wall06 = [[x0,x0p,x1p,x1],[y0,y0p,y1p,y1]];
            }

            function drawWall(wall) {
                context.fillStyle = randomColor();
                context.strokeStyle = "black";
                context.lineWidth = 0.5;
                context.beginPath();
                context.moveTo(wall[0][0],wall[1][0]);
                context.lineTo(wall[0][1],wall[1][1]);
                context.lineTo(wall[0][2],wall[1][2]);
                context.lineTo(wall[0][3],wall[1][3]);
                context.lineTo(wall[0][0],wall[1][0]);
                context.fill();
                context.stroke();
            }

            function rotatePoint(x,y,z,fi) {
                fi*=Math.PI/180;
                arr = [x,y,z,1];
                newX = 0;
                newY = 0;
                newZ = 0;

                tx = -150, ty = -150, tz = -150;

                arrTranslate = [
                    [1,0,0,tx],
                    [0,1,0,ty],
                    [0,0,1,tz],
                    [0,0,0,1]
                ];

                // z
                arrRotate = [
                    [Math.cos(fi),-Math.sin(fi),0,0],
                    [Math.sin(fi),Math.cos(fi),0,0],
                    [0,0,1,0],
                    [0,0,0,1]
                ];

                // translate
                // for (let i = 0; i < arr.length; i++) {
                //     newX += arr[i] * arrTranslate[0][i];
                //     newY += arr[i] * arrTranslate[1][i];
                //     newZ += arr[i] * arrTranslate[2][i];
                // }

                //rotate
                for (let i = 0; i < arr.length; i++) {
                    newX += arr[i] * arrRotate[0][i];
                    newY += arr[i] * arrRotate[1][i];
                    newZ += arr[i] * arrRotate[2][i];
                }

                tx = 150, ty = 150, tz = 150;
                // translate
                // for (let i = 0; i < arr.length; i++) {
                //     newX += arr[i] * arrTranslate[0][i];
                //     newY += arr[i] * arrTranslate[1][i];
                //     newZ += arr[i] * arrTranslate[2][i];
                // }

                x = newX;
                y = newY;
                z = newZ;
                return [newX,newY,newZ];
            }

            function rotatePoints(fi) {
                x0 = rotatePoint(x0,y0,z,fi)[0];
                y0 = rotatePoint(x0,y0,z,fi)[1];
                x1 = rotatePoint(x1,y1,z,fi)[0];
                y1 = rotatePoint(x1,y1,z,fi)[1];
                x2 = rotatePoint(x2,y2,z,fi)[0];
                y2 = rotatePoint(x2,y2,z,fi)[1];
                x3 = rotatePoint(x3,y3,z,fi)[0];
                y3 = rotatePoint(x3,y3,z,fi)[1];

                x0p = rotatePoint(x0p,y0p,z,fi)[0];
                y0p = rotatePoint(x0p,y0p,z,fi)[1];
                x1p = rotatePoint(x1p,y1p,z,fi)[0];
                y1p = rotatePoint(x1p,y1p,z,fi)[1];
                x2p = rotatePoint(x2p,y2p,z,fi)[0];
                y2p = rotatePoint(x2p,y2p,z,fi)[1];
                x3p = rotatePoint(x3p,y3p,z,fi)[0];
                y3p = rotatePoint(x3p,y3p,z,fi)[1];
            }
            
            let inFi = document.getElementById("fi");
            inFi.addEventListener("change", updateImage);

            function updateImage() {
                rotatePoints(inFi.value);
                getWalls();
                updateCanvas();
                drawWall(wall06);
                drawWall(wall04);
                drawWall(wall03);
                drawWall(wall02);
                drawWall(wall05);
                drawWall(wall01);   
            }
            updateImage();
        }
<body onload="draw();">
    <canvas id="canvas"></canvas>
    <div><input type="number" id="fi" value="0"></div>
</body>


Ответы (0 шт):