@eturnity/eturnity_maths 7.20.0 → 7.24.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.
@@ -1,7 +1,7 @@
1
- import RBush from "rbush";
2
- import Queue from "tinyqueue";
3
- import pointInPolygon from "point-in-polygon";
4
- import { orient2d as orient } from "robust-predicates";
1
+ import RBush from 'rbush'
2
+ import Queue from 'tinyqueue'
3
+ import pointInPolygon from 'point-in-polygon'
4
+ import { orient2d as orient } from 'robust-predicates'
5
5
 
6
6
  /**
7
7
  * Since vite uses native ESM, it doesnt support the syntax of "concaveman" library becuase it still uses commonjs, so we need to convert it to ESM.
@@ -10,60 +10,60 @@ import { orient2d as orient } from "robust-predicates";
10
10
  */
11
11
  export default function concaveman(points, concavity, lengthThreshold) {
12
12
  // a relative measure of concavity; higher value means simpler hull
13
- concavity = Math.max(0, concavity === undefined ? 2 : concavity);
13
+ concavity = Math.max(0, concavity === undefined ? 2 : concavity)
14
14
 
15
15
  // when a segment goes below this length threshold, it won't be drilled down further
16
- lengthThreshold = lengthThreshold || 0;
16
+ lengthThreshold = lengthThreshold || 0
17
17
 
18
18
  // start with a convex hull of the points
19
- var hull = fastConvexHull(points);
19
+ var hull = fastConvexHull(points)
20
20
 
21
21
  // index the points with an R-tree
22
- var tree = new RBush(16);
22
+ var tree = new RBush(16)
23
23
  tree.toBBox = function (a) {
24
24
  return {
25
25
  minX: a[0],
26
26
  minY: a[1],
27
27
  maxX: a[0],
28
- maxY: a[1],
29
- };
30
- };
28
+ maxY: a[1]
29
+ }
30
+ }
31
31
  tree.compareMinX = function (a, b) {
32
- return a[0] - b[0];
33
- };
32
+ return a[0] - b[0]
33
+ }
34
34
  tree.compareMinY = function (a, b) {
35
- return a[1] - b[1];
36
- };
35
+ return a[1] - b[1]
36
+ }
37
37
 
38
- tree.load(points);
38
+ tree.load(points)
39
39
 
40
40
  // turn the convex hull into a linked list and populate the initial edge queue with the nodes
41
- var queue = [];
41
+ var queue = []
42
42
  for (var i = 0, last; i < hull.length; i++) {
43
- var p = hull[i];
44
- tree.remove(p);
45
- last = insertNode(p, last);
46
- queue.push(last);
43
+ var p = hull[i]
44
+ tree.remove(p)
45
+ last = insertNode(p, last)
46
+ queue.push(last)
47
47
  }
48
48
 
49
49
  // index the segments with an R-tree (for intersection checks)
50
- var segTree = new RBush(16);
51
- for (i = 0; i < queue.length; i++) segTree.insert(updateBBox(queue[i]));
50
+ var segTree = new RBush(16)
51
+ for (i = 0; i < queue.length; i++) segTree.insert(updateBBox(queue[i]))
52
52
 
53
- var sqConcavity = concavity * concavity;
54
- var sqLenThreshold = lengthThreshold * lengthThreshold;
53
+ var sqConcavity = concavity * concavity
54
+ var sqLenThreshold = lengthThreshold * lengthThreshold
55
55
 
56
56
  // process edges one by one
