clipper2-ts 2.0.1-13 → 2.0.1-15

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.
@@ -7,10 +7,7 @@
7
7
  * Purpose : Constrained Delaunay Triangulation *
8
8
  * License : https://www.boost.org/LICENSE_1_0.txt *
9
9
  *******************************************************************************/
10
- import { InternalClipper } from './Core.js';
11
- // BigInt constant — avoid BigInt literal syntax (0n) to sidestep
12
- // terser BigInt constant-folding issues in some consuming build setups.
13
- const B0 = BigInt(0);
10
+ import { adaptiveOrient2dSign, adaptiveIncircleSign } from './Shewchuk.js';
14
11
  export var TriangulateResult;
15
12
  (function (TriangulateResult) {
16
13
  TriangulateResult[TriangulateResult["success"] = 0] = "success";
@@ -82,6 +79,8 @@ export class Delaunay {
82
79
  firstActive = null;
83
80
  lowermostVertex = null;
84
81
  fastMath = false;
82
+ _edgesA = [null, null, null];
83
+ _edgesB = [null, null, null];
85
84
  constructor(delaunay = true) {
86
85
  this.useDelaunay = delaunay;
87
86
  }
@@ -134,20 +133,18 @@ export class Delaunay {
134
133
  let i0 = 0;
135
134
  let iPrev;
136
135
  let iNext;
137
- const foundIdx = Delaunay.findLocMinIdx(path, len, i0);
138
- if (!foundIdx.found)
136
+ i0 = Delaunay.findLocMinIdx(path, len, i0);
137
+ if (i0 < 0)
139
138
  return;
140
- i0 = foundIdx.idx;
141
139
  iPrev = Delaunay.prev(i0, len);
142
140
  while (path[iPrev].x === path[i0].x && path[iPrev].y === path[i0].y)
143
141
  iPrev = Delaunay.prev(iPrev, len);
144
142
  iNext = Delaunay.next(i0, len);
145
143
  let i = i0;
146
144
  while (this.crossProductSign(path[iPrev], path[i], path[iNext]) === 0) {
147
- const result = Delaunay.findLocMinIdx(path, len, i);
148
- if (!result.found)
149
- return; // entirely collinear path
150
- i = result.idx;
145
+ i = Delaunay.findLocMinIdx(path, len, i);
146
+ if (i < 0)
147
+ return;
151
148
  iPrev = Delaunay.prev(i, len);
152
149
  while (path[iPrev].x === path[i].x && path[iPrev].y === path[i].y)
153
150
  iPrev = Delaunay.prev(iPrev, len);
@@ -161,19 +158,18 @@ export class Delaunay {
161
158
  let vPrev = v0;
162
159
  i = iNext;
163
160
  for (;;) {
161
+ iNext = Delaunay.next(i, len);
162
+ if (this.crossProductSign(vPrev.pt, path[i], path[iNext]) === 0) {
163
+ i = iNext;
164
+ continue;
165
+ }
164
166
  // vPrev is a locMin here
165
167
  this.locMinStack.push(vPrev);
166
- // ? update lowermostVertex ...
167
168
  if (this.lowermostVertex === null ||
168
169
  vPrev.pt.y > this.lowermostVertex.pt.y ||
169
170
  (vPrev.pt.y === this.lowermostVertex.pt.y &&
170
171
  vPrev.pt.x < this.lowermostVertex.pt.x))
171
172
  this.lowermostVertex = vPrev;
172
- iNext = Delaunay.next(i, len);
173
- if (this.crossProductSign(vPrev.pt, path[i], path[iNext]) === 0) {
174
- i = iNext;
175
- continue;
176
- }
177
173
  // ascend up next bound to LocMax
178
174
  while (path[i].y <= vPrev.pt.y) {
179
175
  const v = new Vertex2(path[i]);
@@ -212,9 +208,9 @@ export class Delaunay {
212
208
  const pathLen = this.allVertices.length - vert_cnt;
213
209
  const idx = vert_cnt;
214
210
  if (pathLen < 3 || (pathLen === 3 &&
215
- ((this.distSqr(this.allVertices[idx].pt, this.allVertices[idx + 1].pt) <= 1) ||
216
- (this.distSqr(this.allVertices[idx + 1].pt, this.allVertices[idx + 2].pt) <= 1) ||
217
- (this.distSqr(this.allVertices[idx + 2].pt, this.allVertices[idx].pt) <= 1)))) {
211
+ ((this.distanceSqr(this.allVertices[idx].pt, this.allVertices[idx + 1].pt) <= 1) ||
212
+ (this.distanceSqr(this.allVertices[idx + 1].pt, this.allVertices[idx + 2].pt) <= 1) ||
213
+ (this.distanceSqr(this.allVertices[idx + 2].pt, this.allVertices[idx].pt) <= 1)))) {
218
214
  for (let j = vert_cnt; j < this.allVertices.length; ++j)
219
215
  this.allVertices[j].edges = []; // flag to ignore
220
216
  }
@@ -411,8 +407,10 @@ export class Delaunay {
411
407
  return;
412
408
  let vertA = null;
413
409
  let vertB = null;
414
- const edgesA = [null, null, null];
415
- const edgesB = [null, null, null];
410
+ const edgesA = this._edgesA;
411
+ const edgesB = this._edgesB;
412
+ edgesA[0] = edgesA[1] = edgesA[2] = null;
413
+ edgesB[0] = edgesB[1] = edgesB[2] = null;
416
414
  for (let i = 0; i < 3; ++i) {
417
415
  if (edge.triA.edges[i] === edge)
418
416
  continue;
@@ -537,7 +535,7 @@ export class Delaunay {
537
535
  }
538
536
  return this.createEdge(vBest, vAbove, EdgeKind.loose);
539
537
  }
540
- doTriangulateLeft(edge, pivot, minY) {
538
+ doTriangulateLeft(edge, pivot, minY, limitFan = false) {
541
539
  let vAlt = null;
542
540
  let eAlt = null;
543
541
  const v = (edge.vB === pivot) ? edge.vT : edge.vB;
@@ -559,6 +557,13 @@ export class Delaunay {
559
557
  }
560
558
  if (vAlt === null || vAlt.pt.y < minY || eAlt === null)
561
559
  return;
560
+ // Domiter & Zalik 2008, §3.2: stop fan extension when angle at pivot > pi/2
561
+ if (limitFan) {
562
+ const dvx = v.pt.x - pivot.pt.x, dvy = v.pt.y - pivot.pt.y;
563
+ const dax = vAlt.pt.x - pivot.pt.x, day = vAlt.pt.y - pivot.pt.y;
564
+ if (dvx * dax + dvy * day < 0)
565
+ return;
566
+ }
562
567
  if (vAlt.pt.y < pivot.pt.y) {
563
568
  if (Delaunay.isLeftEdge(eAlt))
564
569
  return;
@@ -573,9 +578,9 @@ export class Delaunay {
573
578
  }
574
579
  this.createTriangle(edge, eAlt, eX);
575
580
  if (!Delaunay.edgeCompleted(eX))
576
- this.doTriangulateLeft(eX, vAlt, minY);
581
+ this.doTriangulateLeft(eX, vAlt, minY, true);
577
582
  }
578
- doTriangulateRight(edge, pivot, minY) {
583
+ doTriangulateRight(edge, pivot, minY, limitFan = false) {
579
584
  let vAlt = null;
580
585
  let eAlt = null;
581
586
  const v = (edge.vB === pivot) ? edge.vT : edge.vB;
@@ -597,6 +602,13 @@ export class Delaunay {
597
602
  }
598
603
  if (vAlt === null || vAlt.pt.y < minY || eAlt === null)
599
604
  return;
605
+ // Domiter & Zalik 2008, §3.2: stop fan extension when angle at pivot > pi/2
606
+ if (limitFan) {
607
+ const dvx = v.pt.x - pivot.pt.x, dvy = v.pt.y - pivot.pt.y;
608
+ const dax = vAlt.pt.x - pivot.pt.x, day = vAlt.pt.y - pivot.pt.y;
609
+ if (dvx * dax + dvy * day < 0)
610
+ return;
611
+ }
600
612
  if (vAlt.pt.y < pivot.pt.y) {
601
613
  if (Delaunay.isRightEdge(eAlt))
602
614
  return;
@@ -611,7 +623,7 @@ export class Delaunay {
611
623
  }
612
624
  this.createTriangle(edge, eX, eAlt);
613
625
  if (!Delaunay.edgeCompleted(eX))
614
- this.doTriangulateRight(eX, vAlt, minY);
626
+ this.doTriangulateRight(eX, vAlt, minY, true);
615
627
  }
616
628
  addEdgeToActives(edge) {
617
629
  if (edge.isActive)
@@ -783,18 +795,12 @@ export class Delaunay {
783
795
  return { result: TriangulateResult.success, solution: sol };
784
796
  }
785
797
  crossProductSign(p1, p2, p3) {
786
- if (!this.fastMath)
787
- return InternalClipper.crossProductSign(p1, p2, p3);
788
- const a = p2.x - p1.x;
789
- const b = p3.y - p2.y;
790
- const c = p2.y - p1.y;
791
- const d = p3.x - p2.x;
792
- const prod1 = a * b;
793
- const prod2 = c * d;
794
- return (prod1 > prod2) ? 1 : (prod1 < prod2) ? -1 : 0;
795
- }
796
- distSqr(pt1, pt2) {
797
- return this.distanceSqr(pt1, pt2);
798
+ if (this.fastMath) {
799
+ const prod1 = (p2.x - p1.x) * (p3.y - p2.y);
800
+ const prod2 = (p2.y - p1.y) * (p3.x - p2.x);
801
+ return (prod1 > prod2) ? 1 : (prod1 < prod2) ? -1 : 0;
802
+ }
803
+ return -adaptiveOrient2dSign(p1.x, p1.y, p2.x, p2.y, p3.x, p3.y);
798
804
  }
799
805
  distanceSqr(a, b) {
800
806
  if (!this.fastMath)
@@ -858,48 +864,16 @@ export class Delaunay {
858
864
  return IntersectKind.none;
859
865
  }
860
866
  inCircleTest(ptA, ptB, ptC, ptD) {
861
- if (!this.fastMath)
862
- return Delaunay.inCircleTest(ptA, ptB, ptC, ptD);
863
- const ax = ptA.x - ptD.x;
864
- const ay = ptA.y - ptD.y;
865
- const bx = ptB.x - ptD.x;
866
- const by = ptB.y - ptD.y;
867
- const cx = ptC.x - ptD.x;
868
- const cy = ptC.y - ptD.y;
869
- const abdet = ax * by - bx * ay;
870
- const bcdet = bx * cy - cx * by;
871
- const cadet = cx * ay - ax * cy;
872
- const alift = ax * ax + ay * ay;
873
- const blift = bx * bx + by * by;
874
- const clift = cx * cx + cy * cy;
875
- const det = alift * bcdet + blift * cadet + clift * abdet;
876
- const permanent = Math.abs(alift * bcdet) + Math.abs(blift * cadet) + Math.abs(clift * abdet);
877
- // Error bound from Shewchuk's "Adaptive Precision Floating-Point Arithmetic
878
- // and Fast Robust Geometric Predicates" (iccerrboundA for 2D in-circle test).
879
- const eps = Number.EPSILON;
880
- const errbound = (10 + 96 * eps) * eps * permanent;
881
- if (det > errbound)
882
- return 1;
883
- if (-det > errbound)
884
- return -1;
885
- const axBig = BigInt(ptA.x) - BigInt(ptD.x);
886
- const ayBig = BigInt(ptA.y) - BigInt(ptD.y);
887
- const bxBig = BigInt(ptB.x) - BigInt(ptD.x);
888
- const byBig = BigInt(ptB.y) - BigInt(ptD.y);
889
- const cxBig = BigInt(ptC.x) - BigInt(ptD.x);
890
- const cyBig = BigInt(ptC.y) - BigInt(ptD.y);
891
- const abdetBig = axBig * byBig - bxBig * ayBig;
892
- const bcdetBig = bxBig * cyBig - cxBig * byBig;
893
- const cadetBig = cxBig * ayBig - axBig * cyBig;
894
- const aliftBig = axBig * axBig + ayBig * ayBig;
895
- const bliftBig = bxBig * bxBig + byBig * byBig;
896
- const cliftBig = cxBig * cxBig + cyBig * cyBig;
897
- const result = aliftBig * bcdetBig + bliftBig * cadetBig + cliftBig * abdetBig;
898
- if (result > B0)
899
- return 1;
900
- if (result < B0)
901
- return -1;
902
- return 0;
867
+ if (this.fastMath) {
868
+ const ax = ptA.x - ptD.x, ay = ptA.y - ptD.y;
869
+ const bx = ptB.x - ptD.x, by = ptB.y - ptD.y;
870
+ const cx = ptC.x - ptD.x, cy = ptC.y - ptD.y;
871
+ const det = (ax * ax + ay * ay) * (bx * cy - cx * by) +
872
+ (bx * bx + by * by) * (cx * ay - ax * cy) +
873
+ (cx * cx + cy * cy) * (ax * by - bx * ay);
874
+ return det > 0 ? 1 : det < 0 ? -1 : 0;
875
+ }
876
+ return adaptiveIncircleSign(ptA.x, ptA.y, ptB.x, ptB.y, ptC.x, ptC.y, ptD.x, ptD.y);
903
877
  }
904
878
  // ---------------------------------------------------------------------
905
879
  // Static / helper functions
@@ -971,20 +945,20 @@ export class Delaunay {
971
945
  }
972
946
  static findLocMinIdx(path, len, idx) {
973
947
  if (len < 3)
974
- return { found: false, idx };
948
+ return -1;
975
949
  const i0 = idx;
976
950
  let n = (idx + 1) % len;
977
951
  while (path[n].y <= path[idx].y) {
978
952
  idx = n;
979
953
  n = (n + 1) % len;
980
954
  if (idx === i0)
981
- return { found: false, idx };
955
+ return -1;
982
956
  }
983
957
  while (path[n].y >= path[idx].y) {
984
958
  idx = n;
985
959
  n = (n + 1) % len;
986
960
  }
987
- return { found: true, idx };
961
+ return idx;
988
962
  }
989
963
  static prev(idx, len) {
990
964
  if (idx === 0)
@@ -1019,213 +993,65 @@ export class Delaunay {
1019
993
  res.push(e.vL.pt);
1020
994
  return res;
1021
995
  }
1022
- static areSafePoints(...pts) {
1023
- for (const pt of pts) {
1024
- if (!Number.isSafeInteger(pt.x) || !Number.isSafeInteger(pt.y))
1025
- return false;
1026
- }
1027
- return true;
1028
- }
1029
996
  static maxSafeDelta = Math.floor(Math.sqrt(Number.MAX_SAFE_INTEGER / 2));
1030
- static areSafeDeltas(...vals) {
1031
- for (const v of vals) {
1032
- if (Math.abs(v) > Delaunay.maxSafeDelta)
1033
- return false;
1034
- }
1035
- return true;
1036
- }
1037
- static inCircleTest(ptA, ptB, ptC, ptD) {
1038
- const ax = ptA.x - ptD.x;
1039
- const ay = ptA.y - ptD.y;
1040
- const bx = ptB.x - ptD.x;
1041
- const by = ptB.y - ptD.y;
1042
- const cx = ptC.x - ptD.x;
1043
- const cy = ptC.y - ptD.y;
1044
- const abdet = ax * by - bx * ay;
1045
- const bcdet = bx * cy - cx * by;
1046
- const cadet = cx * ay - ax * cy;
1047
- const alift = ax * ax + ay * ay;
1048
- const blift = bx * bx + by * by;
1049
- const clift = cx * cx + cy * cy;
1050
- const det = alift * bcdet + blift * cadet + clift * abdet;
1051
- const permanent = Math.abs(alift * bcdet) + Math.abs(blift * cadet) + Math.abs(clift * abdet);
1052
- // Error bound from Shewchuk's "Adaptive Precision Floating-Point Arithmetic
1053
- // and Fast Robust Geometric Predicates" (iccerrboundA for 2D in-circle test).
1054
- // See: https://www.cs.cmu.edu/~quake/robust.html
1055
- const eps = Number.EPSILON;
1056
- const errbound = (10 + 96 * eps) * eps * permanent;
1057
- if (det > errbound)
1058
- return 1;
1059
- if (-det > errbound)
1060
- return -1;
1061
- if (Delaunay.areSafePoints(ptA, ptB, ptC, ptD)) {
1062
- const ax = BigInt(ptA.x) - BigInt(ptD.x);
1063
- const ay = BigInt(ptA.y) - BigInt(ptD.y);
1064
- const bx = BigInt(ptB.x) - BigInt(ptD.x);
1065
- const by = BigInt(ptB.y) - BigInt(ptD.y);
1066
- const cx = BigInt(ptC.x) - BigInt(ptD.x);
1067
- const cy = BigInt(ptC.y) - BigInt(ptD.y);
1068
- const abdet = ax * by - bx * ay;
1069
- const bcdet = bx * cy - cx * by;
1070
- const cadet = cx * ay - ax * cy;
1071
- const alift = ax * ax + ay * ay;
1072
- const blift = bx * bx + by * by;
1073
- const clift = cx * cx + cy * cy;
1074
- const result = alift * bcdet + blift * cadet + clift * abdet;
1075
- if (result > B0)
1076
- return 1;
1077
- if (result < B0)
1078
- return -1;
1079
- return 0;
1080
- }
1081
- return det > 0 ? 1 : det < 0 ? -1 : 0;
1082
- }
1083
997
  static shortestDistFromSegment(pt, segPt1, segPt2) {
1084
998
  const dx = segPt2.x - segPt1.x;
1085
999
  const dy = segPt2.y - segPt1.y;
1086
1000
  const ax = pt.x - segPt1.x;
1087
1001
  const ay = pt.y - segPt1.y;
1088
- const qNum = ax * dx + ay * dy;
1089
- const denom = dx * dx + dy * dy;
1090
- if (Delaunay.areSafeDeltas(dx, dy, ax, ay)) {
1091
- if (qNum < 0)
1092
- return Delaunay.distanceSqr(pt, segPt1);
1093
- if (qNum > denom)
1094
- return Delaunay.distanceSqr(pt, segPt2);
1095
- return (ax * dy - dx * ay) * (ax * dy - dx * ay) / denom;
1096
- }
1097
- if (Delaunay.areSafePoints(pt, segPt1, segPt2)) {
1098
- const dx = BigInt(segPt2.x) - BigInt(segPt1.x);
1099
- const dy = BigInt(segPt2.y) - BigInt(segPt1.y);
1100
- const ax = BigInt(pt.x) - BigInt(segPt1.x);
1101
- const ay = BigInt(pt.y) - BigInt(segPt1.y);
1002
+ const msd = Delaunay.maxSafeDelta;
1003
+ if (Math.abs(dx) <= msd && Math.abs(dy) <= msd && Math.abs(ax) <= msd && Math.abs(ay) <= msd) {
1102
1004
  const qNum = ax * dx + ay * dy;
1103
1005
  const denom = dx * dx + dy * dy;
1104
- if (qNum < B0)
1006
+ if (qNum < 0)
1105
1007
  return Delaunay.distanceSqr(pt, segPt1);
1106
1008
  if (qNum > denom)
1107
1009
  return Delaunay.distanceSqr(pt, segPt2);
1108
- const cross = ax * dy - dx * ay;
1109
- return Number(cross * cross) / Number(denom);
1010
+ return (ax * dy - dx * ay) * (ax * dy - dx * ay) / denom;
1110
1011
  }
1111
- if (qNum < 0)
1012
+ const dxB = BigInt(segPt2.x) - BigInt(segPt1.x);
1013
+ const dyB = BigInt(segPt2.y) - BigInt(segPt1.y);
1014
+ const axB = BigInt(pt.x) - BigInt(segPt1.x);
1015
+ const ayB = BigInt(pt.y) - BigInt(segPt1.y);
1016
+ const qNum = axB * dxB + ayB * dyB;
1017
+ const denom = dxB * dxB + dyB * dyB;
1018
+ const B0 = BigInt(0);
1019
+ if (qNum < B0)
1112
1020
  return Delaunay.distanceSqr(pt, segPt1);
1113
1021
  if (qNum > denom)
1114
1022
  return Delaunay.distanceSqr(pt, segPt2);
1115
- return (ax * dy - dx * ay) * (ax * dy - dx * ay) / denom;
1023
+ const cross = axB * dyB - dxB * ayB;
1024
+ return Number(cross * cross) / Number(denom);
1116
1025
  }
1117
1026
  static segsIntersect(s1a, s1b, s2a, s2b) {
1118
- // ignore segments sharing an end-point
1119
1027
  if ((s1a.x === s2a.x && s1a.y === s2a.y) ||
1120
1028
  (s1a.x === s2b.x && s1a.y === s2b.y) ||
1121
1029
  (s1b.x === s2b.x && s1b.y === s2b.y))
1122
1030
  return IntersectKind.none;
1123
- const dy1 = s1b.y - s1a.y;
1124
- const dx1 = s1b.x - s1a.x;
1125
- const dy2 = s2b.y - s2a.y;
1126
- const dx2 = s2b.x - s2a.x;
1127
- const dxs = s1a.x - s2a.x;
1128
- const dys = s1a.y - s2a.y;
1129
- if (Delaunay.areSafeDeltas(dy1, dx1, dy2, dx2, dxs, dys)) {
1130
- const cp = dy1 * dx2 - dy2 * dx1;
1131
- if (cp === 0)
1132
- return IntersectKind.collinear;
1133
- let t = dxs * dy2 - dys * dx2;
1134
- // nb: testing for t === 0 is unreliable due to float imprecision
1135
- if (t >= 0) {
1136
- if (cp < 0 || t >= cp)
1137
- return IntersectKind.none;
1138
- }
1139
- else {
1140
- if (cp > 0 || t <= cp)
1141
- return IntersectKind.none;
1142
- }
1143
- t = dxs * dy1 - dys * dx1;
1144
- if (t >= 0) {
1145
- if (cp > 0 && t < cp)
1146
- return IntersectKind.intersect;
1147
- }
1148
- else {
1149
- if (cp < 0 && t > cp)
1150
- return IntersectKind.intersect;
1151
- }
1031
+ const d1 = adaptiveOrient2dSign(s2a.x, s2a.y, s2b.x, s2b.y, s1a.x, s1a.y);
1032
+ const d2 = adaptiveOrient2dSign(s2a.x, s2a.y, s2b.x, s2b.y, s1b.x, s1b.y);
1033
+ if (d1 === 0 && d2 === 0)
1034
+ return IntersectKind.collinear;
1035
+ if (d1 === 0 || d2 === 0 || d1 === d2)
1152
1036
  return IntersectKind.none;
1153
- }
1154
- if (Delaunay.areSafePoints(s1a, s1b, s2a, s2b)) {
1155
- const dy1 = BigInt(s1b.y) - BigInt(s1a.y);
1156
- const dx1 = BigInt(s1b.x) - BigInt(s1a.x);
1157
- const dy2 = BigInt(s2b.y) - BigInt(s2a.y);
1158
- const dx2 = BigInt(s2b.x) - BigInt(s2a.x);
1159
- const cp = dy1 * dx2 - dy2 * dx1;
1160
- if (cp === B0)
1161
- return IntersectKind.collinear;
1162
- let t = (BigInt(s1a.x) - BigInt(s2a.x)) * dy2 -
1163
- (BigInt(s1a.y) - BigInt(s2a.y)) * dx2;
1164
- if (t === B0)
1165
- return IntersectKind.none;
1166
- if (t > B0) {
1167
- if (cp < B0 || t >= cp)
1168
- return IntersectKind.none;
1169
- }
1170
- else {
1171
- if (cp > B0 || t <= cp)
1172
- return IntersectKind.none;
1173
- }
1174
- t = (BigInt(s1a.x) - BigInt(s2a.x)) * dy1 -
1175
- (BigInt(s1a.y) - BigInt(s2a.y)) * dx1;
1176
- if (t === B0)
1177
- return IntersectKind.none;
1178
- if (t > B0) {
1179
- if (cp > B0 && t < cp)
1180
- return IntersectKind.intersect;
1181
- }
1182
- else {
1183
- if (cp < B0 && t > cp)
1184
- return IntersectKind.intersect;
1185
- }
1037
+ const d3 = adaptiveOrient2dSign(s1a.x, s1a.y, s1b.x, s1b.y, s2a.x, s2a.y);
1038
+ const d4 = adaptiveOrient2dSign(s1a.x, s1a.y, s1b.x, s1b.y, s2b.x, s2b.y);
1039
+ if (d3 === 0 || d4 === 0 || d3 === d4)
1186
1040
  return IntersectKind.none;
1187
- }
1188
- const cp = dy1 * dx2 - dy2 * dx1;
1189
- if (cp === 0)
1190
- return IntersectKind.collinear;
1191
- let t = dxs * dy2 - dys * dx2;
1192
- // nb: testing for t === 0 is unreliable due to float imprecision
1193
- if (t >= 0) {
1194
- if (cp < 0 || t >= cp)
1195
- return IntersectKind.none;
1196
- }
1197
- else {
1198
- if (cp > 0 || t <= cp)
1199
- return IntersectKind.none;
1200
- }
1201
- t = dxs * dy1 - dys * dx1;
1202
- if (t >= 0) {
1203
- if (cp > 0 && t < cp)
1204
- return IntersectKind.intersect;
1205
- }
1206
- else {
1207
- if (cp < 0 && t > cp)
1208
- return IntersectKind.intersect;
1209
- }
1210
- return IntersectKind.none;
1211
- }
1212
- static distSqr(pt1, pt2) {
1213
- return Delaunay.distanceSqr(pt1, pt2);
1041
+ return IntersectKind.intersect;
1214
1042
  }
1215
1043
  static distanceSqr(a, b) {
1216
1044
  const dx = a.x - b.x;
1217
1045
  const dy = a.y - b.y;
1218
- if (Delaunay.areSafeDeltas(dx, dy)) {
1046
+ const msd = Delaunay.maxSafeDelta;
1047
+ if (Math.abs(dx) <= msd && Math.abs(dy) <= msd) {
1219
1048
  const dist = dx * dx + dy * dy;
1220
1049
  if (dist <= Number.MAX_SAFE_INTEGER)
1221
1050
  return dist;
1222
1051
  }
1223
- if (Delaunay.areSafePoints(a, b)) {
1224
- const dxBig = BigInt(a.x) - BigInt(b.x);
1225
- const dyBig = BigInt(a.y) - BigInt(b.y);
1226
- return Number(dxBig * dxBig + dyBig * dyBig);
1227
- }
1228
- return dx * dx + dy * dy;
1052
+ const dxB = BigInt(a.x) - BigInt(b.x);
1053
+ const dyB = BigInt(a.y) - BigInt(b.y);
1054
+ return Number(dxB * dxB + dyB * dyB);
1229
1055
  }
1230
1056
  }
1231
1057
  //# sourceMappingURL=Triangulation.js.map