@math.gl/polygon 3.6.0-alpha.1 → 3.6.0-alpha.4
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/cut-by-grid.d.ts +8 -7
- package/dist/cut-by-grid.d.ts.map +1 -1
- package/dist/cut-by-grid.js +2 -4
- package/dist/cut-by-mercator-bounds.d.ts +5 -4
- package/dist/cut-by-mercator-bounds.d.ts.map +1 -1
- package/dist/cut-by-mercator-bounds.js +0 -1
- package/dist/earcut.js +1 -1
- package/dist/es5/cut-by-grid.js +83 -70
- package/dist/es5/cut-by-grid.js.map +1 -1
- package/dist/es5/cut-by-mercator-bounds.js +89 -52
- package/dist/es5/cut-by-mercator-bounds.js.map +1 -1
- package/dist/es5/earcut.js +95 -89
- package/dist/es5/earcut.js.map +1 -1
- package/dist/es5/index.js +14 -14
- package/dist/es5/lineclip.js +43 -36
- package/dist/es5/lineclip.js.map +1 -1
- package/dist/es5/polygon-utils.js +66 -56
- package/dist/es5/polygon-utils.js.map +1 -1
- package/dist/es5/polygon.js +44 -31
- package/dist/es5/polygon.js.map +1 -1
- package/dist/es5/utils.js +12 -11
- package/dist/es5/utils.js.map +1 -1
- package/dist/esm/cut-by-grid.js +1 -1
- package/dist/esm/cut-by-grid.js.map +1 -1
- package/dist/esm/cut-by-mercator-bounds.js.map +1 -1
- package/dist/esm/earcut.js.map +1 -1
- package/dist/esm/lineclip.js.map +1 -1
- package/dist/esm/polygon-utils.js.map +1 -1
- package/dist/esm/polygon.js.map +1 -1
- package/dist/esm/utils.js.map +1 -1
- package/dist/lineclip.d.ts +1 -2
- package/dist/lineclip.d.ts.map +1 -1
- package/dist/polygon-utils.d.ts.map +1 -1
- package/dist/polygon.d.ts +3 -2
- package/dist/polygon.d.ts.map +1 -1
- package/dist/polygon.js +1 -1
- package/dist/utils.d.ts +4 -3
- package/dist/utils.d.ts.map +1 -1
- package/package.json +3 -3
- package/src/cut-by-grid.ts +57 -39
- package/src/cut-by-mercator-bounds.ts +31 -21
- package/src/earcut.ts +1 -1
- package/src/lineclip.ts +14 -14
- package/src/polygon-utils.ts +4 -1
- package/src/polygon.ts +9 -8
- package/src/utils.ts +11 -3
package/src/cut-by-grid.ts
CHANGED
|
@@ -1,15 +1,17 @@
|
|
|
1
1
|
/* eslint-disable max-statements, max-depth, complexity, no-unused-expressions */
|
|
2
|
-
import {bitCode, intersect} from './lineclip';
|
|
2
|
+
import {bitCode, intersect, BoundingBox} from './lineclip';
|
|
3
3
|
import {getPointAtIndex, copy, push} from './utils';
|
|
4
4
|
|
|
5
|
+
import type {NumericArray} from '@math.gl/core';
|
|
6
|
+
|
|
5
7
|
export type Polygon = {
|
|
6
|
-
positions:
|
|
7
|
-
holeIndices?:
|
|
8
|
-
|
|
8
|
+
positions: number[];
|
|
9
|
+
holeIndices?: number[];
|
|
10
|
+
edgeTypes?: number[];
|
|
9
11
|
};
|
|
10
12
|
|
|
11
13
|
export function cutPolylineByGrid(
|
|
12
|
-
positions:
|
|
14
|
+
positions: NumericArray,
|
|
13
15
|
options?: {
|
|
14
16
|
size?: number;
|
|
15
17
|
broken?: boolean;
|
|
@@ -18,7 +20,7 @@ export function cutPolylineByGrid(
|
|
|
18
20
|
startIndex?: number;
|
|
19
21
|
endIndex?: number;
|
|
20
22
|
}
|
|
21
|
-
):
|
|
23
|
+
): number[] | number[][] {
|
|
22
24
|
const {
|
|
23
25
|
size = 2,
|
|
24
26
|
broken = false,
|
|
@@ -28,13 +30,13 @@ export function cutPolylineByGrid(
|
|
|
28
30
|
endIndex = positions.length
|
|
29
31
|
} = options || {};
|
|
30
32
|
const numPoints = (endIndex - startIndex) / size;
|
|
31
|
-
let part = [];
|
|
32
|
-
const result = [part];
|
|
33
|
-
const a = getPointAtIndex(positions, 0, size, startIndex);
|
|
34
|
-
let b;
|
|
35
|
-
let codeB;
|
|
36
|
-
const cell = getGridCell(a, gridResolution, gridOffset, []);
|
|
37
|
-
const scratchPoint = [];
|
|
33
|
+
let part: number[] = [];
|
|
34
|
+
const result: number[][] = [part];
|
|
35
|
+
const a: number[] = getPointAtIndex(positions, 0, size, startIndex);
|
|
36
|
+
let b: number[];
|
|
37
|
+
let codeB: number;
|
|
38
|
+
const cell: BoundingBox = getGridCell(a, gridResolution, gridOffset, []);
|
|
39
|
+
const scratchPoint: number[] = [];
|
|
38
40
|
push(part, a);
|
|
39
41
|
|
|
40
42
|
for (let i = 1; i < numPoints; i++) {
|
|
@@ -73,7 +75,7 @@ export function cutPolylineByGrid(
|
|
|
73
75
|
const TYPE_INSIDE = 0;
|
|
74
76
|
const TYPE_BORDER = 1;
|
|
75
77
|
|
|
76
|
-
function concatInPlace(arr1, arr2) {
|
|
78
|
+
function concatInPlace(arr1: number[], arr2: number[]): number[] {
|
|
77
79
|
for (let i = 0; i < arr2.length; i++) {
|
|
78
80
|
arr1.push(arr2[i]);
|
|
79
81
|
}
|
|
@@ -81,30 +83,31 @@ function concatInPlace(arr1, arr2) {
|
|
|
81
83
|
}
|
|
82
84
|
|
|
83
85
|
export function cutPolygonByGrid(
|
|
84
|
-
positions:
|
|
85
|
-
holeIndices:
|
|
86
|
+
positions: number[],
|
|
87
|
+
holeIndices: number[] | null = null,
|
|
86
88
|
options?: {
|
|
87
89
|
size?: number;
|
|
88
90
|
gridResolution?: number;
|
|
89
91
|
gridOffset?: [number, number];
|
|
90
92
|
edgeTypes?: boolean;
|
|
91
93
|
}
|
|
92
|
-
):
|
|
94
|
+
): Polygon[] {
|
|
93
95
|
if (!positions.length) {
|
|
94
96
|
// input is empty
|
|
95
97
|
return [];
|
|
96
98
|
}
|
|
97
99
|
const {size = 2, gridResolution = 10, gridOffset = [0, 0], edgeTypes = false} = options || {};
|
|
98
|
-
const result = [];
|
|
99
|
-
const queue = [
|
|
100
|
+
const result: Polygon[] = [];
|
|
101
|
+
const queue: {pos: number[]; types: number[]; holes: number[]}[] = [
|
|
100
102
|
{
|
|
101
103
|
pos: positions,
|
|
102
|
-
types: edgeTypes
|
|
104
|
+
types: edgeTypes ? (new Array(positions.length / size).fill(TYPE_BORDER) as number[]) : null,
|
|
103
105
|
holes: holeIndices || []
|
|
104
106
|
}
|
|
105
107
|
];
|
|
106
|
-
const bbox = [[], []];
|
|
107
|
-
|
|
108
|
+
const bbox: number[][] = [[], []];
|
|
109
|
+
// @ts-ignore
|
|
110
|
+
let cell: BoundingBox = [];
|
|
108
111
|
|
|
109
112
|
// Recursively bisect polygon until every part fit in a single grid cell
|
|
110
113
|
while (queue.length) {
|
|
@@ -113,7 +116,6 @@ export function cutPolygonByGrid(
|
|
|
113
116
|
// Get the bounding box of the outer polygon
|
|
114
117
|
getBoundingBox(pos, size, holes[0] || pos.length, bbox);
|
|
115
118
|
cell = getGridCell(bbox[0], gridResolution, gridOffset, cell);
|
|
116
|
-
// @ts-expect-error
|
|
117
119
|
const code = bitCode(bbox[1], cell);
|
|
118
120
|
|
|
119
121
|
if (code) {
|
|
@@ -144,13 +146,11 @@ export function cutPolygonByGrid(
|
|
|
144
146
|
}
|
|
145
147
|
} else {
|
|
146
148
|
// Polygon fits in a single cell, no more processing required
|
|
147
|
-
const polygon = {positions: pos};
|
|
149
|
+
const polygon: Polygon = {positions: pos};
|
|
148
150
|
if (edgeTypes) {
|
|
149
|
-
// @ts-expect-error
|
|
150
151
|
polygon.edgeTypes = types;
|
|
151
152
|
}
|
|
152
153
|
if (holes.length) {
|
|
153
|
-
// @ts-expect-error
|
|
154
154
|
polygon.holeIndices = holes;
|
|
155
155
|
}
|
|
156
156
|
|
|
@@ -164,17 +164,25 @@ export function cutPolygonByGrid(
|
|
|
164
164
|
// TYPE_BORDER - edge from the original polygon
|
|
165
165
|
// TYPE_INSIDE - inside the original polygon
|
|
166
166
|
// eslint-disable-next-line max-params
|
|
167
|
-
function bisectPolygon(
|
|
167
|
+
function bisectPolygon(
|
|
168
|
+
positions: NumericArray,
|
|
169
|
+
edgeTypes: number[] | undefined,
|
|
170
|
+
size: number,
|
|
171
|
+
startIndex: number,
|
|
172
|
+
endIndex: number,
|
|
173
|
+
bbox: BoundingBox,
|
|
174
|
+
edge: number
|
|
175
|
+
) {
|
|
168
176
|
const numPoints = (endIndex - startIndex) / size;
|
|
169
|
-
const resultLow = [];
|
|
170
|
-
const resultHigh = [];
|
|
171
|
-
const typesLow = [];
|
|
172
|
-
const typesHigh = [];
|
|
173
|
-
const scratchPoint = [];
|
|
177
|
+
const resultLow: number[] = [];
|
|
178
|
+
const resultHigh: number[] = [];
|
|
179
|
+
const typesLow: number[] = [];
|
|
180
|
+
const typesHigh: number[] = [];
|
|
181
|
+
const scratchPoint: number[] = [];
|
|
174
182
|
|
|
175
|
-
let p;
|
|
176
|
-
let side;
|
|
177
|
-
let type;
|
|
183
|
+
let p: number[];
|
|
184
|
+
let side: number;
|
|
185
|
+
let type: number;
|
|
178
186
|
const prev = getPointAtIndex(positions, numPoints - 1, size, startIndex);
|
|
179
187
|
let prevSide = Math.sign(edge & 8 ? prev[1] - bbox[3] : prev[0] - bbox[2]);
|
|
180
188
|
let prevType = edgeTypes && edgeTypes[numPoints - 1];
|
|
@@ -217,7 +225,12 @@ function bisectPolygon(positions, edgeTypes, size, startIndex, endIndex, bbox, e
|
|
|
217
225
|
];
|
|
218
226
|
}
|
|
219
227
|
|
|
220
|
-
function getGridCell(
|
|
228
|
+
function getGridCell(
|
|
229
|
+
p: number[],
|
|
230
|
+
gridResolution: number,
|
|
231
|
+
gridOffset: [number, number],
|
|
232
|
+
out: number[]
|
|
233
|
+
): BoundingBox {
|
|
221
234
|
const left = Math.floor((p[0] - gridOffset[0]) / gridResolution) * gridResolution + gridOffset[0];
|
|
222
235
|
const bottom =
|
|
223
236
|
Math.floor((p[1] - gridOffset[1]) / gridResolution) * gridResolution + gridOffset[1];
|
|
@@ -225,10 +238,10 @@ function getGridCell(p, gridResolution, gridOffset, out) {
|
|
|
225
238
|
out[1] = bottom;
|
|
226
239
|
out[2] = left + gridResolution;
|
|
227
240
|
out[3] = bottom + gridResolution;
|
|
228
|
-
return out;
|
|
241
|
+
return out as BoundingBox;
|
|
229
242
|
}
|
|
230
243
|
|
|
231
|
-
function moveToNeighborCell(cell, gridResolution, edge) {
|
|
244
|
+
function moveToNeighborCell(cell: number[], gridResolution: number, edge: number): void {
|
|
232
245
|
if (edge & 8) {
|
|
233
246
|
// top
|
|
234
247
|
cell[1] += gridResolution;
|
|
@@ -248,7 +261,12 @@ function moveToNeighborCell(cell, gridResolution, edge) {
|
|
|
248
261
|
}
|
|
249
262
|
}
|
|
250
263
|
|
|
251
|
-
function getBoundingBox(
|
|
264
|
+
function getBoundingBox(
|
|
265
|
+
positions: NumericArray,
|
|
266
|
+
size: number,
|
|
267
|
+
endIndex: number,
|
|
268
|
+
out: number[][]
|
|
269
|
+
): number[][] {
|
|
252
270
|
let minX = Infinity;
|
|
253
271
|
let maxX = -Infinity;
|
|
254
272
|
let minY = Infinity;
|
|
@@ -1,20 +1,21 @@
|
|
|
1
1
|
import {cutPolylineByGrid, cutPolygonByGrid} from './cut-by-grid';
|
|
2
2
|
import {getPointAtIndex, push} from './utils';
|
|
3
3
|
import type {Polygon} from './cut-by-grid';
|
|
4
|
+
import type {NumericArray} from '@math.gl/core';
|
|
4
5
|
|
|
5
6
|
// https://en.wikipedia.org/wiki/Web_Mercator_projection
|
|
6
7
|
const DEFAULT_MAX_LATITUDE = 85.051129;
|
|
7
8
|
|
|
8
9
|
/** https://user-images.githubusercontent.com/2059298/78465769-938b7a00-76ae-11ea-9b95-1f4c26425ab9.png */
|
|
9
10
|
export function cutPolylineByMercatorBounds(
|
|
10
|
-
positions:
|
|
11
|
+
positions: NumericArray,
|
|
11
12
|
options?: {
|
|
12
13
|
size?: number;
|
|
13
14
|
startIndex?: number;
|
|
14
15
|
endIndex?: number;
|
|
15
16
|
normalize?: boolean;
|
|
16
17
|
}
|
|
17
|
-
):
|
|
18
|
+
): number[][] {
|
|
18
19
|
const {size = 2, startIndex = 0, endIndex = positions.length, normalize = true} = options || {};
|
|
19
20
|
|
|
20
21
|
// Remap longitudes so that each segment takes the shorter path
|
|
@@ -26,7 +27,7 @@ export function cutPolylineByMercatorBounds(
|
|
|
26
27
|
broken: true,
|
|
27
28
|
gridResolution: 360,
|
|
28
29
|
gridOffset: [-180, -180]
|
|
29
|
-
});
|
|
30
|
+
}) as number[][];
|
|
30
31
|
|
|
31
32
|
if (normalize) {
|
|
32
33
|
// Each part is guaranteed to be in a single copy of the world
|
|
@@ -35,25 +36,24 @@ export function cutPolylineByMercatorBounds(
|
|
|
35
36
|
shiftLongitudesIntoRange(part, size);
|
|
36
37
|
}
|
|
37
38
|
}
|
|
38
|
-
// @ts-expect-error
|
|
39
39
|
return parts;
|
|
40
40
|
}
|
|
41
41
|
|
|
42
42
|
/** https://user-images.githubusercontent.com/2059298/78465770-94241080-76ae-11ea-809a-6a8534dac1d9.png */
|
|
43
43
|
export function cutPolygonByMercatorBounds(
|
|
44
|
-
positions:
|
|
45
|
-
holeIndices:
|
|
44
|
+
positions: number[],
|
|
45
|
+
holeIndices: number[] | null = null,
|
|
46
46
|
options?: {
|
|
47
47
|
size?: number;
|
|
48
48
|
normalize?: boolean;
|
|
49
49
|
maxLatitude?: number;
|
|
50
50
|
edgeTypes?: boolean;
|
|
51
51
|
}
|
|
52
|
-
):
|
|
52
|
+
): Polygon[] {
|
|
53
53
|
const {size = 2, normalize = true, edgeTypes = false} = options || {};
|
|
54
54
|
holeIndices = holeIndices || [];
|
|
55
|
-
const newPositions = [];
|
|
56
|
-
const newHoleIndices = [];
|
|
55
|
+
const newPositions: number[] = [];
|
|
56
|
+
const newHoleIndices: number[] = [];
|
|
57
57
|
let srcStartIndex = 0;
|
|
58
58
|
let targetIndex = 0;
|
|
59
59
|
|
|
@@ -105,7 +105,12 @@ export function cutPolygonByMercatorBounds(
|
|
|
105
105
|
/* Helpers */
|
|
106
106
|
|
|
107
107
|
// See comments for insertPoleVertices
|
|
108
|
-
function findSplitIndex(
|
|
108
|
+
function findSplitIndex(
|
|
109
|
+
positions: number[],
|
|
110
|
+
size: number,
|
|
111
|
+
startIndex: number,
|
|
112
|
+
endIndex: number
|
|
113
|
+
): number {
|
|
109
114
|
let maxLat = -1;
|
|
110
115
|
let pointIndex = -1;
|
|
111
116
|
for (let i = startIndex + 1; i < endIndex; i += size) {
|
|
@@ -128,12 +133,12 @@ function findSplitIndex(positions, size, startIndex, endIndex) {
|
|
|
128
133
|
// intersect with the ring itself. This is ensured by findSplitIndex, which returns the
|
|
129
134
|
// vertex closest to the pole.
|
|
130
135
|
function insertPoleVertices(
|
|
131
|
-
positions,
|
|
132
|
-
size,
|
|
133
|
-
startIndex,
|
|
134
|
-
endIndex,
|
|
135
|
-
maxLatitude = DEFAULT_MAX_LATITUDE
|
|
136
|
-
) {
|
|
136
|
+
positions: number[],
|
|
137
|
+
size: number,
|
|
138
|
+
startIndex: number,
|
|
139
|
+
endIndex: number,
|
|
140
|
+
maxLatitude: number = DEFAULT_MAX_LATITUDE
|
|
141
|
+
): void {
|
|
137
142
|
// Check if the ring contains a pole
|
|
138
143
|
const firstLng = positions[startIndex];
|
|
139
144
|
const lastLng = positions[endIndex - size];
|
|
@@ -153,9 +158,14 @@ function insertPoleVertices(
|
|
|
153
158
|
}
|
|
154
159
|
}
|
|
155
160
|
|
|
156
|
-
function wrapLongitudesForShortestPath(
|
|
157
|
-
|
|
158
|
-
|
|
161
|
+
function wrapLongitudesForShortestPath(
|
|
162
|
+
positions: NumericArray,
|
|
163
|
+
size: number,
|
|
164
|
+
startIndex: number,
|
|
165
|
+
endIndex: number
|
|
166
|
+
): void {
|
|
167
|
+
let prevLng: number = positions[0];
|
|
168
|
+
let lng: number;
|
|
159
169
|
for (let i = startIndex; i < endIndex; i += size) {
|
|
160
170
|
lng = positions[i];
|
|
161
171
|
const delta = lng - prevLng;
|
|
@@ -166,8 +176,8 @@ function wrapLongitudesForShortestPath(positions, size, startIndex, endIndex) {
|
|
|
166
176
|
}
|
|
167
177
|
}
|
|
168
178
|
|
|
169
|
-
function shiftLongitudesIntoRange(positions, size) {
|
|
170
|
-
let refLng;
|
|
179
|
+
function shiftLongitudesIntoRange(positions: NumericArray, size: number): void {
|
|
180
|
+
let refLng: number;
|
|
171
181
|
const pointCount = positions.length / size;
|
|
172
182
|
|
|
173
183
|
// Find a longitude that is not on the edge of a world
|
package/src/earcut.ts
CHANGED
package/src/lineclip.ts
CHANGED
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
|
|
25
25
|
import {push, copy, getPointAtIndex} from './utils';
|
|
26
26
|
|
|
27
|
-
type BoundingBox = [number, number, number, number];
|
|
27
|
+
export type BoundingBox = [number, number, number, number];
|
|
28
28
|
|
|
29
29
|
/**
|
|
30
30
|
* Cohen-Sutherland line clipping algorithm, adapted to efficiently
|
|
@@ -41,13 +41,13 @@ export function clipPolyline(
|
|
|
41
41
|
): number[][] {
|
|
42
42
|
const {size = 2, startIndex = 0, endIndex = positions.length} = options || {};
|
|
43
43
|
const numPoints = (endIndex - startIndex) / size;
|
|
44
|
-
const result = [];
|
|
45
|
-
let part = [];
|
|
46
|
-
let a;
|
|
47
|
-
let b;
|
|
48
|
-
let codeA = -1;
|
|
49
|
-
let codeB;
|
|
50
|
-
let lastCode;
|
|
44
|
+
const result: number[][] = [];
|
|
45
|
+
let part: number[] = [];
|
|
46
|
+
let a: number[];
|
|
47
|
+
let b: number[];
|
|
48
|
+
let codeA: number = -1;
|
|
49
|
+
let codeB: number;
|
|
50
|
+
let lastCode: number;
|
|
51
51
|
|
|
52
52
|
for (let i = 1; i < numPoints; i++) {
|
|
53
53
|
a = getPointAtIndex(positions, i - 1, size, startIndex, a);
|
|
@@ -114,11 +114,11 @@ export function clipPolygon(
|
|
|
114
114
|
const {size = 2, endIndex = positions.length} = options || {};
|
|
115
115
|
let {startIndex = 0} = options || {};
|
|
116
116
|
let numPoints = (endIndex - startIndex) / size;
|
|
117
|
-
let result;
|
|
118
|
-
let p;
|
|
119
|
-
let prev;
|
|
120
|
-
let inside;
|
|
121
|
-
let prevInside;
|
|
117
|
+
let result: number[];
|
|
118
|
+
let p: number[];
|
|
119
|
+
let prev: number[];
|
|
120
|
+
let inside: boolean;
|
|
121
|
+
let prevInside: boolean;
|
|
122
122
|
|
|
123
123
|
// clip against each side of the clip rectangle
|
|
124
124
|
for (let edge = 1; edge <= 8; edge *= 2) {
|
|
@@ -163,7 +163,7 @@ export function intersect(
|
|
|
163
163
|
// Forces out[snapI] to be on the bbox edge
|
|
164
164
|
// Interpolation introduces precision issue which may cause lineclip to be
|
|
165
165
|
// stuck in an infinite loop
|
|
166
|
-
let snap;
|
|
166
|
+
let snap: number;
|
|
167
167
|
if (edge & 8) {
|
|
168
168
|
// top
|
|
169
169
|
t = (bbox[3] - a[1]) / (b[1] - a[1]);
|
package/src/polygon-utils.ts
CHANGED
|
@@ -132,7 +132,10 @@ export function forEachSegmentInPolygon(
|
|
|
132
132
|
}
|
|
133
133
|
}
|
|
134
134
|
|
|
135
|
-
function reversePolygon(
|
|
135
|
+
function reversePolygon(
|
|
136
|
+
points: NumericArray,
|
|
137
|
+
options: {start?: number; end?: number; size?: number}
|
|
138
|
+
): void {
|
|
136
139
|
const {start = 0, end = points.length, size = 2} = options;
|
|
137
140
|
|
|
138
141
|
const numPoints = (end - start) / size;
|
package/src/polygon.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
/* eslint-disable no-undef, no-console */
|
|
2
2
|
import {isArray} from '@math.gl/core';
|
|
3
3
|
import type {SegmentVisitorPoints} from './polygon-utils';
|
|
4
|
+
import type {NumericArray} from '@math.gl/core';
|
|
4
5
|
|
|
5
6
|
import {
|
|
6
7
|
getPolygonSignedArea,
|
|
@@ -19,11 +20,11 @@ export type PolygonOptions = {
|
|
|
19
20
|
};
|
|
20
21
|
|
|
21
22
|
export default class Polygon {
|
|
22
|
-
points
|
|
23
|
+
points: NumericArray | number[][];
|
|
23
24
|
isFlatArray: boolean;
|
|
24
25
|
options: PolygonOptions;
|
|
25
26
|
|
|
26
|
-
constructor(points
|
|
27
|
+
constructor(points: NumericArray | number[][], options: PolygonOptions = {}) {
|
|
27
28
|
this.points = points;
|
|
28
29
|
this.isFlatArray = !isArray(points[0]);
|
|
29
30
|
|
|
@@ -42,9 +43,9 @@ export default class Polygon {
|
|
|
42
43
|
* @returns Signed area of the polygon.
|
|
43
44
|
*/
|
|
44
45
|
getSignedArea(): number {
|
|
45
|
-
if (this.isFlatArray) return getPolygonSignedArea(this.points, this.options);
|
|
46
|
+
if (this.isFlatArray) return getPolygonSignedArea(this.points as NumericArray, this.options);
|
|
46
47
|
|
|
47
|
-
return getPolygonSignedAreaPoints(this.points, this.options);
|
|
48
|
+
return getPolygonSignedAreaPoints(this.points as number[][], this.options);
|
|
48
49
|
}
|
|
49
50
|
|
|
50
51
|
/**
|
|
@@ -70,7 +71,7 @@ export default class Polygon {
|
|
|
70
71
|
forEachSegment(visitor: SegmentVisitorPoints): void {
|
|
71
72
|
if (this.isFlatArray) {
|
|
72
73
|
forEachSegmentInPolygon(
|
|
73
|
-
this.points,
|
|
74
|
+
this.points as NumericArray,
|
|
74
75
|
// eslint-disable-next-line max-params
|
|
75
76
|
(x1, y1, x2, y2, i1, i2) => {
|
|
76
77
|
// TODO @igorDykhta original visitor uses arrays for each point, but with flat arrays performance degrades if we allocate points for each segment
|
|
@@ -79,7 +80,7 @@ export default class Polygon {
|
|
|
79
80
|
this.options
|
|
80
81
|
);
|
|
81
82
|
} else {
|
|
82
|
-
forEachSegmentInPolygonPoints(this.points, visitor, this.options);
|
|
83
|
+
forEachSegmentInPolygonPoints(this.points as number[][], visitor, this.options);
|
|
83
84
|
}
|
|
84
85
|
}
|
|
85
86
|
|
|
@@ -90,8 +91,8 @@ export default class Polygon {
|
|
|
90
91
|
*/
|
|
91
92
|
modifyWindingDirection(direction: number): boolean {
|
|
92
93
|
if (this.isFlatArray) {
|
|
93
|
-
return modifyPolygonWindingDirection(this.points, direction, this.options);
|
|
94
|
+
return modifyPolygonWindingDirection(this.points as NumericArray, direction, this.options);
|
|
94
95
|
}
|
|
95
|
-
return modifyPolygonWindingDirectionPoints(this.points, direction, this.options);
|
|
96
|
+
return modifyPolygonWindingDirectionPoints(this.points as number[][], direction, this.options);
|
|
96
97
|
}
|
|
97
98
|
}
|
package/src/utils.ts
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
|
|
1
|
+
import type {NumericArray} from '@math.gl/core';
|
|
2
|
+
|
|
3
|
+
export function push(target: number[], source: number[]): boolean {
|
|
2
4
|
const size = source.length;
|
|
3
5
|
const startIndex = target.length;
|
|
4
6
|
|
|
@@ -22,14 +24,20 @@ export function push(target, source) {
|
|
|
22
24
|
return true;
|
|
23
25
|
}
|
|
24
26
|
|
|
25
|
-
export function copy(target, source) {
|
|
27
|
+
export function copy(target: number[], source: Readonly<NumericArray>): void {
|
|
26
28
|
const size = source.length;
|
|
27
29
|
for (let i = 0; i < size; i++) {
|
|
28
30
|
target[i] = source[i];
|
|
29
31
|
}
|
|
30
32
|
}
|
|
31
33
|
|
|
32
|
-
export function getPointAtIndex(
|
|
34
|
+
export function getPointAtIndex(
|
|
35
|
+
positions: NumericArray,
|
|
36
|
+
index: number,
|
|
37
|
+
size: number,
|
|
38
|
+
offset: number,
|
|
39
|
+
out: number[] = []
|
|
40
|
+
): number[] {
|
|
33
41
|
const startI = offset + index * size;
|
|
34
42
|
for (let i = 0; i < size; i++) {
|
|
35
43
|
out[i] = positions[startI + i];
|