57
57
  while (queue.length) {
58
- var node = queue.shift();
59
- var a = node.p;
60
- var b = node.next.p;
58
+ var node = queue.shift()
59
+ var a = node.p
60
+ var b = node.next.p
61
61
 
62
62
  // skip the edge if it's already short enough
63
- var sqLen = getSqDist(a, b);
64
- if (sqLen < sqLenThreshold) continue;
63
+ var sqLen = getSqDist(a, b)
64
+ if (sqLen < sqLenThreshold) continue
65
65
 
66
- var maxSqLen = sqLen / sqConcavity;
66
+ var maxSqLen = sqLen / sqConcavity
67
67
 
68
68
  // find the best connection point for the current edge to flex inward to
69
69
  p = findCandidate(
@@ -74,85 +74,85 @@ export default function concaveman(points, concavity, lengthThreshold) {
74
74
  node.next.next.p,
75
75
  maxSqLen,
76
76
  segTree
77
- );
77
+ )
78
78
 
79
79
  // if we found a connection and it satisfies our concavity measure
80
80
  if (p && Math.min(getSqDist(p, a), getSqDist(p, b)) <= maxSqLen) {
81
81
  // connect the edge endpoints through this point and add 2 new edges to the queue
82
- queue.push(node);
83
- queue.push(insertNode(p, node));
82
+ queue.push(node)
83
+ queue.push(insertNode(p, node))
84
84
 
85
85
  // update point and segment indexes
86
- tree.remove(p);
87
- segTree.remove(node);
88
- segTree.insert(updateBBox(node));
89
- segTree.insert(updateBBox(node.next));
86
+ tree.remove(p)
87
+ segTree.remove(node)
88
+ segTree.insert(updateBBox(node))
89
+ segTree.insert(updateBBox(node.next))
90
90
  }
91
91
  }
92
92
 
93
93
  // convert the resulting hull linked list to an array of points
94
- node = last;
95
- var concave = [];
94
+ node = last
95
+ var concave = []
96
96
  do {
97
- concave.push(node.p);
98
- node = node.next;
99
- } while (node !== last);
97
+ concave.push(node.p)
98
+ node = node.next
99
+ } while (node !== last)
100
100
 
101
- concave.push(node.p);
101
+ concave.push(node.p)
102
102
 
103
- return concave;
103
+ return concave
104
104
  }
105
105
 
106
106
  function findCandidate(tree, a, b, c, d, maxDist, segTree) {
107
- var queue = new Queue([], compareDist);
108
- var node = tree.data;
107
+ var queue = new Queue([], compareDist)
108
+ var node = tree.data
109
109
 
110
110
  // search through the point R-tree with a depth-first search using a priority queue
111
111
  // in the order of distance to the edge (b, c)
112
112
  while (node) {
113
113
  for (var i = 0; i < node.children.length; i++) {
114
- var child = node.children[i];
114
+ var child = node.children[i]
115
115
 
116
- var dist = node.leaf ? sqSegDist(child, b, c) : sqSegBoxDist(b, c, child);
117
- if (dist > maxDist) continue; // skip the node if it's farther than we ever need
116
+ var dist = node.leaf ? sqSegDist(child, b, c) : sqSegBoxDist(b, c, child)
117
+ if (dist > maxDist) continue // skip the node if it's farther than we ever need
118
118
 
119
119
  queue.push({
120
120
  node: child,
121
- dist: dist,
122
- });
121
+ dist: dist
122
+ })
123
123
  }
124
124
 
125
125
  while (queue.length && !queue.peek().node.children) {
126
- var item = queue.pop();
127
- var p = item.node;
126
+ var item = queue.pop()
127
+ var p = item.node
128
128
 
129
129
  // skip all points that are as close to adjacent edges (a,b) and (c,d),
130
130
  // and points that would introduce self-intersections when connected
131
- var d0 = sqSegDist(p, a, b);
132
- var d1 = sqSegDist(p, c, d);
131
+ var d0 = sqSegDist(p, a, b)
132
+ var d1 = sqSegDist(p, c, d)
133
133
  if (
134
134
  item.dist < d0 &&
135
135
  item.dist < d1 &&
136
136
  noIntersections(b, p, segTree) &&
137
137
  noIntersections(c, p, segTree)
138
138
  )
139
- return p;
139
+ return p
140
140
  }
