dgeoutils 2.2.22 → 2.3.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/README.md +5 -0
- package/dist/{DCircle.d.ts → cjs/DCircle.d.ts} +0 -0
- package/dist/cjs/DCircle.js +102 -0
- package/dist/{DLine.d.ts → cjs/DLine.d.ts} +0 -0
- package/dist/cjs/DLine.js +300 -0
- package/dist/{DNumbers.d.ts → cjs/DNumbers.d.ts} +0 -0
- package/dist/cjs/DNumbers.js +30 -0
- package/dist/{DPlane.d.ts → cjs/DPlane.d.ts} +0 -0
- package/dist/cjs/DPlane.js +132 -0
- package/dist/{DPoint.d.ts → cjs/DPoint.d.ts} +0 -0
- package/dist/cjs/DPoint.js +574 -0
- package/dist/{DPolygon.d.ts → cjs/DPolygon.d.ts} +10 -0
- package/dist/cjs/DPolygon.js +1555 -0
- package/dist/{DPolygonLoop.d.ts → cjs/DPolygonLoop.d.ts} +0 -0
- package/dist/cjs/DPolygonLoop.js +401 -0
- package/dist/{FastSearch.d.ts → cjs/FastSearch.d.ts} +0 -0
- package/dist/cjs/FastSearch.js +53 -0
- package/dist/{TraceMatrix.d.ts → cjs/TraceMatrix.d.ts} +0 -0
- package/dist/cjs/TraceMatrix.js +256 -0
- package/dist/{index.d.ts → cjs/index.d.ts} +0 -0
- package/dist/{index.js → cjs/index.js} +0 -0
- package/dist/{utils.d.ts → cjs/utils.d.ts} +1 -1
- package/dist/cjs/utils.js +191 -0
- package/dist/{DCircle.js → es2015/DCircle.js} +14 -18
- package/dist/{DLine.js → es2015/DLine.js} +24 -28
- package/dist/es2015/DNumbers.js +22 -0
- package/dist/{DPlane.js → es2015/DPlane.js} +22 -26
- package/dist/{DPoint.js → es2015/DPoint.js} +52 -56
- package/dist/{DPolygon.js → es2015/DPolygon.js} +102 -100
- package/dist/{DPolygonLoop.js → es2015/DPolygonLoop.js} +1 -5
- package/dist/{FastSearch.js → es2015/FastSearch.js} +1 -5
- package/dist/{TraceMatrix.js → es2015/TraceMatrix.js} +35 -39
- package/dist/es2015/index.js +13 -0
- package/dist/{utils.js → es2015/utils.js} +26 -36
- package/dist/esm/DCircle.js +99 -0
- package/dist/esm/DLine.js +297 -0
- package/dist/esm/DNumbers.js +27 -0
- package/dist/esm/DPlane.js +129 -0
- package/dist/esm/DPoint.js +571 -0
- package/dist/esm/DPolygon.js +1552 -0
- package/dist/esm/DPolygonLoop.js +398 -0
- package/dist/esm/FastSearch.js +50 -0
- package/dist/esm/TraceMatrix.js +253 -0
- package/dist/esm/index.js +13 -0
- package/dist/esm/utils.js +181 -0
- package/dist/umd/dgeoutils.js +3569 -0
- package/dist/umd/dgeoutils.min.js +1 -0
- package/dist/umd/dgeoutils.min.js.map +1 -0
- package/package.json +17 -10
- package/dist/DNumbers.js +0 -26
|
@@ -1,15 +1,12 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
const
|
|
9
|
-
const
|
|
10
|
-
const utils_1 = require("./utils");
|
|
11
|
-
const { buffer: { BufferParameters: { CAP_ROUND, CAP_FLAT, CAP_SQUARE } } } = jsts_1.operation;
|
|
12
|
-
exports.MIN_POINTS_IN_VALID_POLYGON = 3;
|
|
1
|
+
import { DPoint } from './DPoint';
|
|
2
|
+
import { DLine } from './DLine';
|
|
3
|
+
import { DCircle } from './DCircle';
|
|
4
|
+
import { DNumbers } from './DNumbers';
|
|
5
|
+
import { io as jstsIo, operation } from 'jsts';
|
|
6
|
+
import { DPolygonLoop } from './DPolygonLoop';
|
|
7
|
+
import { isDefAndNotNull } from './utils';
|
|
8
|
+
const { buffer: { BufferParameters: { CAP_ROUND, CAP_FLAT, CAP_SQUARE } } } = operation;
|
|
9
|
+
export const MIN_POINTS_IN_VALID_POLYGON = 3;
|
|
13
10
|
const APPROXIMATION_VALUE = 0.1;
|
|
14
11
|
const MAX_CONVEX_ITERATIONS = 100;
|
|
15
12
|
const CLOSE_TO_INTERSECTION_DISTANCE = 0.001;
|
|
@@ -18,21 +15,16 @@ const containCalculator = (poly, p) => {
|
|
|
18
15
|
if (hasSamePoint) {
|
|
19
16
|
return true;
|
|
20
17
|
}
|
|
21
|
-
for (
|
|
22
|
-
const p0 = poly.at(i);
|
|
23
|
-
const p1 = poly.at(i + 1);
|
|
24
|
-
const polygonLine = p0.findLine(p1);
|
|
18
|
+
for (const [, , polygonLine] of poly.loopPointsGenerator(true)()) {
|
|
25
19
|
const onBorder = polygonLine.x(p).equal(p) && polygonLine.inRange(p);
|
|
26
20
|
if (onBorder) {
|
|
27
21
|
return true;
|
|
28
22
|
}
|
|
29
23
|
}
|
|
30
24
|
let totalFi = 0;
|
|
31
|
-
for (
|
|
32
|
-
const
|
|
33
|
-
const
|
|
34
|
-
const line1 = new DLine_1.DLine(p1.x - p.x, p1.y - p.y, 0);
|
|
35
|
-
const line2 = new DLine_1.DLine(p2.x - p.x, p2.y - p.y, 0);
|
|
25
|
+
for (const [{ x, y }, { x: a, y: b }] of poly.loopPointsGenerator()()) {
|
|
26
|
+
const line1 = new DLine(x - p.x, y - p.y, 0);
|
|
27
|
+
const line2 = new DLine(a - p.x, b - p.y, 0);
|
|
36
28
|
const fiDif = line1.findFi(line2);
|
|
37
29
|
if (line1.vectorProduct(line2).c > 0) {
|
|
38
30
|
totalFi += fiDif;
|
|
@@ -55,7 +47,7 @@ const containCalculator = (poly, p) => {
|
|
|
55
47
|
}
|
|
56
48
|
return result;
|
|
57
49
|
};
|
|
58
|
-
class DPolygon {
|
|
50
|
+
export class DPolygon {
|
|
59
51
|
constructor(pPoints = []) {
|
|
60
52
|
this.pPoints = pPoints;
|
|
61
53
|
this.properties = {};
|
|
@@ -63,7 +55,7 @@ class DPolygon {
|
|
|
63
55
|
this.searchStore = {};
|
|
64
56
|
}
|
|
65
57
|
static arrayOfTrianglesToVertices(triangles, height) {
|
|
66
|
-
return triangles.map((v) => (
|
|
58
|
+
return triangles.map((v) => (isDefAndNotNull(height) ? v
|
|
67
59
|
.loop()
|
|
68
60
|
.height(height)
|
|
69
61
|
.run() : v)
|
|
@@ -72,7 +64,7 @@ class DPolygon {
|
|
|
72
64
|
}
|
|
73
65
|
static minAreaRectangleSize(poly) {
|
|
74
66
|
const { first, second, last } = poly.clone().open();
|
|
75
|
-
return new
|
|
67
|
+
return new DPoint(first.distance(second), first.distance(last));
|
|
76
68
|
}
|
|
77
69
|
static toDash(poly) {
|
|
78
70
|
let p = new DPolygon();
|
|
@@ -112,7 +104,7 @@ class DPolygon {
|
|
|
112
104
|
const [path, ...holes] = reg.groups.data
|
|
113
105
|
.split('), (')
|
|
114
106
|
.map((p) => new DPolygon(p.split(', ')
|
|
115
|
-
.map((pares) =>
|
|
107
|
+
.map((pares) => DPoint.parse(pares.split(' ').map(Number)))));
|
|
116
108
|
if (holes && holes.length) {
|
|
117
109
|
path.holes = holes;
|
|
118
110
|
}
|
|
@@ -122,18 +114,18 @@ class DPolygon {
|
|
|
122
114
|
const regexp = /LINESTRING \((?<data>(?:(?!\)$).)*?)\)$/miu;
|
|
123
115
|
const reg = regexp.exec(data);
|
|
124
116
|
res = new DPolygon(reg.groups.data
|
|
125
|
-
.split(', ').map((t) =>
|
|
117
|
+
.split(', ').map((t) => DPoint.parse(t.split(' ').map(Number))));
|
|
126
118
|
}
|
|
127
119
|
if (data.indexOf('POINT') === 0) {
|
|
128
|
-
res = new DPolygon([
|
|
120
|
+
res = new DPolygon([DPoint.parseFromWKT(data)]);
|
|
129
121
|
}
|
|
130
122
|
return res;
|
|
131
123
|
}
|
|
132
124
|
static createSquareBySize(size) {
|
|
133
|
-
return new DPolygon([
|
|
125
|
+
return new DPolygon([DPoint.zero(), size.clone().setX(0), size.clone(), size.clone().setY(0)]).close();
|
|
134
126
|
}
|
|
135
127
|
loop() {
|
|
136
|
-
return new
|
|
128
|
+
return new DPolygonLoop(this);
|
|
137
129
|
}
|
|
138
130
|
set points(p) {
|
|
139
131
|
this.pPoints = p;
|
|
@@ -142,16 +134,16 @@ class DPolygon {
|
|
|
142
134
|
return this.pPoints;
|
|
143
135
|
}
|
|
144
136
|
get maxX() {
|
|
145
|
-
return this.
|
|
137
|
+
return this.reduce((a, r) => Math.max(a, r.x), -Infinity);
|
|
146
138
|
}
|
|
147
139
|
get minX() {
|
|
148
|
-
return this.
|
|
140
|
+
return this.reduce((a, r) => Math.min(a, r.x), Infinity);
|
|
149
141
|
}
|
|
150
142
|
get maxY() {
|
|
151
|
-
return this.
|
|
143
|
+
return this.reduce((a, r) => Math.max(a, r.y), -Infinity);
|
|
152
144
|
}
|
|
153
145
|
get minY() {
|
|
154
|
-
return this.
|
|
146
|
+
return this.reduce((a, r) => Math.min(a, r.y), Infinity);
|
|
155
147
|
}
|
|
156
148
|
get center() {
|
|
157
149
|
return this.leftTop.move(this.size.divide(2));
|
|
@@ -171,24 +163,24 @@ class DPolygon {
|
|
|
171
163
|
get extend() {
|
|
172
164
|
const { minX, minY, maxX, maxY } = this;
|
|
173
165
|
return new DPolygon([
|
|
174
|
-
new
|
|
175
|
-
new
|
|
176
|
-
new
|
|
177
|
-
new
|
|
178
|
-
new
|
|
166
|
+
new DPoint(minX, minY),
|
|
167
|
+
new DPoint(maxX, minY),
|
|
168
|
+
new DPoint(maxX, maxY),
|
|
169
|
+
new DPoint(minX, maxY),
|
|
170
|
+
new DPoint(minX, minY)
|
|
179
171
|
]);
|
|
180
172
|
}
|
|
181
173
|
get size() {
|
|
182
174
|
const { w, h } = this;
|
|
183
|
-
return new
|
|
175
|
+
return new DPoint(w, h);
|
|
184
176
|
}
|
|
185
177
|
get leftTop() {
|
|
186
178
|
const { minX, minY } = this;
|
|
187
|
-
return new
|
|
179
|
+
return new DPoint(minX, minY);
|
|
188
180
|
}
|
|
189
181
|
get rightBottom() {
|
|
190
182
|
const { maxX, maxY } = this;
|
|
191
|
-
return new
|
|
183
|
+
return new DPoint(maxX, maxY);
|
|
192
184
|
}
|
|
193
185
|
get length() {
|
|
194
186
|
return this.pPoints.length;
|
|
@@ -198,18 +190,15 @@ class DPolygon {
|
|
|
198
190
|
}
|
|
199
191
|
get perimeter() {
|
|
200
192
|
let p = 0;
|
|
201
|
-
for (
|
|
202
|
-
p +=
|
|
193
|
+
for (const [p1, p2] of this.loopPointsGenerator()()) {
|
|
194
|
+
p += p1.distance(p2);
|
|
203
195
|
}
|
|
204
196
|
return p;
|
|
205
197
|
}
|
|
206
198
|
get area() {
|
|
207
|
-
const closed = this.deintersection;
|
|
208
199
|
let sum = 0;
|
|
209
|
-
for (
|
|
210
|
-
|
|
211
|
-
const prev = closed.at(i - 1);
|
|
212
|
-
sum += prev.x * cur.y - prev.y * cur.x;
|
|
200
|
+
for (const [{ x, y }, { x: a, y: b }] of this.deintersection.loopPointsGenerator()()) {
|
|
201
|
+
sum += x * b - y * a;
|
|
213
202
|
}
|
|
214
203
|
return Math.abs(sum / 2) - this.holes.reduce((a, hole) => a + hole.area, 0);
|
|
215
204
|
}
|
|
@@ -241,8 +230,7 @@ class DPolygon {
|
|
|
241
230
|
const d = record[j] - record[j - 1];
|
|
242
231
|
if (d > 1) {
|
|
243
232
|
const part = new DPolygon(origin.removePart(record[j - 1], d));
|
|
244
|
-
const allInside = part.
|
|
245
|
-
.reduce((a, e) => a && containCalculator(origin, e), true);
|
|
233
|
+
const allInside = part.reduce((a, e) => a && containCalculator(origin, e), true);
|
|
246
234
|
if (allInside && origin.isClockwise === part.isClockwise) {
|
|
247
235
|
origin.insertAfter(record[j - 1] - 1, ...part.reverse().points);
|
|
248
236
|
p = origin;
|
|
@@ -254,7 +242,7 @@ class DPolygon {
|
|
|
254
242
|
return p;
|
|
255
243
|
}
|
|
256
244
|
get valid() {
|
|
257
|
-
return this.length >
|
|
245
|
+
return this.length > MIN_POINTS_IN_VALID_POLYGON;
|
|
258
246
|
}
|
|
259
247
|
get first() {
|
|
260
248
|
return this.at(0);
|
|
@@ -269,19 +257,18 @@ class DPolygon {
|
|
|
269
257
|
const p = this.convex;
|
|
270
258
|
let resultPolygon = new DPolygon();
|
|
271
259
|
let resultArea = Infinity;
|
|
272
|
-
for (
|
|
273
|
-
const l = p.at(k).findLine(p.at(k + 1));
|
|
260
|
+
for (const [, , l] of p.loopPointsGenerator(true)()) {
|
|
274
261
|
let maxWidth = 0;
|
|
275
262
|
let maxWidthPoint1 = null;
|
|
276
263
|
let maxWidthPoint2 = null;
|
|
277
264
|
let maxHeight = 0;
|
|
278
265
|
let maxHeightPoint = null;
|
|
279
|
-
for (
|
|
280
|
-
const p1 = l.findPoint(l.findPerpendicular(
|
|
281
|
-
const h = p1.distance(
|
|
266
|
+
for (const [z, , , i] of p.loopPointsGenerator()()) {
|
|
267
|
+
const p1 = l.findPoint(l.findPerpendicular(z));
|
|
268
|
+
const h = p1.distance(z);
|
|
282
269
|
if (h >= maxHeight) {
|
|
283
270
|
maxHeight = h;
|
|
284
|
-
maxHeightPoint =
|
|
271
|
+
maxHeightPoint = z;
|
|
285
272
|
}
|
|
286
273
|
for (let j = i; j < p.length - 1; j++) {
|
|
287
274
|
const p2 = l.findPoint(l.findPerpendicular(p.at(j)));
|
|
@@ -324,7 +311,7 @@ class DPolygon {
|
|
|
324
311
|
const p2 = p.first;
|
|
325
312
|
const p3 = p.second;
|
|
326
313
|
const d = p2.findInnerAngle(p1, p3);
|
|
327
|
-
if (d > Math.PI ||
|
|
314
|
+
if (d > Math.PI || DNumbers.likeZero(DNumbers.rad2Deg(d)) || DNumbers.likePI(d) || DNumbers.like2PI(d)) {
|
|
328
315
|
p.removePart(-1, 1);
|
|
329
316
|
}
|
|
330
317
|
else {
|
|
@@ -341,7 +328,7 @@ class DPolygon {
|
|
|
341
328
|
const p2 = p.at(i);
|
|
342
329
|
const p3 = p.at(i + 1);
|
|
343
330
|
const d = p2.findInnerAngle(p1, p3);
|
|
344
|
-
if (d > Math.PI ||
|
|
331
|
+
if (d > Math.PI || DNumbers.likeZero(DNumbers.rad2Deg(d)) || DNumbers.likePI(d) || DNumbers.like2PI(d)) {
|
|
345
332
|
p.removePart(--i, 1);
|
|
346
333
|
}
|
|
347
334
|
}
|
|
@@ -354,11 +341,9 @@ class DPolygon {
|
|
|
354
341
|
}
|
|
355
342
|
get isClockwise() {
|
|
356
343
|
let sum = 0;
|
|
357
|
-
const
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
const p2 = p.at(i);
|
|
361
|
-
sum += (p2.x - p1.x) * (p2.y + p1.y);
|
|
344
|
+
for (const [{ x, y }, { x: a, y: b }] of this.clone().close()
|
|
345
|
+
.loopPointsGenerator()()) {
|
|
346
|
+
sum += (a - x) * (b + y);
|
|
362
347
|
}
|
|
363
348
|
return sum < 0;
|
|
364
349
|
}
|
|
@@ -373,12 +358,12 @@ class DPolygon {
|
|
|
373
358
|
res.holes = [];
|
|
374
359
|
return res;
|
|
375
360
|
}
|
|
361
|
+
reduce(f, v) {
|
|
362
|
+
return this.pPoints.reduce(f, v);
|
|
363
|
+
}
|
|
376
364
|
intersection(l, includeOnly = false) {
|
|
377
365
|
const res = [];
|
|
378
|
-
for (
|
|
379
|
-
const p1 = this.pPoints[i];
|
|
380
|
-
const p2 = this.pPoints[i + 1];
|
|
381
|
-
const line = p1.findLine(p2);
|
|
366
|
+
for (const [, , line] of this.loopPointsGenerator(true)()) {
|
|
382
367
|
const intersect = line.intersection(l, 0, includeOnly);
|
|
383
368
|
if (intersect) {
|
|
384
369
|
res.push(intersect);
|
|
@@ -398,10 +383,10 @@ class DPolygon {
|
|
|
398
383
|
h = `, ${this.holes.map((hole) => hole.toString())
|
|
399
384
|
.join(', ')}`;
|
|
400
385
|
}
|
|
401
|
-
return `POLYGON ((${this.deintersection.
|
|
386
|
+
return `POLYGON ((${this.deintersection.mapArray((r) => `${r.x} ${r.y}${withZ ? ` ${r.z}` : ''}`)
|
|
402
387
|
.join(', ')})${h})`;
|
|
403
388
|
}
|
|
404
|
-
return `LINESTRING (${this.
|
|
389
|
+
return `LINESTRING (${this.mapArray((r) => `${r.x} ${r.y}${withZ ? ` ${r.z}` : ''}`)
|
|
405
390
|
.join(', ')})`;
|
|
406
391
|
}
|
|
407
392
|
filter(f) {
|
|
@@ -409,10 +394,13 @@ class DPolygon {
|
|
|
409
394
|
return this;
|
|
410
395
|
}
|
|
411
396
|
map(f) {
|
|
412
|
-
this.pPoints = this.
|
|
397
|
+
this.pPoints = this.mapArray(f);
|
|
413
398
|
this.holes = this.holes.map((h) => h.map(f));
|
|
414
399
|
return this;
|
|
415
400
|
}
|
|
401
|
+
mapArray(f) {
|
|
402
|
+
return this.pPoints.map(f);
|
|
403
|
+
}
|
|
416
404
|
sort(f) {
|
|
417
405
|
this.points.sort(f);
|
|
418
406
|
return this;
|
|
@@ -443,7 +431,7 @@ class DPolygon {
|
|
|
443
431
|
.reduce((a, h) => a + h.getValue(), ''));
|
|
444
432
|
}
|
|
445
433
|
toString() {
|
|
446
|
-
return `(${this.
|
|
434
|
+
return `(${this.mapArray((r) => r.toString()).join(', ')})`;
|
|
447
435
|
}
|
|
448
436
|
close() {
|
|
449
437
|
const p0 = this.first;
|
|
@@ -497,8 +485,11 @@ class DPolygon {
|
|
|
497
485
|
}
|
|
498
486
|
return false;
|
|
499
487
|
}
|
|
500
|
-
findIndex(
|
|
501
|
-
|
|
488
|
+
findIndex(a) {
|
|
489
|
+
if (a instanceof DPoint) {
|
|
490
|
+
return this.points.findIndex((t) => t.equal(a));
|
|
491
|
+
}
|
|
492
|
+
return this.points.findIndex(a);
|
|
502
493
|
}
|
|
503
494
|
approximation(e = Math.sqrt(this.perimeter) * APPROXIMATION_VALUE) {
|
|
504
495
|
return new DPolygon(this.clone().douglasPeucker(this.pPoints, e));
|
|
@@ -572,11 +563,9 @@ class DPolygon {
|
|
|
572
563
|
}
|
|
573
564
|
const poly = this.deintersection;
|
|
574
565
|
let totalFi = 0;
|
|
575
|
-
for (
|
|
576
|
-
const
|
|
577
|
-
const
|
|
578
|
-
const line1 = new DLine_1.DLine(p1.x - p.x, p1.y - p.y, 0);
|
|
579
|
-
const line2 = new DLine_1.DLine(p2.x - p.x, p2.y - p.y, 0);
|
|
566
|
+
for (const [{ x, y }, { x: a, y: b }] of poly.loopPointsGenerator()()) {
|
|
567
|
+
const line1 = new DLine(x - p.x, y - p.y, 0);
|
|
568
|
+
const line2 = new DLine(a - p.x, b - p.y, 0);
|
|
580
569
|
const fiDif = line1.findFi(line2);
|
|
581
570
|
if (line1.vectorProduct(line2).c > 0) {
|
|
582
571
|
totalFi += fiDif;
|
|
@@ -603,10 +592,7 @@ class DPolygon {
|
|
|
603
592
|
if (hasSamePoint) {
|
|
604
593
|
return true;
|
|
605
594
|
}
|
|
606
|
-
for (
|
|
607
|
-
const p0 = poly.at(i);
|
|
608
|
-
const p1 = poly.at(i + 1);
|
|
609
|
-
const polygonLine = p0.findLine(p1);
|
|
595
|
+
for (const [, , polygonLine] of poly.loopPointsGenerator(true)()) {
|
|
610
596
|
const onBorder = polygonLine.x(p).equal(p) && polygonLine.inRange(p);
|
|
611
597
|
if (onBorder) {
|
|
612
598
|
return true;
|
|
@@ -633,30 +619,28 @@ class DPolygon {
|
|
|
633
619
|
return this;
|
|
634
620
|
}
|
|
635
621
|
static parse(a) {
|
|
636
|
-
return new DPolygon(a.map((r) =>
|
|
622
|
+
return new DPolygon(a.map((r) => DPoint.parse(r)));
|
|
637
623
|
}
|
|
638
624
|
toArrayOfCoords() {
|
|
639
|
-
return this.
|
|
625
|
+
return this.mapArray((r) => r.toCoords());
|
|
640
626
|
}
|
|
641
627
|
divideToPieces(piecesCount) {
|
|
642
628
|
const { fullLength } = this;
|
|
643
629
|
const pieceLength = fullLength / piecesCount;
|
|
644
630
|
let currentPieceLength = pieceLength;
|
|
645
|
-
for (
|
|
646
|
-
const p1 = this.at(i - 1);
|
|
647
|
-
const p2 = this.at(i);
|
|
631
|
+
for (const [p1, p2, , i] of this.loopPointsGenerator()()) {
|
|
648
632
|
const d = p1.distance(p2);
|
|
649
633
|
if (d === currentPieceLength) {
|
|
650
634
|
p2.properties.pieceBorder = true;
|
|
651
635
|
currentPieceLength = pieceLength;
|
|
652
636
|
}
|
|
653
637
|
else if (d - currentPieceLength > 0) {
|
|
654
|
-
const circle = new
|
|
638
|
+
const circle = new DCircle(p1, currentPieceLength);
|
|
655
639
|
const line = p1.findLine(p2);
|
|
656
640
|
const intersectionPoint = line.intersectionWithCircle(circle)
|
|
657
641
|
.filter((p) => line.inRange(p, CLOSE_TO_INTERSECTION_DISTANCE))[0];
|
|
658
642
|
intersectionPoint.properties.pieceBorder = true;
|
|
659
|
-
this.insertAfter(i
|
|
643
|
+
this.insertAfter(i, intersectionPoint);
|
|
660
644
|
currentPieceLength = pieceLength;
|
|
661
645
|
}
|
|
662
646
|
else {
|
|
@@ -863,13 +847,24 @@ class DPolygon {
|
|
|
863
847
|
return this.first.equal(this.last);
|
|
864
848
|
}
|
|
865
849
|
buffer(v, quadrantSegments = 64, type = DPolygon.CAP_ROUND) {
|
|
866
|
-
const reader = new
|
|
850
|
+
const reader = new jstsIo.WKTReader();
|
|
867
851
|
const { noHoles, closed } = this;
|
|
868
852
|
const points = reader
|
|
869
853
|
.read(noHoles.toWKT(closed ? DPolygon.WKT_POLYGON : DPolygon.WKT_LINESTRING))
|
|
870
854
|
.buffer(v, quadrantSegments, type)
|
|
871
855
|
.getCoordinates();
|
|
872
|
-
return new DPolygon(points.map(({ x, y }) => new
|
|
856
|
+
return new DPolygon(points.map(({ x, y }) => new DPoint(x, y)));
|
|
857
|
+
}
|
|
858
|
+
sideBuffers(v, quadrantSegments = 64) {
|
|
859
|
+
const { first, last } = this;
|
|
860
|
+
const buffer = this.buffer(v, quadrantSegments, DPolygon.CAP_FLAT).open();
|
|
861
|
+
const [start0, start1] = first.sortByDistance(buffer).points.map((r) => r.properties.index);
|
|
862
|
+
const [end0, end1] = last.sortByDistance(buffer).points.map((r) => r.properties.index);
|
|
863
|
+
const fromPoint = Math.min(Math.max(start0, start1), Math.max(end0, end1));
|
|
864
|
+
const toPoint = Math.max(Math.min(start0, start1), Math.min(end0, end1));
|
|
865
|
+
const linePart = new DPolygon(buffer.removePart(fromPoint - 1, toPoint - fromPoint + 1));
|
|
866
|
+
buffer.unshift(buffer.pop());
|
|
867
|
+
return [linePart, buffer];
|
|
873
868
|
}
|
|
874
869
|
bezier(step = 0.1) {
|
|
875
870
|
const res = new DPolygon();
|
|
@@ -892,13 +887,21 @@ class DPolygon {
|
|
|
892
887
|
.run();
|
|
893
888
|
return this;
|
|
894
889
|
}
|
|
890
|
+
loopPointsGenerator(withLine = false) {
|
|
891
|
+
const that = this;
|
|
892
|
+
return function* () {
|
|
893
|
+
for (let i = 0; i < that.length - 1; i++) {
|
|
894
|
+
const p1 = that.at(i);
|
|
895
|
+
const p2 = that.at(i + 1);
|
|
896
|
+
yield [p1, p2, withLine ? p1.findLine(p2) : undefined, i];
|
|
897
|
+
}
|
|
898
|
+
};
|
|
899
|
+
}
|
|
895
900
|
getBezierPoint(v) {
|
|
896
901
|
if (this.length === 1) {
|
|
897
902
|
return this.first;
|
|
898
903
|
}
|
|
899
|
-
for (
|
|
900
|
-
const p1 = this.at(i);
|
|
901
|
-
const p2 = this.at(i + 1);
|
|
904
|
+
for (const [p1, p2] of this.loopPointsGenerator()()) {
|
|
902
905
|
p1.move(p2.clone().move(p1.clone().minus())
|
|
903
906
|
.scale(v));
|
|
904
907
|
}
|
|
@@ -943,7 +946,7 @@ class DPolygon {
|
|
|
943
946
|
}
|
|
944
947
|
getJSTSGeometry(p, unionThis, unionThat) {
|
|
945
948
|
const unionOrIntersection = unionThat === unionThis;
|
|
946
|
-
const reader = new
|
|
949
|
+
const reader = new jstsIo.WKTReader();
|
|
947
950
|
const a = reader.read(this.noHoles.toWKT());
|
|
948
951
|
const b = reader.read(p.noHoles.toWKT());
|
|
949
952
|
if (!unionOrIntersection) {
|
|
@@ -964,11 +967,11 @@ class DPolygon {
|
|
|
964
967
|
if (coordinates.length) {
|
|
965
968
|
let result = coordinates.reduce((ak, { x, y }, index) => {
|
|
966
969
|
const lastIndex = ak.length - 1;
|
|
967
|
-
const t = new
|
|
970
|
+
const t = new DPoint(x, y);
|
|
968
971
|
const { first } = ak[lastIndex];
|
|
969
972
|
if (t.equal(first)) {
|
|
970
973
|
if (coordinates[index + 1]) {
|
|
971
|
-
const nextPoint = new
|
|
974
|
+
const nextPoint = new DPoint(coordinates[index + 1].x, coordinates[index + 1].y);
|
|
972
975
|
if (ak[lastIndex].length > 1) {
|
|
973
976
|
ak.push(new DPolygon([nextPoint]));
|
|
974
977
|
}
|
|
@@ -978,7 +981,7 @@ class DPolygon {
|
|
|
978
981
|
ak[lastIndex].push(t);
|
|
979
982
|
}
|
|
980
983
|
return ak;
|
|
981
|
-
}, [new DPolygon([new
|
|
984
|
+
}, [new DPolygon([new DPoint(coordinates[0].x, coordinates[0].y)])]);
|
|
982
985
|
if (unionThat && unionThis && result.length > 1) {
|
|
983
986
|
for (const q of result) {
|
|
984
987
|
for (const r of result) {
|
|
@@ -1026,7 +1029,6 @@ class DPolygon {
|
|
|
1026
1029
|
return null;
|
|
1027
1030
|
}
|
|
1028
1031
|
}
|
|
1029
|
-
exports.DPolygon = DPolygon;
|
|
1030
1032
|
DPolygon.CAP_ROUND = CAP_ROUND;
|
|
1031
1033
|
DPolygon.CAP_FLAT = CAP_FLAT;
|
|
1032
1034
|
DPolygon.CAP_SQUARE = CAP_SQUARE;
|
|
@@ -1,6 +1,3 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.DPolygonLoop = void 0;
|
|
4
1
|
var LoopFunctions;
|
|
5
2
|
(function (LoopFunctions) {
|
|
6
3
|
LoopFunctions[LoopFunctions["getTileFromCoords"] = 0] = "getTileFromCoords";
|
|
@@ -170,7 +167,7 @@ const decodePoolRecord = (a, { functionName, pointArg, numberPointArg, numberArg
|
|
|
170
167
|
}
|
|
171
168
|
return res;
|
|
172
169
|
};
|
|
173
|
-
class DPolygonLoop {
|
|
170
|
+
export class DPolygonLoop {
|
|
174
171
|
constructor(parent) {
|
|
175
172
|
this.parent = parent;
|
|
176
173
|
this.pool = [];
|
|
@@ -393,4 +390,3 @@ class DPolygonLoop {
|
|
|
393
390
|
return this;
|
|
394
391
|
}
|
|
395
392
|
}
|
|
396
|
-
exports.DPolygonLoop = DPolygonLoop;
|
|
@@ -1,7 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.FastSearch = void 0;
|
|
4
|
-
class FastSearch {
|
|
1
|
+
export class FastSearch {
|
|
5
2
|
constructor() {
|
|
6
3
|
this.searchStore = {};
|
|
7
4
|
}
|
|
@@ -26,4 +23,3 @@ class FastSearch {
|
|
|
26
23
|
return this.searchStore[x][y][z || 'undefined'];
|
|
27
24
|
}
|
|
28
25
|
}
|
|
29
|
-
exports.FastSearch = FastSearch;
|
|
@@ -1,15 +1,12 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
const FastSearch_1 = require("./FastSearch");
|
|
7
|
-
const utils_1 = require("./utils");
|
|
8
|
-
var TraceMatrixValues;
|
|
1
|
+
import { DPoint } from './DPoint';
|
|
2
|
+
import { DPolygon, MIN_POINTS_IN_VALID_POLYGON } from './DPolygon';
|
|
3
|
+
import { FastSearch } from './FastSearch';
|
|
4
|
+
import { createArray } from './utils';
|
|
5
|
+
export var TraceMatrixValues;
|
|
9
6
|
(function (TraceMatrixValues) {
|
|
10
7
|
TraceMatrixValues[TraceMatrixValues["f"] = 0] = "f";
|
|
11
8
|
TraceMatrixValues[TraceMatrixValues["t"] = 1] = "t";
|
|
12
|
-
})(TraceMatrixValues
|
|
9
|
+
})(TraceMatrixValues || (TraceMatrixValues = {}));
|
|
13
10
|
const getByPosition = (m, p, defaultValue = TraceMatrixValues.f) => {
|
|
14
11
|
if (m[p.y] === undefined || m[p.y][p.x] === undefined) {
|
|
15
12
|
return defaultValue;
|
|
@@ -23,11 +20,11 @@ const setByPosition = (m, p, value) => {
|
|
|
23
20
|
m[p.y][p.x] = value;
|
|
24
21
|
return m[p.y][p.x];
|
|
25
22
|
};
|
|
26
|
-
class TraceMatrix {
|
|
23
|
+
export class TraceMatrix {
|
|
27
24
|
constructor(size, f) {
|
|
28
25
|
this.size = size;
|
|
29
26
|
this.findGroupByIndex = (m, s) => {
|
|
30
|
-
const res = new
|
|
27
|
+
const res = new DPolygon();
|
|
31
28
|
if (s && getByPosition(m, s) === TraceMatrixValues.t) {
|
|
32
29
|
res.push(s);
|
|
33
30
|
let startIndex = 0;
|
|
@@ -37,7 +34,7 @@ class TraceMatrix {
|
|
|
37
34
|
const r = res.at(startIndex);
|
|
38
35
|
for (let i = -1; i < 2; i++) {
|
|
39
36
|
for (let j = -1; j < 2; j++) {
|
|
40
|
-
const t = new
|
|
37
|
+
const t = new DPoint(r.x + i, r.y + j);
|
|
41
38
|
if (getByPosition(marked, t, TraceMatrixValues.t) === TraceMatrixValues.f &&
|
|
42
39
|
getByPosition(m, t, TraceMatrixValues.f) === TraceMatrixValues.t) {
|
|
43
40
|
res.push(t);
|
|
@@ -59,7 +56,7 @@ class TraceMatrix {
|
|
|
59
56
|
const groups = [group];
|
|
60
57
|
let groupSum = group.length;
|
|
61
58
|
let allGroups = [...group.points];
|
|
62
|
-
const fs = new
|
|
59
|
+
const fs = new FastSearch();
|
|
63
60
|
fs.add(allGroups);
|
|
64
61
|
while (groupSum < this.totalCountInMatrix(m)) {
|
|
65
62
|
let mark = this.findMarked(m);
|
|
@@ -76,22 +73,22 @@ class TraceMatrix {
|
|
|
76
73
|
};
|
|
77
74
|
this.traceGroup = (m, group) => {
|
|
78
75
|
const traceDirections = [
|
|
79
|
-
new
|
|
80
|
-
new
|
|
81
|
-
new
|
|
82
|
-
new
|
|
83
|
-
new
|
|
84
|
-
new
|
|
85
|
-
new
|
|
86
|
-
new
|
|
76
|
+
new DPoint(-1, -1),
|
|
77
|
+
new DPoint(-1, 0),
|
|
78
|
+
new DPoint(-1, 1),
|
|
79
|
+
new DPoint(0, 1),
|
|
80
|
+
new DPoint(1, 1),
|
|
81
|
+
new DPoint(1, 0),
|
|
82
|
+
new DPoint(1, -1),
|
|
83
|
+
new DPoint(0, -1)
|
|
87
84
|
];
|
|
88
85
|
const left = (d) => (d + traceDirections.length + 1) % traceDirections.length;
|
|
89
86
|
const right = (d) => (d + traceDirections.length - 1) % traceDirections.length;
|
|
90
87
|
if (group.length < 2) {
|
|
91
88
|
const t = group.at(0).clone();
|
|
92
|
-
return new
|
|
89
|
+
return new DPolygon([t, t, t]);
|
|
93
90
|
}
|
|
94
|
-
const points = new
|
|
91
|
+
const points = new DPolygon();
|
|
95
92
|
let direction = 0;
|
|
96
93
|
let prevDirection = Infinity;
|
|
97
94
|
let p = group.at(0);
|
|
@@ -115,22 +112,22 @@ class TraceMatrix {
|
|
|
115
112
|
};
|
|
116
113
|
this.createHoleMatrix = (group) => {
|
|
117
114
|
const fullTraceDirections = [
|
|
118
|
-
new
|
|
119
|
-
new
|
|
120
|
-
new
|
|
121
|
-
new
|
|
115
|
+
new DPoint(-1, 0),
|
|
116
|
+
new DPoint(0, 1),
|
|
117
|
+
new DPoint(1, 0),
|
|
118
|
+
new DPoint(0, -1)
|
|
122
119
|
];
|
|
123
120
|
group.prepareToFastSearch();
|
|
124
121
|
const tmpMatrix = TraceMatrix
|
|
125
122
|
.createMatrix(this.size, (p) => group.fastHas(p) ? TraceMatrixValues.t : TraceMatrixValues.f);
|
|
126
|
-
const startCoords = new
|
|
123
|
+
const startCoords = new DPolygon();
|
|
127
124
|
for (let i = 0; i < this.size.w; i++) {
|
|
128
|
-
startCoords.push(new
|
|
129
|
-
startCoords.push(new
|
|
125
|
+
startCoords.push(new DPoint(i, -1));
|
|
126
|
+
startCoords.push(new DPoint(i, this.size.h));
|
|
130
127
|
}
|
|
131
128
|
for (let i = 0; i < this.size.h; i++) {
|
|
132
|
-
startCoords.push(new
|
|
133
|
-
startCoords.push(new
|
|
129
|
+
startCoords.push(new DPoint(-1, i));
|
|
130
|
+
startCoords.push(new DPoint(this.size.w, i));
|
|
134
131
|
}
|
|
135
132
|
while (startCoords.length) {
|
|
136
133
|
const point = startCoords.pop();
|
|
@@ -154,7 +151,7 @@ class TraceMatrix {
|
|
|
154
151
|
const holeMatrixs = groups.map(this.createHoleMatrix);
|
|
155
152
|
const holesGroups = holeMatrixs.map((m) => m && this.findAllGroupsInMatrix(m));
|
|
156
153
|
const holesPaths = holesGroups.map((hg, index) => hg && hg.map((g) => this
|
|
157
|
-
.traceGroup(holeMatrixs[index], g)).filter((r) => r.length >
|
|
154
|
+
.traceGroup(holeMatrixs[index], g)).filter((r) => r.length > MIN_POINTS_IN_VALID_POLYGON));
|
|
158
155
|
return groups.map((g, index) => {
|
|
159
156
|
const res = paths[index];
|
|
160
157
|
if (holesGroups[index] && holesGroups[index].length) {
|
|
@@ -177,8 +174,8 @@ class TraceMatrix {
|
|
|
177
174
|
ini = true;
|
|
178
175
|
continue;
|
|
179
176
|
}
|
|
180
|
-
if (getByPosition(m, new
|
|
181
|
-
return new
|
|
177
|
+
if (getByPosition(m, new DPoint(i, j)) === TraceMatrixValues.t) {
|
|
178
|
+
return new DPoint(i, j);
|
|
182
179
|
}
|
|
183
180
|
}
|
|
184
181
|
}
|
|
@@ -189,7 +186,7 @@ class TraceMatrix {
|
|
|
189
186
|
const s = this.size;
|
|
190
187
|
for (let i = 0; i < s.w; i++) {
|
|
191
188
|
for (let j = 0; j < s.h; j++) {
|
|
192
|
-
if (getByPosition(m, new
|
|
189
|
+
if (getByPosition(m, new DPoint(i, j))) {
|
|
193
190
|
res++;
|
|
194
191
|
}
|
|
195
192
|
}
|
|
@@ -197,8 +194,7 @@ class TraceMatrix {
|
|
|
197
194
|
return res;
|
|
198
195
|
}
|
|
199
196
|
static createMatrix(size, f = () => TraceMatrixValues.f) {
|
|
200
|
-
return
|
|
201
|
-
.map((v, i) =>
|
|
197
|
+
return createArray(size.h)
|
|
198
|
+
.map((v, i) => createArray(size.w).map((v2, j) => f(new DPoint(j, i))));
|
|
202
199
|
}
|
|
203
200
|
}
|
|
204
|
-
exports.TraceMatrix = TraceMatrix;
|