@tscircuit/schematic-trace-solver 0.0.133 → 0.0.135
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/index.d.ts +1 -0
- package/dist/index.js +226 -129
- package/lib/solvers/LongDistancePairSolver/LongDistancePairSolver.ts +140 -6
- package/lib/solvers/TraceLabelOverlapAvoidanceSolver/sub-solvers/OverlapAvoidanceStepSolver/OverlapAvoidanceStepSolver.ts +7 -1
- package/package.json +1 -1
- package/site/bug-reports/bug-report-20260815T073240Z.page.tsx +4 -0
- package/tests/bug-reports/bug-report-20260815T073240Z/__snapshots__/bug-report-20260815T073240Z.snap.svg +79 -0
- package/tests/bug-reports/bug-report-20260815T073240Z/bug-report-20260815T073240Z.json +314 -0
- package/tests/bug-reports/bug-report-20260815T073240Z/bug-report-20260815T073240Z.test.ts +12 -0
- package/tests/repros/__snapshots__/board1096-usb-label-overlap-iteration.snap.svg +133 -0
- package/tests/repros/__snapshots__/repro-type-c-vbus-led-ground-label.snap.svg +66 -0
- package/tests/repros/board1096-usb-label-overlap-iteration.json +663 -0
- package/tests/repros/board1096-usb-label-overlap-iteration.test.ts +16 -0
- package/tests/repros/repro-type-c-vbus-led-ground-label.test.ts +149 -0
package/dist/index.js
CHANGED
|
@@ -325,19 +325,19 @@ var doesPairCrossRestrictedCenterLines = (params) => {
|
|
|
325
325
|
chipMap
|
|
326
326
|
});
|
|
327
327
|
if (restrictedCenterLines.size === 0) return false;
|
|
328
|
-
const
|
|
328
|
+
const EPS14 = 1e-9;
|
|
329
329
|
const crossesSegment = (a, b) => {
|
|
330
330
|
for (const [, rcl] of restrictedCenterLines) {
|
|
331
331
|
if (rcl.axes.has("x") && typeof rcl.x === "number") {
|
|
332
|
-
if ((a.x - rcl.x) * (b.x - rcl.x) < -
|
|
332
|
+
if ((a.x - rcl.x) * (b.x - rcl.x) < -EPS14) return true;
|
|
333
333
|
}
|
|
334
334
|
if (rcl.axes.has("y") && typeof rcl.y === "number") {
|
|
335
|
-
if ((a.y - rcl.y) * (b.y - rcl.y) < -
|
|
335
|
+
if ((a.y - rcl.y) * (b.y - rcl.y) < -EPS14) return true;
|
|
336
336
|
}
|
|
337
337
|
}
|
|
338
338
|
return false;
|
|
339
339
|
};
|
|
340
|
-
if (Math.abs(p1.x - p2.x) <
|
|
340
|
+
if (Math.abs(p1.x - p2.x) < EPS14 || Math.abs(p1.y - p2.y) < EPS14) {
|
|
341
341
|
return crossesSegment({ x: p1.x, y: p1.y }, { x: p2.x, y: p2.y });
|
|
342
342
|
}
|
|
343
343
|
const elbowHV = { x: p2.x, y: p1.y };
|
|
@@ -1424,8 +1424,8 @@ var SchematicTraceSingleLineSolver2 = class extends BaseSolver {
|
|
|
1424
1424
|
if (!collision) {
|
|
1425
1425
|
const first = path[0];
|
|
1426
1426
|
const last = path[path.length - 1];
|
|
1427
|
-
const
|
|
1428
|
-
const samePoint = (p, q) => Math.abs(p.x - q.x) <
|
|
1427
|
+
const EPS14 = 1e-9;
|
|
1428
|
+
const samePoint = (p, q) => Math.abs(p.x - q.x) < EPS14 && Math.abs(p.y - q.y) < EPS14;
|
|
1429
1429
|
if (samePoint(first, { x: PA.x, y: PA.y }) && samePoint(last, { x: PB.x, y: PB.y })) {
|
|
1430
1430
|
this.solvedTracePath = path;
|
|
1431
1431
|
this.solved = true;
|
|
@@ -1709,13 +1709,13 @@ var applyJogToTerminalSegment = ({
|
|
|
1709
1709
|
segmentIndex: si,
|
|
1710
1710
|
offset,
|
|
1711
1711
|
JOG_SIZE,
|
|
1712
|
-
EPS:
|
|
1712
|
+
EPS: EPS14 = 1e-6
|
|
1713
1713
|
}) => {
|
|
1714
1714
|
if (si !== 0 && si !== pts.length - 2) return;
|
|
1715
1715
|
const start = pts[si];
|
|
1716
1716
|
const end = pts[si + 1];
|
|
1717
|
-
const isVertical5 = Math.abs(start.x - end.x) <
|
|
1718
|
-
const isHorizontal4 = Math.abs(start.y - end.y) <
|
|
1717
|
+
const isVertical5 = Math.abs(start.x - end.x) < EPS14;
|
|
1718
|
+
const isHorizontal4 = Math.abs(start.y - end.y) < EPS14;
|
|
1719
1719
|
if (!isVertical5 && !isHorizontal4) return;
|
|
1720
1720
|
const segDir = isVertical5 ? end.y > start.y ? 1 : -1 : end.x > start.x ? 1 : -1;
|
|
1721
1721
|
if (pts.length === 2) {
|
|
@@ -2144,7 +2144,7 @@ var TraceOverlapShiftSolver = class extends BaseSolver {
|
|
|
2144
2144
|
return islands;
|
|
2145
2145
|
}
|
|
2146
2146
|
findNextOverlapIssue() {
|
|
2147
|
-
const
|
|
2147
|
+
const EPS14 = 2e-3;
|
|
2148
2148
|
const netIds = Object.keys(this.traceNetIslands);
|
|
2149
2149
|
for (let i = 0; i < netIds.length; i++) {
|
|
2150
2150
|
for (let j = i + 1; j < netIds.length; j++) {
|
|
@@ -2171,7 +2171,7 @@ var TraceOverlapShiftSolver = class extends BaseSolver {
|
|
|
2171
2171
|
segmentBIndex,
|
|
2172
2172
|
rangeOverlap
|
|
2173
2173
|
}) => {
|
|
2174
|
-
if (rangeOverlap >
|
|
2174
|
+
if (rangeOverlap > EPS14) {
|
|
2175
2175
|
const keyA = `${pathAIndex}:${segmentAIndex}`;
|
|
2176
2176
|
const keyB = `${pathBIndex}:${segmentBIndex}`;
|
|
2177
2177
|
if (!seenA.has(keyA)) {
|
|
@@ -2190,7 +2190,7 @@ var TraceOverlapShiftSolver = class extends BaseSolver {
|
|
|
2190
2190
|
}
|
|
2191
2191
|
return;
|
|
2192
2192
|
}
|
|
2193
|
-
if (rangeOverlap < -
|
|
2193
|
+
if (rangeOverlap < -EPS14) return;
|
|
2194
2194
|
const pathA = pathsA[pathAIndex].tracePath;
|
|
2195
2195
|
const pathB = pathsB[pathBIndex].tracePath;
|
|
2196
2196
|
const segmentAStart = pathA[segmentAIndex];
|
|
@@ -2213,8 +2213,8 @@ var TraceOverlapShiftSolver = class extends BaseSolver {
|
|
|
2213
2213
|
for (let sa = 0; sa < ptsA.length - 1; sa++) {
|
|
2214
2214
|
const a1 = ptsA[sa];
|
|
2215
2215
|
const a2 = ptsA[sa + 1];
|
|
2216
|
-
const aVert = Math.abs(a1.x - a2.x) <
|
|
2217
|
-
const aHorz = Math.abs(a1.y - a2.y) <
|
|
2216
|
+
const aVert = Math.abs(a1.x - a2.x) < EPS14;
|
|
2217
|
+
const aHorz = Math.abs(a1.y - a2.y) < EPS14;
|
|
2218
2218
|
if (!aVert && !aHorz) continue;
|
|
2219
2219
|
for (let pb = 0; pb < pathsB.length; pb++) {
|
|
2220
2220
|
const pathB = pathsB[pb];
|
|
@@ -2225,11 +2225,11 @@ var TraceOverlapShiftSolver = class extends BaseSolver {
|
|
|
2225
2225
|
for (let sb = 0; sb < ptsB.length - 1; sb++) {
|
|
2226
2226
|
const b1 = ptsB[sb];
|
|
2227
2227
|
const b2 = ptsB[sb + 1];
|
|
2228
|
-
const bVert = Math.abs(b1.x - b2.x) <
|
|
2229
|
-
const bHorz = Math.abs(b1.y - b2.y) <
|
|
2228
|
+
const bVert = Math.abs(b1.x - b2.x) < EPS14;
|
|
2229
|
+
const bHorz = Math.abs(b1.y - b2.y) < EPS14;
|
|
2230
2230
|
if (!bVert && !bHorz) continue;
|
|
2231
2231
|
if (aVert && bVert) {
|
|
2232
|
-
if (Math.abs(a1.x - b1.x) <
|
|
2232
|
+
if (Math.abs(a1.x - b1.x) < EPS14) {
|
|
2233
2233
|
recordCollinearInteraction({
|
|
2234
2234
|
pathAIndex: pa,
|
|
2235
2235
|
segmentAIndex: sa,
|
|
@@ -2239,7 +2239,7 @@ var TraceOverlapShiftSolver = class extends BaseSolver {
|
|
|
2239
2239
|
});
|
|
2240
2240
|
}
|
|
2241
2241
|
} else if (aHorz && bHorz) {
|
|
2242
|
-
if (Math.abs(a1.y - b1.y) <
|
|
2242
|
+
if (Math.abs(a1.y - b1.y) < EPS14) {
|
|
2243
2243
|
recordCollinearInteraction({
|
|
2244
2244
|
pathAIndex: pa,
|
|
2245
2245
|
segmentAIndex: sa,
|
|
@@ -2295,14 +2295,14 @@ var TraceOverlapShiftSolver = class extends BaseSolver {
|
|
|
2295
2295
|
return null;
|
|
2296
2296
|
}
|
|
2297
2297
|
findNextDiagonalSegment() {
|
|
2298
|
-
const
|
|
2298
|
+
const EPS14 = 2e-3;
|
|
2299
2299
|
for (const mspPairId in this.correctedTraceMap) {
|
|
2300
2300
|
const tracePath = this.correctedTraceMap[mspPairId].tracePath;
|
|
2301
2301
|
for (let i = 0; i < tracePath.length - 1; i++) {
|
|
2302
2302
|
const p1 = tracePath[i];
|
|
2303
2303
|
const p2 = tracePath[i + 1];
|
|
2304
|
-
const isHorizontal4 = Math.abs(p1.y - p2.y) <
|
|
2305
|
-
const isVertical5 = Math.abs(p1.x - p2.x) <
|
|
2304
|
+
const isHorizontal4 = Math.abs(p1.y - p2.y) < EPS14;
|
|
2305
|
+
const isVertical5 = Math.abs(p1.x - p2.x) < EPS14;
|
|
2306
2306
|
if (!isHorizontal4 && !isVertical5) {
|
|
2307
2307
|
return { mspPairId, tracePath, i, p1, p2 };
|
|
2308
2308
|
}
|
|
@@ -2316,13 +2316,13 @@ var TraceOverlapShiftSolver = class extends BaseSolver {
|
|
|
2316
2316
|
return false;
|
|
2317
2317
|
}
|
|
2318
2318
|
const { mspPairId, tracePath, i, p1, p2 } = diagonalInfo;
|
|
2319
|
-
const
|
|
2319
|
+
const EPS14 = 2e-3;
|
|
2320
2320
|
const p0 = i > 0 ? tracePath[i - 1] : null;
|
|
2321
2321
|
const p3 = i + 2 < tracePath.length ? tracePath[i + 2] : null;
|
|
2322
|
-
const prevIsVertical = p0 ? Math.abs(p0.x - p1.x) <
|
|
2323
|
-
const prevIsHorizontal = p0 ? Math.abs(p0.y - p1.y) <
|
|
2324
|
-
const nextIsVertical = p3 ? Math.abs(p2.x - p3.x) <
|
|
2325
|
-
const nextIsHorizontal = p3 ? Math.abs(p2.y - p3.y) <
|
|
2322
|
+
const prevIsVertical = p0 ? Math.abs(p0.x - p1.x) < EPS14 : false;
|
|
2323
|
+
const prevIsHorizontal = p0 ? Math.abs(p0.y - p1.y) < EPS14 : false;
|
|
2324
|
+
const nextIsVertical = p3 ? Math.abs(p2.x - p3.x) < EPS14 : false;
|
|
2325
|
+
const nextIsHorizontal = p3 ? Math.abs(p2.y - p3.y) < EPS14 : false;
|
|
2326
2326
|
const elbow1 = { x: p1.x, y: p2.y };
|
|
2327
2327
|
const elbow2 = { x: p2.x, y: p1.y };
|
|
2328
2328
|
let score1 = 0;
|
|
@@ -2450,24 +2450,24 @@ var ChipObstacleSpatialIndex = class {
|
|
|
2450
2450
|
};
|
|
2451
2451
|
|
|
2452
2452
|
// lib/solvers/NetLabelPlacementSolver/SingleNetLabelPlacementSolver/collisions.ts
|
|
2453
|
-
function segmentIntersectsRect2(p1, p2, rect,
|
|
2454
|
-
const isVert = Math.abs(p1.x - p2.x) <
|
|
2455
|
-
const isHorz = Math.abs(p1.y - p2.y) <
|
|
2453
|
+
function segmentIntersectsRect2(p1, p2, rect, EPS14 = 1e-9) {
|
|
2454
|
+
const isVert = Math.abs(p1.x - p2.x) < EPS14;
|
|
2455
|
+
const isHorz = Math.abs(p1.y - p2.y) < EPS14;
|
|
2456
2456
|
if (!isVert && !isHorz) return false;
|
|
2457
2457
|
if (isVert) {
|
|
2458
2458
|
const x = p1.x;
|
|
2459
|
-
if (x < rect.minX -
|
|
2459
|
+
if (x < rect.minX - EPS14 || x > rect.maxX + EPS14) return false;
|
|
2460
2460
|
const segMinY = Math.min(p1.y, p2.y);
|
|
2461
2461
|
const segMaxY = Math.max(p1.y, p2.y);
|
|
2462
2462
|
const overlap = Math.min(segMaxY, rect.maxY) - Math.max(segMinY, rect.minY);
|
|
2463
|
-
return overlap >
|
|
2463
|
+
return overlap > EPS14;
|
|
2464
2464
|
} else {
|
|
2465
2465
|
const y = p1.y;
|
|
2466
|
-
if (y < rect.minY -
|
|
2466
|
+
if (y < rect.minY - EPS14 || y > rect.maxY + EPS14) return false;
|
|
2467
2467
|
const segMinX = Math.min(p1.x, p2.x);
|
|
2468
2468
|
const segMaxX = Math.max(p1.x, p2.x);
|
|
2469
2469
|
const overlap = Math.min(segMaxX, rect.maxX) - Math.max(segMinX, rect.minX);
|
|
2470
|
-
return overlap >
|
|
2470
|
+
return overlap > EPS14;
|
|
2471
2471
|
}
|
|
2472
2472
|
}
|
|
2473
2473
|
function rectIntersectsAnyTrace(bounds, inputTraceMap, hostPathId, hostSegIndex) {
|
|
@@ -2864,14 +2864,14 @@ var SingleNetLabelPlacementSolver = class extends BaseSolver {
|
|
|
2864
2864
|
};
|
|
2865
2865
|
let bestCandidate = null;
|
|
2866
2866
|
let bestScore = -Infinity;
|
|
2867
|
-
const
|
|
2867
|
+
const EPS14 = 1e-6;
|
|
2868
2868
|
for (const curr of tracesToScan) {
|
|
2869
2869
|
const pts = curr.tracePath.slice();
|
|
2870
2870
|
for (let si = 0; si < pts.length - 1; si++) {
|
|
2871
2871
|
const a = pts[si];
|
|
2872
2872
|
const b = pts[si + 1];
|
|
2873
|
-
const isH = Math.abs(a.y - b.y) <
|
|
2874
|
-
const isV = Math.abs(a.x - b.x) <
|
|
2873
|
+
const isH = Math.abs(a.y - b.y) < EPS14;
|
|
2874
|
+
const isV = Math.abs(a.x - b.x) < EPS14;
|
|
2875
2875
|
if (!isH && !isV) continue;
|
|
2876
2876
|
const segmentAllowed = isH ? ["y+", "y-"] : ["x+", "x-"];
|
|
2877
2877
|
const candidateOrients = orientations.filter(
|
|
@@ -4193,6 +4193,7 @@ var OverlapAvoidanceStepSolver = class extends BaseSolver {
|
|
|
4193
4193
|
detourCounts = /* @__PURE__ */ new Map();
|
|
4194
4194
|
activeSubSolver = null;
|
|
4195
4195
|
overlapQueue = [];
|
|
4196
|
+
activeOverlap = null;
|
|
4196
4197
|
recentlyFailed = /* @__PURE__ */ new Set();
|
|
4197
4198
|
currentlyProcessingOverlap = null;
|
|
4198
4199
|
decomposedChildLabels = null;
|
|
@@ -4234,11 +4235,13 @@ var OverlapAvoidanceStepSolver = class extends BaseSolver {
|
|
|
4234
4235
|
}
|
|
4235
4236
|
}
|
|
4236
4237
|
this.activeSubSolver = null;
|
|
4238
|
+
this.activeOverlap = null;
|
|
4237
4239
|
this.recentlyFailed.clear();
|
|
4238
4240
|
} else if (this.activeSubSolver.failed) {
|
|
4239
|
-
const overlapId = `${this.
|
|
4241
|
+
const overlapId = `${this.activeOverlap.trace.mspPairId}-${this.activeOverlap.label.globalConnNetId}`;
|
|
4240
4242
|
this.recentlyFailed.add(overlapId);
|
|
4241
4243
|
this.activeSubSolver = null;
|
|
4244
|
+
this.activeOverlap = null;
|
|
4242
4245
|
} else {
|
|
4243
4246
|
}
|
|
4244
4247
|
return;
|
|
@@ -4291,6 +4294,7 @@ var OverlapAvoidanceStepSolver = class extends BaseSolver {
|
|
|
4291
4294
|
actualOverlapLabel.globalConnNetId,
|
|
4292
4295
|
detourCount2 + 1
|
|
4293
4296
|
);
|
|
4297
|
+
this.activeOverlap = nextOverlap;
|
|
4294
4298
|
this.activeSubSolver = new SingleOverlapSolver({
|
|
4295
4299
|
trace: traceToFix,
|
|
4296
4300
|
label: actualOverlapLabel,
|
|
@@ -4328,6 +4332,7 @@ var OverlapAvoidanceStepSolver = class extends BaseSolver {
|
|
|
4328
4332
|
actualOverlapLabel.globalConnNetId,
|
|
4329
4333
|
detourCount2 + 1
|
|
4330
4334
|
);
|
|
4335
|
+
this.activeOverlap = nextOverlap;
|
|
4331
4336
|
this.activeSubSolver = new SingleOverlapSolver({
|
|
4332
4337
|
trace: traceToFix,
|
|
4333
4338
|
label: actualOverlapLabel,
|
|
@@ -4345,6 +4350,7 @@ var OverlapAvoidanceStepSolver = class extends BaseSolver {
|
|
|
4345
4350
|
}
|
|
4346
4351
|
const detourCount = this.detourCounts.get(labelToAvoid.globalConnNetId) ?? 0;
|
|
4347
4352
|
this.detourCounts.set(labelToAvoid.globalConnNetId, detourCount + 1);
|
|
4353
|
+
this.activeOverlap = nextOverlap;
|
|
4348
4354
|
this.activeSubSolver = new SingleOverlapSolver({
|
|
4349
4355
|
trace: traceToFix,
|
|
4350
4356
|
label: labelToAvoid,
|
|
@@ -4619,6 +4625,81 @@ var distance3 = (p1, p2) => {
|
|
|
4619
4625
|
return Math.sqrt(Math.pow(p1.x - p2.x, 2) + Math.pow(p1.y - p2.y, 2));
|
|
4620
4626
|
};
|
|
4621
4627
|
var manhattanDistance = (p1, p2) => Math.abs(p1.x - p2.x) + Math.abs(p1.y - p2.y);
|
|
4628
|
+
var EPS6 = 1e-9;
|
|
4629
|
+
var between = (value, first, second) => value >= Math.min(first, second) - EPS6 && value <= Math.max(first, second) + EPS6;
|
|
4630
|
+
var getAxisAlignedIntersection = (firstStart, firstEnd, secondStart, secondEnd) => {
|
|
4631
|
+
const firstIsHorizontal = Math.abs(firstStart.y - firstEnd.y) <= EPS6;
|
|
4632
|
+
const firstIsVertical = Math.abs(firstStart.x - firstEnd.x) <= EPS6;
|
|
4633
|
+
const secondIsHorizontal = Math.abs(secondStart.y - secondEnd.y) <= EPS6;
|
|
4634
|
+
const secondIsVertical = Math.abs(secondStart.x - secondEnd.x) <= EPS6;
|
|
4635
|
+
if (firstIsHorizontal && secondIsVertical) {
|
|
4636
|
+
const point = { x: secondStart.x, y: firstStart.y };
|
|
4637
|
+
return between(point.x, firstStart.x, firstEnd.x) && between(point.y, secondStart.y, secondEnd.y) ? point : null;
|
|
4638
|
+
}
|
|
4639
|
+
if (firstIsVertical && secondIsHorizontal) {
|
|
4640
|
+
const point = { x: firstStart.x, y: secondStart.y };
|
|
4641
|
+
return between(point.y, firstStart.y, firstEnd.y) && between(point.x, secondStart.x, secondEnd.x) ? point : null;
|
|
4642
|
+
}
|
|
4643
|
+
if (firstIsHorizontal && secondIsHorizontal && Math.abs(firstStart.y - secondStart.y) <= EPS6) {
|
|
4644
|
+
const overlapMin = Math.max(
|
|
4645
|
+
Math.min(firstStart.x, firstEnd.x),
|
|
4646
|
+
Math.min(secondStart.x, secondEnd.x)
|
|
4647
|
+
);
|
|
4648
|
+
const overlapMax = Math.min(
|
|
4649
|
+
Math.max(firstStart.x, firstEnd.x),
|
|
4650
|
+
Math.max(secondStart.x, secondEnd.x)
|
|
4651
|
+
);
|
|
4652
|
+
if (overlapMin > overlapMax + EPS6) return null;
|
|
4653
|
+
return {
|
|
4654
|
+
x: Math.max(overlapMin, Math.min(firstStart.x, overlapMax)),
|
|
4655
|
+
y: firstStart.y
|
|
4656
|
+
};
|
|
4657
|
+
}
|
|
4658
|
+
if (firstIsVertical && secondIsVertical && Math.abs(firstStart.x - secondStart.x) <= EPS6) {
|
|
4659
|
+
const overlapMin = Math.max(
|
|
4660
|
+
Math.min(firstStart.y, firstEnd.y),
|
|
4661
|
+
Math.min(secondStart.y, secondEnd.y)
|
|
4662
|
+
);
|
|
4663
|
+
const overlapMax = Math.min(
|
|
4664
|
+
Math.max(firstStart.y, firstEnd.y),
|
|
4665
|
+
Math.max(secondStart.y, secondEnd.y)
|
|
4666
|
+
);
|
|
4667
|
+
if (overlapMin > overlapMax + EPS6) return null;
|
|
4668
|
+
return {
|
|
4669
|
+
x: firstStart.x,
|
|
4670
|
+
y: Math.max(overlapMin, Math.min(firstStart.y, overlapMax))
|
|
4671
|
+
};
|
|
4672
|
+
}
|
|
4673
|
+
return null;
|
|
4674
|
+
};
|
|
4675
|
+
var clipPathAtFirstIntersection = (tracePath, existingTraces) => {
|
|
4676
|
+
for (let pathIndex = 0; pathIndex < tracePath.length - 1; pathIndex++) {
|
|
4677
|
+
const pathStart = tracePath[pathIndex];
|
|
4678
|
+
const pathEnd = tracePath[pathIndex + 1];
|
|
4679
|
+
const intersections = existingTraces.flatMap(
|
|
4680
|
+
(trace) => trace.tracePath.slice(0, -1).flatMap((traceStart, traceIndex) => {
|
|
4681
|
+
const intersection2 = getAxisAlignedIntersection(
|
|
4682
|
+
pathStart,
|
|
4683
|
+
pathEnd,
|
|
4684
|
+
traceStart,
|
|
4685
|
+
trace.tracePath[traceIndex + 1]
|
|
4686
|
+
);
|
|
4687
|
+
return intersection2 ? [intersection2] : [];
|
|
4688
|
+
})
|
|
4689
|
+
);
|
|
4690
|
+
intersections.sort(
|
|
4691
|
+
(first, second) => distance3(pathStart, first) - distance3(pathStart, second)
|
|
4692
|
+
);
|
|
4693
|
+
const intersection = intersections[0];
|
|
4694
|
+
if (!intersection) continue;
|
|
4695
|
+
const clippedPath = tracePath.slice(0, pathIndex + 1);
|
|
4696
|
+
if (distance3(clippedPath.at(-1), intersection) > EPS6) {
|
|
4697
|
+
clippedPath.push(intersection);
|
|
4698
|
+
}
|
|
4699
|
+
return clippedPath;
|
|
4700
|
+
}
|
|
4701
|
+
return null;
|
|
4702
|
+
};
|
|
4622
4703
|
var LongDistancePairSolver = class extends BaseSolver {
|
|
4623
4704
|
constructor(params) {
|
|
4624
4705
|
super();
|
|
@@ -4733,20 +4814,36 @@ var LongDistancePairSolver = class extends BaseSolver {
|
|
|
4733
4814
|
} else if (this.subSolver?.solved) {
|
|
4734
4815
|
const newTracePath = this.subSolver.solvedTracePath;
|
|
4735
4816
|
if (newTracePath && this.currentCandidatePair) {
|
|
4817
|
+
const [p1, p2] = this.currentCandidatePair;
|
|
4818
|
+
const globalConnNetId = this.netConnMap.getNetConnectedToId(p1.pinId);
|
|
4819
|
+
const sameNetTraces = this.allSolvedTraces.filter(
|
|
4820
|
+
(trace) => trace.globalConnNetId === globalConnNetId
|
|
4821
|
+
);
|
|
4822
|
+
const inputNetConnection = this.inputProblem.netConnections.find(
|
|
4823
|
+
(connection) => connection.pinIds.length === 3 && connection.pinIds.includes(p1.pinId) && connection.pinIds.includes(p2.pinId)
|
|
4824
|
+
);
|
|
4825
|
+
const sourceChip = this.chipMap[p1.chipId];
|
|
4826
|
+
const targetRailTrace = sameNetTraces.find(
|
|
4827
|
+
(trace) => trace.pinIds.includes(p2.pinId) && trace.pins.every((pin) => pin.chipId === p2.chipId)
|
|
4828
|
+
);
|
|
4829
|
+
const canJoinThreePinNet = inputNetConnection !== void 0 && sourceChip?.pins.length === 2 && targetRailTrace !== void 0;
|
|
4830
|
+
const junctionTracePath = canJoinThreePinNet ? clipPathAtFirstIntersection(newTracePath, sameNetTraces) : null;
|
|
4831
|
+
const acceptedTracePath = junctionTracePath ?? newTracePath;
|
|
4832
|
+
const tracesToCheck = junctionTracePath ? this.allSolvedTraces.filter(
|
|
4833
|
+
(trace) => trace.globalConnNetId !== globalConnNetId
|
|
4834
|
+
) : this.allSolvedTraces;
|
|
4736
4835
|
const isTraceClear = !doesTraceOverlapWithExistingTraces(
|
|
4737
|
-
|
|
4738
|
-
|
|
4836
|
+
acceptedTracePath,
|
|
4837
|
+
tracesToCheck
|
|
4739
4838
|
);
|
|
4740
4839
|
if (isTraceClear) {
|
|
4741
|
-
const [p1, p2] = this.currentCandidatePair;
|
|
4742
|
-
const globalConnNetId = this.netConnMap.getNetConnectedToId(p1.pinId);
|
|
4743
4840
|
const mspPairId = `${p1.pinId}-${p2.pinId}`;
|
|
4744
4841
|
const newSolvedTrace = {
|
|
4745
4842
|
mspPairId,
|
|
4746
4843
|
dcConnNetId: globalConnNetId,
|
|
4747
4844
|
globalConnNetId,
|
|
4748
4845
|
pins: [p1, p2],
|
|
4749
|
-
tracePath:
|
|
4846
|
+
tracePath: acceptedTracePath,
|
|
4750
4847
|
mspConnectionPairIds: [mspPairId],
|
|
4751
4848
|
pinIds: [p1.pinId, p2.pinId]
|
|
4752
4849
|
};
|
|
@@ -5525,9 +5622,9 @@ var moveRailSegments = (trace, segments, coordinate) => {
|
|
|
5525
5622
|
};
|
|
5526
5623
|
|
|
5527
5624
|
// lib/solvers/RailNetLabelCornerPlacementSolver/geometry.ts
|
|
5528
|
-
var
|
|
5625
|
+
var EPS7 = 1e-6;
|
|
5529
5626
|
var isTraceLine = (trace) => getUniquePinCount(trace.pinIds) >= 2;
|
|
5530
|
-
var rectsOverlap = (a, b) => Math.min(a.maxX, b.maxX) - Math.max(a.minX, b.minX) >
|
|
5627
|
+
var rectsOverlap = (a, b) => Math.min(a.maxX, b.maxX) - Math.max(a.minX, b.minX) > EPS7 && Math.min(a.maxY, b.maxY) - Math.max(a.minY, b.minY) > EPS7;
|
|
5531
5628
|
var getTraceCorners = (path) => {
|
|
5532
5629
|
const corners = [];
|
|
5533
5630
|
for (let i = 1; i < path.length - 1; i++) {
|
|
@@ -5551,11 +5648,11 @@ var getUniquePinCount = (pinIds) => new Set(pinIds).size;
|
|
|
5551
5648
|
var isTraceCorner = (a, b, c) => getSegmentOrientation(a, b) !== getSegmentOrientation(b, c);
|
|
5552
5649
|
var isPointOnSegment = (point, start, end) => {
|
|
5553
5650
|
if (getSegmentOrientation(start, end) === "horizontal") {
|
|
5554
|
-
return Math.abs(point.y - start.y) <=
|
|
5651
|
+
return Math.abs(point.y - start.y) <= EPS7 && point.x >= Math.min(start.x, end.x) - EPS7 && point.x <= Math.max(start.x, end.x) + EPS7;
|
|
5555
5652
|
}
|
|
5556
|
-
return Math.abs(point.x - start.x) <=
|
|
5653
|
+
return Math.abs(point.x - start.x) <= EPS7 && point.y >= Math.min(start.y, end.y) - EPS7 && point.y <= Math.max(start.y, end.y) + EPS7;
|
|
5557
5654
|
};
|
|
5558
|
-
var getSegmentOrientation = (a, b) => Math.abs(a.y - b.y) <=
|
|
5655
|
+
var getSegmentOrientation = (a, b) => Math.abs(a.y - b.y) <= EPS7 ? "horizontal" : "vertical";
|
|
5559
5656
|
|
|
5560
5657
|
// lib/solvers/TraceCleanupSolver/sameNetRailAlignment/preservesLabelAnchors.ts
|
|
5561
5658
|
var getAnchoredTraceIds = (label, traces) => new Set(
|
|
@@ -5571,17 +5668,17 @@ var preservesLabelAnchors = (labels, before, after) => labels.every((label) => {
|
|
|
5571
5668
|
});
|
|
5572
5669
|
|
|
5573
5670
|
// lib/solvers/Example28Solver/types.ts
|
|
5574
|
-
var
|
|
5671
|
+
var EPS8 = 1e-9;
|
|
5575
5672
|
|
|
5576
5673
|
// lib/solvers/Example28Solver/segmentRunsAlongRectBoundary.ts
|
|
5577
5674
|
var segmentRunsAlongRectBoundary = (start, end, rect) => {
|
|
5578
|
-
const isVertical5 = Math.abs(start.x - end.x) <
|
|
5579
|
-
const isHorizontal4 = Math.abs(start.y - end.y) <
|
|
5675
|
+
const isVertical5 = Math.abs(start.x - end.x) < EPS8;
|
|
5676
|
+
const isHorizontal4 = Math.abs(start.y - end.y) < EPS8;
|
|
5580
5677
|
if (isVertical5) {
|
|
5581
|
-
return Math.abs(start.x - rect.minX) <
|
|
5678
|
+
return Math.abs(start.x - rect.minX) < EPS8 || Math.abs(start.x - rect.maxX) < EPS8;
|
|
5582
5679
|
}
|
|
5583
5680
|
if (isHorizontal4) {
|
|
5584
|
-
return Math.abs(start.y - rect.minY) <
|
|
5681
|
+
return Math.abs(start.y - rect.minY) < EPS8 || Math.abs(start.y - rect.maxY) < EPS8;
|
|
5585
5682
|
}
|
|
5586
5683
|
return false;
|
|
5587
5684
|
};
|
|
@@ -5596,10 +5693,10 @@ var getPathLength2 = (path) => {
|
|
|
5596
5693
|
return length;
|
|
5597
5694
|
};
|
|
5598
5695
|
var getDistance2 = (a, b) => Math.abs(a.x - b.x) + Math.abs(a.y - b.y);
|
|
5599
|
-
var isAxisAlignedSegment = (start, end) => Math.abs(start.x - end.x) <
|
|
5600
|
-
var getSegmentOrientation2 = (start, end) => Math.abs(start.y - end.y) <
|
|
5696
|
+
var isAxisAlignedSegment = (start, end) => Math.abs(start.x - end.x) < EPS8 || Math.abs(start.y - end.y) < EPS8;
|
|
5697
|
+
var getSegmentOrientation2 = (start, end) => Math.abs(start.y - end.y) < EPS8 ? "horizontal" : "vertical";
|
|
5601
5698
|
var projectPointToSegment = (point, start, end) => {
|
|
5602
|
-
if (Math.abs(start.x - end.x) <
|
|
5699
|
+
if (Math.abs(start.x - end.x) < EPS8) {
|
|
5603
5700
|
return {
|
|
5604
5701
|
x: start.x,
|
|
5605
5702
|
y: Math.min(
|
|
@@ -5608,7 +5705,7 @@ var projectPointToSegment = (point, start, end) => {
|
|
|
5608
5705
|
)
|
|
5609
5706
|
};
|
|
5610
5707
|
}
|
|
5611
|
-
if (Math.abs(start.y - end.y) <
|
|
5708
|
+
if (Math.abs(start.y - end.y) < EPS8) {
|
|
5612
5709
|
return {
|
|
5613
5710
|
x: Math.min(
|
|
5614
5711
|
Math.max(point.x, Math.min(start.x, end.x)),
|
|
@@ -5651,9 +5748,9 @@ var findSegmentContainingPoint = (path, point) => {
|
|
|
5651
5748
|
};
|
|
5652
5749
|
var isPointWithinSegmentPrimaryRange = (point, segment) => {
|
|
5653
5750
|
if (segment.orientation === "horizontal") {
|
|
5654
|
-
return point.x >= Math.min(segment.start.x, segment.end.x) -
|
|
5751
|
+
return point.x >= Math.min(segment.start.x, segment.end.x) - EPS8 && point.x <= Math.max(segment.start.x, segment.end.x) + EPS8;
|
|
5655
5752
|
}
|
|
5656
|
-
return point.y >= Math.min(segment.start.y, segment.end.y) -
|
|
5753
|
+
return point.y >= Math.min(segment.start.y, segment.end.y) - EPS8 && point.y <= Math.max(segment.start.y, segment.end.y) + EPS8;
|
|
5657
5754
|
};
|
|
5658
5755
|
var findPreferredReroutedSegment = (path, originalSegmentIndex, originalSegmentCount, orientation, anchorPoint) => {
|
|
5659
5756
|
const matchingSegments = getSegments(path).filter(
|
|
@@ -5681,24 +5778,24 @@ var projectPointToPath = (point, path) => {
|
|
|
5681
5778
|
return bestPoint;
|
|
5682
5779
|
};
|
|
5683
5780
|
var segmentsIntersect = (a1, a2, b1, b2) => {
|
|
5684
|
-
const aVertical = Math.abs(a1.x - a2.x) <
|
|
5685
|
-
const bVertical = Math.abs(b1.x - b2.x) <
|
|
5686
|
-
const
|
|
5781
|
+
const aVertical = Math.abs(a1.x - a2.x) < EPS8;
|
|
5782
|
+
const bVertical = Math.abs(b1.x - b2.x) < EPS8;
|
|
5783
|
+
const between2 = (value, p1, p2) => value >= Math.min(p1, p2) - EPS8 && value <= Math.max(p1, p2) + EPS8;
|
|
5687
5784
|
if (aVertical && bVertical) {
|
|
5688
|
-
if (Math.abs(a1.x - b1.x) >
|
|
5785
|
+
if (Math.abs(a1.x - b1.x) > EPS8) return false;
|
|
5689
5786
|
const overlap = Math.min(Math.max(a1.y, a2.y), Math.max(b1.y, b2.y)) - Math.max(Math.min(a1.y, a2.y), Math.min(b1.y, b2.y));
|
|
5690
|
-
return overlap >
|
|
5787
|
+
return overlap > EPS8;
|
|
5691
5788
|
}
|
|
5692
5789
|
if (!aVertical && !bVertical) {
|
|
5693
|
-
if (Math.abs(a1.y - b1.y) >
|
|
5790
|
+
if (Math.abs(a1.y - b1.y) > EPS8) return false;
|
|
5694
5791
|
const overlap = Math.min(Math.max(a1.x, a2.x), Math.max(b1.x, b2.x)) - Math.max(Math.min(a1.x, a2.x), Math.min(b1.x, b2.x));
|
|
5695
|
-
return overlap >
|
|
5792
|
+
return overlap > EPS8;
|
|
5696
5793
|
}
|
|
5697
5794
|
const verticalA = aVertical ? a1 : b1;
|
|
5698
5795
|
const verticalB = aVertical ? a2 : b2;
|
|
5699
5796
|
const horizontalA = aVertical ? b1 : a1;
|
|
5700
5797
|
const horizontalB = aVertical ? b2 : a2;
|
|
5701
|
-
return
|
|
5798
|
+
return between2(verticalA.x, horizontalA.x, horizontalB.x) && between2(horizontalA.y, verticalA.y, verticalB.y);
|
|
5702
5799
|
};
|
|
5703
5800
|
var countPathIntersections = (pathA, pathB) => {
|
|
5704
5801
|
let count = 0;
|
|
@@ -6068,7 +6165,7 @@ var getTraceObstacles = (allTraces, excludeTraceId) => {
|
|
|
6068
6165
|
|
|
6069
6166
|
// lib/solvers/TraceCleanupSolver/sub-solver/findIntersectionsWithObstacles.ts
|
|
6070
6167
|
import { getSegmentIntersection } from "@tscircuit/math-utils/line-intersections";
|
|
6071
|
-
var
|
|
6168
|
+
var EPS9 = 1e-6;
|
|
6072
6169
|
var findIntersectionsWithObstacles = (p1, p2, obstacles) => {
|
|
6073
6170
|
const intersections = [];
|
|
6074
6171
|
for (const obstacle of obstacles) {
|
|
@@ -6087,17 +6184,17 @@ var findIntersectionsWithObstacles = (p1, p2, obstacles) => {
|
|
|
6087
6184
|
}
|
|
6088
6185
|
return intersections;
|
|
6089
6186
|
};
|
|
6090
|
-
var isSamePoint = (first, second) => Math.abs(first.x - second.x) <
|
|
6187
|
+
var isSamePoint = (first, second) => Math.abs(first.x - second.x) < EPS9 && Math.abs(first.y - second.y) < EPS9;
|
|
6091
6188
|
var findPerpendicularPathCrossings = (path, otherPath) => {
|
|
6092
6189
|
const crossings = [];
|
|
6093
6190
|
for (let pathSegmentIndex = 1; pathSegmentIndex < path.length - 2; pathSegmentIndex++) {
|
|
6094
6191
|
const start = path[pathSegmentIndex];
|
|
6095
6192
|
const end = path[pathSegmentIndex + 1];
|
|
6096
|
-
const isVertical5 = Math.abs(start.x - end.x) <
|
|
6193
|
+
const isVertical5 = Math.abs(start.x - end.x) < EPS9;
|
|
6097
6194
|
for (let otherPathSegmentIndex = 1; otherPathSegmentIndex < otherPath.length - 2; otherPathSegmentIndex++) {
|
|
6098
6195
|
const otherStart = otherPath[otherPathSegmentIndex];
|
|
6099
6196
|
const otherEnd = otherPath[otherPathSegmentIndex + 1];
|
|
6100
|
-
const otherIsVertical = Math.abs(otherStart.x - otherEnd.x) <
|
|
6197
|
+
const otherIsVertical = Math.abs(otherStart.x - otherEnd.x) < EPS9;
|
|
6101
6198
|
if (isVertical5 === otherIsVertical) continue;
|
|
6102
6199
|
const intersection = getSegmentIntersection(
|
|
6103
6200
|
start,
|
|
@@ -6117,8 +6214,8 @@ var findPerpendicularPathCrossings = (path, otherPath) => {
|
|
|
6117
6214
|
};
|
|
6118
6215
|
|
|
6119
6216
|
// lib/solvers/TraceCleanupSolver/sub-solver/generateLShapeRerouteCandidates.ts
|
|
6120
|
-
var
|
|
6121
|
-
var isVertical3 = (a, b, eps =
|
|
6217
|
+
var EPS10 = 1e-6;
|
|
6218
|
+
var isVertical3 = (a, b, eps = EPS10) => Math.abs(a.x - b.x) < eps;
|
|
6122
6219
|
var generateLShapeRerouteCandidates = ({
|
|
6123
6220
|
lShape,
|
|
6124
6221
|
rectangle,
|
|
@@ -6131,7 +6228,7 @@ var generateLShapeRerouteCandidates = ({
|
|
|
6131
6228
|
let c2;
|
|
6132
6229
|
let i1_padded = interactionPoint1;
|
|
6133
6230
|
let i2_padded = interactionPoint2;
|
|
6134
|
-
if (Math.abs(p2.x - x) <
|
|
6231
|
+
if (Math.abs(p2.x - x) < EPS10 && Math.abs(p2.y - (y + height)) < EPS10) {
|
|
6135
6232
|
c2 = { x: x + width + padding, y: y - padding };
|
|
6136
6233
|
if (isVertical3(p1, p2)) {
|
|
6137
6234
|
i1_padded = { x: interactionPoint1.x, y: interactionPoint1.y - padding };
|
|
@@ -6143,7 +6240,7 @@ var generateLShapeRerouteCandidates = ({
|
|
|
6143
6240
|
} else {
|
|
6144
6241
|
i2_padded = { x: interactionPoint2.x + padding, y: interactionPoint2.y };
|
|
6145
6242
|
}
|
|
6146
|
-
} else if (Math.abs(p2.x - (x + width)) <
|
|
6243
|
+
} else if (Math.abs(p2.x - (x + width)) < EPS10 && Math.abs(p2.y - (y + height)) < EPS10) {
|
|
6147
6244
|
c2 = { x: x - padding, y: y - padding };
|
|
6148
6245
|
if (isVertical3(p1, p2)) {
|
|
6149
6246
|
i1_padded = { x: interactionPoint1.x, y: interactionPoint1.y - padding };
|
|
@@ -6155,7 +6252,7 @@ var generateLShapeRerouteCandidates = ({
|
|
|
6155
6252
|
} else {
|
|
6156
6253
|
i2_padded = { x: interactionPoint2.x - padding, y: interactionPoint2.y };
|
|
6157
6254
|
}
|
|
6158
|
-
} else if (Math.abs(p2.x - x) <
|
|
6255
|
+
} else if (Math.abs(p2.x - x) < EPS10 && Math.abs(p2.y - y) < EPS10) {
|
|
6159
6256
|
c2 = { x: x + width + padding, y: y + height + padding };
|
|
6160
6257
|
if (isVertical3(p1, p2)) {
|
|
6161
6258
|
i1_padded = { x: interactionPoint1.x, y: interactionPoint1.y + padding };
|
|
@@ -6167,7 +6264,7 @@ var generateLShapeRerouteCandidates = ({
|
|
|
6167
6264
|
} else {
|
|
6168
6265
|
i2_padded = { x: interactionPoint2.x + padding, y: interactionPoint2.y };
|
|
6169
6266
|
}
|
|
6170
|
-
} else if (Math.abs(p2.x - (x + width)) <
|
|
6267
|
+
} else if (Math.abs(p2.x - (x + width)) < EPS10 && Math.abs(p2.y - y) < EPS10) {
|
|
6171
6268
|
c2 = { x: x - padding, y: y + height + padding };
|
|
6172
6269
|
if (isVertical3(p1, p2)) {
|
|
6173
6270
|
i1_padded = { x: interactionPoint1.x, y: interactionPoint1.y + padding };
|
|
@@ -6195,7 +6292,7 @@ var generatePerpendicularTraceDetours = ({
|
|
|
6195
6292
|
const buildDetours = (path, index) => {
|
|
6196
6293
|
const start = path[index];
|
|
6197
6294
|
const end = path[index + 1];
|
|
6198
|
-
const movingAxis = Math.abs(start.x - end.x) <
|
|
6295
|
+
const movingAxis = Math.abs(start.x - end.x) < EPS10 ? "y" : "x";
|
|
6199
6296
|
const detourAxis = movingAxis === "x" ? "y" : "x";
|
|
6200
6297
|
const gate = obstacleStart[movingAxis] + Math.sign(start[movingAxis] - obstacleStart[movingAxis]) * clearance;
|
|
6201
6298
|
const obstacleRange = [obstacleStart[detourAxis], obstacleEnd[detourAxis]];
|
|
@@ -6793,9 +6890,9 @@ var UntangleTraceSubsolver = class extends BaseSolver {
|
|
|
6793
6890
|
};
|
|
6794
6891
|
|
|
6795
6892
|
// lib/solvers/TraceCleanupSolver/is4PointRectangle.ts
|
|
6796
|
-
var
|
|
6797
|
-
var sameX = (a, b) => Math.abs(a.x - b.x) <=
|
|
6798
|
-
var sameY = (a, b) => Math.abs(a.y - b.y) <=
|
|
6893
|
+
var EPS11 = 1e-6;
|
|
6894
|
+
var sameX = (a, b) => Math.abs(a.x - b.x) <= EPS11;
|
|
6895
|
+
var sameY = (a, b) => Math.abs(a.y - b.y) <= EPS11;
|
|
6799
6896
|
var is4PointRectangle = (path) => {
|
|
6800
6897
|
if (path.length !== 4) return false;
|
|
6801
6898
|
const [p0, p1, p2, p3] = path;
|
|
@@ -7070,7 +7167,7 @@ var doesPathRunAlongChipBoundary = (path, chipObstacles) => {
|
|
|
7070
7167
|
const end = path[i + 1];
|
|
7071
7168
|
for (const obstacle of chipObstacles) {
|
|
7072
7169
|
if (!segmentRunsAlongRectBoundary(start, end, obstacle)) continue;
|
|
7073
|
-
if (getSegmentOverlapWithRectSpan(start, end, obstacle) >
|
|
7170
|
+
if (getSegmentOverlapWithRectSpan(start, end, obstacle) > EPS8) {
|
|
7074
7171
|
return true;
|
|
7075
7172
|
}
|
|
7076
7173
|
}
|
|
@@ -7085,13 +7182,13 @@ var getChipBoundaryOverlap = (path, chipObstacles) => {
|
|
|
7085
7182
|
for (const obstacle of chipObstacles) {
|
|
7086
7183
|
if (!segmentRunsAlongRectBoundary(start, end, obstacle)) continue;
|
|
7087
7184
|
const overlap = getSegmentOverlapWithRectSpan(start, end, obstacle);
|
|
7088
|
-
if (overlap >
|
|
7185
|
+
if (overlap > EPS8) total += overlap;
|
|
7089
7186
|
}
|
|
7090
7187
|
}
|
|
7091
7188
|
return total;
|
|
7092
7189
|
};
|
|
7093
7190
|
var getSegmentOverlapWithRectSpan = (start, end, rect) => {
|
|
7094
|
-
const isVertical5 = Math.abs(start.x - end.x) <
|
|
7191
|
+
const isVertical5 = Math.abs(start.x - end.x) < EPS8;
|
|
7095
7192
|
if (isVertical5) {
|
|
7096
7193
|
return Math.min(Math.max(start.y, end.y), rect.maxY) - Math.max(Math.min(start.y, end.y), rect.minY);
|
|
7097
7194
|
}
|
|
@@ -7855,16 +7952,16 @@ var createPortOnlyLabelConnectorTrace = ({
|
|
|
7855
7952
|
// lib/solvers/AvailableNetOrientationSolver/constants.ts
|
|
7856
7953
|
var LABEL_SEARCH_STEP = 0.05;
|
|
7857
7954
|
var WICK_CLEARANCE = 1e-3;
|
|
7858
|
-
var
|
|
7859
|
-
var TRACE_BOUNDARY_TOLERANCE = WICK_CLEARANCE +
|
|
7955
|
+
var EPS12 = 1e-9;
|
|
7956
|
+
var TRACE_BOUNDARY_TOLERANCE = WICK_CLEARANCE + EPS12;
|
|
7860
7957
|
var CANDIDATE_SELECTED_COLOR2 = "blue";
|
|
7861
7958
|
var CANDIDATE_REJECTED_COLOR2 = "red";
|
|
7862
7959
|
|
|
7863
7960
|
// lib/solvers/AvailableNetOrientationSolver/geometry.ts
|
|
7864
7961
|
var isYOrientation = (orientation) => orientation === "y+" || orientation === "y-";
|
|
7865
7962
|
var isXOrientation = (orientation) => orientation === "x+" || orientation === "x-";
|
|
7866
|
-
var rectsOverlap2 = (a, b) => Math.min(a.maxX, b.maxX) - Math.max(a.minX, b.minX) >
|
|
7867
|
-
var rangesOverlap = (minA, maxA, minB, maxB) => Math.min(maxA, maxB) - Math.max(minA, minB) >
|
|
7963
|
+
var rectsOverlap2 = (a, b) => Math.min(a.maxX, b.maxX) - Math.max(a.minX, b.minX) > EPS12 && Math.min(a.maxY, b.maxY) - Math.max(a.minY, b.minY) > EPS12;
|
|
7964
|
+
var rangesOverlap = (minA, maxA, minB, maxB) => Math.min(maxA, maxB) - Math.max(minA, minB) > EPS12;
|
|
7868
7965
|
var traceCrossesBoundsInterior = (bounds, traceMap) => {
|
|
7869
7966
|
for (const trace of Object.values(traceMap)) {
|
|
7870
7967
|
const points = trace.tracePath;
|
|
@@ -7887,7 +7984,7 @@ var segmentCrossesBoundsInterior = (p1, p2, bounds) => {
|
|
|
7887
7984
|
return false;
|
|
7888
7985
|
}
|
|
7889
7986
|
if (sameX2(p1, p2)) {
|
|
7890
|
-
if (p1.x <= interiorBounds.minX +
|
|
7987
|
+
if (p1.x <= interiorBounds.minX + EPS12 || p1.x >= interiorBounds.maxX - EPS12) {
|
|
7891
7988
|
return false;
|
|
7892
7989
|
}
|
|
7893
7990
|
return rangesOverlap(
|
|
@@ -7898,7 +7995,7 @@ var segmentCrossesBoundsInterior = (p1, p2, bounds) => {
|
|
|
7898
7995
|
);
|
|
7899
7996
|
}
|
|
7900
7997
|
if (sameY2(p1, p2)) {
|
|
7901
|
-
if (p1.y <= interiorBounds.minY +
|
|
7998
|
+
if (p1.y <= interiorBounds.minY + EPS12 || p1.y >= interiorBounds.maxY - EPS12) {
|
|
7902
7999
|
return false;
|
|
7903
8000
|
}
|
|
7904
8001
|
return rangesOverlap(
|
|
@@ -7954,8 +8051,8 @@ var simplifyOrthogonalPath = (path) => {
|
|
|
7954
8051
|
return simplified;
|
|
7955
8052
|
};
|
|
7956
8053
|
var pointsEqual2 = (a, b) => sameX2(a, b) && sameY2(a, b);
|
|
7957
|
-
var sameX2 = (a, b) => Math.abs(a.x - b.x) <=
|
|
7958
|
-
var sameY2 = (a, b) => Math.abs(a.y - b.y) <=
|
|
8054
|
+
var sameX2 = (a, b) => Math.abs(a.x - b.x) <= EPS12;
|
|
8055
|
+
var sameY2 = (a, b) => Math.abs(a.y - b.y) <= EPS12;
|
|
7959
8056
|
var getMaxSearchDistance = (inputProblem) => {
|
|
7960
8057
|
const maxChipWidth = Math.max(
|
|
7961
8058
|
...inputProblem.chips.map((chip) => chip.width),
|
|
@@ -8411,7 +8508,7 @@ var AvailableNetOrientationSolver = class extends BaseSolver {
|
|
|
8411
8508
|
index,
|
|
8412
8509
|
pin: this.pinMap[otherLabel.pinIds[0]]
|
|
8413
8510
|
})).filter(
|
|
8414
|
-
({ index, pin: otherPin }) => this.crowdedPortOnlyLabelIndices.has(index) && otherPin?.chipId === pin.chipId && otherPin.x > pin.x +
|
|
8511
|
+
({ index, pin: otherPin }) => this.crowdedPortOnlyLabelIndices.has(index) && otherPin?.chipId === pin.chipId && otherPin.x > pin.x + EPS12
|
|
8415
8512
|
).sort((a, b) => a.pin.x - b.pin.x)[0]?.pin;
|
|
8416
8513
|
if (orientation === "y-" && nextPinToRight) return null;
|
|
8417
8514
|
const anchorX = orientation === "y-" ? Math.max(
|
|
@@ -8444,7 +8541,7 @@ var AvailableNetOrientationSolver = class extends BaseSolver {
|
|
|
8444
8541
|
const centeredAnchorY = hasUpFacingStack ? (lowestUpFacingLabelY + highestUpFacingLabelY) / 2 : stackedAnchorY;
|
|
8445
8542
|
const anchorYs = orientation === "y-" ? [centeredAnchorY, stackedAnchorY] : [stackedAnchorY];
|
|
8446
8543
|
for (const anchorY of anchorYs) {
|
|
8447
|
-
if (anchorY - label.anchorPoint.y > this.maxSearchDistance +
|
|
8544
|
+
if (anchorY - label.anchorPoint.y > this.maxSearchDistance + EPS12) {
|
|
8448
8545
|
continue;
|
|
8449
8546
|
}
|
|
8450
8547
|
const candidate = this.createCandidate(
|
|
@@ -8473,11 +8570,11 @@ var AvailableNetOrientationSolver = class extends BaseSolver {
|
|
|
8473
8570
|
if (trace.globalConnNetId !== label.globalConnNetId) return false;
|
|
8474
8571
|
const path = trace.tracePath;
|
|
8475
8572
|
return path.some((point, pointIndex) => {
|
|
8476
|
-
if (Math.abs(point.x - label.anchorPoint.x) >
|
|
8573
|
+
if (Math.abs(point.x - label.anchorPoint.x) > EPS12 || Math.abs(point.y - label.anchorPoint.y) > EPS12) {
|
|
8477
8574
|
return false;
|
|
8478
8575
|
}
|
|
8479
8576
|
return [path[pointIndex - 1], path[pointIndex + 1]].some(
|
|
8480
|
-
(neighbor) => neighbor && Math.abs(neighbor.x - point.x) <=
|
|
8577
|
+
(neighbor) => neighbor && Math.abs(neighbor.x - point.x) <= EPS12 && (neighbor.y - point.y) * direction.y > EPS12
|
|
8481
8578
|
);
|
|
8482
8579
|
});
|
|
8483
8580
|
});
|
|
@@ -8567,7 +8664,7 @@ var AvailableNetOrientationSolver = class extends BaseSolver {
|
|
|
8567
8664
|
orientation
|
|
8568
8665
|
);
|
|
8569
8666
|
if (outwardDirection.x === 0 && outwardDirection.y === 0) continue;
|
|
8570
|
-
for (let distance5 = LABEL_SEARCH_STEP; distance5 <= this.maxSearchDistance +
|
|
8667
|
+
for (let distance5 = LABEL_SEARCH_STEP; distance5 <= this.maxSearchDistance + EPS12; distance5 += LABEL_SEARCH_STEP) {
|
|
8571
8668
|
const anchorPoint = {
|
|
8572
8669
|
x: connectorSource.x + outwardDirection.x * distance5,
|
|
8573
8670
|
y: connectorSource.y + outwardDirection.y * distance5
|
|
@@ -8622,7 +8719,7 @@ var AvailableNetOrientationSolver = class extends BaseSolver {
|
|
|
8622
8719
|
);
|
|
8623
8720
|
const maxSearchDistance = this.getSearchDistanceLimit(label, orientation);
|
|
8624
8721
|
const maxOutwardDistance = outwardDirection.x === 0 && outwardDirection.y === 0 ? 0 : this.maxSearchDistance;
|
|
8625
|
-
for (let outwardDistance = 0; outwardDistance <= maxOutwardDistance +
|
|
8722
|
+
for (let outwardDistance = 0; outwardDistance <= maxOutwardDistance + EPS12; outwardDistance += LABEL_SEARCH_STEP) {
|
|
8626
8723
|
const baseAnchor = {
|
|
8627
8724
|
x: initialBaseAnchor.x + outwardDirection.x * outwardDistance,
|
|
8628
8725
|
y: initialBaseAnchor.y + outwardDirection.y * outwardDistance
|
|
@@ -8696,7 +8793,7 @@ var AvailableNetOrientationSolver = class extends BaseSolver {
|
|
|
8696
8793
|
phase = "shift",
|
|
8697
8794
|
stopOnTraceCollision = true
|
|
8698
8795
|
} = params;
|
|
8699
|
-
for (let distance5 = LABEL_SEARCH_STEP; distance5 <= maxSearchDistance +
|
|
8796
|
+
for (let distance5 = LABEL_SEARCH_STEP; distance5 <= maxSearchDistance + EPS12; distance5 += LABEL_SEARCH_STEP) {
|
|
8700
8797
|
const anchorPoint = {
|
|
8701
8798
|
x: baseAnchor.x + direction.x * distance5,
|
|
8702
8799
|
y: baseAnchor.y + direction.y * distance5
|
|
@@ -9002,9 +9099,9 @@ var AvailableNetOrientationSolver = class extends BaseSolver {
|
|
|
9002
9099
|
const { anchorPoint, orientation } = candidate;
|
|
9003
9100
|
const chipBounds = chip.bounds;
|
|
9004
9101
|
if (isYOrientation(orientation)) {
|
|
9005
|
-
return anchorPoint.x < chipBounds.minX -
|
|
9102
|
+
return anchorPoint.x < chipBounds.minX - EPS12 || anchorPoint.x > chipBounds.maxX + EPS12;
|
|
9006
9103
|
}
|
|
9007
|
-
return anchorPoint.y < chipBounds.minY -
|
|
9104
|
+
return anchorPoint.y < chipBounds.minY - EPS12 || anchorPoint.y > chipBounds.maxY + EPS12;
|
|
9008
9105
|
});
|
|
9009
9106
|
}
|
|
9010
9107
|
getBoundsStatus(candidateBoundsCheck) {
|
|
@@ -9105,8 +9202,8 @@ var AvailableNetOrientationSolver = class extends BaseSolver {
|
|
|
9105
9202
|
if (!chip) return null;
|
|
9106
9203
|
const sides = new Set(
|
|
9107
9204
|
pins.map((pin) => {
|
|
9108
|
-
if (Math.abs(pin.x - chip.bounds.minX) <=
|
|
9109
|
-
if (Math.abs(pin.x - chip.bounds.maxX) <=
|
|
9205
|
+
if (Math.abs(pin.x - chip.bounds.minX) <= EPS12) return "left";
|
|
9206
|
+
if (Math.abs(pin.x - chip.bounds.maxX) <= EPS12) return "right";
|
|
9110
9207
|
return null;
|
|
9111
9208
|
})
|
|
9112
9209
|
);
|
|
@@ -9139,8 +9236,8 @@ var AvailableNetOrientationSolver = class extends BaseSolver {
|
|
|
9139
9236
|
sharesChipBoundary(bounds) {
|
|
9140
9237
|
for (const chip of this.chipObstacleSpatialIndex.chips) {
|
|
9141
9238
|
const chipBounds = chip.bounds;
|
|
9142
|
-
const adjacentToVerticalSide = Math.abs(bounds.minX - chipBounds.maxX) <= WICK_CLEARANCE +
|
|
9143
|
-
const adjacentToHorizontalSide = Math.abs(bounds.minY - chipBounds.maxY) <= WICK_CLEARANCE +
|
|
9239
|
+
const adjacentToVerticalSide = Math.abs(bounds.minX - chipBounds.maxX) <= WICK_CLEARANCE + EPS12 || Math.abs(bounds.maxX - chipBounds.minX) <= WICK_CLEARANCE + EPS12;
|
|
9240
|
+
const adjacentToHorizontalSide = Math.abs(bounds.minY - chipBounds.maxY) <= WICK_CLEARANCE + EPS12 || Math.abs(bounds.maxY - chipBounds.minY) <= WICK_CLEARANCE + EPS12;
|
|
9144
9241
|
if (adjacentToVerticalSide && rangesOverlap(
|
|
9145
9242
|
bounds.minY,
|
|
9146
9243
|
bounds.maxY,
|
|
@@ -9202,7 +9299,7 @@ var AvailableNetOrientationSolver = class extends BaseSolver {
|
|
|
9202
9299
|
let nearestDistance = Number.POSITIVE_INFINITY;
|
|
9203
9300
|
for (const chip of this.chipObstacleSpatialIndex.chips) {
|
|
9204
9301
|
const bounds = chip.bounds;
|
|
9205
|
-
if (point.x < bounds.minX -
|
|
9302
|
+
if (point.x < bounds.minX - EPS12 || point.x > bounds.maxX + EPS12 || point.y < bounds.minY - EPS12 || point.y > bounds.maxY + EPS12) {
|
|
9206
9303
|
continue;
|
|
9207
9304
|
}
|
|
9208
9305
|
for (const [side, distance5] of getSideDistances(point, bounds)) {
|
|
@@ -9219,8 +9316,8 @@ var AvailableNetOrientationSolver = class extends BaseSolver {
|
|
|
9219
9316
|
let nearestDistanceSq = Number.POSITIVE_INFINITY;
|
|
9220
9317
|
for (const chip of this.chipObstacleSpatialIndex.chips) {
|
|
9221
9318
|
const bounds = chip.bounds;
|
|
9222
|
-
const dx = point.x < bounds.minX -
|
|
9223
|
-
const dy = point.y < bounds.minY -
|
|
9319
|
+
const dx = point.x < bounds.minX - EPS12 ? bounds.minX - point.x : point.x > bounds.maxX + EPS12 ? point.x - bounds.maxX : 0;
|
|
9320
|
+
const dy = point.y < bounds.minY - EPS12 ? bounds.minY - point.y : point.y > bounds.maxY + EPS12 ? point.y - bounds.maxY : 0;
|
|
9224
9321
|
if (dx === 0 && dy === 0) continue;
|
|
9225
9322
|
const distanceSq = dx ** 2 + dy ** 2;
|
|
9226
9323
|
if (distanceSq >= nearestDistanceSq) continue;
|
|
@@ -9536,7 +9633,7 @@ var RailNetLabelCornerPlacementSolver = class extends BaseSolver {
|
|
|
9536
9633
|
for (const anchorPoint of getTraceCorners(path)) {
|
|
9537
9634
|
const cornerIndex = path.indexOf(anchorPoint);
|
|
9538
9635
|
const anchorAlignedToPin = pins.some(
|
|
9539
|
-
(pin) => Math.abs(pin.x - anchorPoint.x) <=
|
|
9636
|
+
(pin) => Math.abs(pin.x - anchorPoint.x) <= EPS7
|
|
9540
9637
|
);
|
|
9541
9638
|
const pinAligned = anchorAlignedToPin || allowRailAlignedFallback && this.isPinAlignedCorner(path, cornerIndex);
|
|
9542
9639
|
if (!pinAligned) continue;
|
|
@@ -9576,12 +9673,12 @@ var RailNetLabelCornerPlacementSolver = class extends BaseSolver {
|
|
|
9576
9673
|
return traceCrossesBoundsInterior(bounds, otherNetTraceMap);
|
|
9577
9674
|
}
|
|
9578
9675
|
pointsEqual(a, b) {
|
|
9579
|
-
return Math.abs(a.x - b.x) <=
|
|
9676
|
+
return Math.abs(a.x - b.x) <= EPS7 && Math.abs(a.y - b.y) <= EPS7;
|
|
9580
9677
|
}
|
|
9581
9678
|
getVerticalSegmentPointIndices(path, cornerIndex) {
|
|
9582
9679
|
const corner = path[cornerIndex];
|
|
9583
|
-
const previousIsVertical = Math.abs(path[cornerIndex - 1].x - corner.x) <=
|
|
9584
|
-
const nextIsVertical = Math.abs(path[cornerIndex + 1].x - corner.x) <=
|
|
9680
|
+
const previousIsVertical = Math.abs(path[cornerIndex - 1].x - corner.x) <= EPS7;
|
|
9681
|
+
const nextIsVertical = Math.abs(path[cornerIndex + 1].x - corner.x) <= EPS7;
|
|
9585
9682
|
if (previousIsVertical === nextIsVertical) return null;
|
|
9586
9683
|
const indices = previousIsVertical ? [cornerIndex - 1, cornerIndex] : [cornerIndex, cornerIndex + 1];
|
|
9587
9684
|
return indices;
|
|
@@ -9631,7 +9728,7 @@ var RailNetLabelCornerPlacementSolver = class extends BaseSolver {
|
|
|
9631
9728
|
const end = otherTrace.tracePath[i + 1];
|
|
9632
9729
|
if (!segmentCrossesBoundsInterior(start, end, labelBounds)) continue;
|
|
9633
9730
|
const halfLabelWidth = label.width / 2;
|
|
9634
|
-
if (Math.abs(start.x - end.x) <=
|
|
9731
|
+
if (Math.abs(start.x - end.x) <= EPS7) {
|
|
9635
9732
|
shiftedCoordinates.add(
|
|
9636
9733
|
start.x - halfLabelWidth - LABEL_TRACE_CLEARANCE3
|
|
9637
9734
|
);
|
|
@@ -9649,7 +9746,7 @@ var RailNetLabelCornerPlacementSolver = class extends BaseSolver {
|
|
|
9649
9746
|
}
|
|
9650
9747
|
}
|
|
9651
9748
|
return [...shiftedCoordinates].flatMap((x) => {
|
|
9652
|
-
if (Math.abs(x - corner.x) <=
|
|
9749
|
+
if (Math.abs(x - corner.x) <= EPS7) return [];
|
|
9653
9750
|
const reroutedTracePath = simplifyPath(
|
|
9654
9751
|
path.map(
|
|
9655
9752
|
(point, pointIndex) => verticalPointIndices.includes(pointIndex) ? { ...point, x } : point
|
|
@@ -9780,11 +9877,11 @@ var getOrientationConstraint = (inputProblem, label) => {
|
|
|
9780
9877
|
};
|
|
9781
9878
|
|
|
9782
9879
|
// lib/solvers/TraceAnchoredNetLabelOverlapSolver/geometry.ts
|
|
9783
|
-
var
|
|
9880
|
+
var EPS13 = 1e-6;
|
|
9784
9881
|
var TRACE_BOUNDARY_TOLERANCE2 = 1e-6;
|
|
9785
9882
|
var getLabelBounds = (label) => getRectBounds(label.center, label.width, label.height);
|
|
9786
|
-
var rectsOverlap3 = (a, b) => Math.min(a.maxX, b.maxX) - Math.max(a.minX, b.minX) >
|
|
9787
|
-
var rectsTouchOrOverlap = (a, b) => Math.min(a.maxX, b.maxX) - Math.max(a.minX, b.minX) >= -
|
|
9883
|
+
var rectsOverlap3 = (a, b) => Math.min(a.maxX, b.maxX) - Math.max(a.minX, b.minX) > EPS13 && Math.min(a.maxY, b.maxY) - Math.max(a.minY, b.minY) > EPS13;
|
|
9884
|
+
var rectsTouchOrOverlap = (a, b) => Math.min(a.maxX, b.maxX) - Math.max(a.minX, b.minX) >= -EPS13 && Math.min(a.maxY, b.maxY) - Math.max(a.minY, b.minY) >= -EPS13;
|
|
9788
9885
|
var traceCrossesBoundsInterior2 = (bounds, traces) => {
|
|
9789
9886
|
for (const trace of traces) {
|
|
9790
9887
|
const points = trace.tracePath;
|
|
@@ -9830,7 +9927,7 @@ var getPointAtTraceDistance = (trace, distance5) => {
|
|
|
9830
9927
|
const end = trace.tracePath[i + 1];
|
|
9831
9928
|
const segmentLength = getManhattanDistance(start, end);
|
|
9832
9929
|
const nextDistance = pathDistance + segmentLength;
|
|
9833
|
-
if (distance5 <= nextDistance +
|
|
9930
|
+
if (distance5 <= nextDistance + EPS13) {
|
|
9834
9931
|
const offset = Math.max(
|
|
9835
9932
|
0,
|
|
9836
9933
|
Math.min(segmentLength, distance5 - pathDistance)
|
|
@@ -9869,7 +9966,7 @@ var segmentCrossesBoundsInterior2 = (start, end, bounds) => {
|
|
|
9869
9966
|
return false;
|
|
9870
9967
|
}
|
|
9871
9968
|
if (isVertical4(start, end)) {
|
|
9872
|
-
if (start.x <= interior.minX +
|
|
9969
|
+
if (start.x <= interior.minX + EPS13 || start.x >= interior.maxX - EPS13) {
|
|
9873
9970
|
return false;
|
|
9874
9971
|
}
|
|
9875
9972
|
return rangesOverlap2(
|
|
@@ -9880,7 +9977,7 @@ var segmentCrossesBoundsInterior2 = (start, end, bounds) => {
|
|
|
9880
9977
|
);
|
|
9881
9978
|
}
|
|
9882
9979
|
if (isHorizontal3(start, end)) {
|
|
9883
|
-
if (start.y <= interior.minY +
|
|
9980
|
+
if (start.y <= interior.minY + EPS13 || start.y >= interior.maxY - EPS13) {
|
|
9884
9981
|
return false;
|
|
9885
9982
|
}
|
|
9886
9983
|
return rangesOverlap2(
|
|
@@ -9894,10 +9991,10 @@ var segmentCrossesBoundsInterior2 = (start, end, bounds) => {
|
|
|
9894
9991
|
};
|
|
9895
9992
|
var isPointOnSegment2 = (point, start, end) => {
|
|
9896
9993
|
if (isHorizontal3(start, end)) {
|
|
9897
|
-
return Math.abs(point.y - start.y) <=
|
|
9994
|
+
return Math.abs(point.y - start.y) <= EPS13 && point.x >= Math.min(start.x, end.x) - EPS13 && point.x <= Math.max(start.x, end.x) + EPS13;
|
|
9898
9995
|
}
|
|
9899
9996
|
if (isVertical4(start, end)) {
|
|
9900
|
-
return Math.abs(point.x - start.x) <=
|
|
9997
|
+
return Math.abs(point.x - start.x) <= EPS13 && point.y >= Math.min(start.y, end.y) - EPS13 && point.y <= Math.max(start.y, end.y) + EPS13;
|
|
9901
9998
|
}
|
|
9902
9999
|
return false;
|
|
9903
10000
|
};
|
|
@@ -9905,9 +10002,9 @@ var getSegmentDirection = (start, end) => ({
|
|
|
9905
10002
|
x: isVertical4(start, end) ? 0 : Math.sign(end.x - start.x),
|
|
9906
10003
|
y: isHorizontal3(start, end) ? 0 : Math.sign(end.y - start.y)
|
|
9907
10004
|
});
|
|
9908
|
-
var isHorizontal3 = (start, end) => Math.abs(start.y - end.y) <=
|
|
9909
|
-
var isVertical4 = (start, end) => Math.abs(start.x - end.x) <=
|
|
9910
|
-
var rangesOverlap2 = (minA, maxA, minB, maxB) => Math.min(maxA, maxB) - Math.max(minA, minB) >
|
|
10005
|
+
var isHorizontal3 = (start, end) => Math.abs(start.y - end.y) <= EPS13;
|
|
10006
|
+
var isVertical4 = (start, end) => Math.abs(start.x - end.x) <= EPS13;
|
|
10007
|
+
var rangesOverlap2 = (minA, maxA, minB, maxB) => Math.min(maxA, maxB) - Math.max(minA, minB) > EPS13;
|
|
9911
10008
|
var getUniquePinCount2 = (pinIds) => new Set(pinIds).size;
|
|
9912
10009
|
|
|
9913
10010
|
// lib/solvers/TraceAnchoredNetLabelOverlapSolver/candidates.ts
|
|
@@ -9964,7 +10061,7 @@ var getCandidateDistances = (traceLength, vertexDistances) => {
|
|
|
9964
10061
|
for (const distance5 of vertexDistances) {
|
|
9965
10062
|
distances.add(roundDistance(distance5));
|
|
9966
10063
|
}
|
|
9967
|
-
return [...distances].filter((distance5) => distance5 >= -
|
|
10064
|
+
return [...distances].filter((distance5) => distance5 >= -EPS13 && distance5 <= traceLength + EPS13).sort((a, b) => a - b);
|
|
9968
10065
|
};
|
|
9969
10066
|
var getOrientationsForPoint = (params) => {
|
|
9970
10067
|
const { inputProblem, label, point, orientationConstraint } = params;
|
|
@@ -10053,13 +10150,13 @@ var getOutwardOrientationOptions = (point, chipBounds) => {
|
|
|
10053
10150
|
};
|
|
10054
10151
|
var getOutwardAxisOption = (params) => {
|
|
10055
10152
|
const { value, min, max, center, positiveOrientation, negativeOrientation } = params;
|
|
10056
|
-
if (value > max +
|
|
10153
|
+
if (value > max + EPS13) {
|
|
10057
10154
|
return {
|
|
10058
10155
|
orientation: positiveOrientation,
|
|
10059
10156
|
outwardScore: 1 + value - max
|
|
10060
10157
|
};
|
|
10061
10158
|
}
|
|
10062
|
-
if (value < min -
|
|
10159
|
+
if (value < min - EPS13) {
|
|
10063
10160
|
return {
|
|
10064
10161
|
orientation: negativeOrientation,
|
|
10065
10162
|
outwardScore: 1 + min - value
|
|
@@ -10070,7 +10167,7 @@ var getOutwardAxisOption = (params) => {
|
|
|
10070
10167
|
outwardScore: getNormalizedCenterDistance(value, center, max - min)
|
|
10071
10168
|
};
|
|
10072
10169
|
};
|
|
10073
|
-
var getNormalizedCenterDistance = (value, center, span) => Math.abs(value - center) / Math.max(
|
|
10170
|
+
var getNormalizedCenterDistance = (value, center, span) => Math.abs(value - center) / Math.max(EPS13, span / 2);
|
|
10074
10171
|
var ALL_ORIENTATIONS = ["x+", "x-", "y+", "y-"];
|
|
10075
10172
|
var getFlippedOrientation = (orientation) => {
|
|
10076
10173
|
switch (orientation) {
|
|
@@ -10143,7 +10240,7 @@ var getNetLabelHeight = (inputProblem, label) => {
|
|
|
10143
10240
|
)?.netLabelHeight;
|
|
10144
10241
|
};
|
|
10145
10242
|
var roundDistance = (distance5) => Number(distance5.toFixed(6));
|
|
10146
|
-
var isSamePlacement = (label, point, orientation) => Math.abs(point.x - label.anchorPoint.x) <=
|
|
10243
|
+
var isSamePlacement = (label, point, orientation) => Math.abs(point.x - label.anchorPoint.x) <= EPS13 && Math.abs(point.y - label.anchorPoint.y) <= EPS13 && orientation === label.orientation;
|
|
10147
10244
|
|
|
10148
10245
|
// lib/solvers/TraceAnchoredNetLabelOverlapSolver/visualize.ts
|
|
10149
10246
|
var CANDIDATE_SELECTED_COLOR4 = "blue";
|