141
141
 
142
- node = queue.pop();
143
- if (node) node = node.node;
142
+ node = queue.pop()
143
+ if (node) node = node.node
144
144
  }
145
145
 
146
- return null;
146
+ return null
147
147
  }
148
148
 
149
149
  function compareDist(a, b) {
150
- return a.dist - b.dist;
150
+ return a.dist - b.dist
151
151
  }
152
152
 
153
153
  // square distance from a segment bounding box to the given one
154
154
  function sqSegBoxDist(a, b, bbox) {
155
- if (inside(a, bbox) || inside(b, bbox)) return 0;
155
+ if (inside(a, bbox) || inside(b, bbox)) return 0
156
156
  var d1 = sqSegSegDist(
157
157
  a[0],
158
158
  a[1],
@@ -162,8 +162,8 @@ function sqSegBoxDist(a, b, bbox) {
162
162
  bbox.minY,
163
163
  bbox.maxX,
164
164
  bbox.minY
165
- );
166
- if (d1 === 0) return 0;
165
+ )
166
+ if (d1 === 0) return 0
167
167
  var d2 = sqSegSegDist(
168
168
  a[0],
169
169
  a[1],
@@ -173,8 +173,8 @@ function sqSegBoxDist(a, b, bbox) {
173
173
  bbox.minY,
174
174
  bbox.minX,
175
175
  bbox.maxY
176
- );
177
- if (d2 === 0) return 0;
176
+ )
177
+ if (d2 === 0) return 0
178
178
  var d3 = sqSegSegDist(
179
179
  a[0],
180
180
  a[1],
@@ -184,8 +184,8 @@ function sqSegBoxDist(a, b, bbox) {
184
184
  bbox.minY,
185
185
  bbox.maxX,
186
186
  bbox.maxY
187
- );
188
- if (d3 === 0) return 0;
187
+ )
188
+ if (d3 === 0) return 0
189
189
  var d4 = sqSegSegDist(
190
190
  a[0],
191
191
  a[1],
@@ -195,9 +195,9 @@ function sqSegBoxDist(a, b, bbox) {
195
195
  bbox.maxY,
196
196
  bbox.maxX,
197
197
  bbox.maxY
198
- );
199
- if (d4 === 0) return 0;
200
- return Math.min(d1, d2, d3, d4);
198
+ )
199
+ if (d4 === 0) return 0
200
+ return Math.min(d1, d2, d3, d4)
201
201
  }
202
202
 
203
203
  function inside(a, bbox) {
@@ -206,30 +206,30 @@ function inside(a, bbox) {
206
206
  a[0] <= bbox.maxX &&
207
207
  a[1] >= bbox.minY &&
208
208
  a[1] <= bbox.maxY
209
- );
209
+ )
210
210
  }
211
211
 
212
212
  // check if the edge (a,b) doesn't intersect any other edges
213
213
  function noIntersections(a, b, segTree) {
214
- var minX = Math.min(a[0], b[0]);
215
- var minY = Math.min(a[1], b[1]);
216
- var maxX = Math.max(a[0], b[0]);
217
- var maxY = Math.max(a[1], b[1]);
214
+ var minX = Math.min(a[0], b[0])
215
+ var minY = Math.min(a[1], b[1])
216
+ var maxX = Math.max(a[0], b[0])
217
+ var maxY = Math.max(a[1], b[1])
218
218
 
219
219
  var edges = segTree.search({
220
220
  minX: minX,
221
221
  minY: minY,
222
222
  maxX: maxX,
223
- maxY: maxY,
224
- });
223
+ maxY: maxY
224
+ })
225
225
  for (var i = 0; i < edges.length; i++) {
226
- if (intersects(edges[i].p, edges[i].next.p, a, b)) return false;
226
+ if (intersects(edges[i].p, edges[i].next.p, a, b)) return false
227
227
  }
