generated from gxc-solutions/gxc-template-repo
Added Matrix2d class, update Transform class
This commit is contained in:
parent
e5f5f3a08e
commit
4dbba31ed5
7 changed files with 159 additions and 1 deletions
|
|
@ -1 +1,15 @@
|
|||
import { Rectangle, Transform } from "../models";
|
||||
|
||||
export const degToRad = (deg: number) => (deg * Math.PI) / 180;
|
||||
export const radToDeg = (radians: number) => radians * (180 / Math.PI);
|
||||
|
||||
export const getBounds = (rectangle: Rectangle, transform: Transform) => {
|
||||
const { top, left, bottom, right } = rectangle;
|
||||
|
||||
const matrix2d = transform.toMatrix2D();
|
||||
|
||||
const topLeft = matrix2d.transformPoint({ x: left, y: top });
|
||||
const bottomRight = matrix2d.transformPoint({ x: right, y: bottom });
|
||||
|
||||
return Rectangle.fromPoints(topLeft.x, topLeft.y, bottomRight.x, bottomRight.y);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -7,3 +7,16 @@ export interface IPoint {
|
|||
x: number;
|
||||
y: number;
|
||||
}
|
||||
|
||||
export interface ITransform {
|
||||
scaleX: number;
|
||||
scaleY: number;
|
||||
|
||||
translateY: number;
|
||||
translateX: number;
|
||||
|
||||
skewY: number;
|
||||
skewX: number;
|
||||
|
||||
rotate: number;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
import { IPoint } from "../interfaces";
|
||||
import { Point } from "./point";
|
||||
import { Rectangle } from "./rectangle";
|
||||
|
||||
export class Ellipse {
|
||||
center = new Point();
|
||||
|
|
@ -19,4 +20,17 @@ export class Ellipse {
|
|||
this.radiusX = radiusX;
|
||||
this.radiusY = radiusY;
|
||||
}
|
||||
|
||||
static fromRectangle(rectangle: Rectangle) {
|
||||
return new Ellipse(rectangle.center, rectangle.width / 2, rectangle.height / 2);
|
||||
}
|
||||
|
||||
toRectangle() {
|
||||
return Rectangle.fromPoints(
|
||||
this.center.x - this.radiusX,
|
||||
this.center.y - this.radiusY,
|
||||
this.center.x + this.radiusX,
|
||||
this.center.y + this.radiusY,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,3 +4,4 @@ export * from "./size";
|
|||
export * from "./ellipse";
|
||||
export * from "./rectangle";
|
||||
export * from "./transform";
|
||||
export * from "./matrix-2d";
|
||||
|
|
|
|||
78
lib/src/models/matrix-2d.ts
Normal file
78
lib/src/models/matrix-2d.ts
Normal file
|
|
@ -0,0 +1,78 @@
|
|||
import { IPoint } from "../interfaces";
|
||||
import { Point } from "./point";
|
||||
|
||||
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],
|
||||
];
|
||||
|
||||
export class Matrix2D {
|
||||
private _matrix: Matrix;
|
||||
|
||||
constructor(matrix?: Matrix) {
|
||||
this._matrix = matrix ?? DEF_MATRIX;
|
||||
}
|
||||
|
||||
clone(): Matrix2D {
|
||||
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];
|
||||
}
|
||||
}
|
||||
}
|
||||
return new Matrix2D(m);
|
||||
}
|
||||
|
||||
translate(x: number, y: number): Matrix2D {
|
||||
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],
|
||||
]);
|
||||
return this.multiply(rotationMatrix);
|
||||
}
|
||||
|
||||
scale(sx: number, sy: number): Matrix2D {
|
||||
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,
|
||||
);
|
||||
}
|
||||
|
||||
getData(): Matrix {
|
||||
return structuredClone(this._matrix);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,3 +1,7 @@
|
|||
import { degToRad, radToDeg } from "../functions";
|
||||
import { ITransform } from "../interfaces";
|
||||
import { Matrix2D } from "./matrix-2d";
|
||||
|
||||
export class Transform {
|
||||
scaleX = 1;
|
||||
scaleY = 1;
|
||||
|
|
@ -9,4 +13,38 @@ export class Transform {
|
|||
skewX = 0;
|
||||
|
||||
rotate = 0;
|
||||
|
||||
constructor(transform?: Partial<ITransform>) {
|
||||
this.scaleX = transform?.scaleX ?? 1;
|
||||
this.scaleY = transform?.scaleY ?? 1;
|
||||
this.translateX = transform?.translateX ?? 0;
|
||||
this.translateY = transform?.translateY ?? 0;
|
||||
this.skewY = transform?.scaleY ?? 0;
|
||||
this.skewX = transform?.scaleX ?? 0;
|
||||
this.rotate = transform?.rotate ?? 0;
|
||||
}
|
||||
|
||||
toMatrix2D(): Matrix2D {
|
||||
const matrix = new Matrix2D();
|
||||
matrix.translate(this.translateX, this.translateY).rotate(degToRad(this.rotate)).scale(this.scaleX, this.scaleY);
|
||||
return matrix;
|
||||
}
|
||||
|
||||
static fromMatrix2D(matrix: Matrix2D): Transform {
|
||||
const m = matrix.getData();
|
||||
const transform = new Transform();
|
||||
|
||||
// Извлечение масштаба
|
||||
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]);
|
||||
|
||||
// Извлечение поворота
|
||||
transform.rotate = radToDeg(Math.atan2(m[0][1], m[0][0]));
|
||||
|
||||
// Извлечение сдвига
|
||||
transform.translateX = m[0][2];
|
||||
transform.translateY = m[1][2];
|
||||
|
||||
return transform;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@gxc-solutions/math",
|
||||
"version": "0.0.2",
|
||||
"version": "0.0.3",
|
||||
"main": "index.js",
|
||||
"author": "GXC Solutions",
|
||||
"publishConfig": {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue