2d矩阵(3*3矩阵)
2026-05-02 02:29:15
265
分类:Algorithm
CSS3中的矩阵指的是一个方法,书写为matrix()和matrix3d(),前者是元素2D平面的移动变换(transform),后者则是3D变换。
2D变换矩阵为3*3;3D变换则是4*4的矩阵。
CSS3中的移动、旋转、缩放、倾斜都是基于matrix()实现的。
CSS3 2D矩阵:matrix(a,b,c,d,e,f);

矩阵转换:

矩阵与位移、缩放、旋转、倾斜:
位移:matrix(1, 0, 0, 1, 30, 30);
缩放: matrix(1, 0, 0, 1, 30, 30);
旋转:matrix(cosθ,sinθ,-sinθ,cosθ,0,0); // θ为旋转角度
倾斜:matrix(1,tan(θ),tan(θ),1,0,0); // 第一个tan(θ)为y轴,第二个x轴
下面是运用于canvas的一个Matrix3类:
/**
* 3x3矩阵操作类 对应context.transform(a,b,c,d,e,f);详细参考http://blog.vr-seesee.com/detail/173
* a c e
* b d f
* 0 0 1
* a水平缩放 c垂直倾斜 e水平移动
* b水平倾斜 d垂直缩放 f垂直移动
*
* 注意:如果同缩放、旋转和位移,需要先缩放再旋转再位移
*/
class Matrix3 {
constructor() {
this.isMatrix3 = true;
this.elements = [
1, 0, 0,
0, 1, 0,
0, 0, 1
]
}
// 重置
identity() {
this.set(
1, 0, 0,
0, 1, 0,
0, 0, 1
);
return this;
}
clone() {
return new this.constructor(this.elements)
}
set(n11, n12, n13, n21, n22, n23, n31, n32, n33) {
var te = this.elements;
te[0] = n11; te[1] = n21; te[2] = n31;
te[3] = n12; te[4] = n22; te[5] = n32;
te[6] = n13; te[7] = n23; te[8] = n33;
return this;
}
/**
* 两矩阵相乘
* @param a 矩阵a
* @param b 矩阵b
* @returns {Matrix3}
*/
multiplyMatrices(a, b) {
var ae = a.elements;
var be = b.elements;
var te = this.elements;
var a11 = ae[0], a12 = ae[3], a13 = ae[6];
var a21 = ae[1], a22 = ae[4], a23 = ae[7];
var a31 = ae[2], a32 = ae[5], a33 = ae[8];
var b11 = be[0], b12 = be[3], b13 = be[6];
var b21 = be[1], b22 = be[4], b23 = be[7];
var b31 = be[2], b32 = be[5], b33 = be[8];
te[0] = a11 * b11 + a12 * b21 + a13 * b31;
te[3] = a11 * b12 + a12 * b22 + a13 * b32;
te[6] = a11 * b13 + a12 * b23 + a13 * b33;
te[1] = a21 * b11 + a22 * b21 + a23 * b31;
te[4] = a21 * b12 + a22 * b22 + a23 * b32;
te[7] = a21 * b13 + a22 * b23 + a23 * b33;
te[2] = a31 * b11 + a32 * b21 + a33 * b31;
te[5] = a31 * b12 + a32 * b22 + a33 * b32;
te[8] = a31 * b13 + a32 * b23 + a33 * b33;
return this;
}
/**
* 矩阵左乘向量
* @param s 矩阵
* @returns {Matrix3}
*/
multiplyScalar(s) {
var te = this.elements;
te[0] *= s; te[3] *= s; te[6] *= s;
te[1] *= s; te[4] *= s; te[7] *= s;
te[2] *= s; te[5] *= s; te[8] *= s;
return this;
}
/**
* 缩放
* @param sx 水平缩放
* @param sy 垂直缩放
* @returns {Matrix3}
*/
scale(sx, sy) {
var te = this.elements;
te[0] *= sx; te[3] *= sx; te[6] *= sx;
te[1] *= sy; te[4] *= sy; te[7] *= sy;
return this;
}
/**
* 旋转
* @param theta 旋转弧度
* @returns {Matrix3}
*/
rotate(theta) {
var c = Math.cos(theta);
var s = Math.sin(theta);
var te = this.elements;
var a11 = te[0], a12 = te[3], a13 = te[6];
var a21 = te[1], a22 = te[4], a23 = te[7];
te[0] = c * a11 + s * a21;
te[3] = c * a12 + s * a22;
te[6] = c * a13 + s * a23;
te[1] = -s * a11 + c * a21;
te[4] = -s * a12 + c * a22;
te[7] = -s * a13 + c * a23;
return this;
}
/**
* 移动
* @param tx 水平移动
* @param ty 垂直移动
* @returns {Matrix3}
*/
translate(tx, ty) {
var te = this.elements;
te[0] += tx * te[2]; te[3] += tx * te[5]; te[6] += tx * te[8];
te[1] += ty * te[2]; te[4] += ty * te[5]; te[7] += ty * te[8];
return this;
}
equals(matrix) {
var te = this.elements;
var me = matrix.elements;
for (var i = 0; i < 9; i++) {
if (te[i] !== me[i]) return false;
}
return true;
}
}具体例子:Canvas矩阵实现缩放、旋转、位移
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Canvas矩阵实现缩放、旋转、位移</title>
<script src="../xcanvas/src/math/Math.js"></script>
<script src="../xcanvas/src/math/Matrix3.js"></script>
</head>
<body>
<canvas id="myCanvas" width="600" height="600" style="border:1px solid #d3d3d3;">
您的浏览器不支持 HTML5 canvas 标签。
</canvas>
<script>
let m1 = new Matrix3();
let ele = m1.elements;
m1.scale(2, 2);
m1.rotate(30 * _Math.DEG2RAD);
m1.translate(300, 300);
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
ctx.transform(ele[0], ele[1], ele[3], ele[4], ele[6], ele[7]);
ctx.fillStyle = "red";
ctx.fillRect(0, 0, 200, 100);
</script>
</body>
</html>