228
- return true;
228
+ return true
229
229
  }
230
230
 
231
231
  function cross(p1, p2, p3) {
232
- return orient(p1[0], p1[1], p2[0], p2[1], p3[0], p3[1]);
232
+ return orient(p1[0], p1[1], p2[0], p2[1], p3[0], p3[1])
233
233
  }
234
234
 
235
235
  // check if the edges (p1,q1) and (p2,q2) intersect
@@ -239,45 +239,45 @@ function intersects(p1, q1, p2, q2) {
239
239
  q1 !== p2 &&
240
240
  cross(p1, q1, p2) > 0 !== cross(p1, q1, q2) > 0 &&
241
241
  cross(p2, q2, p1) > 0 !== cross(p2, q2, q1) > 0
242
- );
242
+ )
243
243
  }
244
244
 
245
245
  // update the bounding box of a node's edge
246
246
  function updateBBox(node) {
247
- var p1 = node.p;
248
- var p2 = node.next.p;
249
- node.minX = Math.min(p1[0], p2[0]);
250
- node.minY = Math.min(p1[1], p2[1]);
251
- node.maxX = Math.max(p1[0], p2[0]);
252
- node.maxY = Math.max(p1[1], p2[1]);
253
- return node;
247
+ var p1 = node.p
248
+ var p2 = node.next.p
249
+ node.minX = Math.min(p1[0], p2[0])
250
+ node.minY = Math.min(p1[1], p2[1])
251
+ node.maxX = Math.max(p1[0], p2[0])
252
+ node.maxY = Math.max(p1[1], p2[1])
253
+ return node
254
254
  }
255
255
 
256
256
  // speed up convex hull by filtering out points inside quadrilateral formed by 4 extreme points
257
257
  function fastConvexHull(points) {
258
- var left = points[0];
259
- var top = points[0];
260
- var right = points[0];
261
- var bottom = points[0];
258
+ var left = points[0]
259
+ var top = points[0]
260
+ var right = points[0]
261
+ var bottom = points[0]
262
262
 
263
263
  // find the leftmost, rightmost, topmost and bottommost points
264
264
  for (var i = 0; i < points.length; i++) {
265
- var p = points[i];
266
- if (p[0] < left[0]) left = p;
267
- if (p[0] > right[0]) right = p;
268
- if (p[1] < top[1]) top = p;
269
- if (p[1] > bottom[1]) bottom = p;
265
+ var p = points[i]
266
+ if (p[0] < left[0]) left = p
267
+ if (p[0] > right[0]) right = p
268
+ if (p[1] < top[1]) top = p
269
+ if (p[1] > bottom[1]) bottom = p
270
270
  }
271
271
 
272
272
  // filter out points that are inside the resulting quadrilateral
273
- var cull = [left, top, right, bottom];
274
- var filtered = cull.slice();
273
+ var cull = [left, top, right, bottom]
274
+ var filtered = cull.slice()
275
275
  for (i = 0; i < points.length; i++) {
276
- if (!pointInPolygon(points[i], cull)) filtered.push(points[i]);
276
+ if (!pointInPolygon(points[i], cull)) filtered.push(points[i])
277
277
  }
278
278
 
279
279
  // get convex hull around the filtered points
280
- return convexHull(filtered);
280
+ return convexHull(filtered)
281
281
  }
282
282
 
283
283
  // create a new node in a doubly linked list
@@ -289,27 +289,27 @@ function insertNode(p, prev) {
289
289
  minX: 0,
290
290
  minY: 0,
291
291
  maxX: 0,
292
- maxY: 0,
293
- };
292
+ maxY: 0
293
+ }
294
294
 
295
295
  if (!prev) {
296
- node.prev = node;
297
- node.next = node;
296
+ node.prev = node
297
+ node.next = node
298
298
  } else {
299
- node.next = prev.next;
300
- node.prev = prev;
301
- prev.next.prev = node;
302
- prev.next = node;
299
+ node.next = prev.next
300
+ node.prev = prev
301
+ prev.next.prev = node
302
+ prev.next = node
303
303
  }
