Release package version 0.0.5
All checks were successful
CI / build (push) Successful in 28s

Update matrix 2d
This commit is contained in:
Andrey Kernichniy 2026-03-21 23:33:19 +07:00
parent 8c0e798bc7
commit b38fb6e7eb
4 changed files with 76 additions and 51 deletions

2
.gitignore vendored
View file

@ -30,4 +30,4 @@ yarn-error.log
.DS_Store
Thumbs.db
playground/gxc-canvas-viewer/**/*.*
playground/*/**/*.*

View file

@ -1,78 +1,103 @@
import { IPoint } from "../interfaces";
import { Point } from "./point";
export type Matrix = [[number, number, number], [number, number, number], [number, number, number]];
export type Matrix = [number, number, number, number, number, number, number, number, number];
const DEF_MATRIX: Matrix = [
[1, 0, 0],
[0, 1, 0],
[0, 0, 1],
];
const DEF_MATRIX: Matrix = [1, 0, 0, 0, 1, 0, 0, 0, 1];
export class Matrix2D {
private _matrix: Matrix;
get m00() {
return this._matrix[0];
}
get m01() {
return this._matrix[1];
}
get m02() {
return this._matrix[2];
}
get m10() {
return this._matrix[3];
}
get m11() {
return this._matrix[4];
}
get m12() {
return this._matrix[5];
}
get m20() {
return this._matrix[6];
}
get m21() {
return this._matrix[7];
}
get m22() {
return this._matrix[8];
}
constructor(matrix?: Matrix) {
this._matrix = matrix ?? DEF_MATRIX;
}
clone(): Matrix2D {
return new Matrix2D(this.getData());
return new Matrix2D([...this.getData()]);
}
multiply(matrix: Matrix2D): Matrix2D {
const m = structuredClone(DEF_MATRIX);
for (let i = 0; i < 3; i++) {
for (let j = 0; j < 3; j++) {
m[i][j] = 0;
for (let k = 0; k < 3; k++) {
m[i][j] += this._matrix[i][k] * matrix._matrix[k][j];
}
}
}
const a = this._matrix;
const b = matrix.getData();
const m = DEF_MATRIX.slice() as Matrix;
m[0] = a[0] * b[0] + a[1] * b[3] + a[2] * b[6];
m[1] = a[0] * b[1] + a[1] * b[4] + a[2] * b[7];
m[2] = a[0] * b[2] + a[1] * b[5] + a[2] * b[8];
m[3] = a[3] * b[0] + a[4] * b[3] + a[5] * b[6];
m[4] = a[3] * b[1] + a[4] * b[4] + a[5] * b[7];
m[5] = a[3] * b[2] + a[4] * b[5] + a[5] * b[8];
m[6] = a[6] * b[0] + a[7] * b[3] + a[8] * b[6];
m[7] = a[6] * b[1] + a[7] * b[4] + a[8] * b[7];
m[8] = a[6] * b[2] + a[7] * b[5] + a[8] * b[8];
return new Matrix2D(m);
}
translate(x: number, y: number): Matrix2D {
const translationMatrix = new Matrix2D([
[1, 0, x],
[0, 1, y],
[0, 0, 1],
]);
const translationMatrix = new Matrix2D([1, 0, x, 0, 1, y, 0, 0, 1]);
return this.multiply(translationMatrix);
}
rotate(angle: number): Matrix2D {
const cos = Math.cos(angle);
const sin = Math.sin(angle);
const rotationMatrix = new Matrix2D([
[cos, -sin, 0],
[sin, cos, 0],
[0, 0, 1],
]);
const rotationMatrix = new Matrix2D([cos, -sin, 0, sin, cos, 0, 0, 0, 1]);
return this.multiply(rotationMatrix);
}
scale(sx: number, sy: number): Matrix2D {
const scaleMatrix = new Matrix2D([
[sx, 0, 0],
[0, sy, 0],
[0, 0, 1],
]);
const scaleMatrix = new Matrix2D([sx, 0, 0, 0, sy, 0, 0, 0, 1]);
return this.multiply(scaleMatrix);
}
transformPoint(point: IPoint): Point {
const x = point.x;
const y = point.y;
const w = this._matrix[2][0] * x + this._matrix[2][1] * y + this._matrix[2][2];
return new Point(
(this._matrix[0][0] * x + this._matrix[0][1] * y + this._matrix[0][2]) / w,
(this._matrix[1][0] * x + this._matrix[1][1] * y + this._matrix[1][2]) / w,
);
const w = this.m20 * x + this.m21 * y + this.m22;
return new Point((this.m00 * x + this.m01 * y + this.m02) / w, (this.m10 * x + this.m11 * y + this.m12) / w);
}
getData(): Matrix {
return structuredClone(this._matrix);
return this._matrix;
}
}

View file

@ -31,20 +31,20 @@ export class Transform {
}
static fromMatrix2D(matrix: Matrix2D): Transform {
const m = matrix.getData();
const transform = new Transform();
const scaleX = Math.sqrt(matrix.m00 * matrix.m00 + matrix.m01 * matrix.m01);
const scaleY = Math.sqrt(matrix.m10 * matrix.m10 + matrix.m11 * matrix.m11);
// Извлечение масштаба
transform.scaleX = Math.sqrt(m[0][0] * m[0][0] + m[0][1] * m[0][1]);
transform.scaleY = Math.sqrt(m[1][0] * m[1][0] + m[1][1] * m[1][1]);
const rotate = radToDeg(Math.atan2(matrix.m01, matrix.m00));
// Извлечение поворота
transform.rotate = radToDeg(Math.atan2(m[0][1], m[0][0]));
const translateX = matrix.m02;
const translateY = matrix.m12;
// Извлечение сдвига
transform.translateX = m[0][2];
transform.translateY = m[1][2];
return transform;
return new Transform({
scaleX,
scaleY,
rotate,
translateX,
translateY,
});
}
}

View file

@ -1,6 +1,6 @@
{
"name": "@gxc-solutions/math",
"version": "0.0.4",
"version": "0.0.5",
"main": "index.js",
"author": "GXC Solutions",
"publishConfig": {