@gitborlando/geo 4.1.0 → 5.1.0

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.
@@ -0,0 +1,143 @@
1
+ interface IXY {
2
+ x: number;
3
+ y: number;
4
+ }
5
+ interface IRect {
6
+ x: number;
7
+ y: number;
8
+ width: number;
9
+ height: number;
10
+ }
11
+ interface IRectWithCenter extends IRect {
12
+ centerX: number;
13
+ centerY: number;
14
+ }
15
+
16
+ type IAxis = {
17
+ widthAxis: IXY;
18
+ heightAxis: IXY;
19
+ };
20
+ declare class OBB {
21
+ #private;
22
+ x: number;
23
+ y: number;
24
+ width: number;
25
+ height: number;
26
+ rotation: number;
27
+ center: IXY;
28
+ axis: IAxis;
29
+ aabb: AABB;
30
+ vertexes: [IXY, IXY, IXY, IXY];
31
+ constructor(x: number, y: number, width: number, height: number, rotation: number);
32
+ get xy(): {
33
+ x: number;
34
+ y: number;
35
+ };
36
+ calcVertexXY: () => [{
37
+ x: number;
38
+ y: number;
39
+ }, {
40
+ x: number;
41
+ y: number;
42
+ }, {
43
+ x: number;
44
+ y: number;
45
+ }, {
46
+ x: number;
47
+ y: number;
48
+ }];
49
+ clone: () => OBB;
50
+ projectAt: (anotherAxis: IXY) => number;
51
+ collide: (another: OBB) => boolean;
52
+ static identityOBB(): OBB;
53
+ static fromRect(rect: IRect, rotation?: number): OBB;
54
+ static fromCenter(center: IXY, width: number, height: number, rotation?: number): OBB;
55
+ static fromAABB(aabb: AABB): OBB;
56
+ }
57
+
58
+ declare class AABB {
59
+ minX: number;
60
+ minY: number;
61
+ maxX: number;
62
+ maxY: number;
63
+ constructor(minX: number, minY: number, maxX: number, maxY: number);
64
+ static rect(aabb: AABB): IRectWithCenter;
65
+ static rectTuple(aabb: AABB): readonly [number, number, number, number];
66
+ static update(aabb: AABB, minX: number, minY: number, maxX: number, maxY: number): AABB;
67
+ static updateFromRect(aabb: AABB, rect: IRect): AABB;
68
+ static shift(aabb: AABB, delta: IXY): AABB;
69
+ static collide(one: AABB, another: AABB): boolean;
70
+ static include(one: AABB, another: AABB): number;
71
+ static extend(aabb: AABB, ...expands: [number] | [number, number, number, number]): AABB;
72
+ static merge(aabbList: AABB[] | Set<AABB>): AABB;
73
+ static fromOBB(obb: OBB): AABB;
74
+ static updateFromOBB(aabb: AABB, obb: OBB): AABB;
75
+ }
76
+
77
+ declare class Angle {
78
+ static cos(angle: number): number;
79
+ static sin(angle: number): number;
80
+ static cosSin(angle: number): {
81
+ cos: number;
82
+ sin: number;
83
+ };
84
+ static tan(angle: number): number;
85
+ static atan2(y: number, x: number): number;
86
+ static angleFy(radians: number): number;
87
+ static radianFy(angle: number): number;
88
+ static normal(angle: number): number;
89
+ static minor(angle: number): number;
90
+ static snap(angle: number, step?: number): number;
91
+ static sweep(v1: IXY, v2?: IXY, clockwise?: boolean): number;
92
+ }
93
+
94
+ declare function twoDecimal(number: number): number;
95
+ declare function minMax(val: number, min: number, max: number): number;
96
+
97
+ declare class XY {
98
+ x: number;
99
+ y: number;
100
+ constructor(x: number, y: number);
101
+ $(): {
102
+ x: number;
103
+ y: number;
104
+ };
105
+ tuple(): readonly [number, number];
106
+ plus(...others: IXY[]): this;
107
+ plusNum(num: number): this;
108
+ minus(...others: IXY[]): this;
109
+ multiply(...numbers: number[]): this;
110
+ multiplyNum(num: number): this;
111
+ divide(...numbers: number[]): this;
112
+ rotate(origin: IXY, rotation: number): this;
113
+ static $(x?: number, y?: number): {
114
+ x: number;
115
+ y: number;
116
+ };
117
+ static of(xy: IXY): XY;
118
+ static from(x: number, y: number): XY;
119
+ static center(wh: {
120
+ width: number;
121
+ height: number;
122
+ }): XY;
123
+ static leftTop(e: {
124
+ left: number;
125
+ top: number;
126
+ }): XY;
127
+ static client(e: {
128
+ clientX: number;
129
+ clientY: number;
130
+ }): XY;
131
+ static xAxis(rotation?: number): XY;
132
+ static yAxis(rotation?: number): XY;
133
+ static dot(self: IXY, another: IXY): number;
134
+ static distance(self: IXY, another: IXY): number;
135
+ static vector(self: IXY, another: IXY): XY;
136
+ static symmetric(self: IXY, origin?: {
137
+ x: number;
138
+ y: number;
139
+ }): XY;
140
+ static lerp(self: IXY, origin: IXY, t: number): XY;
141
+ }
142
+
143
+ export { AABB, Angle, type IRect, type IRectWithCenter, type IXY, OBB, XY, minMax, twoDecimal };
package/dist/index.js ADDED
@@ -0,0 +1,348 @@
1
+ // src/angle.ts
2
+ var Angle = class _Angle {
3
+ static cos(angle) {
4
+ return Math.cos(_Angle.radianFy(angle));
5
+ }
6
+ static sin(angle) {
7
+ return Math.sin(_Angle.radianFy(angle));
8
+ }
9
+ static cosSin(angle) {
10
+ const radians = _Angle.radianFy(angle);
11
+ return { cos: Math.cos(radians), sin: Math.sin(radians) };
12
+ }
13
+ static tan(angle) {
14
+ return Math.tan(_Angle.radianFy(angle));
15
+ }
16
+ static atan2(y, x) {
17
+ return _Angle.angleFy(Math.atan2(y, x));
18
+ }
19
+ static angleFy(radians) {
20
+ return radians * (180 / Math.PI);
21
+ }
22
+ static radianFy(angle) {
23
+ return angle * (Math.PI / 180);
24
+ }
25
+ static normal(angle) {
26
+ return (angle % 360 + 360) % 360;
27
+ }
28
+ static minor(angle) {
29
+ return Math.min(angle, 360 - angle);
30
+ }
31
+ static snap(angle, step = 90) {
32
+ return _Angle.normal(Math.round(angle / step) * step);
33
+ }
34
+ static sweep(v1, v2 = XY.xAxis(), clockwise = false) {
35
+ const dot = v1.x * v2.x + v1.y * v2.y;
36
+ const det = v1.x * v2.y - v1.y * v2.x;
37
+ return _Angle.normal(_Angle.atan2(det, dot) * (clockwise ? 1 : -1));
38
+ }
39
+ };
40
+
41
+ // src/xy.ts
42
+ var XY = class _XY {
43
+ constructor(x, y) {
44
+ this.x = x;
45
+ this.y = y;
46
+ }
47
+ $() {
48
+ return { x: this.x, y: this.y };
49
+ }
50
+ tuple() {
51
+ return [this.x, this.y];
52
+ }
53
+ plus(...others) {
54
+ this.x = others.reduce((sum, cur) => sum + cur.x, this.x);
55
+ this.y = others.reduce((sum, cur) => sum + cur.y, this.y);
56
+ return this;
57
+ }
58
+ plusNum(num) {
59
+ this.x += num;
60
+ this.y += num;
61
+ return this;
62
+ }
63
+ minus(...others) {
64
+ this.x = others.reduce((sum, cur) => sum - cur.x, this.x);
65
+ this.y = others.reduce((sum, cur) => sum - cur.y, this.y);
66
+ return this;
67
+ }
68
+ multiply(...numbers) {
69
+ const n = numbers.reduce((a, b) => a * b, 1);
70
+ this.x *= n;
71
+ this.y *= n;
72
+ return this;
73
+ }
74
+ multiplyNum(num) {
75
+ this.x *= num;
76
+ this.y *= num;
77
+ return this;
78
+ }
79
+ divide(...numbers) {
80
+ const n = numbers.reduce((a, b) => a * b, 1);
81
+ this.x /= n;
82
+ this.y /= n;
83
+ return this;
84
+ }
85
+ rotate(origin, rotation) {
86
+ const { cos, sin } = Angle.cosSin(rotation);
87
+ const dx = this.x - origin.x;
88
+ const dy = this.y - origin.y;
89
+ this.x = dx * cos - dy * sin + origin.x;
90
+ this.y = dx * sin + dy * cos + origin.y;
91
+ return this;
92
+ }
93
+ static $(x = 0, y = 0) {
94
+ return { x, y };
95
+ }
96
+ static of(xy) {
97
+ return new _XY(xy.x, xy.y);
98
+ }
99
+ static from(x, y) {
100
+ return new _XY(x, y);
101
+ }
102
+ static center(wh) {
103
+ return new _XY(wh.width / 2, wh.height / 2);
104
+ }
105
+ static leftTop(e) {
106
+ return new _XY(e.left, e.top);
107
+ }
108
+ static client(e) {
109
+ return new _XY(e.clientX, e.clientY);
110
+ }
111
+ static xAxis(rotation = 0) {
112
+ const { cos, sin } = Angle.cosSin(rotation);
113
+ return new _XY(cos, sin);
114
+ }
115
+ static yAxis(rotation = 0) {
116
+ const { cos, sin } = Angle.cosSin(rotation);
117
+ return new _XY(-sin, cos);
118
+ }
119
+ static dot(self, another) {
120
+ return self.x * another.x + self.y * another.y;
121
+ }
122
+ static distance(self, another) {
123
+ return Math.hypot(self.x - another.x, self.y - another.y);
124
+ }
125
+ static vector(self, another) {
126
+ return new _XY(self.x - another.x, self.y - another.y);
127
+ }
128
+ static symmetric(self, origin = _XY.$()) {
129
+ return new _XY(2 * origin.x - self.x, 2 * origin.y - self.y);
130
+ }
131
+ static lerp(self, origin, t) {
132
+ const distance = _XY.distance(self, origin);
133
+ return new _XY(
134
+ self.x + (self.x - origin.x) * (t / distance),
135
+ self.y + (self.y - origin.y) * (t / distance)
136
+ );
137
+ }
138
+ };
139
+
140
+ // src/aabb.ts
141
+ var AABB = class _AABB {
142
+ constructor(minX, minY, maxX, maxY) {
143
+ this.minX = minX;
144
+ this.minY = minY;
145
+ this.maxX = maxX;
146
+ this.maxY = maxY;
147
+ }
148
+ static rect(aabb) {
149
+ return {
150
+ x: aabb.minX,
151
+ y: aabb.minY,
152
+ width: aabb.maxX - aabb.minX,
153
+ height: aabb.maxY - aabb.minY,
154
+ centerX: aabb.minX + (aabb.maxX - aabb.minX) / 2,
155
+ centerY: aabb.minY + (aabb.maxY - aabb.minY) / 2
156
+ };
157
+ }
158
+ static rectTuple(aabb) {
159
+ return [
160
+ aabb.minX,
161
+ aabb.minY,
162
+ aabb.maxX - aabb.minX,
163
+ aabb.maxY - aabb.minY
164
+ ];
165
+ }
166
+ static update(aabb, minX, minY, maxX, maxY) {
167
+ aabb.minX = minX;
168
+ aabb.minY = minY;
169
+ aabb.maxX = maxX;
170
+ aabb.maxY = maxY;
171
+ return aabb;
172
+ }
173
+ static updateFromRect(aabb, rect) {
174
+ return _AABB.update(
175
+ aabb,
176
+ rect.x,
177
+ rect.y,
178
+ rect.x + rect.width,
179
+ rect.y + rect.height
180
+ );
181
+ }
182
+ static shift(aabb, delta) {
183
+ aabb.minX += delta.x;
184
+ aabb.minY += delta.y;
185
+ aabb.maxX += delta.x;
186
+ aabb.maxY += delta.y;
187
+ return aabb;
188
+ }
189
+ static collide(one, another) {
190
+ return one.minX <= another.maxX && one.maxX >= another.minX && one.minY <= another.maxY && one.maxY >= another.minY;
191
+ }
192
+ static include(one, another) {
193
+ let result = 1;
194
+ let [large, small] = [one, another];
195
+ if (one.maxX - one.minX < another.maxX - another.minX) {
196
+ result = 0;
197
+ large = another;
198
+ small = one;
199
+ }
200
+ const included = large.minX <= small.minX && large.maxX >= small.maxX && large.minY <= small.minY && large.maxY >= small.maxY;
201
+ return included ? result : -1;
202
+ }
203
+ static extend(aabb, ...expands) {
204
+ const { minX, minY, maxX, maxY } = aabb;
205
+ if (expands.length === 1) {
206
+ const expand = expands[0];
207
+ return new _AABB(minX - expand, minY - expand, maxX + expand, maxY + expand);
208
+ } else {
209
+ return new _AABB(
210
+ minX - expands[0],
211
+ minY - expands[1],
212
+ maxX + expands[2],
213
+ maxY + expands[3]
214
+ );
215
+ }
216
+ }
217
+ static merge(aabbList) {
218
+ if (Array.isArray(aabbList)) {
219
+ if (aabbList.length === 0) return new _AABB(0, 0, 0, 0);
220
+ } else {
221
+ if (aabbList.size === 0) return new _AABB(0, 0, 0, 0);
222
+ }
223
+ let xMin = Infinity, yMin = Infinity, xMax = -Infinity, yMax = -Infinity;
224
+ for (const aabb of aabbList) {
225
+ xMin = Math.min(xMin, aabb.minX);
226
+ yMin = Math.min(yMin, aabb.minY);
227
+ xMax = Math.max(xMax, aabb.maxX);
228
+ yMax = Math.max(yMax, aabb.maxY);
229
+ }
230
+ return new _AABB(xMin, yMin, xMax, yMax);
231
+ }
232
+ static fromOBB(obb) {
233
+ const width = obb.projectAt(XY.$(1, 0));
234
+ const height = obb.projectAt(XY.$(0, 1));
235
+ return new _AABB(
236
+ obb.center.x - width / 2,
237
+ obb.center.y - height / 2,
238
+ obb.center.x + width / 2,
239
+ obb.center.y + height / 2
240
+ );
241
+ }
242
+ static updateFromOBB(aabb, obb) {
243
+ const width = obb.projectAt(XY.$(1, 0));
244
+ const height = obb.projectAt(XY.$(0, 1));
245
+ aabb.minX = obb.center.x - width / 2;
246
+ aabb.minY = obb.center.y - height / 2;
247
+ aabb.maxX = obb.center.x + width / 2;
248
+ aabb.maxY = obb.center.y + height / 2;
249
+ return aabb;
250
+ }
251
+ };
252
+
253
+ // src/misc.ts
254
+ function twoDecimal(number) {
255
+ return Number(number.toFixed(Number.isInteger(number) ? 0 : 2));
256
+ }
257
+ function minMax(val, min, max) {
258
+ return Math.min(Math.max(val, min), max);
259
+ }
260
+
261
+ // src/obb.ts
262
+ var OBB = class _OBB {
263
+ constructor(x, y, width, height, rotation) {
264
+ this.x = x;
265
+ this.y = y;
266
+ this.width = width;
267
+ this.height = height;
268
+ this.rotation = rotation;
269
+ this.center = this.#calcCenter();
270
+ this.axis = this.#calcAxis();
271
+ this.vertexes = this.calcVertexXY();
272
+ this.aabb = AABB.fromOBB(this);
273
+ }
274
+ center;
275
+ axis;
276
+ aabb;
277
+ vertexes;
278
+ get xy() {
279
+ return XY.$(this.x, this.y);
280
+ }
281
+ #calcCenter = () => {
282
+ const center = XY.center(this);
283
+ return center.rotate(this.xy, this.rotation);
284
+ };
285
+ #calcAxis = () => {
286
+ const { cos, sin } = Angle.cosSin(this.rotation);
287
+ const widthAxis = XY.$(cos, -sin);
288
+ const heightAxis = XY.$(sin, cos);
289
+ return this.axis = { widthAxis, heightAxis };
290
+ };
291
+ calcVertexXY = () => {
292
+ const cos = Angle.cos(this.rotation);
293
+ const sin = Angle.sin(this.rotation);
294
+ const cosWidth = cos * this.width;
295
+ const sinWidth = sin * this.width;
296
+ const cosHeight = cos * this.height;
297
+ const sinHeight = sin * this.height;
298
+ const TL = XY.$(this.x, this.y);
299
+ const TR = XY.$(this.x + cosWidth, this.y + sinWidth);
300
+ const BR = XY.$(this.x + cosWidth - sinHeight, this.y + sinWidth + cosHeight);
301
+ const BL = XY.$(this.x - sinHeight, this.y + cosHeight);
302
+ return this.vertexes = [TL, TR, BR, BL];
303
+ };
304
+ clone = () => {
305
+ return new _OBB(this.x, this.y, this.width, this.height, this.rotation);
306
+ };
307
+ projectAt = (anotherAxis) => {
308
+ const { widthAxis, heightAxis } = this.axis;
309
+ return Math.abs(XY.dot(widthAxis, anotherAxis)) * this.width + Math.abs(XY.dot(heightAxis, anotherAxis)) * this.height;
310
+ };
311
+ collide = (another) => {
312
+ const centerVector = XY.vector(this.center, another.center);
313
+ if (this.projectAt(another.axis.widthAxis) + another.width <= 2 * Math.abs(XY.dot(centerVector, another.axis.widthAxis)))
314
+ return false;
315
+ if (this.projectAt(another.axis.heightAxis) + another.height <= 2 * Math.abs(XY.dot(centerVector, another.axis.heightAxis)))
316
+ return false;
317
+ if (another.projectAt(this.axis.widthAxis) + this.width <= 2 * Math.abs(XY.dot(centerVector, this.axis.widthAxis)))
318
+ return false;
319
+ if (another.projectAt(this.axis.heightAxis) + this.height <= 2 * Math.abs(XY.dot(centerVector, this.axis.heightAxis)))
320
+ return false;
321
+ return true;
322
+ };
323
+ static identityOBB() {
324
+ return new _OBB(0, 0, 0, 0, 0);
325
+ }
326
+ static fromRect(rect, rotation = 0) {
327
+ const { x, y, width, height } = rect;
328
+ return new _OBB(x, y, width, height, rotation);
329
+ }
330
+ static fromCenter(center, width, height, rotation = 0) {
331
+ const dx = center.x - width / 2;
332
+ const dy = center.y - height / 2;
333
+ const xy = XY.from(dx, dy).rotate(center, rotation);
334
+ return new _OBB(xy.x, xy.y, width, height, rotation);
335
+ }
336
+ static fromAABB(aabb) {
337
+ const { minX, minY, maxX, maxY } = aabb;
338
+ return new _OBB(minX, minY, maxX - minX, maxY - minY, 0);
339
+ }
340
+ };
341
+ export {
342
+ AABB,
343
+ Angle,
344
+ OBB,
345
+ XY,
346
+ minMax,
347
+ twoDecimal
348
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gitborlando/geo",
3
- "version": "4.1.0",
3
+ "version": "5.1.0",
4
4
  "description": "",
5
5
  "type": "module",
6
6
  "exports": {
@@ -9,6 +9,10 @@
9
9
  "types": "./dist/index.d.ts"
10
10
  }
11
11
  },