304
- return node;
304
+ return node
305
305
  }
306
306
 
307
307
  // square distance between 2 points
308
308
  function getSqDist(p1, p2) {
309
309
  var dx = p1[0] - p2[0],
310
- dy = p1[1] - p2[1];
310
+ dy = p1[1] - p2[1]
311
311
 
312
- return dx * dx + dy * dy;
312
+ return dx * dx + dy * dy
313
313
  }
314
314
 
315
315
  // square distance from a point to a segment
@@ -317,127 +317,127 @@ function sqSegDist(p, p1, p2) {
317
317
  var x = p1[0],
318
318
  y = p1[1],
319
319
  dx = p2[0] - x,
320
- dy = p2[1] - y;
320
+ dy = p2[1] - y
321
321
 
322
322
  if (dx !== 0 || dy !== 0) {
323
- var t = ((p[0] - x) * dx + (p[1] - y) * dy) / (dx * dx + dy * dy);
323
+ var t = ((p[0] - x) * dx + (p[1] - y) * dy) / (dx * dx + dy * dy)
324
324
 
325
325
  if (t > 1) {
326
- x = p2[0];
327
- y = p2[1];
326
+ x = p2[0]
327
+ y = p2[1]
328
328
  } else if (t > 0) {
329
- x += dx * t;
330
- y += dy * t;
329
+ x += dx * t
330
+ y += dy * t
331
331
  }
332
332
  }
333
333
 
334
- dx = p[0] - x;
335
- dy = p[1] - y;
334
+ dx = p[0] - x
335
+ dy = p[1] - y
336
336
 
337
- return dx * dx + dy * dy;
337
+ return dx * dx + dy * dy
338
338
  }
339
339
 
340
340
  // segment to segment distance, ported from http://geomalgorithms.com/a07-_distance.html by Dan Sunday
