@tscircuit/capacity-autorouter 0.0.42 → 0.0.43
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 +8 -0
- package/dist/index.js +363 -114
- package/dist/index.js.map +1 -1
- package/package.json +5 -3
package/dist/index.js
CHANGED
|
@@ -68,6 +68,9 @@ var BaseSolver = class {
|
|
|
68
68
|
}
|
|
69
69
|
_step() {
|
|
70
70
|
}
|
|
71
|
+
getConstructorParams() {
|
|
72
|
+
throw new Error("getConstructorParams not implemented");
|
|
73
|
+
}
|
|
71
74
|
solve() {
|
|
72
75
|
const startTime = Date.now();
|
|
73
76
|
while (!this.solved && !this.failed) {
|
|
@@ -1938,6 +1941,86 @@ function distance(p1, p2) {
|
|
|
1938
1941
|
return Math.sqrt(dx * dx + dy * dy);
|
|
1939
1942
|
}
|
|
1940
1943
|
|
|
1944
|
+
// node_modules/@tscircuit/math-utils/dist/chunk-MHHTZHOJ.js
|
|
1945
|
+
function getBoundingBox(box) {
|
|
1946
|
+
const halfWidth = box.width / 2;
|
|
1947
|
+
const halfHeight = box.height / 2;
|
|
1948
|
+
return {
|
|
1949
|
+
minX: box.center.x - halfWidth,
|
|
1950
|
+
maxX: box.center.x + halfWidth,
|
|
1951
|
+
minY: box.center.y - halfHeight,
|
|
1952
|
+
maxY: box.center.y + halfHeight
|
|
1953
|
+
};
|
|
1954
|
+
}
|
|
1955
|
+
function computeDistanceBetweenBoxes(boxA, boxB) {
|
|
1956
|
+
const a = getBoundingBox(boxA);
|
|
1957
|
+
const b = getBoundingBox(boxB);
|
|
1958
|
+
const dx = Math.max(a.minX - b.maxX, b.minX - a.maxX, 0);
|
|
1959
|
+
const dy = Math.max(a.minY - b.maxY, b.minY - a.maxY, 0);
|
|
1960
|
+
const pointA = { x: 0, y: 0 };
|
|
1961
|
+
const pointB = { x: 0, y: 0 };
|
|
1962
|
+
if (dx === 0 && dy === 0) {
|
|
1963
|
+
return { distance: 0, pointA: boxA.center, pointB: boxB.center };
|
|
1964
|
+
}
|
|
1965
|
+
pointA.x = clamp(boxA.center.x, b.minX, b.maxX);
|
|
1966
|
+
pointA.y = clamp(boxA.center.y, b.minY, b.maxY);
|
|
1967
|
+
pointB.x = clamp(boxB.center.x, a.minX, a.maxX);
|
|
1968
|
+
pointB.y = clamp(boxB.center.y, a.minY, a.maxY);
|
|
1969
|
+
const distance6 = Math.hypot(pointA.x - pointB.x, pointA.y - pointB.y);
|
|
1970
|
+
return { distance: distance6, pointA, pointB };
|
|
1971
|
+
}
|
|
1972
|
+
function clamp(value, min, max) {
|
|
1973
|
+
return Math.max(min, Math.min(max, value));
|
|
1974
|
+
}
|
|
1975
|
+
|
|
1976
|
+
// node_modules/@tscircuit/math-utils/dist/chunk-OMVVSGKD.js
|
|
1977
|
+
function segmentToBoundsMinDistance(a, b, bounds) {
|
|
1978
|
+
const topLeft = { x: bounds.minX, y: bounds.minY };
|
|
1979
|
+
const topRight = { x: bounds.maxX, y: bounds.minY };
|
|
1980
|
+
const bottomLeft = { x: bounds.minX, y: bounds.maxY };
|
|
1981
|
+
const bottomRight = { x: bounds.maxX, y: bounds.maxY };
|
|
1982
|
+
if (doSegmentsIntersect(a, b, topLeft, topRight) || doSegmentsIntersect(a, b, topRight, bottomRight) || doSegmentsIntersect(a, b, bottomRight, bottomLeft) || doSegmentsIntersect(a, b, bottomLeft, topLeft)) {
|
|
1983
|
+
return 0;
|
|
1984
|
+
}
|
|
1985
|
+
if (a.x >= bounds.minX && a.x <= bounds.maxX && a.y >= bounds.minY && a.y <= bounds.maxY && b.x >= bounds.minX && b.x <= bounds.maxX && b.y >= bounds.minY && b.y <= bounds.maxY) {
|
|
1986
|
+
return 0;
|
|
1987
|
+
}
|
|
1988
|
+
const distances = [
|
|
1989
|
+
pointToSegmentDistance(topLeft, a, b),
|
|
1990
|
+
pointToSegmentDistance(topRight, a, b),
|
|
1991
|
+
pointToSegmentDistance(bottomLeft, a, b),
|
|
1992
|
+
pointToSegmentDistance(bottomRight, a, b)
|
|
1993
|
+
];
|
|
1994
|
+
if (a.x >= bounds.minX && a.x <= bounds.maxX && a.y >= bounds.minY && a.y <= bounds.maxY) {
|
|
1995
|
+
return 0;
|
|
1996
|
+
}
|
|
1997
|
+
if (b.x >= bounds.minX && b.x <= bounds.maxX && b.y >= bounds.minY && b.y <= bounds.maxY) {
|
|
1998
|
+
return 0;
|
|
1999
|
+
}
|
|
2000
|
+
if (a.x < bounds.minX || a.x > bounds.maxX || a.y < bounds.minY || a.y > bounds.maxY) {
|
|
2001
|
+
const closestX = clamp(a.x, bounds.minX, bounds.maxX);
|
|
2002
|
+
const closestY = clamp(a.y, bounds.minY, bounds.maxY);
|
|
2003
|
+
distances.push(distance(a, { x: closestX, y: closestY }));
|
|
2004
|
+
}
|
|
2005
|
+
if (b.x < bounds.minX || b.x > bounds.maxX || b.y < bounds.minY || b.y > bounds.maxY) {
|
|
2006
|
+
const closestX = clamp(b.x, bounds.minX, bounds.maxX);
|
|
2007
|
+
const closestY = clamp(b.y, bounds.minY, bounds.maxY);
|
|
2008
|
+
distances.push(distance(b, { x: closestX, y: closestY }));
|
|
2009
|
+
}
|
|
2010
|
+
return Math.min(...distances);
|
|
2011
|
+
}
|
|
2012
|
+
function segmentToBoxMinDistance(a, b, box) {
|
|
2013
|
+
const halfWidth = box.width / 2;
|
|
2014
|
+
const halfHeight = box.height / 2;
|
|
2015
|
+
const bounds = {
|
|
2016
|
+
minX: box.center.x - halfWidth,
|
|
2017
|
+
maxX: box.center.x + halfWidth,
|
|
2018
|
+
minY: box.center.y - halfHeight,
|
|
2019
|
+
maxY: box.center.y + halfHeight
|
|
2020
|
+
};
|
|
2021
|
+
return segmentToBoundsMinDistance(a, b, bounds);
|
|
2022
|
+
}
|
|
2023
|
+
|
|
1941
2024
|
// lib/data-structures/SingleRouteCandidatePriorityQueue.ts
|
|
1942
2025
|
var SingleRouteCandidatePriorityQueue = class {
|
|
1943
2026
|
heap = [];
|
|
@@ -3573,13 +3656,13 @@ function findClosestPointToABCWithinBounds(A, B, C, radius, bounds) {
|
|
|
3573
3656
|
x: (A.x + B.x + C.x) / 3,
|
|
3574
3657
|
y: (A.y + B.y + C.y) / 3
|
|
3575
3658
|
};
|
|
3576
|
-
const
|
|
3659
|
+
const distance6 = (p1, p2) => {
|
|
3577
3660
|
return Math.sqrt((p2.x - p1.x) ** 2 + (p2.y - p1.y) ** 2);
|
|
3578
3661
|
};
|
|
3579
3662
|
const isValidPoint = (point) => {
|
|
3580
|
-
const distToA =
|
|
3581
|
-
const distToB =
|
|
3582
|
-
const distToC =
|
|
3663
|
+
const distToA = distance6(point, A);
|
|
3664
|
+
const distToB = distance6(point, B);
|
|
3665
|
+
const distToC = distance6(point, C);
|
|
3583
3666
|
const withinBounds = point.x >= bounds.minX && point.x <= bounds.maxX && point.y >= bounds.minY && point.y <= bounds.maxY;
|
|
3584
3667
|
return distToA >= radius && distToB >= radius && distToC >= radius && withinBounds;
|
|
3585
3668
|
};
|
|
@@ -3623,10 +3706,10 @@ function findClosestPointToABCWithinBounds(A, B, C, radius, bounds) {
|
|
|
3623
3706
|
};
|
|
3624
3707
|
const result = [];
|
|
3625
3708
|
const epsilon = 1e-6;
|
|
3626
|
-
if (Math.abs(
|
|
3709
|
+
if (Math.abs(distance6(intersection1, c1) - r) < epsilon && Math.abs(distance6(intersection1, c2) - r) < epsilon) {
|
|
3627
3710
|
result.push(intersection1);
|
|
3628
3711
|
}
|
|
3629
|
-
if (Math.abs(
|
|
3712
|
+
if (Math.abs(distance6(intersection2, c1) - r) < epsilon && Math.abs(distance6(intersection2, c2) - r) < epsilon) {
|
|
3630
3713
|
result.push(intersection2);
|
|
3631
3714
|
}
|
|
3632
3715
|
return result;
|
|
@@ -3650,7 +3733,7 @@ function findClosestPointToABCWithinBounds(A, B, C, radius, bounds) {
|
|
|
3650
3733
|
const interiorCandidates = validCandidates.filter((p) => !isOnBoundary(p));
|
|
3651
3734
|
if (interiorCandidates.length > 0) {
|
|
3652
3735
|
interiorCandidates.sort(
|
|
3653
|
-
(a, b) =>
|
|
3736
|
+
(a, b) => distance6(a, avgPoint) - distance6(b, avgPoint)
|
|
3654
3737
|
);
|
|
3655
3738
|
return interiorCandidates[0];
|
|
3656
3739
|
}
|
|
@@ -3662,7 +3745,7 @@ function findClosestPointToABCWithinBounds(A, B, C, radius, bounds) {
|
|
|
3662
3745
|
for (let y = bounds.minY + 1; y < bounds.maxY; y += gridStep) {
|
|
3663
3746
|
const point = { x, y };
|
|
3664
3747
|
if (isValidPoint(point)) {
|
|
3665
|
-
const dist =
|
|
3748
|
+
const dist = distance6(point, avgPoint);
|
|
3666
3749
|
if (dist < bestDistance) {
|
|
3667
3750
|
bestDistance = dist;
|
|
3668
3751
|
bestPoint = point;
|
|
@@ -3697,7 +3780,7 @@ function findClosestPointToABCWithinBounds(A, B, C, radius, bounds) {
|
|
|
3697
3780
|
const validBoundaryPoints = boundaryPoints.filter(isValidPoint);
|
|
3698
3781
|
if (validBoundaryPoints.length > 0) {
|
|
3699
3782
|
validBoundaryPoints.sort(
|
|
3700
|
-
(a, b) =>
|
|
3783
|
+
(a, b) => distance6(a, avgPoint) - distance6(b, avgPoint)
|
|
3701
3784
|
);
|
|
3702
3785
|
return validBoundaryPoints[0];
|
|
3703
3786
|
}
|
|
@@ -3705,9 +3788,9 @@ function findClosestPointToABCWithinBounds(A, B, C, radius, bounds) {
|
|
|
3705
3788
|
let leastBadPoint = { x: bounds.minX, y: bounds.minY };
|
|
3706
3789
|
for (const point of [...allCandidates, ...boundaryPoints]) {
|
|
3707
3790
|
if (point.x >= bounds.minX && point.x <= bounds.maxX && point.y >= bounds.minY && point.y <= bounds.maxY) {
|
|
3708
|
-
const violationA = Math.max(0, radius -
|
|
3709
|
-
const violationB = Math.max(0, radius -
|
|
3710
|
-
const violationC = Math.max(0, radius -
|
|
3791
|
+
const violationA = Math.max(0, radius - distance6(point, A));
|
|
3792
|
+
const violationB = Math.max(0, radius - distance6(point, B));
|
|
3793
|
+
const violationC = Math.max(0, radius - distance6(point, C));
|
|
3711
3794
|
const totalViolation = violationA + violationB + violationC;
|
|
3712
3795
|
if (totalViolation < minViolation) {
|
|
3713
3796
|
minViolation = totalViolation;
|
|
@@ -3722,12 +3805,62 @@ function findClosestPointToABCWithinBounds(A, B, C, radius, bounds) {
|
|
|
3722
3805
|
function findPointToGetAroundCircle(A, C, Q) {
|
|
3723
3806
|
const B = computeTangentPoint(C, A, Q.center, Q.radius);
|
|
3724
3807
|
const D = computeTangentPoint(A, C, Q.center, Q.radius);
|
|
3725
|
-
const
|
|
3726
|
-
|
|
3727
|
-
|
|
3728
|
-
|
|
3729
|
-
|
|
3730
|
-
|
|
3808
|
+
const distBC = distance2(B, C);
|
|
3809
|
+
const distAD = distance2(A, D);
|
|
3810
|
+
const minDistThreshold = 1e-6;
|
|
3811
|
+
const BIsValid = distBC > minDistThreshold;
|
|
3812
|
+
const DIsValid = distAD > minDistThreshold;
|
|
3813
|
+
let E;
|
|
3814
|
+
if (!BIsValid || !DIsValid) {
|
|
3815
|
+
const midAC = {
|
|
3816
|
+
x: (A.x + C.x) / 2,
|
|
3817
|
+
y: (A.y + C.y) / 2
|
|
3818
|
+
};
|
|
3819
|
+
const distFromCenter = distance2(midAC, Q.center);
|
|
3820
|
+
if (distFromCenter < Q.radius * 1.1) {
|
|
3821
|
+
const dirFromCenter = {
|
|
3822
|
+
x: (midAC.x - Q.center.x) / distFromCenter,
|
|
3823
|
+
y: (midAC.y - Q.center.y) / distFromCenter
|
|
3824
|
+
};
|
|
3825
|
+
E = {
|
|
3826
|
+
x: Q.center.x + dirFromCenter.x * Q.radius * 1.2,
|
|
3827
|
+
y: Q.center.y + dirFromCenter.y * Q.radius * 1.2
|
|
3828
|
+
};
|
|
3829
|
+
} else {
|
|
3830
|
+
E = midAC;
|
|
3831
|
+
}
|
|
3832
|
+
} else {
|
|
3833
|
+
E = {
|
|
3834
|
+
x: (B.x + D.x) / 2,
|
|
3835
|
+
y: (B.y + D.y) / 2
|
|
3836
|
+
};
|
|
3837
|
+
const distBE = distance2(B, E);
|
|
3838
|
+
const distDE = distance2(D, E);
|
|
3839
|
+
if (Math.abs(distBE - distDE) > Math.min(distBE, distDE) * 0.5) {
|
|
3840
|
+
const distAB = distance2(A, B);
|
|
3841
|
+
const distCD = distance2(C, D);
|
|
3842
|
+
const totalDist = distAB + distCD;
|
|
3843
|
+
if (totalDist > minDistThreshold) {
|
|
3844
|
+
const weightB = distCD / totalDist;
|
|
3845
|
+
const weightD = distAB / totalDist;
|
|
3846
|
+
E = {
|
|
3847
|
+
x: B.x * weightB + D.x * weightD,
|
|
3848
|
+
y: B.y * weightB + D.y * weightD
|
|
3849
|
+
};
|
|
3850
|
+
}
|
|
3851
|
+
}
|
|
3852
|
+
const distEToCenter = distance2(E, Q.center);
|
|
3853
|
+
if (distEToCenter < Q.radius * 1.05) {
|
|
3854
|
+
const dirFromCenter = {
|
|
3855
|
+
x: (E.x - Q.center.x) / distEToCenter,
|
|
3856
|
+
y: (E.y - Q.center.y) / distEToCenter
|
|
3857
|
+
};
|
|
3858
|
+
E = {
|
|
3859
|
+
x: Q.center.x + dirFromCenter.x * Q.radius * 1.2,
|
|
3860
|
+
y: Q.center.y + dirFromCenter.y * Q.radius * 1.2
|
|
3861
|
+
};
|
|
3862
|
+
}
|
|
3863
|
+
}
|
|
3731
3864
|
return { B, D, E };
|
|
3732
3865
|
}
|
|
3733
3866
|
function computeTangentPoint(observationPoint, referencePoint, circleCenter, radius) {
|
|
@@ -3736,8 +3869,29 @@ function computeTangentPoint(observationPoint, referencePoint, circleCenter, rad
|
|
|
3736
3869
|
circleCenter.y - observationPoint.y
|
|
3737
3870
|
];
|
|
3738
3871
|
const CQLength = Math.sqrt(CQ[0] * CQ[0] + CQ[1] * CQ[1]);
|
|
3739
|
-
if (CQLength
|
|
3740
|
-
|
|
3872
|
+
if (CQLength <= radius) {
|
|
3873
|
+
if (CQLength < 1e-8) {
|
|
3874
|
+
const refVec = [
|
|
3875
|
+
referencePoint.x - observationPoint.x,
|
|
3876
|
+
referencePoint.y - observationPoint.y
|
|
3877
|
+
];
|
|
3878
|
+
const refLength = Math.sqrt(refVec[0] * refVec[0] + refVec[1] * refVec[1]);
|
|
3879
|
+
if (refLength < 1e-8) {
|
|
3880
|
+
return {
|
|
3881
|
+
x: circleCenter.x + radius,
|
|
3882
|
+
y: circleCenter.y
|
|
3883
|
+
};
|
|
3884
|
+
}
|
|
3885
|
+
return {
|
|
3886
|
+
x: circleCenter.x + refVec[0] / refLength * radius,
|
|
3887
|
+
y: circleCenter.y + refVec[1] / refLength * radius
|
|
3888
|
+
};
|
|
3889
|
+
}
|
|
3890
|
+
const CQUnit2 = [CQ[0] / CQLength, CQ[1] / CQLength];
|
|
3891
|
+
return {
|
|
3892
|
+
x: circleCenter.x - CQUnit2[0] * radius,
|
|
3893
|
+
y: circleCenter.y - CQUnit2[1] * radius
|
|
3894
|
+
};
|
|
3741
3895
|
}
|
|
3742
3896
|
const CR = [
|
|
3743
3897
|
referencePoint.x - observationPoint.x,
|
|
@@ -3761,23 +3915,108 @@ function computeTangentPoint(observationPoint, referencePoint, circleCenter, rad
|
|
|
3761
3915
|
y: observationPoint.y + d * unitToTangent[1]
|
|
3762
3916
|
};
|
|
3763
3917
|
}
|
|
3764
|
-
function
|
|
3765
|
-
const
|
|
3766
|
-
const
|
|
3767
|
-
|
|
3768
|
-
|
|
3769
|
-
|
|
3770
|
-
|
|
3771
|
-
|
|
3772
|
-
|
|
3773
|
-
|
|
3774
|
-
|
|
3775
|
-
|
|
3776
|
-
|
|
3918
|
+
function distance2(p1, p2) {
|
|
3919
|
+
const dx = p2.x - p1.x;
|
|
3920
|
+
const dy = p2.y - p1.y;
|
|
3921
|
+
return Math.sqrt(dx * dx + dy * dy);
|
|
3922
|
+
}
|
|
3923
|
+
|
|
3924
|
+
// lib/solvers/HighDensitySolver/TwoRouteHighDensitySolver/calculateSideTraversal.ts
|
|
3925
|
+
var EPSILON = 1e-9;
|
|
3926
|
+
function calculateSegmentTraversal(startPoint, endPoint, bounds) {
|
|
3927
|
+
const startAngle = pointToAngle(startPoint, bounds);
|
|
3928
|
+
let endAngle = pointToAngle(endPoint, bounds);
|
|
3929
|
+
if (endAngle < startAngle) {
|
|
3930
|
+
endAngle += 2 * Math.PI;
|
|
3931
|
+
}
|
|
3932
|
+
if (Math.abs(endAngle - startAngle) < EPSILON) {
|
|
3933
|
+
return { left: 0, top: 0, right: 0, bottom: 0 };
|
|
3934
|
+
}
|
|
3935
|
+
return calculateSidePercentages(startAngle, endAngle, bounds);
|
|
3936
|
+
}
|
|
3937
|
+
function calculateTraversalPercentages(A, B, C, bounds) {
|
|
3938
|
+
const percentagesAB = calculateSegmentTraversal(A, B, bounds);
|
|
3939
|
+
const percentagesBC = calculateSegmentTraversal(B, C, bounds);
|
|
3940
|
+
const totalPercentages = {
|
|
3941
|
+
left: Math.min(1, percentagesAB.left + percentagesBC.left),
|
|
3942
|
+
top: Math.min(1, percentagesAB.top + percentagesBC.top),
|
|
3943
|
+
right: Math.min(1, percentagesAB.right + percentagesBC.right),
|
|
3944
|
+
bottom: Math.min(1, percentagesAB.bottom + percentagesBC.bottom)
|
|
3945
|
+
};
|
|
3946
|
+
for (const key in totalPercentages) {
|
|
3947
|
+
if (Math.abs(totalPercentages[key]) < EPSILON) {
|
|
3948
|
+
totalPercentages[key] = 0;
|
|
3949
|
+
}
|
|
3950
|
+
}
|
|
3951
|
+
return totalPercentages;
|
|
3952
|
+
}
|
|
3953
|
+
function pointToAngle(point, bounds) {
|
|
3954
|
+
const width = bounds.maxX - bounds.minX;
|
|
3955
|
+
const height = bounds.maxY - bounds.minY;
|
|
3956
|
+
if (width < EPSILON && height < EPSILON) return 0;
|
|
3957
|
+
const perimeter = 2 * (width + height);
|
|
3958
|
+
if (perimeter < EPSILON) return 0;
|
|
3959
|
+
let distance6 = 0;
|
|
3960
|
+
if (Math.abs(point.y - bounds.maxY) < EPSILON && point.x >= bounds.minX - EPSILON && point.x <= bounds.maxX + EPSILON) {
|
|
3961
|
+
distance6 = Math.max(0, Math.min(width, point.x - bounds.minX));
|
|
3962
|
+
} else if (Math.abs(point.x - bounds.maxX) < EPSILON && point.y >= bounds.minY - EPSILON && point.y <= bounds.maxY + EPSILON) {
|
|
3963
|
+
distance6 = width + Math.max(0, Math.min(height, bounds.maxY - point.y));
|
|
3964
|
+
} else if (Math.abs(point.y - bounds.minY) < EPSILON && point.x >= bounds.minX - EPSILON && point.x <= bounds.maxX + EPSILON) {
|
|
3965
|
+
distance6 = width + height + Math.max(0, Math.min(width, bounds.maxX - point.x));
|
|
3966
|
+
} else if (Math.abs(point.x - bounds.minX) < EPSILON && point.y >= bounds.minY - EPSILON && point.y <= bounds.maxY + EPSILON) {
|
|
3967
|
+
distance6 = width + height + width + Math.max(0, Math.min(height, point.y - bounds.minY));
|
|
3968
|
+
} else {
|
|
3969
|
+
throw new Error(
|
|
3970
|
+
`Point (${point.x}, ${point.y}) does not lie on the boundary defined by ${JSON.stringify(bounds)}`
|
|
3971
|
+
);
|
|
3777
3972
|
}
|
|
3778
|
-
|
|
3779
|
-
|
|
3780
|
-
|
|
3973
|
+
distance6 = Math.max(0, Math.min(perimeter, distance6));
|
|
3974
|
+
return perimeter > EPSILON ? distance6 / perimeter * (2 * Math.PI) : 0;
|
|
3975
|
+
}
|
|
3976
|
+
function calculateSidePercentages(startAngle, endAngle, bounds) {
|
|
3977
|
+
const width = bounds.maxX - bounds.minX;
|
|
3978
|
+
const height = bounds.maxY - bounds.minY;
|
|
3979
|
+
if (width < EPSILON && height < EPSILON)
|
|
3980
|
+
return { left: 0, top: 0, right: 0, bottom: 0 };
|
|
3981
|
+
const perimeter = 2 * (width + height);
|
|
3982
|
+
if (perimeter < EPSILON) return { left: 0, top: 0, right: 0, bottom: 0 };
|
|
3983
|
+
const angleTopEnd = width / perimeter * (2 * Math.PI);
|
|
3984
|
+
const angleRightEnd = (width + height) / perimeter * (2 * Math.PI);
|
|
3985
|
+
const angleBottomEnd = (width + width + height) / perimeter * (2 * Math.PI);
|
|
3986
|
+
const angleLeftEnd = 2 * Math.PI;
|
|
3987
|
+
const sides = [
|
|
3988
|
+
{ name: "top", start: 0, end: angleTopEnd, length: width },
|
|
3989
|
+
{ name: "right", start: angleTopEnd, end: angleRightEnd, length: height },
|
|
3990
|
+
{
|
|
3991
|
+
name: "bottom",
|
|
3992
|
+
start: angleRightEnd,
|
|
3993
|
+
end: angleBottomEnd,
|
|
3994
|
+
length: width
|
|
3995
|
+
},
|
|
3996
|
+
{ name: "left", start: angleBottomEnd, end: angleLeftEnd, length: height }
|
|
3997
|
+
// Ends at 2PI
|
|
3998
|
+
];
|
|
3999
|
+
const result = { left: 0, top: 0, right: 0, bottom: 0 };
|
|
4000
|
+
const totalAngleTraversal = endAngle - startAngle;
|
|
4001
|
+
if (totalAngleTraversal < EPSILON) return result;
|
|
4002
|
+
for (const side of sides) {
|
|
4003
|
+
const sideAngleRange = side.end - side.start;
|
|
4004
|
+
if (sideAngleRange < EPSILON || side.length < EPSILON) continue;
|
|
4005
|
+
const overlapStart = Math.max(startAngle, side.start);
|
|
4006
|
+
const overlapEnd = Math.min(endAngle, side.end);
|
|
4007
|
+
if (overlapStart < overlapEnd - EPSILON) {
|
|
4008
|
+
const traversedAngleOnSide = overlapEnd - overlapStart;
|
|
4009
|
+
const percentage = traversedAngleOnSide / sideAngleRange;
|
|
4010
|
+
result[side.name] += Math.max(0, percentage);
|
|
4011
|
+
}
|
|
4012
|
+
}
|
|
4013
|
+
for (const key in result) {
|
|
4014
|
+
result[key] = Math.max(
|
|
4015
|
+
0,
|
|
4016
|
+
Math.min(1, result[key])
|
|
4017
|
+
);
|
|
4018
|
+
}
|
|
4019
|
+
return result;
|
|
3781
4020
|
}
|
|
3782
4021
|
|
|
3783
4022
|
// lib/solvers/HighDensitySolver/TwoRouteHighDensitySolver/SingleTransitionCrossingRouteSolver.ts
|
|
@@ -3864,17 +4103,30 @@ var SingleTransitionCrossingRouteSolver = class extends BaseSolver {
|
|
|
3864
4103
|
const ntrP1 = transitionRoute.A.z !== flatRouteZ ? transitionRoute.A : transitionRoute.B;
|
|
3865
4104
|
const marginFromBorderWithTrace = this.obstacleMargin * 2 + this.viaDiameter / 2 + this.traceThickness;
|
|
3866
4105
|
const marginFromBorderWithoutTrace = this.obstacleMargin + this.viaDiameter / 2;
|
|
4106
|
+
const A = flatRoute.A;
|
|
4107
|
+
const B = ntrP1;
|
|
4108
|
+
const C = flatRoute.B;
|
|
4109
|
+
const sideTraversal = calculateTraversalPercentages(A, B, C, this.bounds);
|
|
4110
|
+
const viaBounds = {
|
|
4111
|
+
minX: this.bounds.minX + (sideTraversal.left > 0.5 ? marginFromBorderWithTrace : marginFromBorderWithoutTrace),
|
|
4112
|
+
minY: this.bounds.minY + (sideTraversal.bottom > 0.5 ? marginFromBorderWithTrace : marginFromBorderWithoutTrace),
|
|
4113
|
+
maxX: this.bounds.maxX - (sideTraversal.right > 0.5 ? marginFromBorderWithTrace : marginFromBorderWithoutTrace),
|
|
4114
|
+
maxY: this.bounds.maxY - (sideTraversal.top > 0.5 ? marginFromBorderWithTrace : marginFromBorderWithoutTrace)
|
|
4115
|
+
};
|
|
4116
|
+
if (viaBounds.maxY < viaBounds.minY) {
|
|
4117
|
+
viaBounds.minY = (viaBounds.minY + viaBounds.maxY) / 2;
|
|
4118
|
+
viaBounds.maxY = viaBounds.minY;
|
|
4119
|
+
}
|
|
4120
|
+
if (viaBounds.maxX < viaBounds.minX) {
|
|
4121
|
+
viaBounds.minX = (viaBounds.minX + viaBounds.maxX) / 2;
|
|
4122
|
+
viaBounds.maxX = viaBounds.minX;
|
|
4123
|
+
}
|
|
3867
4124
|
return findClosestPointToABCWithinBounds(
|
|
3868
|
-
|
|
3869
|
-
|
|
3870
|
-
|
|
4125
|
+
A,
|
|
4126
|
+
B,
|
|
4127
|
+
C,
|
|
3871
4128
|
marginFromBorderWithTrace,
|
|
3872
|
-
|
|
3873
|
-
minX: this.bounds.minX + marginFromBorderWithoutTrace,
|
|
3874
|
-
minY: this.bounds.minY + marginFromBorderWithoutTrace,
|
|
3875
|
-
maxX: this.bounds.maxX - marginFromBorderWithTrace,
|
|
3876
|
-
maxY: this.bounds.maxY - marginFromBorderWithTrace
|
|
3877
|
-
}
|
|
4129
|
+
viaBounds
|
|
3878
4130
|
);
|
|
3879
4131
|
}
|
|
3880
4132
|
/**
|
|
@@ -4662,13 +4914,13 @@ function buildMinimumSpanningTree(points) {
|
|
|
4662
4914
|
if (point.x === neighbor.x && point.y === neighbor.y) {
|
|
4663
4915
|
continue;
|
|
4664
4916
|
}
|
|
4665
|
-
const
|
|
4917
|
+
const distance6 = Math.sqrt(
|
|
4666
4918
|
(point.x - neighbor.x) ** 2 + (point.y - neighbor.y) ** 2
|
|
4667
4919
|
);
|
|
4668
4920
|
edges.push({
|
|
4669
4921
|
from: point,
|
|
4670
4922
|
to: neighbor,
|
|
4671
|
-
weight:
|
|
4923
|
+
weight: distance6
|
|
4672
4924
|
});
|
|
4673
4925
|
}
|
|
4674
4926
|
}
|
|
@@ -6489,11 +6741,11 @@ var CapacityPathingSolver = class extends BaseSolver {
|
|
|
6489
6741
|
let closestNode = this.nodes[0];
|
|
6490
6742
|
let minDistance = Number.MAX_VALUE;
|
|
6491
6743
|
for (const node of nodesWithTargets) {
|
|
6492
|
-
const
|
|
6744
|
+
const distance6 = Math.sqrt(
|
|
6493
6745
|
(node.center.x - point.x) ** 2 + (node.center.y - point.y) ** 2
|
|
6494
6746
|
);
|
|
6495
|
-
if (
|
|
6496
|
-
minDistance =
|
|
6747
|
+
if (distance6 < minDistance) {
|
|
6748
|
+
minDistance = distance6;
|
|
6497
6749
|
closestNode = node;
|
|
6498
6750
|
}
|
|
6499
6751
|
}
|
|
@@ -7085,7 +7337,7 @@ var CapacityNodeTree = class {
|
|
|
7085
7337
|
};
|
|
7086
7338
|
|
|
7087
7339
|
// lib/solvers/SingleLayerNodeMerger/SingleLayerNodeMergerSolver.ts
|
|
7088
|
-
var
|
|
7340
|
+
var EPSILON2 = 5e-3;
|
|
7089
7341
|
var SingleLayerNodeMergerSolver = class extends BaseSolver {
|
|
7090
7342
|
nodeMap;
|
|
7091
7343
|
currentBatchNodeIds;
|
|
@@ -7244,7 +7496,7 @@ var SingleLayerNodeMergerSolver = class extends BaseSolver {
|
|
|
7244
7496
|
adjacentNodesToLeft.reduce((acc, adjNode) => {
|
|
7245
7497
|
return acc + adjNode.height;
|
|
7246
7498
|
}, 0) - rootNode.height
|
|
7247
|
-
) <
|
|
7499
|
+
) < EPSILON2;
|
|
7248
7500
|
if (leftAdjNodesTakeUpEntireHeight && leftAdjNodesAreAllSameSize) {
|
|
7249
7501
|
rootNode.width += leftAdjNodeWidth;
|
|
7250
7502
|
rootNode.center.x = rootNode.center.x - leftAdjNodeWidth / 2;
|
|
@@ -7264,7 +7516,7 @@ var SingleLayerNodeMergerSolver = class extends BaseSolver {
|
|
|
7264
7516
|
adjacentNodesToRight.reduce((acc, adjNode) => {
|
|
7265
7517
|
return acc + adjNode.height;
|
|
7266
7518
|
}, 0) - rootNode.height
|
|
7267
|
-
) <
|
|
7519
|
+
) < EPSILON2;
|
|
7268
7520
|
if (rightAdjNodesTakeUpEntireHeight && rightAdjNodesAreAllSameSize) {
|
|
7269
7521
|
rootNode.width += rightAdjNodeWidth;
|
|
7270
7522
|
rootNode.center.x = rootNode.center.x + rightAdjNodeWidth / 2;
|
|
@@ -7284,7 +7536,7 @@ var SingleLayerNodeMergerSolver = class extends BaseSolver {
|
|
|
7284
7536
|
adjacentNodesToTop.reduce((acc, adjNode) => {
|
|
7285
7537
|
return acc + adjNode.width;
|
|
7286
7538
|
}, 0) - rootNode.width
|
|
7287
|
-
) <
|
|
7539
|
+
) < EPSILON2;
|
|
7288
7540
|
if (topAdjNodesTakeUpEntireWidth && topAdjNodesAreAllSameSize) {
|
|
7289
7541
|
rootNode.height += topAdjNodeHeight;
|
|
7290
7542
|
rootNode.center.y = rootNode.center.y + topAdjNodeHeight / 2;
|
|
@@ -7304,7 +7556,7 @@ var SingleLayerNodeMergerSolver = class extends BaseSolver {
|
|
|
7304
7556
|
adjacentNodesToBottom.reduce((acc, adjNode) => {
|
|
7305
7557
|
return acc + adjNode.width;
|
|
7306
7558
|
}, 0) - rootNode.width
|
|
7307
|
-
) <
|
|
7559
|
+
) < EPSILON2;
|
|
7308
7560
|
if (bottomAdjNodesTakeUpEntireWidth && bottomAdjNodesAreAllSameSize) {
|
|
7309
7561
|
rootNode.height += bottomAdjNodeHeight;
|
|
7310
7562
|
rootNode.center.y = rootNode.center.y - bottomAdjNodeHeight / 2;
|
|
@@ -7401,6 +7653,15 @@ var SingleSimplifiedPathSolver = class extends BaseSolver {
|
|
|
7401
7653
|
this.newRoute = [this.inputRoute.route[0]];
|
|
7402
7654
|
this.newVias = [];
|
|
7403
7655
|
}
|
|
7656
|
+
getConstructorParams() {
|
|
7657
|
+
return {
|
|
7658
|
+
inputRoute: this.inputRoute,
|
|
7659
|
+
otherHdRoutes: this.otherHdRoutes,
|
|
7660
|
+
obstacles: this.obstacles,
|
|
7661
|
+
connMap: this.connMap.netMap,
|
|
7662
|
+
colorMap: this.colorMap
|
|
7663
|
+
};
|
|
7664
|
+
}
|
|
7404
7665
|
get simplifiedRoute() {
|
|
7405
7666
|
return {
|
|
7406
7667
|
connectionName: this.inputRoute.connectionName,
|
|
@@ -7541,23 +7802,23 @@ function pointToSegmentDistance4(P, Q1, Q2) {
|
|
|
7541
7802
|
const w = { x: P.x - Q1.x, y: P.y - Q1.y };
|
|
7542
7803
|
const c1 = dotProduct(w, v);
|
|
7543
7804
|
if (c1 <= 0) {
|
|
7544
|
-
return
|
|
7805
|
+
return distance5(P, Q1);
|
|
7545
7806
|
}
|
|
7546
7807
|
const c2 = dotProduct(v, v);
|
|
7547
7808
|
if (c2 <= c1) {
|
|
7548
|
-
return
|
|
7809
|
+
return distance5(P, Q2);
|
|
7549
7810
|
}
|
|
7550
7811
|
const b = c1 / c2;
|
|
7551
7812
|
const Pb = {
|
|
7552
7813
|
x: Q1.x + b * v.x,
|
|
7553
7814
|
y: Q1.y + b * v.y
|
|
7554
7815
|
};
|
|
7555
|
-
return
|
|
7816
|
+
return distance5(P, Pb);
|
|
7556
7817
|
}
|
|
7557
7818
|
function dotProduct(v1, v2) {
|
|
7558
7819
|
return v1.x * v2.x + v1.y * v2.y;
|
|
7559
7820
|
}
|
|
7560
|
-
function
|
|
7821
|
+
function distance5(p1, p2) {
|
|
7561
7822
|
const dx = p2.x - p1.x;
|
|
7562
7823
|
const dy = p2.y - p1.y;
|
|
7563
7824
|
return Math.sqrt(dx * dx + dy * dy);
|
|
@@ -7617,6 +7878,7 @@ var SegmentTree = class {
|
|
|
7617
7878
|
}
|
|
7618
7879
|
buckets;
|
|
7619
7880
|
CELL_SIZE = 0.4;
|
|
7881
|
+
SEGMENT_MARGIN = 0.2;
|
|
7620
7882
|
getBucketKey(x, y) {
|
|
7621
7883
|
return `${Math.floor(x / this.CELL_SIZE)}x${Math.floor(y / this.CELL_SIZE)}`;
|
|
7622
7884
|
}
|
|
@@ -7626,10 +7888,10 @@ var SegmentTree = class {
|
|
|
7626
7888
|
getSegmentsThatCouldIntersect(A, B) {
|
|
7627
7889
|
const segments = [];
|
|
7628
7890
|
const alreadyAddedSegments = /* @__PURE__ */ new Set();
|
|
7629
|
-
const minX = Math.min(A.x, B.x);
|
|
7630
|
-
const minY = Math.min(A.y, B.y);
|
|
7631
|
-
const maxX = Math.max(A.x, B.x);
|
|
7632
|
-
const maxY = Math.max(A.y, B.y);
|
|
7891
|
+
const minX = Math.min(A.x, B.x) - this.SEGMENT_MARGIN;
|
|
7892
|
+
const minY = Math.min(A.y, B.y) - this.SEGMENT_MARGIN;
|
|
7893
|
+
const maxX = Math.max(A.x, B.x) + this.SEGMENT_MARGIN;
|
|
7894
|
+
const maxY = Math.max(A.y, B.y) + this.SEGMENT_MARGIN;
|
|
7633
7895
|
const bucketMinX = Math.floor(minX / this.CELL_SIZE) * this.CELL_SIZE;
|
|
7634
7896
|
const bucketMinY = Math.floor(minY / this.CELL_SIZE) * this.CELL_SIZE;
|
|
7635
7897
|
for (let x = bucketMinX; x <= maxX; x += this.CELL_SIZE) {
|
|
@@ -7669,7 +7931,8 @@ var SingleSimplifiedPathSolver5 = class extends SingleSimplifiedPathSolver {
|
|
|
7669
7931
|
filteredObstaclePathSegments = [];
|
|
7670
7932
|
filteredVias = [];
|
|
7671
7933
|
segmentTree;
|
|
7672
|
-
OBSTACLE_MARGIN = 0.
|
|
7934
|
+
OBSTACLE_MARGIN = 0.1;
|
|
7935
|
+
TRACE_THICKNESS = 0.15;
|
|
7673
7936
|
TAIL_JUMP_RATIO = 0.8;
|
|
7674
7937
|
constructor(params) {
|
|
7675
7938
|
super(params);
|
|
@@ -7689,6 +7952,14 @@ var SingleSimplifiedPathSolver5 = class extends SingleSimplifiedPathSolver {
|
|
|
7689
7952
|
},
|
|
7690
7953
|
{ minX: Infinity, maxX: -Infinity, minY: Infinity, maxY: -Infinity }
|
|
7691
7954
|
);
|
|
7955
|
+
const boundsBox = {
|
|
7956
|
+
center: {
|
|
7957
|
+
x: (bounds.minX + bounds.maxX) / 2,
|
|
7958
|
+
y: (bounds.minY + bounds.maxY) / 2
|
|
7959
|
+
},
|
|
7960
|
+
width: bounds.maxX - bounds.minX,
|
|
7961
|
+
height: bounds.maxY - bounds.minY
|
|
7962
|
+
};
|
|
7692
7963
|
this.filteredObstacles = this.obstacles.filter(
|
|
7693
7964
|
(obstacle) => !obstacle.connectedTo.some(
|
|
7694
7965
|
(id) => this.connMap.areIdsConnected(this.inputRoute.connectionName, id)
|
|
@@ -7699,11 +7970,11 @@ var SingleSimplifiedPathSolver5 = class extends SingleSimplifiedPathSolver {
|
|
|
7699
7970
|
)) {
|
|
7700
7971
|
return false;
|
|
7701
7972
|
}
|
|
7702
|
-
const
|
|
7703
|
-
|
|
7704
|
-
|
|
7705
|
-
|
|
7706
|
-
return
|
|
7973
|
+
const { distance: distance6 } = computeDistanceBetweenBoxes(boundsBox, obstacle);
|
|
7974
|
+
if (distance6 < this.OBSTACLE_MARGIN + 0.5) {
|
|
7975
|
+
return true;
|
|
7976
|
+
}
|
|
7977
|
+
return false;
|
|
7707
7978
|
});
|
|
7708
7979
|
this.filteredObstaclePathSegments = this.otherHdRoutes.flatMap(
|
|
7709
7980
|
(hdRoute) => {
|
|
@@ -7775,15 +8046,15 @@ var SingleSimplifiedPathSolver5 = class extends SingleSimplifiedPathSolver {
|
|
|
7775
8046
|
return p1.x === p2.x && p1.y === p2.y && p1.z === p2.z;
|
|
7776
8047
|
}
|
|
7777
8048
|
// Get point at a specific distance along the path
|
|
7778
|
-
getPointAtDistance(
|
|
7779
|
-
|
|
8049
|
+
getPointAtDistance(distance6) {
|
|
8050
|
+
distance6 = Math.max(0, Math.min(distance6, this.totalPathLength));
|
|
7780
8051
|
const segment = this.pathSegments.find(
|
|
7781
|
-
(seg) =>
|
|
8052
|
+
(seg) => distance6 >= seg.startDistance && distance6 <= seg.endDistance
|
|
7782
8053
|
);
|
|
7783
8054
|
if (!segment) {
|
|
7784
8055
|
return this.inputRoute.route[this.inputRoute.route.length - 1];
|
|
7785
8056
|
}
|
|
7786
|
-
const factor = (
|
|
8057
|
+
const factor = (distance6 - segment.startDistance) / segment.length;
|
|
7787
8058
|
return {
|
|
7788
8059
|
x: segment.start.x + factor * (segment.end.x - segment.start.x),
|
|
7789
8060
|
y: segment.start.y + factor * (segment.end.y - segment.start.y),
|
|
@@ -7792,17 +8063,17 @@ var SingleSimplifiedPathSolver5 = class extends SingleSimplifiedPathSolver {
|
|
|
7792
8063
|
};
|
|
7793
8064
|
}
|
|
7794
8065
|
// Find nearest index in the original route for a given distance
|
|
7795
|
-
getNearestIndexForDistance(
|
|
7796
|
-
if (
|
|
7797
|
-
if (
|
|
8066
|
+
getNearestIndexForDistance(distance6) {
|
|
8067
|
+
if (distance6 <= 0) return 0;
|
|
8068
|
+
if (distance6 >= this.totalPathLength)
|
|
7798
8069
|
return this.inputRoute.route.length - 1;
|
|
7799
8070
|
const segmentIndex = this.pathSegments.findIndex(
|
|
7800
|
-
(seg) =>
|
|
8071
|
+
(seg) => distance6 >= seg.startDistance && distance6 <= seg.endDistance
|
|
7801
8072
|
);
|
|
7802
8073
|
if (segmentIndex === -1) return 0;
|
|
7803
8074
|
const segment = this.pathSegments[segmentIndex];
|
|
7804
8075
|
const midDistance = (segment.startDistance + segment.endDistance) / 2;
|
|
7805
|
-
return
|
|
8076
|
+
return distance6 > midDistance ? segmentIndex + 1 : segmentIndex;
|
|
7806
8077
|
}
|
|
7807
8078
|
// Check if a path segment is valid
|
|
7808
8079
|
isValidPathSegment(start, end) {
|
|
@@ -7810,49 +8081,27 @@ var SingleSimplifiedPathSolver5 = class extends SingleSimplifiedPathSolver {
|
|
|
7810
8081
|
if (!obstacle.zLayers?.includes(start.z)) {
|
|
7811
8082
|
continue;
|
|
7812
8083
|
}
|
|
7813
|
-
const
|
|
7814
|
-
|
|
7815
|
-
const obstacleTop = obstacle.center.y - obstacle.height / 2 - this.OBSTACLE_MARGIN;
|
|
7816
|
-
const obstacleBottom = obstacle.center.y + obstacle.height / 2 + this.OBSTACLE_MARGIN;
|
|
7817
|
-
if (doSegmentsIntersect(
|
|
7818
|
-
{ x: start.x, y: start.y },
|
|
7819
|
-
{ x: end.x, y: end.y },
|
|
7820
|
-
{ x: obstacleLeft, y: obstacleTop },
|
|
7821
|
-
{ x: obstacleRight, y: obstacleTop }
|
|
7822
|
-
) || doSegmentsIntersect(
|
|
7823
|
-
{ x: start.x, y: start.y },
|
|
7824
|
-
{ x: end.x, y: end.y },
|
|
7825
|
-
{ x: obstacleRight, y: obstacleTop },
|
|
7826
|
-
{ x: obstacleRight, y: obstacleBottom }
|
|
7827
|
-
) || doSegmentsIntersect(
|
|
7828
|
-
{ x: start.x, y: start.y },
|
|
7829
|
-
{ x: end.x, y: end.y },
|
|
7830
|
-
{ x: obstacleRight, y: obstacleBottom },
|
|
7831
|
-
{ x: obstacleLeft, y: obstacleBottom }
|
|
7832
|
-
) || doSegmentsIntersect(
|
|
7833
|
-
{ x: start.x, y: start.y },
|
|
7834
|
-
{ x: end.x, y: end.y },
|
|
7835
|
-
{ x: obstacleLeft, y: obstacleBottom },
|
|
7836
|
-
{ x: obstacleLeft, y: obstacleTop }
|
|
7837
|
-
)) {
|
|
8084
|
+
const distToObstacle = segmentToBoxMinDistance(start, end, obstacle);
|
|
8085
|
+
if (distToObstacle < this.OBSTACLE_MARGIN + this.TRACE_THICKNESS / 2) {
|
|
7838
8086
|
return false;
|
|
7839
8087
|
}
|
|
7840
8088
|
}
|
|
7841
8089
|
const segmentsThatCouldIntersect = this.segmentTree.getSegmentsThatCouldIntersect(start, end);
|
|
7842
|
-
for (const [otherSegA, otherSegB] of segmentsThatCouldIntersect) {
|
|
8090
|
+
for (const [otherSegA, otherSegB, segId] of segmentsThatCouldIntersect) {
|
|
7843
8091
|
if (otherSegA.z === start.z && otherSegB.z === start.z) {
|
|
7844
|
-
|
|
8092
|
+
const distBetweenSegments = minimumDistanceBetweenSegments(
|
|
7845
8093
|
{ x: start.x, y: start.y },
|
|
7846
8094
|
{ x: end.x, y: end.y },
|
|
7847
8095
|
{ x: otherSegA.x, y: otherSegA.y },
|
|
7848
8096
|
{ x: otherSegB.x, y: otherSegB.y }
|
|
7849
|
-
)
|
|
8097
|
+
);
|
|
8098
|
+
if (distBetweenSegments < this.OBSTACLE_MARGIN + this.TRACE_THICKNESS) {
|
|
7850
8099
|
return false;
|
|
7851
8100
|
}
|
|
7852
8101
|
}
|
|
7853
8102
|
}
|
|
7854
8103
|
for (const via of this.filteredVias) {
|
|
7855
|
-
if (pointToSegmentDistance(via, start, end) < this.OBSTACLE_MARGIN + via.diameter / 2) {
|
|
8104
|
+
if (pointToSegmentDistance(via, start, end) < this.OBSTACLE_MARGIN + via.diameter / 2 + this.TRACE_THICKNESS / 2) {
|
|
7856
8105
|
return false;
|
|
7857
8106
|
}
|
|
7858
8107
|
}
|
|
@@ -7904,10 +8153,10 @@ var SingleSimplifiedPathSolver5 = class extends SingleSimplifiedPathSolver {
|
|
|
7904
8153
|
}
|
|
7905
8154
|
this.currentStepSize = this.maxStepSize;
|
|
7906
8155
|
}
|
|
7907
|
-
moveHead(
|
|
7908
|
-
this.lastHeadMoveDistance =
|
|
8156
|
+
moveHead(distance6) {
|
|
8157
|
+
this.lastHeadMoveDistance = distance6;
|
|
7909
8158
|
this.headDistanceAlongPath = Math.min(
|
|
7910
|
-
this.headDistanceAlongPath +
|
|
8159
|
+
this.headDistanceAlongPath + distance6,
|
|
7911
8160
|
this.totalPathLength
|
|
7912
8161
|
);
|
|
7913
8162
|
}
|
|
@@ -8045,9 +8294,9 @@ var SingleSimplifiedPathSolver5 = class extends SingleSimplifiedPathSolver {
|
|
|
8045
8294
|
color: "red",
|
|
8046
8295
|
label: ["Tentative Head", `z: ${tentativeHead.z}`].join("\n")
|
|
8047
8296
|
});
|
|
8048
|
-
let
|
|
8049
|
-
while (
|
|
8050
|
-
const point = this.getPointAtDistance(
|
|
8297
|
+
let distance6 = 0;
|
|
8298
|
+
while (distance6 < this.totalPathLength) {
|
|
8299
|
+
const point = this.getPointAtDistance(distance6);
|
|
8051
8300
|
graphics.circles.push({
|
|
8052
8301
|
center: {
|
|
8053
8302
|
x: point.x,
|
|
@@ -8056,7 +8305,7 @@ var SingleSimplifiedPathSolver5 = class extends SingleSimplifiedPathSolver {
|
|
|
8056
8305
|
radius: 0.05,
|
|
8057
8306
|
fill: "rgba(100, 100, 100, 0.5)"
|
|
8058
8307
|
});
|
|
8059
|
-
|
|
8308
|
+
distance6 += this.totalPathLength / 20;
|
|
8060
8309
|
}
|
|
8061
8310
|
if (this.lastValidPath && this.lastValidPath.length > 1) {
|
|
8062
8311
|
for (let i = 0; i < this.lastValidPath.length - 1; i++) {
|