@gitborlando/geo 1.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/dist/index.js ADDED
@@ -0,0 +1,558 @@
1
+ // src/math.ts
2
+ var { sqrt, abs, min, max, round, floor, ceil, random } = Math;
3
+ function pow2(number) {
4
+ return Math.pow(number, 2);
5
+ }
6
+ function pow3(number) {
7
+ return Math.pow(number, 3);
8
+ }
9
+ function multiply(...numbers) {
10
+ return numbers.reduce((i, all) => all *= i, 1);
11
+ }
12
+ function divide(a, b) {
13
+ return b === 0 ? 1 : a / b;
14
+ }
15
+ function numberHalfFix(number) {
16
+ const integerPart = ~~number;
17
+ const floatPart = number - integerPart;
18
+ const halfFixed = floatPart >= 0.75 ? 1 : floatPart >= 0.25 ? 0.5 : 0;
19
+ return integerPart + halfFixed;
20
+ }
21
+
22
+ // src/angle.ts
23
+ var { PI, cos, sin, tan, acos, asin, atan, atan2 } = Math;
24
+ var Angle = class _Angle {
25
+ static Cos(angle) {
26
+ return cos(_Angle.RadianFy(angle));
27
+ }
28
+ static Sin(angle) {
29
+ return sin(_Angle.RadianFy(angle));
30
+ }
31
+ static Tan(angle) {
32
+ return tan(_Angle.RadianFy(angle));
33
+ }
34
+ static ACos(angle) {
35
+ return _Angle.AngleFy(acos(_Angle.RadianFy(angle)));
36
+ }
37
+ static ASin(angle) {
38
+ return _Angle.AngleFy(asin(_Angle.RadianFy(angle)));
39
+ }
40
+ static ATan(angle) {
41
+ return _Angle.AngleFy(atan(_Angle.RadianFy(angle)));
42
+ }
43
+ static ATan2(y, x) {
44
+ return _Angle.AngleFy(atan2(y, x));
45
+ }
46
+ static AngleFy(radians) {
47
+ return radians * (180 / Math.PI);
48
+ }
49
+ static RadianFy(angle) {
50
+ return angle * (Math.PI / 180);
51
+ }
52
+ static Normal(angle) {
53
+ return (angle + 360) % 360;
54
+ }
55
+ static Snap(angle, step = 90) {
56
+ return _Angle.Normal(Math.round(angle / step) * step);
57
+ }
58
+ static RotatePoint(ax, ay, ox, oy, angle) {
59
+ const radian = _Angle.RadianFy(angle);
60
+ return {
61
+ x: (ax - ox) * cos(radian) - (ay - oy) * sin(radian) + ox,
62
+ y: (ax - ox) * sin(radian) + (ay - oy) * cos(radian) + oy
63
+ };
64
+ }
65
+ };
66
+
67
+ // src/xy.ts
68
+ function xy_(x = 0, y = 0) {
69
+ return { x, y };
70
+ }
71
+ function xy_client(e) {
72
+ return { x: e.clientX, y: e.clientY };
73
+ }
74
+ function xy_from(xy) {
75
+ return { x: xy.x, y: xy.y };
76
+ }
77
+ function xy_center(xy) {
78
+ return { x: xy.centerX, y: xy.centerY };
79
+ }
80
+ function xy_mutate(self, another) {
81
+ self.x = another.x;
82
+ self.y = another.y;
83
+ }
84
+ function xy_plus(self, another) {
85
+ return { x: self.x + another.x, y: self.y + another.y };
86
+ }
87
+ function xy_plus_mutate(self, another) {
88
+ self.x = self.x + another.x;
89
+ self.y = self.y + another.y;
90
+ }
91
+ function xy_plus_all(...xys) {
92
+ return xys.reduce((a, b) => xy_plus(a, b));
93
+ }
94
+ function xy_minus(self, another) {
95
+ return { x: self.x - another.x, y: self.y - another.y };
96
+ }
97
+ function xy_minus_mutate(self, another) {
98
+ self.x = self.x - another.x;
99
+ self.y = self.y - another.y;
100
+ }
101
+ function xy_multiply(self, ...numbers) {
102
+ const n = numbers.reduce((a, b) => a * b, 1);
103
+ return { x: self.x * n, y: self.y * n };
104
+ }
105
+ function xy_multiply_mutate(self, ...numbers) {
106
+ const n = numbers.reduce((a, b) => a * b, 1);
107
+ self.x = self.x * n;
108
+ self.y = self.y * n;
109
+ }
110
+ function xy_divide(self, ...numbers) {
111
+ const n = numbers.reduce((a, b) => a * b, 1);
112
+ return { x: self.x / n, y: self.y / n };
113
+ }
114
+ function xy_distance(self, another = xy_(0, 0)) {
115
+ return Math.sqrt((self.x - another.x) ** 2 + (self.y - another.y) ** 2);
116
+ }
117
+ function xy_rotate(self, origin, rotation) {
118
+ if (rotation === 0) return self;
119
+ return Angle.RotatePoint(self.x, self.y, origin.x, origin.y, rotation);
120
+ }
121
+ function xy_dot(self, another) {
122
+ return self.x * another.x + self.y * another.y;
123
+ }
124
+ function xy_symmetric(self, origin) {
125
+ return { x: 2 * origin.x - self.x, y: 2 * origin.y - self.y };
126
+ }
127
+ function xy_opposite(self) {
128
+ return { x: -self.x, y: -self.y };
129
+ }
130
+ function xy_getRotation(self, another, origin) {
131
+ return Angle.AngleFy(
132
+ Math.atan2(self.y - origin.y, self.x - origin.x) - Math.atan2(another.y - origin.y, another.x - origin.x)
133
+ );
134
+ }
135
+ function xy_toArray(self) {
136
+ return [self.x, self.y];
137
+ }
138
+ function xy_xAxis(rotation) {
139
+ return { x: Angle.Cos(rotation), y: Angle.Sin(rotation) };
140
+ }
141
+ function xy_yAxis(rotation) {
142
+ return { x: -Angle.Sin(rotation), y: Angle.Cos(rotation) };
143
+ }
144
+ var XY = class _XY {
145
+ constructor(x, y) {
146
+ this.x = x;
147
+ this.y = y;
148
+ }
149
+ from(xy) {
150
+ this.x = xy.x;
151
+ this.y = xy.y;
152
+ return this;
153
+ }
154
+ client(e) {
155
+ this.x = e.clientX;
156
+ this.y = e.clientY;
157
+ return this;
158
+ }
159
+ center(xy) {
160
+ this.x = xy.centerX;
161
+ this.y = xy.centerY;
162
+ return this;
163
+ }
164
+ plus(another) {
165
+ this.x = this.x + another.x;
166
+ this.y = this.y + another.y;
167
+ return this;
168
+ }
169
+ minus(another) {
170
+ this.x = this.x - another.x;
171
+ this.y = this.y - another.y;
172
+ return this;
173
+ }
174
+ multiply(...numbers) {
175
+ const n = numbers.reduce((a, b) => a * b, 1);
176
+ this.x = this.x * n;
177
+ this.y = this.y * n;
178
+ return this;
179
+ }
180
+ divide(...numbers) {
181
+ const n = numbers.reduce((a, b) => a * b, 1);
182
+ this.x = this.x / n;
183
+ this.y = this.y / n;
184
+ return this;
185
+ }
186
+ distance(another) {
187
+ return sqrt((this.x - another.x) ** 2 + (this.y - another.y) ** 2);
188
+ }
189
+ rotate(origin, rotation) {
190
+ if (rotation === 0) return this;
191
+ return Angle.RotatePoint(this.x, this.y, origin.x, origin.y, rotation);
192
+ }
193
+ dot(another) {
194
+ return this.x * another.x + this.y * another.y;
195
+ }
196
+ opposite() {
197
+ return { x: -this.x, y: -this.y };
198
+ }
199
+ symmetric(another, origin) {
200
+ return { x: 2 * origin.x - another.x, y: 2 * origin.y - another.y };
201
+ }
202
+ angle(another, origin) {
203
+ return Angle.AngleFy(
204
+ Math.atan2(this.y - origin.y, this.x - origin.x) - Math.atan2(another.y - origin.y, another.x - origin.x)
205
+ );
206
+ }
207
+ static From(xy) {
208
+ return new _XY(xy.x, xy.y);
209
+ }
210
+ static FromArray(arr) {
211
+ return new _XY(arr[0], arr[1]);
212
+ }
213
+ };
214
+
215
+ // src/aabb.ts
216
+ var AABB = class _AABB {
217
+ constructor(minX, minY, maxX, maxY) {
218
+ this.minX = minX;
219
+ this.minY = minY;
220
+ this.maxX = maxX;
221
+ this.maxY = maxY;
222
+ }
223
+ static Rect(aabb) {
224
+ return {
225
+ x: aabb.minX,
226
+ y: aabb.minY,
227
+ width: aabb.maxX - aabb.minX,
228
+ height: aabb.maxY - aabb.minY,
229
+ centerX: aabb.minX + (aabb.maxX - aabb.minX) / 2,
230
+ centerY: aabb.minY + (aabb.maxY - aabb.minY) / 2
231
+ };
232
+ }
233
+ static Collide(one, another) {
234
+ return one.minX <= another.maxX && one.maxX >= another.minX && one.minY <= another.maxY && one.maxY >= another.minY;
235
+ }
236
+ static Include(one, another) {
237
+ let result = 1;
238
+ let [large, small] = [one, another];
239
+ if (one.maxX - one.minX < another.maxX - another.minX) {
240
+ result = 0;
241
+ large = another;
242
+ small = one;
243
+ }
244
+ const included = large.minX <= small.minX && large.maxX >= small.maxX && large.minY <= small.minY && large.maxY >= small.maxY;
245
+ return included ? result : -1;
246
+ }
247
+ static Expand(aabb, ...expands) {
248
+ const { minX, minY, maxX, maxY } = aabb;
249
+ if (expands.length === 1) {
250
+ const expand = expands[0];
251
+ return new _AABB(minX - expand, minY - expand, maxX + expand, maxY + expand);
252
+ } else {
253
+ return new _AABB(
254
+ minX - expands[0],
255
+ minY - expands[1],
256
+ maxX + expands[2],
257
+ maxY + expands[3]
258
+ );
259
+ }
260
+ }
261
+ static Merge(...aabbList) {
262
+ let [xMin, yMin, xMax, yMax] = [Infinity, Infinity, -Infinity, -Infinity];
263
+ aabbList.forEach((aabb) => {
264
+ xMin = min(xMin, aabb.minX);
265
+ yMin = min(yMin, aabb.minY);
266
+ xMax = max(xMax, aabb.maxX);
267
+ yMax = max(yMax, aabb.maxY);
268
+ });
269
+ return new _AABB(xMin, yMin, xMax, yMax);
270
+ }
271
+ static FromOBB(obb) {
272
+ const width = obb.projectionLengthAt(xy_(1, 0));
273
+ const height = obb.projectionLengthAt(xy_(0, 1));
274
+ return new _AABB(
275
+ obb.center.x - width / 2,
276
+ obb.center.y - height / 2,
277
+ obb.center.x + width / 2,
278
+ obb.center.y + height / 2
279
+ );
280
+ }
281
+ };
282
+
283
+ // src/matrix.ts
284
+ var Matrix = class _Matrix {
285
+ static Create() {
286
+ return [1, 0, 0, 1, 0, 0];
287
+ }
288
+ static Invert(matrix) {
289
+ const [a, b, c, d, e, f] = matrix;
290
+ const invDet = 1 / (a * d - b * c);
291
+ return [d, -b, -c, a, c * f - d * e, b * e - a * f].map(
292
+ (i) => i * invDet
293
+ );
294
+ }
295
+ static ApplyPoint(xy, matrix) {
296
+ const { x, y } = xy;
297
+ const [a, b, c, d, e, f] = matrix;
298
+ return xy_(a * x + c * y + e, b * x + d * y + f);
299
+ }
300
+ static ApplyAABB(aabb, matrix) {
301
+ const { minX, minY, maxX, maxY } = aabb;
302
+ const xy1 = _Matrix.ApplyPoint(xy_(minX, minY), matrix);
303
+ const xy2 = _Matrix.ApplyPoint(xy_(maxX, minY), matrix);
304
+ const xy3 = _Matrix.ApplyPoint(xy_(maxX, maxY), matrix);
305
+ const xy4 = _Matrix.ApplyPoint(xy_(minX, maxY), matrix);
306
+ return {
307
+ minX: min(xy1.x, xy2.x, xy3.x, xy4.x),
308
+ minY: min(xy1.y, xy2.y, xy3.y, xy4.y),
309
+ maxX: max(xy1.x, xy2.x, xy3.x, xy4.x),
310
+ maxY: max(xy1.y, xy2.y, xy3.y, xy4.y)
311
+ };
312
+ }
313
+ static InvertPoint(xy, matrix) {
314
+ return _Matrix.ApplyPoint(xy, _Matrix.Invert(matrix));
315
+ }
316
+ static InvertAABB(aabb, matrix) {
317
+ return _Matrix.ApplyAABB(aabb, _Matrix.Invert(matrix));
318
+ }
319
+ };
320
+
321
+ // src/obb.ts
322
+ var OBB = class _OBB {
323
+ constructor(x, y, width, height, rotation) {
324
+ this.x = x;
325
+ this.y = y;
326
+ this.width = width;
327
+ this.height = height;
328
+ this.rotation = rotation;
329
+ this.center = this.#calcCenter();
330
+ this.axis = this.#calcAxis();
331
+ this.vertexes = this.calcVertexXY();
332
+ this.aabb = AABB.FromOBB(this);
333
+ }
334
+ center;
335
+ axis;
336
+ aabb;
337
+ vertexes;
338
+ get xy() {
339
+ return xy_(this.x, this.y);
340
+ }
341
+ #calcCenter = () => {
342
+ const center = xy_(this.x + this.width / 2, this.y + this.height / 2);
343
+ return xy_rotate(center, xy_(this.x, this.y), this.rotation);
344
+ };
345
+ #calcAxis = () => {
346
+ const cos2 = Angle.Cos(this.rotation);
347
+ const sin2 = Angle.Sin(this.rotation);
348
+ const widthAxis = xy_(cos2, -sin2);
349
+ const heightAxis = xy_(sin2, cos2);
350
+ return this.axis = { widthAxis, heightAxis };
351
+ };
352
+ calcVertexXY = () => {
353
+ const cos2 = Angle.Cos(this.rotation);
354
+ const sin2 = Angle.Sin(this.rotation);
355
+ const cosWidth = cos2 * this.width;
356
+ const sinWidth = sin2 * this.width;
357
+ const cosHeight = cos2 * this.height;
358
+ const sinHeight = sin2 * this.height;
359
+ const TL = xy_(this.x, this.y);
360
+ const TR = xy_(this.x + cosWidth, this.y + sinWidth);
361
+ const BR = xy_(this.x + cosWidth - sinHeight, this.y + sinWidth + cosHeight);
362
+ const BL = xy_(this.x - sinHeight, this.y + cosHeight);
363
+ return this.vertexes = [TL, TR, BR, BL];
364
+ };
365
+ clone = () => {
366
+ return new _OBB(this.x, this.y, this.width, this.height, this.rotation);
367
+ };
368
+ projectionLengthAt = (anotherAxis) => {
369
+ const { widthAxis, heightAxis } = this.axis;
370
+ return Math.abs(xy_dot(widthAxis, anotherAxis)) * this.width + Math.abs(xy_dot(heightAxis, anotherAxis)) * this.height;
371
+ };
372
+ collide = (another) => {
373
+ const centerVector = xy_minus(this.center, another.center);
374
+ if (this.projectionLengthAt(another.axis.widthAxis) + another.width <= 2 * Math.abs(xy_dot(centerVector, another.axis.widthAxis)))
375
+ return false;
376
+ if (this.projectionLengthAt(another.axis.heightAxis) + another.height <= 2 * Math.abs(xy_dot(centerVector, another.axis.heightAxis)))
377
+ return false;
378
+ if (another.projectionLengthAt(this.axis.widthAxis) + this.width <= 2 * Math.abs(xy_dot(centerVector, this.axis.widthAxis)))
379
+ return false;
380
+ if (another.projectionLengthAt(this.axis.heightAxis) + this.height <= 2 * Math.abs(xy_dot(centerVector, this.axis.heightAxis)))
381
+ return false;
382
+ return true;
383
+ };
384
+ static IdentityOBB() {
385
+ return new _OBB(0, 0, 0, 0, 0);
386
+ }
387
+ static FromRect(rect, rotation = 0) {
388
+ const { x, y, width, height } = rect;
389
+ return new _OBB(x, y, width, height, rotation);
390
+ }
391
+ static FromAABB(aabb) {
392
+ const { minX, minY, maxX, maxY } = aabb;
393
+ return new _OBB(minX, minY, maxX - minX, maxY - minY, 0);
394
+ }
395
+ };
396
+
397
+ // src/points-of-bezier.ts
398
+ function distance(p1, p2) {
399
+ return Math.sqrt(distanceSq(p1, p2));
400
+ }
401
+ function distanceSq(p1, p2) {
402
+ return Math.pow(p1.x - p2.x, 2) + Math.pow(p1.y - p2.y, 2);
403
+ }
404
+ function distanceToSegmentSq(p, v, w) {
405
+ const l2 = distanceSq(v, w);
406
+ if (l2 === 0) {
407
+ return distanceSq(p, v);
408
+ }
409
+ let t = ((p.x - v.x) * (w.x - v.x) + (p.y - v.y) * (w.y - v.y)) / l2;
410
+ t = Math.max(0, Math.min(1, t));
411
+ return distanceSq(p, lerp(v, w, t));
412
+ }
413
+ function lerp(a, b, t) {
414
+ return { x: a.x + (b.x - a.x) * t, y: a.y + (b.y - a.y) * t };
415
+ }
416
+ function flatness(points, offset) {
417
+ const p1 = points[offset + 0];
418
+ const p2 = points[offset + 1];
419
+ const p3 = points[offset + 2];
420
+ const p4 = points[offset + 3];
421
+ let ux = 3 * p2.x - 2 * p1.x - p4.x;
422
+ ux *= ux;
423
+ let uy = 3 * p2.y - 2 * p1.y - p4.y;
424
+ uy *= uy;
425
+ let vx = 3 * p3.x - 2 * p4.x - p1.x;
426
+ vx *= vx;
427
+ let vy = 3 * p3.y - 2 * p4.y - p1.y;
428
+ vy *= vy;
429
+ if (ux < vx) {
430
+ ux = vx;
431
+ }
432
+ if (uy < vy) {
433
+ uy = vy;
434
+ }
435
+ return ux + uy;
436
+ }
437
+ function getPointsOnBezierCurveWithSplitting(points, offset, tolerance, newPoints) {
438
+ const outPoints = newPoints || [];
439
+ if (flatness(points, offset) < tolerance) {
440
+ const p0 = points[offset + 0];
441
+ if (outPoints.length) {
442
+ const d = distance(outPoints[outPoints.length - 1], p0);
443
+ if (d > 1) {
444
+ outPoints.push(p0);
445
+ }
446
+ } else {
447
+ outPoints.push(p0);
448
+ }
449
+ outPoints.push(points[offset + 3]);
450
+ } else {
451
+ const t = 0.5;
452
+ const p1 = points[offset + 0];
453
+ const p2 = points[offset + 1];
454
+ const p3 = points[offset + 2];
455
+ const p4 = points[offset + 3];
456
+ const q1 = lerp(p1, p2, t);
457
+ const q2 = lerp(p2, p3, t);
458
+ const q3 = lerp(p3, p4, t);
459
+ const r1 = lerp(q1, q2, t);
460
+ const r2 = lerp(q2, q3, t);
461
+ const red = lerp(r1, r2, t);
462
+ getPointsOnBezierCurveWithSplitting([p1, q1, r1, red], 0, tolerance, outPoints);
463
+ getPointsOnBezierCurveWithSplitting([red, r2, q3, p4], 0, tolerance, outPoints);
464
+ }
465
+ return outPoints;
466
+ }
467
+ function simplify(points, distance2) {
468
+ return simplifyPoints(points, 0, points.length, distance2);
469
+ }
470
+ function simplifyPoints(points, start, end, epsilon, newPoints) {
471
+ const outPoints = newPoints || [];
472
+ const s = points[start];
473
+ const e = points[end - 1];
474
+ let maxDistSq = 0;
475
+ let maxNdx = 1;
476
+ for (let i = start + 1; i < end - 1; ++i) {
477
+ const distSq = distanceToSegmentSq(points[i], s, e);
478
+ if (distSq > maxDistSq) {
479
+ maxDistSq = distSq;
480
+ maxNdx = i;
481
+ }
482
+ }
483
+ if (Math.sqrt(maxDistSq) > epsilon) {
484
+ simplifyPoints(points, start, maxNdx + 1, epsilon, outPoints);
485
+ simplifyPoints(points, maxNdx, end, epsilon, outPoints);
486
+ } else {
487
+ if (!outPoints.length) {
488
+ outPoints.push(s);
489
+ }
490
+ outPoints.push(e);
491
+ }
492
+ return outPoints;
493
+ }
494
+ function pointsOnBezierCurves(points, tolerance = 0.15, distance2) {
495
+ const newPoints = [];
496
+ const numSegments = (points.length - 1) / 3;
497
+ for (let i = 0; i < numSegments; i++) {
498
+ const offset = i * 3;
499
+ getPointsOnBezierCurveWithSplitting(points, offset, tolerance, newPoints);
500
+ }
501
+ if (distance2 && distance2 > 0) {
502
+ return simplifyPoints(newPoints, 0, newPoints.length, distance2);
503
+ }
504
+ return newPoints;
505
+ }
506
+ export {
507
+ AABB,
508
+ Angle,
509
+ Matrix,
510
+ OBB,
511
+ PI,
512
+ XY,
513
+ abs,
514
+ acos,
515
+ asin,
516
+ atan,
517
+ atan2,
518
+ ceil,
519
+ cos,
520
+ divide,
521
+ floor,
522
+ max,
523
+ min,
524
+ multiply,
525
+ numberHalfFix,
526
+ pointsOnBezierCurves,
527
+ pow2,
528
+ pow3,
529
+ random,
530
+ round,
531
+ simplify,
532
+ simplifyPoints,
533
+ sin,
534
+ sqrt,
535
+ tan,
536
+ xy_,
537
+ xy_center,
538
+ xy_client,
539
+ xy_distance,
540
+ xy_divide,
541
+ xy_dot,
542
+ xy_from,
543
+ xy_getRotation,
544
+ xy_minus,
545
+ xy_minus_mutate,
546
+ xy_multiply,
547
+ xy_multiply_mutate,
548
+ xy_mutate,
549
+ xy_opposite,
550
+ xy_plus,
551
+ xy_plus_all,
552
+ xy_plus_mutate,
553
+ xy_rotate,
554
+ xy_symmetric,
555
+ xy_toArray,
556
+ xy_xAxis,
557
+ xy_yAxis
558
+ };
package/package.json ADDED
@@ -0,0 +1,31 @@
1
+ {
2
+ "name": "@gitborlando/geo",
3
+ "version": "1.0.1",
4
+ "description": "",
5
+ "type": "module",
6
+ "exports": {
7
+ ".": {
8
+ "import": "./src/index.js",
9
+ "types": "./src/index.d.ts"
10
+ }
11
+ },
12
+ "publishConfig": {
13
+ "access": "public",
14
+ "registry": "https://registry.npmjs.org"
15
+ },
16
+ "keywords": [],
17
+ "author": "",
18
+ "license": "ISC",
19
+ "devDependencies": {
20
+ "@vitest/ui": "^3.2.4",
21
+ "vitest": "^3.2.4"
22
+ },
23
+ "scripts": {
24
+ "dev": "tsup --watch",
25
+ "build": "tsup",
26
+ "clean": "rm -rf node_modules",
27
+ "test": "vitest",
28
+ "test:run": "vitest run",
29
+ "test:ui": "vitest --ui"
30
+ }
31
+ }
package/src/aabb.ts ADDED
@@ -0,0 +1,89 @@
1
+ import { max, min } from './math'
2
+ import { OBB } from './obb'
3
+ import { IRectWithCenter } from './types'
4
+ import { xy_ } from './xy'
5
+
6
+ export class AABB {
7
+ constructor(
8
+ public minX: number,
9
+ public minY: number,
10
+ public maxX: number,
11
+ public maxY: number,
12
+ ) {}
13
+
14
+ static Rect(aabb: AABB): IRectWithCenter {
15
+ return {
16
+ x: aabb.minX,
17
+ y: aabb.minY,
18
+ width: aabb.maxX - aabb.minX,
19
+ height: aabb.maxY - aabb.minY,
20
+ centerX: aabb.minX + (aabb.maxX - aabb.minX) / 2,
21
+ centerY: aabb.minY + (aabb.maxY - aabb.minY) / 2,
22
+ }
23
+ }
24
+
25
+ static Collide(one: AABB, another: AABB): boolean {
26
+ return (
27
+ one.minX <= another.maxX &&
28
+ one.maxX >= another.minX &&
29
+ one.minY <= another.maxY &&
30
+ one.maxY >= another.minY
31
+ )
32
+ }
33
+
34
+ static Include(one: AABB, another: AABB) {
35
+ let result = 1
36
+ let [large, small] = [one, another]
37
+ if (one.maxX - one.minX < another.maxX - another.minX) {
38
+ result = 0
39
+ large = another
40
+ small = one
41
+ }
42
+ const included =
43
+ large.minX <= small.minX &&
44
+ large.maxX >= small.maxX &&
45
+ large.minY <= small.minY &&
46
+ large.maxY >= small.maxY
47
+ return included ? result : -1
48
+ }
49
+
50
+ static Expand(
51
+ aabb: AABB,
52
+ ...expands: [number] | [number, number, number, number]
53
+ ): AABB {
54
+ const { minX, minY, maxX, maxY } = aabb
55
+ if (expands.length === 1) {
56
+ const expand = expands[0]
57
+ return new AABB(minX - expand, minY - expand, maxX + expand, maxY + expand)
58
+ } else {
59
+ return new AABB(
60
+ minX - expands[0],
61
+ minY - expands[1],
62
+ maxX + expands[2],
63
+ maxY + expands[3],
64
+ )
65
+ }
66
+ }
67
+
68
+ static Merge(...aabbList: AABB[]) {
69
+ let [xMin, yMin, xMax, yMax] = [Infinity, Infinity, -Infinity, -Infinity]
70
+ aabbList.forEach((aabb) => {
71
+ xMin = min(xMin, aabb.minX)
72
+ yMin = min(yMin, aabb.minY)
73
+ xMax = max(xMax, aabb.maxX)
74
+ yMax = max(yMax, aabb.maxY)
75
+ })
76
+ return new AABB(xMin, yMin, xMax, yMax)
77
+ }
78
+
79
+ static FromOBB(obb: OBB) {
80
+ const width = obb.projectionLengthAt(xy_(1, 0))
81
+ const height = obb.projectionLengthAt(xy_(0, 1))
82
+ return new AABB(
83
+ obb.center.x - width / 2,
84
+ obb.center.y - height / 2,
85
+ obb.center.x + width / 2,
86
+ obb.center.y + height / 2,
87
+ )
88
+ }
89
+ }