如何从旋转/平移/缩放值计算SVG变换矩阵?

如何从旋转/平移/缩放值计算SVG变换矩阵?,svg,coordinate-transformation,Svg,Coordinate Transformation,我有以下详细资料: <g transform="translate(20, 50) scale(1, 1) rotate(-30 10 25)"> 需要将上述行更改为: <g transform="matrix(?,?,?,?,?,?)"> 有人能帮我实现这一点吗?首先使用document.getElementById获取g元素(如果它有id属性或其他适当的方法),然后调用例如 var g=document.getElementById(“”); g、 tra

我有以下详细资料:

<g transform="translate(20, 50) scale(1, 1) rotate(-30 10 25)">

需要将上述行更改为:

<g transform="matrix(?,?,?,?,?,?)">


有人能帮我实现这一点吗?

首先使用document.getElementById获取g元素(如果它有id属性或其他适当的方法),然后调用例如

var g=document.getElementById(“”);
g、 transform.baseVal.consolid();
Translate(tx,ty)可以写成矩阵:

1  0  tx
0  1  ty
0  0  1
sx  0  0
0  sy  0
0   0  1
标度(sx,sy)可以写成矩阵:

1  0  tx
0  1  ty
0  0  1
sx  0  0
0  sy  0
0   0  1
旋转(a)可以写成矩阵:

cos(a)  -sin(a)  0
sin(a)   cos(a)  0
0        0       1
旋转(a,cx,cy)是平移(-cx,cy)、度旋转和回(cx,cy)平移的组合,其给出:

cos(a)  -sin(a)  -cx × cos(a) + cy × sin(a) + cx
sin(a)   cos(a)  -cx × sin(a) - cy × cos(a) + cy
0        0       1
如果将其与平移矩阵相乘,则得到:

cos(a)  -sin(a)  -cx × cos(a) + cy × sin(a) + cx + tx
sin(a)   cos(a)  -cx × sin(a) - cy × cos(a) + cy + ty
0        0       1
对应于SVG变换矩阵:

(cos(a),sin(a),-sin(a),cos(a),-cx×cos(a)+cy×sin(a)+cx+tx,-cx×sin(a)-cy×cos(a)+cy+ty)

在您的情况下,即:
矩阵(0.866,-0.50.50.866 8.84 58.35)

如果包含比例(sx,sy)变换,则矩阵为:

(sx×cos(a),sy×sin(a),-sx×sin(a),sy×cos(a),(-cx×cos(a)+cy×sin(a)+cx)×sx+tx,(-cx×sin(a)-cy×cos(a)+cy)×sy ty)

请注意,这假设您正在按照编写转换的顺序进行转换。

可能有帮助:

  • 如何找到变换点的实际坐标

  • 已接受答案的实施:

    function multiplyMatrices(matrixA, matrixB) {
        let aNumRows = matrixA.length;
        let aNumCols = matrixA[0].length;
        let bNumRows = matrixB.length;
        let bNumCols = matrixB[0].length;
        let newMatrix = new Array(aNumRows);
    
        for (let r = 0; r < aNumRows; ++r) {
            newMatrix[r] = new Array(bNumCols);
    
            for (let c = 0; c < bNumCols; ++c) {
                newMatrix[r][c] = 0;
    
                for (let i = 0; i < aNumCols; ++i) {
                    newMatrix[r][c] += matrixA[r][i] * matrixB[i][c];
                }
            }
        }
    
        return newMatrix;
    }
    
    let translation = {
        x: 200,
        y: 50
    };
    let scaling = {
        x: 1.5,
        y: 1.5
    };
    let angleInDegrees = 25;
    let angleInRadians = angleInDegrees * (Math.PI / 180);
    let translationMatrix = [
        [1, 0, translation.x],
        [0, 1, translation.y],
        [0, 0, 1],
    ];
    let scalingMatrix = [
        [scaling.x, 0, 0],
        [0, scaling.y, 0],
        [0, 0, 1],
    ];
    let rotationMatrix = [
        [Math.cos(angleInRadians), -Math.sin(angleInRadians), 0],
        [Math.sin(angleInRadians), Math.cos(angleInRadians), 0],
        [0, 0, 1],
    ];
    let transformMatrix = multiplyMatrices(multiplyMatrices(translationMatrix, scalingMatrix), rotationMatrix);
    
    console.log(`matrix(${transformMatrix[0][0]}, ${transformMatrix[1][0]}, ${transformMatrix[0][1]}, ${transformMatrix[1][1]}, ${transformMatrix[0][2]}, ${transformMatrix[1][2]})`);
    
    函数多重矩阵(matrixA,matrixB){
    设aNumRows=矩阵长度;
    设aNumCols=matrixA[0]。长度;
    设bNumRows=matrixB.length;
    设bNumCols=matrixB[0]。长度;
    设newMatrix=newarray(aNumRows);
    for(设r=0;r

  • 我正试图通过C/iOS目标来实现这一点。有没有得到矩阵的一般方法?虽然彼得斯的答案解释了理论,以及你如何手动计算矩阵,但我认为罗伯茨的答案应该是公认的答案。您应该使用el.transform.baseVal.consolidate()。没有必要重新发明轮子。@Manfred OP无法使用它,因为他在对我的答案的评论中解释了这一点,那么他究竟为什么会接受它?老实说,我没有读他的评论,但OP在问题中没有提到目标C/iOS。我面临着与OPs问题中所述相同的问题,几乎接受了公认的答案,尽管我真正需要的是本机javascript函数consolidate()。@Manfred There's the breaks;-),提问者在写问题时往往没有明确设置他们操作的约束条件。很高兴我的回答对你有所帮助。你能详细说明a、cx、cy、tx和ty吗?在你的例子中,a=-30(度),cx=10,cy=25,tx=20,ty=50(sx=1,sy=1)。通常,旋转表示为旋转(a,cx,cy),平移表示为平移(tx,ty)。对不起,在“旋转(a,cx,cy)”中,'-cx.cos(a)中的点代表什么?来自JavaScript背景的我不明白在没有Math.cos()的情况下直接将cos/sin应用于对象意味着什么。@NickBudden我用它作为乘法的简写,但为了减少歧义,我已经切换到乘法符号。这非常有用。我已经很多年没有做矩阵计算了。所以cx和cy是偏移量,不是坐标。。。?