12
+ "files": [
13
+ "dist",
14
+ "src"
15
+ ],
12
16
  "publishConfig": {
13
17
  "access": "public",
14
18
  "registry": "https://registry.npmjs.org"
package/src/aabb.ts CHANGED
@@ -1,6 +1,5 @@
1
- import { max, min } from './math'
2
1
  import { OBB } from './obb'
3
- import { IRectWithCenter } from './types'
2
+ import { IRect, IRectWithCenter, IXY } from './types'
4
3
  import { XY } from './xy'
5
4
 
6
5
  export class AABB {
@@ -31,6 +30,32 @@ export class AABB {
31
30
  ] as const
32
31
  }
33
32
 
33
+ static update(aabb: AABB, minX: number, minY: number, maxX: number, maxY: number) {
34
+ aabb.minX = minX
35
+ aabb.minY = minY
36
+ aabb.maxX = maxX
37
+ aabb.maxY = maxY
38
+ return aabb
39
+ }
40
+
41
+ static updateFromRect(aabb: AABB, rect: IRect) {
42
+ return AABB.update(
43
+ aabb,
44
+ rect.x,
45
+ rect.y,
46
+ rect.x + rect.width,
47
+ rect.y + rect.height,
48
+ )
49
+ }
50
+
51
+ static shift(aabb: AABB, delta: IXY) {
52
+ aabb.minX += delta.x
53
+ aabb.minY += delta.y
54
+ aabb.maxX += delta.x
55
+ aabb.maxY += delta.y
56
+ return aabb
57
+ }
58
+
34
59
  static collide(one: AABB, another: AABB): boolean {
35
60
  return (
36
61
  one.minX <= another.maxX &&
@@ -74,20 +99,29 @@ export class AABB {
74
99
  }
75
100
  }
76
101
 
77
- static merge(...aabbList: AABB[]) {
78
- let [xMin, yMin, xMax, yMax] = [Infinity, Infinity, -Infinity, -Infinity]
79
- aabbList.forEach((aabb) => {
80
- xMin = min(xMin, aabb.minX)
81
- yMin = min(yMin, aabb.minY)
82
- xMax = max(xMax, aabb.maxX)
83
- yMax = max(yMax, aabb.maxY)
84
- })
102
+ static merge(aabbList: AABB[] | Set<AABB>) {
103
+ if (Array.isArray(aabbList)) {
104
+ if (aabbList.length === 0) return new AABB(0, 0, 0, 0)
105
+ } else {
106
+ if (aabbList.size === 0) return new AABB(0, 0, 0, 0)
107
+ }
108
+
109
+ let xMin = Infinity,
110
+ yMin = Infinity,
111
+ xMax = -Infinity,
112
+ yMax = -Infinity
113
+ for (const aabb of aabbList) {
114
+ xMin = Math.min(xMin, aabb.minX)
115
+ yMin = Math.min(yMin, aabb.minY)
116
+ xMax = Math.max(xMax, aabb.maxX)
117
+ yMax = Math.max(yMax, aabb.maxY)
118
+ }
85
119
  return new AABB(xMin, yMin, xMax, yMax)
86
120
  }
87
121
 
88
122
  static fromOBB(obb: OBB) {
89
- const width = obb.projectionLengthAt(XY._(1, 0))
90
- const height = obb.projectionLengthAt(XY._(0, 1))
123
+ const width = obb.projectAt(XY.$(1, 0))
124
+ const height = obb.projectAt(XY.$(0, 1))
91
125
  return new AABB(
92
126
  obb.center.x - width / 2,
93
127
  obb.center.y - height / 2,
@@ -95,4 +129,14 @@ export class AABB {
95
129
  obb.center.y + height / 2,
96
130
  )
97
131
  }
132
+
133
+ static updateFromOBB(aabb: AABB, obb: OBB) {
134
+ const width = obb.projectAt(XY.$(1, 0))
135
+ const height = obb.projectAt(XY.$(0, 1))
136
+ aabb.minX = obb.center.x - width / 2
137
+ aabb.minY = obb.center.y - height / 2
138
+ aabb.maxX = obb.center.x + width / 2
139
+ aabb.maxY = obb.center.y + height / 2
140
+ return aabb
141
+ }
98
142
  }
package/src/angle.ts CHANGED
@@ -1,32 +1,26 @@
1
- export const { PI, cos, sin, tan, acos, asin, atan, atan2 } = Math
1
+ import { IXY } from './types'
2
+ import { XY } from './xy'
2
3
 
3
4
  export class Angle {
4
5
  static cos(angle: number) {
5
- return cos(Angle.radianFy(angle))
6
+ return Math.cos(Angle.radianFy(angle))
6
7
  }
7
8
 
8
9
  static sin(angle: number) {
9
- return sin(Angle.radianFy(angle))
10
+ return Math.sin(Angle.radianFy(angle))
10
11
  }
11
12
 
12
- static tan(angle: number) {
13
- return tan(Angle.radianFy(angle))
14
- }
15
-
16
- static acos(angle: number) {
17
- return Angle.angleFy(acos(Angle.radianFy(angle)))
18
- }
19
-
20
- static asin(angle: number) {
21
- return Angle.angleFy(asin(Angle.radianFy(angle)))
13
+ static cosSin(angle: number) {
14
+ const radians = Angle.radianFy(angle)
15
+ return { cos: Math.cos(radians), sin: Math.sin(radians) }
22
16
  }
23
17
 
24
- static atan(angle: number) {
25
- return Angle.angleFy(atan(Angle.radianFy(angle)))
18
+ static tan(angle: number) {
19
+ return Math.tan(Angle.radianFy(angle))
26
20
  }
27
21
 
28
22
  static atan2(y: number, x: number) {
29
- return Angle.angleFy(atan2(y, x))
23
+ return Angle.angleFy(Math.atan2(y, x))
30
24
  }
31
25
 
32
26
  static angleFy(radians: number) {
@@ -38,18 +32,20 @@ export class Angle {
38
32
  }
39
33
 
40
34
  static normal(angle: number) {
41
- return (angle + 360) % 360
35
+ return ((angle % 360) + 360) % 360
36
+ }
37
+
38
+ static minor(angle: number) {
39
+ return Math.min(angle, 360 - angle)
42
40
  }
43
41
 
44
42
  static snap(angle: number, step = 90) {
45
43
  return Angle.normal(Math.round(angle / step) * step)
46
44
  }
47
45
 
48
- static rotatePoint(ax: number, ay: number, ox: number, oy: number, angle: number) {
49
- const radian = Angle.radianFy(angle)
50
- return {
51
- x: (ax - ox) * cos(radian) - (ay - oy) * sin(radian) + ox,
52
- y: (ax - ox) * sin(radian) + (ay - oy) * cos(radian) + oy,
53
- }
46
+ static sweep(v1: IXY, v2: IXY = XY.xAxis(), clockwise = false) {
47
+ const dot = v1.x * v2.x + v1.y * v2.y
48
+ const det = v1.x * v2.y - v1.y * v2.x
49
+ return Angle.normal(Angle.atan2(det, dot) * (clockwise ? 1 : -1))
54
50
  }
55
51
  }
package/src/index.ts CHANGED
@@ -1,8 +1,6 @@
1
1
  export * from './aabb'
2
2
  export * from './angle'
3
- export * from './math'
4
- export * from './matrix'
3
+ export * from './misc'
5
4
  export * from './obb'
6
- export * from './points-of-bezier'
7
5
  export * from './types'
8
6
  export * from './xy'
package/src/misc.ts ADDED
@@ -0,0 +1,7 @@
1
+ export function twoDecimal(number: number) {
2
+ return Number(number.toFixed(Number.isInteger(number) ? 0 : 2))
3
+ }
4
+
5
+ export function minMax(val: number, min: number, max: number) {
6
+ return Math.min(Math.max(val, min), max)
7
+ }