@immugio/three-math-extensions 0.1.0 → 0.2.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,14 @@
1
+ import { Vec2 } from "./Vec2";
2
+
3
+ export class BoundingBox {
4
+ constructor(public minX: number, public maxX: number, public minY: number, public maxY: number) {
5
+ }
6
+
7
+ public equals(other: BoundingBox): boolean {
8
+ return this.minX === other.minX && this.maxX === other.maxX && this.minY === other.minY && this.maxY === other.maxY;
9
+ }
10
+
11
+ public get size(): Vec2 {
12
+ return new Vec2(this.maxX - this.minX, this.maxY - this.minY);
13
+ }
14
+ }
package/src/Polygon.ts CHANGED
@@ -1,19 +1,20 @@
1
1
  import { Point2 } from "./Point2";
2
2
  import { Vec2 } from "./Vec2";
3
- import { Size2 } from "./Size2";
3
+ import { Rectangle } from "./Rectangle";
4
+ import { BoundingBox } from "./BoundingBox";
4
5
 
5
6
  export class Polygon {
6
7
 
7
8
  constructor(public contour: Vec2[], public holes?: Vec2[][]) {
8
9
  }
9
10
 
10
- public static fromPoints(contour: Point2[], holes?: Point2[][]) {
11
- return new Polygon(contour.map(p => Vec2.fromPoint(p)), holes?.map(h => h.map(p => Vec2.fromPoint(p))));
11
+ public static fromPoints(contour: Point2[], holes?: Point2[][]): Polygon {
12
+ return new Polygon(contour.map(p => Vec2.fromPoint(p)), holes?.map(h => h.map(p => Vec2.fromPoint(p))) );
12
13
  }
13
14
 
14
- public get size(): Size2 {
15
- const {minX, maxX, minY, maxY} = this.boundingBox();
16
- return new Size2(maxX - minX, maxY - minY);
15
+ public get size(): Vec2 {
16
+ const { minX, maxX, minY, maxY } = this.boundingBox();
17
+ return new Vec2(maxX - minX, maxY - minY);
17
18
  }
18
19
 
19
20
  public centerOnOrigin(): Polygon {
@@ -36,7 +37,7 @@ export class Polygon {
36
37
  }
37
38
 
38
39
  public center(): Vec2 {
39
- const {minX, maxX, minY, maxY} = this.boundingBox();
40
+ const { minX, maxX, minY, maxY } = this.boundingBox();
40
41
 
41
42
  const x = (maxX + minX) / 2;
42
43
  const y = (maxY + minY) / 2;
@@ -46,7 +47,7 @@ export class Polygon {
46
47
 
47
48
  public ensureLastPoint(): Polygon {
48
49
  function ensure(points: Vec2[]): void {
49
- if (points[0].x !== points.at(-1).x || points[0].y !== points.at(-1).y) {
50
+ if (!points[0].equals(points.at(-1))) {
50
51
  points.push(points[0].clone());
51
52
  }
52
53
  }
@@ -60,7 +61,7 @@ export class Polygon {
60
61
  return this;
61
62
  }
62
63
 
63
- public boundingBox(): { minX: number, maxX: number, minY: number, maxY: number } {
64
+ public boundingBox(): BoundingBox {
64
65
  let minX = Infinity, maxX = -Infinity, minY = Infinity, maxY = -Infinity;
65
66
 
66
67
  for (const p of this.contour) {
@@ -70,7 +71,7 @@ export class Polygon {
70
71
  if (maxY < p.y) maxY = p.y;
71
72
  }
72
73
 
73
- return {minX, maxX, minY, maxY};
74
+ return new BoundingBox(minX, maxX, minY, maxY);
74
75
  }
75
76
 
76
77
  public toBoundingPolygon(): Polygon {
@@ -96,4 +97,47 @@ export class Polygon {
96
97
  point.x = point.x < centerX ? centerX + xDistanceToCenter : centerX - xDistanceToCenter;
97
98
  }
98
99
  }
99
- }
100
+
101
+ public toRectangle(): Rectangle {
102
+ const bounding = this.boundingBox();
103
+ return new Rectangle(bounding.minX, bounding.maxX, bounding.minY, bounding.maxY);
104
+ }
105
+
106
+ public clone(): Polygon {
107
+ return new Polygon(this.contour.map(p => p.clone()), this.holes?.map(h => h.map(p => p.clone())));
108
+ }
109
+
110
+ public equals(other: Polygon): boolean {
111
+ if (this.contour.length !== other.contour.length) {
112
+ return false;
113
+ }
114
+
115
+ for (let i = 0; i < this.contour.length; i++) {
116
+ if (!this.contour[i].equals(other.contour[i])) {
117
+ return false;
118
+ }
119
+ }
120
+
121
+ if (this.holes?.length !== other.holes?.length) {
122
+ return false;
123
+ }
124
+
125
+ for (let i = 0; i < this.holes?.length; i++) {
126
+ const hole = this.holes[i];
127
+ const otherHole = other.holes[i];
128
+
129
+ if (hole.length !== otherHole.length) {
130
+ return false;
131
+ }
132
+
133
+ for (let j = 0; j < hole.length; j++) {
134
+ if (!hole[j].equals(otherHole[j])) {
135
+ return false;
136
+ }
137
+ }
138
+ }
139
+
140
+ return true;
141
+ }
142
+ }
143
+
@@ -0,0 +1,93 @@
1
+ import { Polygon } from "./Polygon";
2
+ import { Vec2 } from "./Vec2";
3
+ import { Point2 } from "./Point2";
4
+
5
+ export class Rectangle {
6
+
7
+ constructor(public leftX: number, public rightX: number, public topY: number, public bottomY: number) { }
8
+
9
+ public clone(): Rectangle {
10
+ return new Rectangle(this.leftX, this.rightX, this.topY, this.bottomY);
11
+ }
12
+
13
+ public get size(): Vec2 {
14
+ return new Vec2(
15
+ this.rightX - this.leftX,
16
+ this.topY - this.bottomY
17
+ );
18
+ }
19
+
20
+ public get center(): Vec2 {
21
+ return new Vec2(
22
+ (this.leftX + this.rightX) / 2,
23
+ (this.topY + this.bottomY) / 2
24
+ );
25
+ }
26
+
27
+ public get offset(): Vec2 {
28
+ return new Vec2(
29
+ (this.leftX + this.rightX) / -2,
30
+ (this.topY + this.bottomY) / -2
31
+ );
32
+ }
33
+
34
+ public overlaps(other: Rectangle): boolean {
35
+ // Proof is by contradiction. Any one of four conditions guarantees that NO OVERLAP CAN EXIST.
36
+ const result = this.bottomY >= other.topY || this.topY <= other.bottomY || this.rightX <= other.leftX || this.leftX >= other.rightX;
37
+
38
+ return !result;
39
+ }
40
+
41
+ public get hasSize(): boolean {
42
+ return this.rightX - this.leftX > 1 && this.topY - this.bottomY > 1;
43
+ }
44
+
45
+ public translate(diff: Point2): Rectangle {
46
+ this.leftX += diff.x;
47
+ this.rightX += diff.x;
48
+ this.topY += diff.y;
49
+ this.bottomY += diff.y;
50
+
51
+ return this;
52
+ }
53
+
54
+ public centerOnOrigin(): Rectangle {
55
+ const center = this.center;
56
+ this.leftX -= center.x;
57
+ this.rightX -= center.x;
58
+ this.topY -= center.y;
59
+ this.bottomY -= center.y;
60
+
61
+ return this;
62
+ }
63
+
64
+ public toPolygon(): Polygon {
65
+ return new Polygon(this.toPoints());
66
+ }
67
+
68
+ /**
69
+ * The polygon is always constructed as "clockwise", assuming X axis to the right and Y axis down.
70
+ */
71
+ public toPoints(): Vec2[] {
72
+ return [
73
+ new Vec2(this.leftX, Math.min(this.topY, this.bottomY)),
74
+ new Vec2(this.rightX, Math.min(this.topY, this.bottomY)),
75
+ new Vec2(this.rightX, Math.max(this.topY, this.bottomY)),
76
+ new Vec2(this.leftX, Math.max(this.topY, this.bottomY)),
77
+ ];
78
+ }
79
+
80
+ public flipVertical(xCenter: number): Rectangle {
81
+ const left = xCenter - (this.rightX - xCenter);
82
+ const right = xCenter - (this.leftX - xCenter);
83
+
84
+ this.leftX = left;
85
+ this.rightX = right;
86
+
87
+ return this;
88
+ }
89
+
90
+ public equals(other: Rectangle): boolean {
91
+ return !!other && this.leftX === other.leftX && this.rightX === other.rightX && this.topY === other.topY && this.bottomY === other.bottomY;
92
+ }
93
+ }
package/src/Vec3.ts CHANGED
@@ -3,7 +3,7 @@ import { Vec2 } from "./Vec2";
3
3
  import { Point3 } from "./Point3";
4
4
 
5
5
  /**
6
- * Vec3 represents a 2D vector. It extends `Vector3` from the `threejs` library.
6
+ * Vec3 represents a 3D vector. It extends `Vector3` from the `threejs` library.
7
7
  */
8
8
  export class Vec3 extends Vector3 {
9
9
 
package/src/index.ts CHANGED
@@ -1,4 +1,8 @@
1
1
  export { Vec2 } from "./Vec2";
2
2
  export { Vec3 } from "./Vec3";
3
3
  export { Line2D } from "./Line2D";
4
- export { Line3D } from "./Line3D";
4
+ export { Line3D } from "./Line3D";
5
+ export { Size2 } from "./Size2";
6
+ export { Polygon } from "./Polygon";
7
+ export { BoundingBox } from "./BoundingBox";
8
+ export { Rectangle } from "./Rectangle";
@@ -0,0 +1,10 @@
1
+ import { Vec2 } from "./Vec2";
2
+ export declare class BoundingBox {
3
+ minX: number;
4
+ maxX: number;
5
+ minY: number;
6
+ maxY: number;
7
+ constructor(minX: number, maxX: number, minY: number, maxY: number);
8
+ equals(other: BoundingBox): boolean;
9
+ get size(): Vec2;
10
+ }
@@ -1,22 +1,21 @@
1
1
  import { Point2 } from "./Point2";
2
2
  import { Vec2 } from "./Vec2";
3
- import { Size2 } from "./Size2";
3
+ import { Rectangle } from "./Rectangle";
4
+ import { BoundingBox } from "./BoundingBox";
4
5
  export declare class Polygon {
5
6
  contour: Vec2[];
6
7
  holes?: Vec2[][];
7
8
  constructor(contour: Vec2[], holes?: Vec2[][]);
8
9
  static fromPoints(contour: Point2[], holes?: Point2[][]): Polygon;
9
- get size(): Size2;
10
+ get size(): Vec2;
10
11
  centerOnOrigin(): Polygon;
11
12
  center(): Vec2;
12
13
  ensureLastPoint(): Polygon;
13
- boundingBox(): {
14
- minX: number;
15
- maxX: number;
16
- minY: number;
17
- maxY: number;
18
- };
14
+ boundingBox(): BoundingBox;
19
15
  toBoundingPolygon(): Polygon;
20
16
  flip(): Polygon;
21
17
  private flipSingle;
18
+ toRectangle(): Rectangle;
19
+ clone(): Polygon;
20
+ equals(other: Polygon): boolean;
22
21
  }
@@ -0,0 +1,25 @@
1
+ import { Polygon } from "./Polygon";
2
+ import { Vec2 } from "./Vec2";
3
+ import { Point2 } from "./Point2";
4
+ export declare class Rectangle {
5
+ leftX: number;
6
+ rightX: number;
7
+ topY: number;
8
+ bottomY: number;
9
+ constructor(leftX: number, rightX: number, topY: number, bottomY: number);
10
+ clone(): Rectangle;
11
+ get size(): Vec2;
12
+ get center(): Vec2;
13
+ get offset(): Vec2;
14
+ overlaps(other: Rectangle): boolean;
15
+ get hasSize(): boolean;
16
+ translate(diff: Point2): Rectangle;
17
+ centerOnOrigin(): Rectangle;
18
+ toPolygon(): Polygon;
19
+ /**
20
+ * The polygon is always constructed as "clockwise", assuming X axis to the right and Y axis down.
21
+ */
22
+ toPoints(): Vec2[];
23
+ flipVertical(xCenter: number): Rectangle;
24
+ equals(other: Rectangle): boolean;
25
+ }
package/types/Vec3.d.ts CHANGED
@@ -2,7 +2,7 @@ import { Vector3 } from "three";
2
2
  import { Vec2 } from "./Vec2";
3
3
  import { Point3 } from "./Point3";
4
4
  /**
5
- * Vec3 represents a 2D vector. It extends `Vector3` from the `threejs` library.
5
+ * Vec3 represents a 3D vector. It extends `Vector3` from the `threejs` library.
6
6
  */
7
7
  export declare class Vec3 extends Vector3 {
8
8
  #private;
package/types/index.d.ts CHANGED
@@ -2,3 +2,7 @@ export { Vec2 } from "./Vec2";
2
2
  export { Vec3 } from "./Vec3";
3
3
  export { Line2D } from "./Line2D";
4
4
  export { Line3D } from "./Line3D";
5
+ export { Size2 } from "./Size2";
6
+ export { Polygon } from "./Polygon";
7
+ export { BoundingBox } from "./BoundingBox";
8
+ export { Rectangle } from "./Rectangle";