generated from gxc-solutions/gxc-template-repo
Update matrix 2d
This commit is contained in:
parent
8c0e798bc7
commit
b38fb6e7eb
4 changed files with 76 additions and 51 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
|
@ -30,4 +30,4 @@ yarn-error.log
|
||||||
.DS_Store
|
.DS_Store
|
||||||
Thumbs.db
|
Thumbs.db
|
||||||
|
|
||||||
playground/gxc-canvas-viewer/**/*.*
|
playground/*/**/*.*
|
||||||
|
|
@ -1,78 +1,103 @@
|
||||||
import { IPoint } from "../interfaces";
|
import { IPoint } from "../interfaces";
|
||||||
import { Point } from "./point";
|
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 = [
|
const DEF_MATRIX: Matrix = [1, 0, 0, 0, 1, 0, 0, 0, 1];
|
||||||
[1, 0, 0],
|
|
||||||
[0, 1, 0],
|
|
||||||
[0, 0, 1],
|
|
||||||
];
|
|
||||||
|
|
||||||
export class Matrix2D {
|
export class Matrix2D {
|
||||||
private _matrix: Matrix;
|
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) {
|
constructor(matrix?: Matrix) {
|
||||||
this._matrix = matrix ?? DEF_MATRIX;
|
this._matrix = matrix ?? DEF_MATRIX;
|
||||||
}
|
}
|
||||||
|
|
||||||
clone(): Matrix2D {
|
clone(): Matrix2D {
|
||||||
return new Matrix2D(this.getData());
|
return new Matrix2D([...this.getData()]);
|
||||||
}
|
}
|
||||||
|
|
||||||
multiply(matrix: Matrix2D): Matrix2D {
|
multiply(matrix: Matrix2D): Matrix2D {
|
||||||
const m = structuredClone(DEF_MATRIX);
|
const a = this._matrix;
|
||||||
for (let i = 0; i < 3; i++) {
|
const b = matrix.getData();
|
||||||
for (let j = 0; j < 3; j++) {
|
|
||||||
m[i][j] = 0;
|
const m = DEF_MATRIX.slice() as Matrix;
|
||||||
for (let k = 0; k < 3; k++) {
|
|
||||||
m[i][j] += this._matrix[i][k] * matrix._matrix[k][j];
|
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);
|
return new Matrix2D(m);
|
||||||
}
|
}
|
||||||
|
|
||||||
translate(x: number, y: number): Matrix2D {
|
translate(x: number, y: number): Matrix2D {
|
||||||
const translationMatrix = new Matrix2D([
|
const translationMatrix = new Matrix2D([1, 0, x, 0, 1, y, 0, 0, 1]);
|
||||||
[1, 0, x],
|
|
||||||
[0, 1, y],
|
|
||||||
[0, 0, 1],
|
|
||||||
]);
|
|
||||||
return this.multiply(translationMatrix);
|
return this.multiply(translationMatrix);
|
||||||
}
|
}
|
||||||
|
|
||||||
rotate(angle: number): Matrix2D {
|
rotate(angle: number): Matrix2D {
|
||||||
const cos = Math.cos(angle);
|
const cos = Math.cos(angle);
|
||||||
const sin = Math.sin(angle);
|
const sin = Math.sin(angle);
|
||||||
const rotationMatrix = new Matrix2D([
|
const rotationMatrix = new Matrix2D([cos, -sin, 0, sin, cos, 0, 0, 0, 1]);
|
||||||
[cos, -sin, 0],
|
|
||||||
[sin, cos, 0],
|
|
||||||
[0, 0, 1],
|
|
||||||
]);
|
|
||||||
return this.multiply(rotationMatrix);
|
return this.multiply(rotationMatrix);
|
||||||
}
|
}
|
||||||
|
|
||||||
scale(sx: number, sy: number): Matrix2D {
|
scale(sx: number, sy: number): Matrix2D {
|
||||||
const scaleMatrix = new Matrix2D([
|
const scaleMatrix = new Matrix2D([sx, 0, 0, 0, sy, 0, 0, 0, 1]);
|
||||||
[sx, 0, 0],
|
|
||||||
[0, sy, 0],
|
|
||||||
[0, 0, 1],
|
|
||||||
]);
|
|
||||||
return this.multiply(scaleMatrix);
|
return this.multiply(scaleMatrix);
|
||||||
}
|
}
|
||||||
|
|
||||||
transformPoint(point: IPoint): Point {
|
transformPoint(point: IPoint): Point {
|
||||||
const x = point.x;
|
const x = point.x;
|
||||||
const y = point.y;
|
const y = point.y;
|
||||||
const w = this._matrix[2][0] * x + this._matrix[2][1] * y + this._matrix[2][2];
|
const w = this.m20 * x + this.m21 * y + this.m22;
|
||||||
return new Point(
|
return new Point((this.m00 * x + this.m01 * y + this.m02) / w, (this.m10 * x + this.m11 * y + this.m12) / w);
|
||||||
(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,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
getData(): Matrix {
|
getData(): Matrix {
|
||||||
return structuredClone(this._matrix);
|
return this._matrix;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -31,20 +31,20 @@ export class Transform {
|
||||||
}
|
}
|
||||||
|
|
||||||
static fromMatrix2D(matrix: Matrix2D): Transform {
|
static fromMatrix2D(matrix: Matrix2D): Transform {
|
||||||
const m = matrix.getData();
|
const scaleX = Math.sqrt(matrix.m00 * matrix.m00 + matrix.m01 * matrix.m01);
|
||||||
const transform = new Transform();
|
const scaleY = Math.sqrt(matrix.m10 * matrix.m10 + matrix.m11 * matrix.m11);
|
||||||
|
|
||||||
// Извлечение масштаба
|
const rotate = radToDeg(Math.atan2(matrix.m01, matrix.m00));
|
||||||
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 translateX = matrix.m02;
|
||||||
transform.rotate = radToDeg(Math.atan2(m[0][1], m[0][0]));
|
const translateY = matrix.m12;
|
||||||
|
|
||||||
// Извлечение сдвига
|
return new Transform({
|
||||||
transform.translateX = m[0][2];
|
scaleX,
|
||||||
transform.translateY = m[1][2];
|
scaleY,
|
||||||
|
rotate,
|
||||||
return transform;
|
translateX,
|
||||||
|
translateY,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "@gxc-solutions/math",
|
"name": "@gxc-solutions/math",
|
||||||
"version": "0.0.4",
|
"version": "0.0.5",
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"author": "GXC Solutions",
|
"author": "GXC Solutions",
|
||||||
"publishConfig": {
|
"publishConfig": {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue