Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/437.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 二维变换,旋转不符合预期_Javascript_Html_Linear Algebra - Fatal编程技术网

Javascript 二维变换,旋转不符合预期

Javascript 二维变换,旋转不符合预期,javascript,html,linear-algebra,Javascript,Html,Linear Algebra,我试图用javascript在2d空间实现一组基本的欧几里德变换,我的旋转似乎有问题 // simple 2d html5 interface "use strict"; class Point{ constructor(x,y){ this.x = x; this.y = y; } mul(c){ this.x *= c; this.y *= c; } } class TransMatr

我试图用javascript在2d空间实现一组基本的欧几里德变换,我的旋转似乎有问题

    // simple 2d html5 interface
"use strict";

class Point{
    constructor(x,y){
        this.x = x;
        this.y = y;
    }
    mul(c){
        this.x *= c;
        this.y *= c;
    }
}

class TransMatrix{
    /*    see https://pages.mtu.edu/~shene/COURSES/cs3621/NOTES/geometry/geo-tran.html
     *    for more info.
     *    c1 c2 c3
     *    c4 c5 c6
     *    c7 c8 c9 
     */
    constructor(){
        this.c1 = 1;
        this.c2 = 0;
        this.c3 = 0;

        this.c4 = 0;
        this.c5 = 1;
        this.c6 = 0;

        this.c7 = 0;
        this.c8 = 0;
        this.c9 = 1;
    }

    applyMatrix(point){
        point.x = this.c1*point.x + this.c2*point.y + this.c3;
        point.y = this.c4*point.x + this.c5*point.y + this.c6;
    }

    copy(){
        var matrix = new TransMatrix();
        matrix.c1 = this.c1;
        matrix.c2 = this.c2;
        matrix.c3 = this.c3;

        matrix.c4 = this.c4;
        matrix.c5 = this.c5;
        matrix.c6 = this.c6;

        matrix.c7 = this.c7;
        matrix.c8 = this.c8;
        matrix.c9 = this.c9;
        return matrix;
    }

    translation(x,y){
        var newMatrix = this.copy();

        newMatrix.c3 += x;
        newMatrix.c6 += y;

        return newMatrix;
    }
    scale(s){
        var newMatrix = this.copy();

        newMatrix.c1 += s;
        newMatrix.c5 += s;

        return newMatrix;
    }
    rotation(r){ //radians
        var newMatrix = this.copy();

        newMatrix.c1 += Math.cos(r);
        newMatrix.c2 += -Math.sin(r);
        newMatrix.c4 += Math.sin(r);
        newMatrix.c5 += Math.cos(r);

        return newMatrix;
    }
}

function drawHexagon(canvas, matrix, strokeColor, fillColor) {
    if (!canvas) {
        return;
    }

    var points = [new Point(0.5 ,  1),
                  new Point(1   ,  0),
                  new Point(0.5 , -1),
                  new Point(-0.5, -1),
                  new Point(-1  ,  0),
                  new Point(-0.5,  1)
    ];

    points.forEach(point => {
        matrix.applyMatrix(point);
    });

    drawHexagonLit(canvas,points[0],points[1],points[2],points[3],points[4],points[5], "red", "green");
}

function drawHexagonLit(canvas, p1, p2, p3 ,p4 ,p5, p6, strokeColor, fillColor){ // add border cases here
    if(!canvas){
        return;
    }
    var ctx = canvas.getContext("2d");
    if(!ctx){
        return;
    }
    ctx.beginPath();
    ctx.moveTo(p1.x, p1.y);
    ctx.lineTo(p2.x, p2.y);
    ctx.lineTo(p3.x, p3.y);
    ctx.lineTo(p4.x, p4.y);
    ctx.lineTo(p5.x, p5.y);
    ctx.lineTo(p6.x, p6.y);
    ctx.lineTo(p1.x, p1.y);
    ctx.strokeStyle = strokeColor;
    ctx.fillColor = fillColor;
    ctx.stroke();
    ctx.fill();
    ctx.closePath();
}


function dynamicBackgroundInit(canvas){
    if(!canvas){
        return;
    }
    var worldMatrix = new TransMatrix();

    var rotate = 0;

    function step(){
        canvas.getContext("2d").clearRect(0, 0, canvas.width, canvas.height);
        rotate += 0.01;
        var transform = worldMatrix.rotation(rotate); // this is better reflected by a matrix inside an object
        transform = transform.translation(50,50);
        transform = transform.scale(30,30);
        drawHexagon(canvas, transform, "red", "green");
        window.requestAnimationFrame(step);
    }

    window.requestAnimationFrame(step);
}

呼叫和翻译按预期进行,但轮换似乎效果不佳。最初我以为我只是在一个外部原点上旋转,但我不再这么认为,因为当初始对象只是简单地放大时,问题仍然存在。

您的转换代码会产生瑕疵,因为您在转换之前和之后都使用点坐标,因此,在第二行中,使用转换后的坐标,而不是原始坐标:

applyMatrix(point){
        point.x = this.c1*point.x + this.c2*point.y + this.c3;
        point.y = this.c4*point.x + this.c5*point.y + this.c6; // transformed point.x is used instead of the original point.x
}

相反,请执行以下操作:

applyMatrix(point){
        var x = point.x, y = point.y;
        point.x = this.c1*x + this.c2*y + this.c3;
        point.y = this.c4*x + this.c5*y + this.c6;
    }

在您尝试同时应用的任何其他变换中,对原始坐标使用类似的缓存。首先将它们存储在临时变量中,然后使用原始坐标和新坐标作为不同的变量进行应用

我应用了修复,它似乎有效,但旋转虽然居中,但似乎仍被限制在一个非常窄的角度范围内。主要是因为我不能只复制矩阵,我必须正确地将它们相乘。