341
341
  function sqSegSegDist(x0, y0, x1, y1, x2, y2, x3, y3) {
342
- var ux = x1 - x0;
343
- var uy = y1 - y0;
344
- var vx = x3 - x2;
345
- var vy = y3 - y2;
346
- var wx = x0 - x2;
347
- var wy = y0 - y2;
348
- var a = ux * ux + uy * uy;
349
- var b = ux * vx + uy * vy;
350
- var c = vx * vx + vy * vy;
351
- var d = ux * wx + uy * wy;
352
- var e = vx * wx + vy * wy;
353
- var D = a * c - b * b;
354
-
355
- var sc, sN, tc, tN;
356
- var sD = D;
357
- var tD = D;
342
+ var ux = x1 - x0
343
+ var uy = y1 - y0
344
+ var vx = x3 - x2
345
+ var vy = y3 - y2
346
+ var wx = x0 - x2
347
+ var wy = y0 - y2
348
+ var a = ux * ux + uy * uy
349
+ var b = ux * vx + uy * vy
350
+ var c = vx * vx + vy * vy
351
+ var d = ux * wx + uy * wy
352
+ var e = vx * wx + vy * wy
353
+ var D = a * c - b * b
354
+
355
+ var sc, sN, tc, tN
356
+ var sD = D
357
+ var tD = D
358
358
 
359
359
  if (D === 0) {
360
- sN = 0;
361
- sD = 1;
362
- tN = e;
363
- tD = c;
360
+ sN = 0
361
+ sD = 1
362
+ tN = e
363
+ tD = c
364
364
  } else {
365
- sN = b * e - c * d;
366
- tN = a * e - b * d;
365
+ sN = b * e - c * d
366
+ tN = a * e - b * d
367
367
  if (sN < 0) {
368
- sN = 0;
369
- tN = e;
370
- tD = c;
368
+ sN = 0
369
+ tN = e
370
+ tD = c
371
371
  } else if (sN > sD) {
372
- sN = sD;
373
- tN = e + b;
374
- tD = c;
372
+ sN = sD
373
+ tN = e + b
374
+ tD = c
375
375
  }
376
376
  }
377
377
 
378
378
  if (tN < 0.0) {
379
- tN = 0.0;
380
- if (-d < 0.0) sN = 0.0;
381
- else if (-d > a) sN = sD;
379
+ tN = 0.0
380
+ if (-d < 0.0) sN = 0.0
381
+ else if (-d > a) sN = sD
382
382
  else {
383
- sN = -d;
384
- sD = a;
383
+ sN = -d
384
+ sD = a
385
385
  }
386
386
  } else if (tN > tD) {
387
- tN = tD;
388
- if (-d + b < 0.0) sN = 0;
389
- else if (-d + b > a) sN = sD;
387
+ tN = tD
388
+ if (-d + b < 0.0) sN = 0
389
+ else if (-d + b > a) sN = sD
390
390
  else {
391
- sN = -d + b;
392
- sD = a;
391
+ sN = -d + b
392
+ sD = a
393
393
  }
394
394
  }
395
395
 
396
- sc = sN === 0 ? 0 : sN / sD;
397
- tc = tN === 0 ? 0 : tN / tD;
396
+ sc = sN === 0 ? 0 : sN / sD
397
+ tc = tN === 0 ? 0 : tN / tD
398
398
 
399
- var cx = (1 - sc) * x0 + sc * x1;
400
- var cy = (1 - sc) * y0 + sc * y1;
401
- var cx2 = (1 - tc) * x2 + tc * x3;
402
- var cy2 = (1 - tc) * y2 + tc * y3;
403
- var dx = cx2 - cx;
404
- var dy = cy2 - cy;
399
+ var cx = (1 - sc) * x0 + sc * x1
400
+ var cy = (1 - sc) * y0 + sc * y1
401
+ var cx2 = (1 - tc) * x2 + tc * x3
402
+ var cy2 = (1 - tc) * y2 + tc * y3
403
+ var dx = cx2 - cx
404
+ var dy = cy2 - cy
405
405
 
406
- return dx * dx + dy * dy;
406
+ return dx * dx + dy * dy
407
407
  }
408
408
 
409
409
  function compareByX(a, b) {
410
- return a[0] === b[0] ? a[1] - b[1] : a[0] - b[0];
410
+ return a[0] === b[0] ? a[1] - b[1] : a[0] - b[0]
411
411
  }
412
412
 
413
413
  function convexHull(points) {
414
- points.sort(compareByX);
414
+ points.sort(compareByX)
415
415
 
416
- var lower = [];
416
+ var lower = []
417
417
  for (var i = 0; i < points.length; i++) {
418
418
  while (
419
419
  lower.length >= 2 &&
420
420
  cross(lower[lower.length - 2], lower[lower.length - 1], points[i]) <= 0
421
421
  ) {
422
- lower.pop();
422
+ lower.pop()
423
423
  }
424
- lower.push(points[i]);
424
+ lower.push(points[i])
425
425
  }
426
426
 
427
- var upper = [];
427
+ var upper = []
428
428
  for (var ii = points.length - 1; ii >= 0; ii--) {
429
429
  while (
430
430
  upper.length >= 2 &&
431
431
  cross(upper[upper.length - 2], upper[upper.length - 1], points[ii]) <= 0
432
432
  ) {
433
- upper.pop();
433
+ upper.pop()
434
434
  }
435
- upper.push(points[ii]);
435
+ upper.push(points[ii])
436
436
  }
437
437
 
438
- upper.pop();
439
- lower.pop();
440
- return lower.concat(upper);
438
+ upper.pop()
439
+ lower.pop()
440
+ return lower.concat(upper)
441
441
  }
442
442
 
443
- export { concaveman };
443
+ export { concaveman }