bpmatrixjs 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/Geometry/Rect.d.ts +32 -0
- package/lib/Geometry/Rect.js +134 -0
- package/lib/Geometry/index.d.ts +1 -0
- package/lib/Geometry/index.js +1 -0
- package/lib/Math/Mat3.d.ts +130 -0
- package/lib/Math/Mat3.js +294 -0
- package/lib/Math/Vec2.d.ts +171 -0
- package/lib/Math/Vec2.js +251 -0
- package/lib/Math/index.d.ts +2 -0
- package/lib/Math/index.js +2 -0
- package/lib/Utils/index.d.ts +9 -0
- package/lib/Utils/index.js +11 -0
- package/lib/index.d.ts +10 -0
- package/lib/index.js +10 -0
- package/package.json +57 -0
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
interface RectGeometryData {
|
|
2
|
+
geometry: Float32Array;
|
|
3
|
+
uv: Float32Array;
|
|
4
|
+
width: number;
|
|
5
|
+
height: number;
|
|
6
|
+
radius: number;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* 数值钳制
|
|
10
|
+
* @param value 当前值
|
|
11
|
+
* @param min 最小值
|
|
12
|
+
* @param max 最大值
|
|
13
|
+
* @returns 钳制结果
|
|
14
|
+
*/
|
|
15
|
+
/**
|
|
16
|
+
* 生成矩形几何
|
|
17
|
+
* 以(0, 0)为中心
|
|
18
|
+
* 圆角半径会自动限制到半宽半高的较小值
|
|
19
|
+
* @param width 宽度
|
|
20
|
+
* @param height 高度
|
|
21
|
+
* @param radius 圆角半径
|
|
22
|
+
* @returns 几何数据
|
|
23
|
+
*/
|
|
24
|
+
declare const CreateRectGeometry: (width: number, height: number, radius?: number) => RectGeometryData;
|
|
25
|
+
/**
|
|
26
|
+
* 矩形几何工具
|
|
27
|
+
*/
|
|
28
|
+
declare const Rect: {
|
|
29
|
+
CreateGeometry: (width: number, height: number, radius?: number) => RectGeometryData;
|
|
30
|
+
};
|
|
31
|
+
export { CreateRectGeometry, Rect };
|
|
32
|
+
export type { RectGeometryData };
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
import { Clamp } from "../Utils/index.js";
|
|
2
|
+
/**
|
|
3
|
+
* 生成矩形边界点
|
|
4
|
+
* @param halfWidth 半宽
|
|
5
|
+
* @param halfHeight 半高
|
|
6
|
+
* @param radius 圆角半径
|
|
7
|
+
* @returns 边界点列表
|
|
8
|
+
*/
|
|
9
|
+
const CreatePerimeterPoints = (halfWidth, halfHeight, radius) => {
|
|
10
|
+
if (halfWidth === 0 || halfHeight === 0) {
|
|
11
|
+
return [];
|
|
12
|
+
}
|
|
13
|
+
if (radius === 0) {
|
|
14
|
+
return [
|
|
15
|
+
[halfWidth, halfHeight],
|
|
16
|
+
[halfWidth, -halfHeight],
|
|
17
|
+
[-halfWidth, -halfHeight],
|
|
18
|
+
[-halfWidth, halfHeight],
|
|
19
|
+
];
|
|
20
|
+
}
|
|
21
|
+
const segments = GetCornerSegments(radius);
|
|
22
|
+
const points = [];
|
|
23
|
+
PushArc(points, halfWidth - radius, halfHeight - radius, radius, Math.PI * 0.5, 0, segments, true);
|
|
24
|
+
PushArc(points, halfWidth - radius, -halfHeight + radius, radius, 0, -Math.PI * 0.5, segments, false);
|
|
25
|
+
PushArc(points, -halfWidth + radius, -halfHeight + radius, radius, -Math.PI * 0.5, -Math.PI, segments, false);
|
|
26
|
+
PushArc(points, -halfWidth + radius, halfHeight - radius, radius, Math.PI, Math.PI * 0.5, segments, false);
|
|
27
|
+
return points;
|
|
28
|
+
};
|
|
29
|
+
/**
|
|
30
|
+
* 添加圆角圆弧点
|
|
31
|
+
* @param points 点数组
|
|
32
|
+
* @param centerX 圆心X
|
|
33
|
+
* @param centerY 圆心Y
|
|
34
|
+
* @param radius 圆角半径
|
|
35
|
+
* @param startAngle 起始弧度
|
|
36
|
+
* @param endAngle 结束弧度
|
|
37
|
+
* @param segments 分段数
|
|
38
|
+
* @param includeStart 是否包含起始点
|
|
39
|
+
* @returns 无返回值
|
|
40
|
+
*/
|
|
41
|
+
const PushArc = (points, centerX, centerY, radius, startAngle, endAngle, segments, includeStart) => {
|
|
42
|
+
const startIndex = includeStart ? 0 : 1;
|
|
43
|
+
for (let index = startIndex; index <= segments; index += 1) {
|
|
44
|
+
const t = index / segments;
|
|
45
|
+
const angle = startAngle + (endAngle - startAngle) * t;
|
|
46
|
+
const x = centerX + Math.cos(angle) * radius;
|
|
47
|
+
const y = centerY + Math.sin(angle) * radius;
|
|
48
|
+
points.push([x, y]);
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
/**
|
|
52
|
+
* 生成位置缓冲
|
|
53
|
+
* @param points 边界点列表
|
|
54
|
+
* @returns 位置缓冲
|
|
55
|
+
*/
|
|
56
|
+
const CreateGeometryBuffer = (points) => {
|
|
57
|
+
if (points.length < 3) {
|
|
58
|
+
return new Float32Array(0);
|
|
59
|
+
}
|
|
60
|
+
const geometry = [];
|
|
61
|
+
for (let index = 0; index < points.length; index += 1) {
|
|
62
|
+
const current = points[index];
|
|
63
|
+
const next = points[(index + 1) % points.length];
|
|
64
|
+
geometry.push(0, 0, current[0], current[1], next[0], next[1]);
|
|
65
|
+
}
|
|
66
|
+
return new Float32Array(geometry);
|
|
67
|
+
};
|
|
68
|
+
/**
|
|
69
|
+
* 生成UV缓冲
|
|
70
|
+
* @param points 边界点列表
|
|
71
|
+
* @param width 宽度
|
|
72
|
+
* @param height 高度
|
|
73
|
+
* @returns UV缓冲
|
|
74
|
+
*/
|
|
75
|
+
const CreateUvBuffer = (points, width, height) => {
|
|
76
|
+
if (points.length < 3 || width === 0 || height === 0) {
|
|
77
|
+
return new Float32Array(0);
|
|
78
|
+
}
|
|
79
|
+
const uv = [];
|
|
80
|
+
const halfWidth = width * 0.5;
|
|
81
|
+
const halfHeight = height * 0.5;
|
|
82
|
+
for (let index = 0; index < points.length; index += 1) {
|
|
83
|
+
const current = points[index];
|
|
84
|
+
const next = points[(index + 1) % points.length];
|
|
85
|
+
uv.push(0.5, 0.5, (current[0] + halfWidth) / width, (current[1] + halfHeight) / height, (next[0] + halfWidth) / width, (next[1] + halfHeight) / height);
|
|
86
|
+
}
|
|
87
|
+
return new Float32Array(uv);
|
|
88
|
+
};
|
|
89
|
+
/**
|
|
90
|
+
* 计算圆角分段数
|
|
91
|
+
* @param radius 圆角半径
|
|
92
|
+
* @returns 分段数
|
|
93
|
+
*/
|
|
94
|
+
const GetCornerSegments = (radius) => {
|
|
95
|
+
return Math.max(2, Math.ceil(radius / 8));
|
|
96
|
+
};
|
|
97
|
+
/**
|
|
98
|
+
* 数值钳制
|
|
99
|
+
* @param value 当前值
|
|
100
|
+
* @param min 最小值
|
|
101
|
+
* @param max 最大值
|
|
102
|
+
* @returns 钳制结果
|
|
103
|
+
*/
|
|
104
|
+
/**
|
|
105
|
+
* 生成矩形几何
|
|
106
|
+
* 以(0, 0)为中心
|
|
107
|
+
* 圆角半径会自动限制到半宽半高的较小值
|
|
108
|
+
* @param width 宽度
|
|
109
|
+
* @param height 高度
|
|
110
|
+
* @param radius 圆角半径
|
|
111
|
+
* @returns 几何数据
|
|
112
|
+
*/
|
|
113
|
+
const CreateRectGeometry = (width, height, radius = 0) => {
|
|
114
|
+
const safeWidth = Math.max(0, width);
|
|
115
|
+
const safeHeight = Math.max(0, height);
|
|
116
|
+
const halfWidth = safeWidth * 0.5;
|
|
117
|
+
const halfHeight = safeHeight * 0.5;
|
|
118
|
+
const safeRadius = Clamp(radius, 0, Math.min(halfWidth, halfHeight));
|
|
119
|
+
const points = CreatePerimeterPoints(halfWidth, halfHeight, safeRadius);
|
|
120
|
+
return {
|
|
121
|
+
geometry: CreateGeometryBuffer(points),
|
|
122
|
+
uv: CreateUvBuffer(points, safeWidth, safeHeight),
|
|
123
|
+
width: safeWidth,
|
|
124
|
+
height: safeHeight,
|
|
125
|
+
radius: safeRadius,
|
|
126
|
+
};
|
|
127
|
+
};
|
|
128
|
+
/**
|
|
129
|
+
* 矩形几何工具
|
|
130
|
+
*/
|
|
131
|
+
const Rect = {
|
|
132
|
+
CreateGeometry: CreateRectGeometry,
|
|
133
|
+
};
|
|
134
|
+
export { CreateRectGeometry, Rect };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { CreateRectGeometry, Rect, type RectGeometryData } from "./Rect.js";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { CreateRectGeometry, Rect } from "./Rect.js";
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
import { type Vec2Like } from "./Vec2.js";
|
|
2
|
+
type Mat3Data = [
|
|
3
|
+
number,
|
|
4
|
+
number,
|
|
5
|
+
number,
|
|
6
|
+
number,
|
|
7
|
+
number,
|
|
8
|
+
number,
|
|
9
|
+
number,
|
|
10
|
+
number,
|
|
11
|
+
number
|
|
12
|
+
];
|
|
13
|
+
interface Mat3Like {
|
|
14
|
+
data: Mat3Data;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* 3x3矩阵
|
|
18
|
+
* @class
|
|
19
|
+
* @implements Mat3Like
|
|
20
|
+
* @example
|
|
21
|
+
* ```ts
|
|
22
|
+
* const mat3 = new Mat3([1, 0, 0, 0, 1, 0, 0, 0, 1]);
|
|
23
|
+
* ```
|
|
24
|
+
*/
|
|
25
|
+
declare class Matrix3 implements Mat3Like {
|
|
26
|
+
/**
|
|
27
|
+
* 矩阵数组
|
|
28
|
+
* 采用列主序:
|
|
29
|
+
* [m00, m10, m20, m01, m11, m21, m02, m12, m22]
|
|
30
|
+
*/
|
|
31
|
+
data: Mat3Data;
|
|
32
|
+
/**
|
|
33
|
+
* 创建3x3矩阵
|
|
34
|
+
* @param data 矩阵数组
|
|
35
|
+
*/
|
|
36
|
+
constructor(data?: Readonly<Mat3Data>);
|
|
37
|
+
/**
|
|
38
|
+
* 设置为单位矩阵
|
|
39
|
+
* @returns 当前矩阵
|
|
40
|
+
*/
|
|
41
|
+
identity(): this;
|
|
42
|
+
/**
|
|
43
|
+
* 设置矩阵数组
|
|
44
|
+
* @param data 矩阵数组
|
|
45
|
+
* @returns 当前矩阵
|
|
46
|
+
*/
|
|
47
|
+
set(data: Readonly<Mat3Data>): this;
|
|
48
|
+
/**
|
|
49
|
+
* 设置平移分量
|
|
50
|
+
* @param vec2 平移向量
|
|
51
|
+
* @returns 当前矩阵
|
|
52
|
+
*/
|
|
53
|
+
setTranslate(vec2: Readonly<Vec2Like>): this;
|
|
54
|
+
/**
|
|
55
|
+
* 设置缩放分量
|
|
56
|
+
* @param vec2 缩放向量
|
|
57
|
+
* @returns 当前矩阵
|
|
58
|
+
*/
|
|
59
|
+
setScale(vec2: Readonly<Vec2Like>): this;
|
|
60
|
+
/**
|
|
61
|
+
* 设置旋转分量
|
|
62
|
+
* @param angle 弧度
|
|
63
|
+
* @returns 当前矩阵
|
|
64
|
+
*/
|
|
65
|
+
setRotation(angle: number): this;
|
|
66
|
+
/**
|
|
67
|
+
* 获取平移分量
|
|
68
|
+
* @param vec2 输出向量
|
|
69
|
+
* @returns 输出向量
|
|
70
|
+
*/
|
|
71
|
+
getTranslate(vec2?: Vec2Like): Vec2Like;
|
|
72
|
+
/**
|
|
73
|
+
* 获取缩放分量
|
|
74
|
+
* @param vec2 输出向量
|
|
75
|
+
* @returns 输出向量
|
|
76
|
+
*/
|
|
77
|
+
getScale(vec2?: Vec2Like): Vec2Like;
|
|
78
|
+
/**
|
|
79
|
+
* 获取旋转弧度
|
|
80
|
+
* @returns 旋转弧度
|
|
81
|
+
*/
|
|
82
|
+
getRotation(): number;
|
|
83
|
+
/**
|
|
84
|
+
* 矩阵乘法
|
|
85
|
+
* 传入标量时执行标量乘法
|
|
86
|
+
* 传入一个矩阵时执行当前矩阵右乘目标矩阵
|
|
87
|
+
* 传入两个矩阵时执行 a * b 并写回当前矩阵
|
|
88
|
+
* @param value 标量或矩阵a
|
|
89
|
+
* @param mat3 矩阵b
|
|
90
|
+
* @returns 当前矩阵
|
|
91
|
+
*/
|
|
92
|
+
mul(value: number | Readonly<Mat3Like>, mat3?: Readonly<Mat3Like>): this;
|
|
93
|
+
/**
|
|
94
|
+
* 转置矩阵
|
|
95
|
+
* @returns 当前矩阵
|
|
96
|
+
*/
|
|
97
|
+
transpose(): this;
|
|
98
|
+
/**
|
|
99
|
+
* 求矩阵行列式
|
|
100
|
+
* @returns 行列式
|
|
101
|
+
*/
|
|
102
|
+
det(): number;
|
|
103
|
+
/**
|
|
104
|
+
* 求逆矩阵
|
|
105
|
+
* 不可逆时保持原矩阵不变
|
|
106
|
+
* @returns 当前矩阵
|
|
107
|
+
*/
|
|
108
|
+
invert(): this;
|
|
109
|
+
/**
|
|
110
|
+
* 复制目标矩阵
|
|
111
|
+
* @param mat3 目标矩阵
|
|
112
|
+
* @returns 当前矩阵
|
|
113
|
+
*/
|
|
114
|
+
copy(mat3: Readonly<Mat3Like>): this;
|
|
115
|
+
/**
|
|
116
|
+
* 克隆矩阵
|
|
117
|
+
* @returns 新的矩阵实例
|
|
118
|
+
*/
|
|
119
|
+
clone(): Matrix3;
|
|
120
|
+
/**
|
|
121
|
+
* 判断矩阵是否完全相等
|
|
122
|
+
* @param mat3 目标矩阵
|
|
123
|
+
* @returns 是否相等
|
|
124
|
+
*/
|
|
125
|
+
equals(mat3: Readonly<Mat3Like>): boolean;
|
|
126
|
+
private multiplyData;
|
|
127
|
+
}
|
|
128
|
+
declare const Mat3: typeof Matrix3;
|
|
129
|
+
export { Mat3, Matrix3 };
|
|
130
|
+
export type { Mat3Data, Mat3Like };
|
package/lib/Math/Mat3.js
ADDED
|
@@ -0,0 +1,294 @@
|
|
|
1
|
+
import { Vec2 } from "./Vec2.js";
|
|
2
|
+
/**
|
|
3
|
+
* 3x3矩阵
|
|
4
|
+
* @class
|
|
5
|
+
* @implements Mat3Like
|
|
6
|
+
* @example
|
|
7
|
+
* ```ts
|
|
8
|
+
* const mat3 = new Mat3([1, 0, 0, 0, 1, 0, 0, 0, 1]);
|
|
9
|
+
* ```
|
|
10
|
+
*/
|
|
11
|
+
class Matrix3 {
|
|
12
|
+
/**
|
|
13
|
+
* 矩阵数组
|
|
14
|
+
* 采用列主序:
|
|
15
|
+
* [m00, m10, m20, m01, m11, m21, m02, m12, m22]
|
|
16
|
+
*/
|
|
17
|
+
data;
|
|
18
|
+
/**
|
|
19
|
+
* 创建3x3矩阵
|
|
20
|
+
* @param data 矩阵数组
|
|
21
|
+
*/
|
|
22
|
+
constructor(data) {
|
|
23
|
+
this.data = CreateIdentityData();
|
|
24
|
+
if (data !== undefined) {
|
|
25
|
+
this.set(data);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* 设置为单位矩阵
|
|
30
|
+
* @returns 当前矩阵
|
|
31
|
+
*/
|
|
32
|
+
identity() {
|
|
33
|
+
this.data[0] = 1;
|
|
34
|
+
this.data[1] = 0;
|
|
35
|
+
this.data[2] = 0;
|
|
36
|
+
this.data[3] = 0;
|
|
37
|
+
this.data[4] = 1;
|
|
38
|
+
this.data[5] = 0;
|
|
39
|
+
this.data[6] = 0;
|
|
40
|
+
this.data[7] = 0;
|
|
41
|
+
this.data[8] = 1;
|
|
42
|
+
return this;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* 设置矩阵数组
|
|
46
|
+
* @param data 矩阵数组
|
|
47
|
+
* @returns 当前矩阵
|
|
48
|
+
*/
|
|
49
|
+
set(data) {
|
|
50
|
+
this.data[0] = data[0];
|
|
51
|
+
this.data[1] = data[1];
|
|
52
|
+
this.data[2] = data[2];
|
|
53
|
+
this.data[3] = data[3];
|
|
54
|
+
this.data[4] = data[4];
|
|
55
|
+
this.data[5] = data[5];
|
|
56
|
+
this.data[6] = data[6];
|
|
57
|
+
this.data[7] = data[7];
|
|
58
|
+
this.data[8] = data[8];
|
|
59
|
+
return this;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* 设置平移分量
|
|
63
|
+
* @param vec2 平移向量
|
|
64
|
+
* @returns 当前矩阵
|
|
65
|
+
*/
|
|
66
|
+
setTranslate(vec2) {
|
|
67
|
+
this.data[6] = vec2.x;
|
|
68
|
+
this.data[7] = vec2.y;
|
|
69
|
+
return this;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* 设置缩放分量
|
|
73
|
+
* @param vec2 缩放向量
|
|
74
|
+
* @returns 当前矩阵
|
|
75
|
+
*/
|
|
76
|
+
setScale(vec2) {
|
|
77
|
+
const rotation = this.getRotation();
|
|
78
|
+
const cos = Math.cos(rotation);
|
|
79
|
+
const sin = Math.sin(rotation);
|
|
80
|
+
this.data[0] = cos * vec2.x;
|
|
81
|
+
this.data[1] = sin * vec2.x;
|
|
82
|
+
this.data[3] = -sin * vec2.y;
|
|
83
|
+
this.data[4] = cos * vec2.y;
|
|
84
|
+
return this;
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* 设置旋转分量
|
|
88
|
+
* @param angle 弧度
|
|
89
|
+
* @returns 当前矩阵
|
|
90
|
+
*/
|
|
91
|
+
setRotation(angle) {
|
|
92
|
+
const scale = this.getScale();
|
|
93
|
+
const cos = Math.cos(angle);
|
|
94
|
+
const sin = Math.sin(angle);
|
|
95
|
+
this.data[0] = cos * scale.x;
|
|
96
|
+
this.data[1] = sin * scale.x;
|
|
97
|
+
this.data[3] = -sin * scale.y;
|
|
98
|
+
this.data[4] = cos * scale.y;
|
|
99
|
+
return this;
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* 获取平移分量
|
|
103
|
+
* @param vec2 输出向量
|
|
104
|
+
* @returns 输出向量
|
|
105
|
+
*/
|
|
106
|
+
getTranslate(vec2 = new Vec2()) {
|
|
107
|
+
vec2.x = this.data[6];
|
|
108
|
+
vec2.y = this.data[7];
|
|
109
|
+
return vec2;
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* 获取缩放分量
|
|
113
|
+
* @param vec2 输出向量
|
|
114
|
+
* @returns 输出向量
|
|
115
|
+
*/
|
|
116
|
+
getScale(vec2 = new Vec2()) {
|
|
117
|
+
vec2.x = Math.hypot(this.data[0], this.data[1]);
|
|
118
|
+
vec2.y = Math.hypot(this.data[3], this.data[4]);
|
|
119
|
+
return vec2;
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* 获取旋转弧度
|
|
123
|
+
* @returns 旋转弧度
|
|
124
|
+
*/
|
|
125
|
+
getRotation() {
|
|
126
|
+
return Math.atan2(this.data[1], this.data[0]);
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* 矩阵乘法
|
|
130
|
+
* 传入标量时执行标量乘法
|
|
131
|
+
* 传入一个矩阵时执行当前矩阵右乘目标矩阵
|
|
132
|
+
* 传入两个矩阵时执行 a * b 并写回当前矩阵
|
|
133
|
+
* @param value 标量或矩阵a
|
|
134
|
+
* @param mat3 矩阵b
|
|
135
|
+
* @returns 当前矩阵
|
|
136
|
+
*/
|
|
137
|
+
mul(value, mat3) {
|
|
138
|
+
if (typeof value === "number") {
|
|
139
|
+
this.data[0] *= value;
|
|
140
|
+
this.data[1] *= value;
|
|
141
|
+
this.data[2] *= value;
|
|
142
|
+
this.data[3] *= value;
|
|
143
|
+
this.data[4] *= value;
|
|
144
|
+
this.data[5] *= value;
|
|
145
|
+
this.data[6] *= value;
|
|
146
|
+
this.data[7] *= value;
|
|
147
|
+
this.data[8] *= value;
|
|
148
|
+
return this;
|
|
149
|
+
}
|
|
150
|
+
const left = mat3 === undefined ? this.data : value.data;
|
|
151
|
+
const right = mat3 === undefined ? value.data : mat3.data;
|
|
152
|
+
return this.multiplyData(left, right);
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* 转置矩阵
|
|
156
|
+
* @returns 当前矩阵
|
|
157
|
+
*/
|
|
158
|
+
transpose() {
|
|
159
|
+
const m01 = this.data[3];
|
|
160
|
+
const m02 = this.data[6];
|
|
161
|
+
const m12 = this.data[7];
|
|
162
|
+
this.data[3] = this.data[1];
|
|
163
|
+
this.data[6] = this.data[2];
|
|
164
|
+
this.data[7] = this.data[5];
|
|
165
|
+
this.data[1] = m01;
|
|
166
|
+
this.data[2] = m02;
|
|
167
|
+
this.data[5] = m12;
|
|
168
|
+
return this;
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* 求矩阵行列式
|
|
172
|
+
* @returns 行列式
|
|
173
|
+
*/
|
|
174
|
+
det() {
|
|
175
|
+
const a00 = this.data[0];
|
|
176
|
+
const a10 = this.data[1];
|
|
177
|
+
const a20 = this.data[2];
|
|
178
|
+
const a01 = this.data[3];
|
|
179
|
+
const a11 = this.data[4];
|
|
180
|
+
const a21 = this.data[5];
|
|
181
|
+
const a02 = this.data[6];
|
|
182
|
+
const a12 = this.data[7];
|
|
183
|
+
const a22 = this.data[8];
|
|
184
|
+
return a00 * (a11 * a22 - a21 * a12)
|
|
185
|
+
- a01 * (a10 * a22 - a20 * a12)
|
|
186
|
+
+ a02 * (a10 * a21 - a20 * a11);
|
|
187
|
+
}
|
|
188
|
+
/**
|
|
189
|
+
* 求逆矩阵
|
|
190
|
+
* 不可逆时保持原矩阵不变
|
|
191
|
+
* @returns 当前矩阵
|
|
192
|
+
*/
|
|
193
|
+
invert() {
|
|
194
|
+
const a00 = this.data[0];
|
|
195
|
+
const a10 = this.data[1];
|
|
196
|
+
const a20 = this.data[2];
|
|
197
|
+
const a01 = this.data[3];
|
|
198
|
+
const a11 = this.data[4];
|
|
199
|
+
const a21 = this.data[5];
|
|
200
|
+
const a02 = this.data[6];
|
|
201
|
+
const a12 = this.data[7];
|
|
202
|
+
const a22 = this.data[8];
|
|
203
|
+
const b00 = a11 * a22 - a21 * a12;
|
|
204
|
+
const b01 = -(a10 * a22 - a20 * a12);
|
|
205
|
+
const b02 = a10 * a21 - a20 * a11;
|
|
206
|
+
const b10 = -(a01 * a22 - a21 * a02);
|
|
207
|
+
const b11 = a00 * a22 - a20 * a02;
|
|
208
|
+
const b12 = -(a00 * a21 - a20 * a01);
|
|
209
|
+
const b20 = a01 * a12 - a11 * a02;
|
|
210
|
+
const b21 = -(a00 * a12 - a10 * a02);
|
|
211
|
+
const b22 = a00 * a11 - a10 * a01;
|
|
212
|
+
const determinant = a00 * b00 + a01 * b01 + a02 * b02;
|
|
213
|
+
if (determinant === 0) {
|
|
214
|
+
return this;
|
|
215
|
+
}
|
|
216
|
+
const inverseDeterminant = 1 / determinant;
|
|
217
|
+
this.data[0] = b00 * inverseDeterminant;
|
|
218
|
+
this.data[1] = b01 * inverseDeterminant;
|
|
219
|
+
this.data[2] = b02 * inverseDeterminant;
|
|
220
|
+
this.data[3] = b10 * inverseDeterminant;
|
|
221
|
+
this.data[4] = b11 * inverseDeterminant;
|
|
222
|
+
this.data[5] = b12 * inverseDeterminant;
|
|
223
|
+
this.data[6] = b20 * inverseDeterminant;
|
|
224
|
+
this.data[7] = b21 * inverseDeterminant;
|
|
225
|
+
this.data[8] = b22 * inverseDeterminant;
|
|
226
|
+
return this;
|
|
227
|
+
}
|
|
228
|
+
/**
|
|
229
|
+
* 复制目标矩阵
|
|
230
|
+
* @param mat3 目标矩阵
|
|
231
|
+
* @returns 当前矩阵
|
|
232
|
+
*/
|
|
233
|
+
copy(mat3) {
|
|
234
|
+
return this.set(mat3.data);
|
|
235
|
+
}
|
|
236
|
+
/**
|
|
237
|
+
* 克隆矩阵
|
|
238
|
+
* @returns 新的矩阵实例
|
|
239
|
+
*/
|
|
240
|
+
clone() {
|
|
241
|
+
return new Matrix3(this.data);
|
|
242
|
+
}
|
|
243
|
+
/**
|
|
244
|
+
* 判断矩阵是否完全相等
|
|
245
|
+
* @param mat3 目标矩阵
|
|
246
|
+
* @returns 是否相等
|
|
247
|
+
*/
|
|
248
|
+
equals(mat3) {
|
|
249
|
+
return this.data[0] === mat3.data[0]
|
|
250
|
+
&& this.data[1] === mat3.data[1]
|
|
251
|
+
&& this.data[2] === mat3.data[2]
|
|
252
|
+
&& this.data[3] === mat3.data[3]
|
|
253
|
+
&& this.data[4] === mat3.data[4]
|
|
254
|
+
&& this.data[5] === mat3.data[5]
|
|
255
|
+
&& this.data[6] === mat3.data[6]
|
|
256
|
+
&& this.data[7] === mat3.data[7]
|
|
257
|
+
&& this.data[8] === mat3.data[8];
|
|
258
|
+
}
|
|
259
|
+
multiplyData(left, right) {
|
|
260
|
+
const a00 = left[0];
|
|
261
|
+
const a10 = left[1];
|
|
262
|
+
const a20 = left[2];
|
|
263
|
+
const a01 = left[3];
|
|
264
|
+
const a11 = left[4];
|
|
265
|
+
const a21 = left[5];
|
|
266
|
+
const a02 = left[6];
|
|
267
|
+
const a12 = left[7];
|
|
268
|
+
const a22 = left[8];
|
|
269
|
+
const b00 = right[0];
|
|
270
|
+
const b10 = right[1];
|
|
271
|
+
const b20 = right[2];
|
|
272
|
+
const b01 = right[3];
|
|
273
|
+
const b11 = right[4];
|
|
274
|
+
const b21 = right[5];
|
|
275
|
+
const b02 = right[6];
|
|
276
|
+
const b12 = right[7];
|
|
277
|
+
const b22 = right[8];
|
|
278
|
+
this.data[0] = a00 * b00 + a01 * b10 + a02 * b20;
|
|
279
|
+
this.data[1] = a10 * b00 + a11 * b10 + a12 * b20;
|
|
280
|
+
this.data[2] = a20 * b00 + a21 * b10 + a22 * b20;
|
|
281
|
+
this.data[3] = a00 * b01 + a01 * b11 + a02 * b21;
|
|
282
|
+
this.data[4] = a10 * b01 + a11 * b11 + a12 * b21;
|
|
283
|
+
this.data[5] = a20 * b01 + a21 * b11 + a22 * b21;
|
|
284
|
+
this.data[6] = a00 * b02 + a01 * b12 + a02 * b22;
|
|
285
|
+
this.data[7] = a10 * b02 + a11 * b12 + a12 * b22;
|
|
286
|
+
this.data[8] = a20 * b02 + a21 * b12 + a22 * b22;
|
|
287
|
+
return this;
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
const CreateIdentityData = () => {
|
|
291
|
+
return [1, 0, 0, 0, 1, 0, 0, 0, 1];
|
|
292
|
+
};
|
|
293
|
+
const Mat3 = Matrix3;
|
|
294
|
+
export { Mat3, Matrix3 };
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
import type { Mat3Like } from "./Mat3.js";
|
|
2
|
+
interface Vec2Like {
|
|
3
|
+
x: number;
|
|
4
|
+
y: number;
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* 2D向量
|
|
8
|
+
* @class
|
|
9
|
+
* @implements Vec2Like
|
|
10
|
+
* @description 2D向量类
|
|
11
|
+
* @example
|
|
12
|
+
* ```ts
|
|
13
|
+
* const vec2 = new Vec2(x, y);
|
|
14
|
+
* ```
|
|
15
|
+
*/
|
|
16
|
+
declare class Vector2 implements Vec2Like {
|
|
17
|
+
/**
|
|
18
|
+
* X分量
|
|
19
|
+
*/
|
|
20
|
+
x: number;
|
|
21
|
+
/**
|
|
22
|
+
* Y分量
|
|
23
|
+
*/
|
|
24
|
+
y: number;
|
|
25
|
+
/**
|
|
26
|
+
* 创建2D向量
|
|
27
|
+
* @param x X分量
|
|
28
|
+
* @param y Y分量
|
|
29
|
+
*/
|
|
30
|
+
constructor(x?: number, y?: number);
|
|
31
|
+
/**
|
|
32
|
+
* 当前向量加上目标向量
|
|
33
|
+
* @param vec2 目标向量
|
|
34
|
+
* @returns 当前向量
|
|
35
|
+
*/
|
|
36
|
+
add(vec2: Readonly<Vec2Like>): this;
|
|
37
|
+
/**
|
|
38
|
+
* 当前向量减去目标向量
|
|
39
|
+
* @param vec2 目标向量
|
|
40
|
+
* @returns 当前向量
|
|
41
|
+
*/
|
|
42
|
+
sub(vec2: Readonly<Vec2Like>): this;
|
|
43
|
+
/**
|
|
44
|
+
* 当前向量按分量乘以目标向量
|
|
45
|
+
* @param vec2 目标向量
|
|
46
|
+
* @returns 当前向量
|
|
47
|
+
*/
|
|
48
|
+
mul(vec2: Readonly<Vec2Like>): this;
|
|
49
|
+
/**
|
|
50
|
+
* 当前向量按分量除以目标向量
|
|
51
|
+
* @param vec2 目标向量
|
|
52
|
+
* @returns 当前向量
|
|
53
|
+
*/
|
|
54
|
+
div(vec2: Readonly<Vec2Like>): this;
|
|
55
|
+
/**
|
|
56
|
+
* 计算与目标向量的点乘
|
|
57
|
+
* @param vec2 目标向量
|
|
58
|
+
* @returns 点乘结果
|
|
59
|
+
*/
|
|
60
|
+
dot(vec2: Readonly<Vec2Like>): number;
|
|
61
|
+
/**
|
|
62
|
+
* 计算与目标向量的叉乘
|
|
63
|
+
* @param vec2 目标向量
|
|
64
|
+
* @returns 叉乘结果
|
|
65
|
+
*/
|
|
66
|
+
crs(vec2: Readonly<Vec2Like>): number;
|
|
67
|
+
/**
|
|
68
|
+
* 计算与目标向量的距离
|
|
69
|
+
* @param vec2 目标向量
|
|
70
|
+
* @returns 距离
|
|
71
|
+
*/
|
|
72
|
+
dist(vec2: Readonly<Vec2Like>): number;
|
|
73
|
+
/**
|
|
74
|
+
* 计算与目标向量的距离平方
|
|
75
|
+
* @param vec2 目标向量
|
|
76
|
+
* @returns 距离平方
|
|
77
|
+
*/
|
|
78
|
+
distSq(vec2: Readonly<Vec2Like>): number;
|
|
79
|
+
/**
|
|
80
|
+
* 获取向量长度
|
|
81
|
+
* @returns 向量长度
|
|
82
|
+
*/
|
|
83
|
+
len(): number;
|
|
84
|
+
/**
|
|
85
|
+
* 获取向量长度平方
|
|
86
|
+
* @returns 向量长度平方
|
|
87
|
+
*/
|
|
88
|
+
lenSq(): number;
|
|
89
|
+
/**
|
|
90
|
+
* 将当前向量归一化
|
|
91
|
+
* @returns 当前向量
|
|
92
|
+
*/
|
|
93
|
+
normal(): this;
|
|
94
|
+
/**
|
|
95
|
+
* 复制目标向量的分量到当前向量
|
|
96
|
+
* @param vec2 目标向量
|
|
97
|
+
* @returns 当前向量
|
|
98
|
+
*/
|
|
99
|
+
copy(vec2: Readonly<Vec2Like>): this;
|
|
100
|
+
/**
|
|
101
|
+
* 克隆当前向量
|
|
102
|
+
* @returns 新的向量实例
|
|
103
|
+
*/
|
|
104
|
+
clone(): Vector2;
|
|
105
|
+
/**
|
|
106
|
+
* 设置向量分量
|
|
107
|
+
* @param x X分量
|
|
108
|
+
* @param y Y分量
|
|
109
|
+
* @returns 当前向量
|
|
110
|
+
*/
|
|
111
|
+
set(x: number, y: number): this;
|
|
112
|
+
/**
|
|
113
|
+
* 设置X分量
|
|
114
|
+
* @param x X分量
|
|
115
|
+
* @returns 当前向量
|
|
116
|
+
*/
|
|
117
|
+
setX(x: number): this;
|
|
118
|
+
/**
|
|
119
|
+
* 设置Y分量
|
|
120
|
+
* @param y Y分量
|
|
121
|
+
* @returns 当前向量
|
|
122
|
+
*/
|
|
123
|
+
setY(y: number): this;
|
|
124
|
+
/**
|
|
125
|
+
* 应用矩阵变换
|
|
126
|
+
* @param mat3 目标矩阵
|
|
127
|
+
* @returns 当前向量
|
|
128
|
+
*/
|
|
129
|
+
apply(mat3: Readonly<Mat3Like>): this;
|
|
130
|
+
/**
|
|
131
|
+
* 按分量取较大值
|
|
132
|
+
* @param vec2 目标向量
|
|
133
|
+
* @returns 当前向量
|
|
134
|
+
*/
|
|
135
|
+
max(vec2: Readonly<Vec2Like>): this;
|
|
136
|
+
/**
|
|
137
|
+
* 按分量取较小值
|
|
138
|
+
* @param vec2 目标向量
|
|
139
|
+
* @returns 当前向量
|
|
140
|
+
*/
|
|
141
|
+
min(vec2: Readonly<Vec2Like>): this;
|
|
142
|
+
/**
|
|
143
|
+
* 将当前向量限制在最小值和最大值之间
|
|
144
|
+
* @param min 最小向量
|
|
145
|
+
* @param max 最大向量
|
|
146
|
+
* @returns 当前向量
|
|
147
|
+
*/
|
|
148
|
+
clamp(min: Readonly<Vec2Like>, max: Readonly<Vec2Like>): this;
|
|
149
|
+
/**
|
|
150
|
+
* 乘以标量
|
|
151
|
+
* @param value 标量
|
|
152
|
+
* @returns 当前向量
|
|
153
|
+
*/
|
|
154
|
+
scl(value: number): this;
|
|
155
|
+
/**
|
|
156
|
+
* 获取向量弧度
|
|
157
|
+
* 传入目标向量时,返回与目标向量的夹角弧度
|
|
158
|
+
* @param vec2 目标向量
|
|
159
|
+
* @returns 弧度值
|
|
160
|
+
*/
|
|
161
|
+
angle(vec2?: Readonly<Vec2Like>): number;
|
|
162
|
+
/**
|
|
163
|
+
* 判断是否与目标向量完全相等
|
|
164
|
+
* @param vec2 目标向量
|
|
165
|
+
* @returns 是否相等
|
|
166
|
+
*/
|
|
167
|
+
equals(vec2: Readonly<Vec2Like>): boolean;
|
|
168
|
+
}
|
|
169
|
+
declare const Vec2: typeof Vector2;
|
|
170
|
+
export { Vec2, Vector2 };
|
|
171
|
+
export type { Vec2Like };
|
package/lib/Math/Vec2.js
ADDED
|
@@ -0,0 +1,251 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 2D向量
|
|
3
|
+
* @class
|
|
4
|
+
* @implements Vec2Like
|
|
5
|
+
* @description 2D向量类
|
|
6
|
+
* @example
|
|
7
|
+
* ```ts
|
|
8
|
+
* const vec2 = new Vec2(x, y);
|
|
9
|
+
* ```
|
|
10
|
+
*/
|
|
11
|
+
class Vector2 {
|
|
12
|
+
/**
|
|
13
|
+
* X分量
|
|
14
|
+
*/
|
|
15
|
+
x;
|
|
16
|
+
/**
|
|
17
|
+
* Y分量
|
|
18
|
+
*/
|
|
19
|
+
y;
|
|
20
|
+
/**
|
|
21
|
+
* 创建2D向量
|
|
22
|
+
* @param x X分量
|
|
23
|
+
* @param y Y分量
|
|
24
|
+
*/
|
|
25
|
+
constructor(x = 0, y = 0) {
|
|
26
|
+
this.x = x;
|
|
27
|
+
this.y = y;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* 当前向量加上目标向量
|
|
31
|
+
* @param vec2 目标向量
|
|
32
|
+
* @returns 当前向量
|
|
33
|
+
*/
|
|
34
|
+
add(vec2) {
|
|
35
|
+
this.x += vec2.x;
|
|
36
|
+
this.y += vec2.y;
|
|
37
|
+
return this;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* 当前向量减去目标向量
|
|
41
|
+
* @param vec2 目标向量
|
|
42
|
+
* @returns 当前向量
|
|
43
|
+
*/
|
|
44
|
+
sub(vec2) {
|
|
45
|
+
this.x -= vec2.x;
|
|
46
|
+
this.y -= vec2.y;
|
|
47
|
+
return this;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* 当前向量按分量乘以目标向量
|
|
51
|
+
* @param vec2 目标向量
|
|
52
|
+
* @returns 当前向量
|
|
53
|
+
*/
|
|
54
|
+
mul(vec2) {
|
|
55
|
+
this.x *= vec2.x;
|
|
56
|
+
this.y *= vec2.y;
|
|
57
|
+
return this;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* 当前向量按分量除以目标向量
|
|
61
|
+
* @param vec2 目标向量
|
|
62
|
+
* @returns 当前向量
|
|
63
|
+
*/
|
|
64
|
+
div(vec2) {
|
|
65
|
+
this.x /= vec2.x;
|
|
66
|
+
this.y /= vec2.y;
|
|
67
|
+
return this;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* 计算与目标向量的点乘
|
|
71
|
+
* @param vec2 目标向量
|
|
72
|
+
* @returns 点乘结果
|
|
73
|
+
*/
|
|
74
|
+
dot(vec2) {
|
|
75
|
+
return this.x * vec2.x + this.y * vec2.y;
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* 计算与目标向量的叉乘
|
|
79
|
+
* @param vec2 目标向量
|
|
80
|
+
* @returns 叉乘结果
|
|
81
|
+
*/
|
|
82
|
+
crs(vec2) {
|
|
83
|
+
return this.x * vec2.y - this.y * vec2.x;
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* 计算与目标向量的距离
|
|
87
|
+
* @param vec2 目标向量
|
|
88
|
+
* @returns 距离
|
|
89
|
+
*/
|
|
90
|
+
dist(vec2) {
|
|
91
|
+
return Math.sqrt(this.distSq(vec2));
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* 计算与目标向量的距离平方
|
|
95
|
+
* @param vec2 目标向量
|
|
96
|
+
* @returns 距离平方
|
|
97
|
+
*/
|
|
98
|
+
distSq(vec2) {
|
|
99
|
+
const dx = this.x - vec2.x;
|
|
100
|
+
const dy = this.y - vec2.y;
|
|
101
|
+
return dx * dx + dy * dy;
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* 获取向量长度
|
|
105
|
+
* @returns 向量长度
|
|
106
|
+
*/
|
|
107
|
+
len() {
|
|
108
|
+
return Math.sqrt(this.lenSq());
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* 获取向量长度平方
|
|
112
|
+
* @returns 向量长度平方
|
|
113
|
+
*/
|
|
114
|
+
lenSq() {
|
|
115
|
+
return this.x * this.x + this.y * this.y;
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* 将当前向量归一化
|
|
119
|
+
* @returns 当前向量
|
|
120
|
+
*/
|
|
121
|
+
normal() {
|
|
122
|
+
const length = this.len();
|
|
123
|
+
if (length === 0) {
|
|
124
|
+
return this;
|
|
125
|
+
}
|
|
126
|
+
this.x /= length;
|
|
127
|
+
this.y /= length;
|
|
128
|
+
return this;
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* 复制目标向量的分量到当前向量
|
|
132
|
+
* @param vec2 目标向量
|
|
133
|
+
* @returns 当前向量
|
|
134
|
+
*/
|
|
135
|
+
copy(vec2) {
|
|
136
|
+
this.x = vec2.x;
|
|
137
|
+
this.y = vec2.y;
|
|
138
|
+
return this;
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* 克隆当前向量
|
|
142
|
+
* @returns 新的向量实例
|
|
143
|
+
*/
|
|
144
|
+
clone() {
|
|
145
|
+
return new Vector2(this.x, this.y);
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* 设置向量分量
|
|
149
|
+
* @param x X分量
|
|
150
|
+
* @param y Y分量
|
|
151
|
+
* @returns 当前向量
|
|
152
|
+
*/
|
|
153
|
+
set(x, y) {
|
|
154
|
+
this.x = x;
|
|
155
|
+
this.y = y;
|
|
156
|
+
return this;
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* 设置X分量
|
|
160
|
+
* @param x X分量
|
|
161
|
+
* @returns 当前向量
|
|
162
|
+
*/
|
|
163
|
+
setX(x) {
|
|
164
|
+
this.x = x;
|
|
165
|
+
return this;
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* 设置Y分量
|
|
169
|
+
* @param y Y分量
|
|
170
|
+
* @returns 当前向量
|
|
171
|
+
*/
|
|
172
|
+
setY(y) {
|
|
173
|
+
this.y = y;
|
|
174
|
+
return this;
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* 应用矩阵变换
|
|
178
|
+
* @param mat3 目标矩阵
|
|
179
|
+
* @returns 当前向量
|
|
180
|
+
*/
|
|
181
|
+
apply(mat3) {
|
|
182
|
+
const x = this.x;
|
|
183
|
+
const y = this.y;
|
|
184
|
+
this.x = mat3.data[0] * x + mat3.data[3] * y + mat3.data[6];
|
|
185
|
+
this.y = mat3.data[1] * x + mat3.data[4] * y + mat3.data[7];
|
|
186
|
+
return this;
|
|
187
|
+
}
|
|
188
|
+
/**
|
|
189
|
+
* 按分量取较大值
|
|
190
|
+
* @param vec2 目标向量
|
|
191
|
+
* @returns 当前向量
|
|
192
|
+
*/
|
|
193
|
+
max(vec2) {
|
|
194
|
+
this.x = Math.max(this.x, vec2.x);
|
|
195
|
+
this.y = Math.max(this.y, vec2.y);
|
|
196
|
+
return this;
|
|
197
|
+
}
|
|
198
|
+
/**
|
|
199
|
+
* 按分量取较小值
|
|
200
|
+
* @param vec2 目标向量
|
|
201
|
+
* @returns 当前向量
|
|
202
|
+
*/
|
|
203
|
+
min(vec2) {
|
|
204
|
+
this.x = Math.min(this.x, vec2.x);
|
|
205
|
+
this.y = Math.min(this.y, vec2.y);
|
|
206
|
+
return this;
|
|
207
|
+
}
|
|
208
|
+
/**
|
|
209
|
+
* 将当前向量限制在最小值和最大值之间
|
|
210
|
+
* @param min 最小向量
|
|
211
|
+
* @param max 最大向量
|
|
212
|
+
* @returns 当前向量
|
|
213
|
+
*/
|
|
214
|
+
clamp(min, max) {
|
|
215
|
+
this.x = Math.min(Math.max(this.x, min.x), max.x);
|
|
216
|
+
this.y = Math.min(Math.max(this.y, min.y), max.y);
|
|
217
|
+
return this;
|
|
218
|
+
}
|
|
219
|
+
/**
|
|
220
|
+
* 乘以标量
|
|
221
|
+
* @param value 标量
|
|
222
|
+
* @returns 当前向量
|
|
223
|
+
*/
|
|
224
|
+
scl(value) {
|
|
225
|
+
this.x *= value;
|
|
226
|
+
this.y *= value;
|
|
227
|
+
return this;
|
|
228
|
+
}
|
|
229
|
+
/**
|
|
230
|
+
* 获取向量弧度
|
|
231
|
+
* 传入目标向量时,返回与目标向量的夹角弧度
|
|
232
|
+
* @param vec2 目标向量
|
|
233
|
+
* @returns 弧度值
|
|
234
|
+
*/
|
|
235
|
+
angle(vec2) {
|
|
236
|
+
if (vec2 === undefined) {
|
|
237
|
+
return Math.atan2(this.y, this.x);
|
|
238
|
+
}
|
|
239
|
+
return Math.atan2(this.crs(vec2), this.dot(vec2));
|
|
240
|
+
}
|
|
241
|
+
/**
|
|
242
|
+
* 判断是否与目标向量完全相等
|
|
243
|
+
* @param vec2 目标向量
|
|
244
|
+
* @returns 是否相等
|
|
245
|
+
*/
|
|
246
|
+
equals(vec2) {
|
|
247
|
+
return this.x === vec2.x && this.y === vec2.y;
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
const Vec2 = Vector2;
|
|
251
|
+
export { Vec2, Vector2 };
|
package/lib/index.d.ts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import * as Geometry from "./Geometry/index.js";
|
|
2
|
+
import * as Math from "./Math/index.js";
|
|
3
|
+
import * as Utils from "./Utils/index.js";
|
|
4
|
+
declare const BPMatrixJS: {
|
|
5
|
+
Geometry: typeof Geometry;
|
|
6
|
+
Math: typeof Math;
|
|
7
|
+
Utils: typeof Utils;
|
|
8
|
+
};
|
|
9
|
+
export default BPMatrixJS;
|
|
10
|
+
export { BPMatrixJS, Geometry, Math, Utils };
|
package/lib/index.js
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import * as Geometry from "./Geometry/index.js";
|
|
2
|
+
import * as Math from "./Math/index.js";
|
|
3
|
+
import * as Utils from "./Utils/index.js";
|
|
4
|
+
const BPMatrixJS = {
|
|
5
|
+
Geometry,
|
|
6
|
+
Math,
|
|
7
|
+
Utils,
|
|
8
|
+
};
|
|
9
|
+
export default BPMatrixJS;
|
|
10
|
+
export { BPMatrixJS, Geometry, Math, Utils };
|
package/package.json
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "bpmatrixjs",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"main": "./lib/index.js",
|
|
6
|
+
"module": "./lib/index.js",
|
|
7
|
+
"types": "./lib/index.d.ts",
|
|
8
|
+
"files": [
|
|
9
|
+
"lib"
|
|
10
|
+
],
|
|
11
|
+
"exports": {
|
|
12
|
+
".": {
|
|
13
|
+
"types": "./lib/index.d.ts",
|
|
14
|
+
"import": "./lib/index.js"
|
|
15
|
+
},
|
|
16
|
+
"./Math": {
|
|
17
|
+
"types": "./lib/Math/index.d.ts",
|
|
18
|
+
"import": "./lib/Math/index.js"
|
|
19
|
+
},
|
|
20
|
+
"./Math/*": {
|
|
21
|
+
"types": "./lib/Math/*.d.ts",
|
|
22
|
+
"import": "./lib/Math/*.js"
|
|
23
|
+
},
|
|
24
|
+
"./Geometry": {
|
|
25
|
+
"types": "./lib/Geometry/index.d.ts",
|
|
26
|
+
"import": "./lib/Geometry/index.js"
|
|
27
|
+
},
|
|
28
|
+
"./Geometry/*": {
|
|
29
|
+
"types": "./lib/Geometry/*.d.ts",
|
|
30
|
+
"import": "./lib/Geometry/*.js"
|
|
31
|
+
},
|
|
32
|
+
"./Utils": {
|
|
33
|
+
"types": "./lib/Utils/index.d.ts",
|
|
34
|
+
"import": "./lib/Utils/index.js"
|
|
35
|
+
}
|
|
36
|
+
},
|
|
37
|
+
"scripts": {
|
|
38
|
+
"dev": "vite --host",
|
|
39
|
+
"build": "npm run build:lib && npm run build:app",
|
|
40
|
+
"build:app": "tsc && vite build",
|
|
41
|
+
"build:lib": "tsc -p tsconfig.lib.json",
|
|
42
|
+
"preview": "vite preview",
|
|
43
|
+
"lint": "eslint .",
|
|
44
|
+
"lint:fix": "eslint . --fix",
|
|
45
|
+
"pack:check": "npm pack --dry-run"
|
|
46
|
+
},
|
|
47
|
+
"devDependencies": {
|
|
48
|
+
"@types/node": "^24.0.13",
|
|
49
|
+
"@eslint/js": "^9.32.0",
|
|
50
|
+
"@stylistic/eslint-plugin": "^5.2.3",
|
|
51
|
+
"eslint": "^9.32.0",
|
|
52
|
+
"globals": "^16.3.0",
|
|
53
|
+
"typescript": "~6.0.2",
|
|
54
|
+
"typescript-eslint": "^8.38.0",
|
|
55
|
+
"vite": "^8.1.1"
|
|
56
|
+
}
|
|
57
|
+
}
|