calculate-packing 0.0.16 → 0.0.18
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 +3 -1
- package/dist/index.js +186 -191
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -36,8 +36,10 @@ interface PackedComponent extends InputComponent {
|
|
|
36
36
|
x: number;
|
|
37
37
|
y: number;
|
|
38
38
|
};
|
|
39
|
-
/** Rotation in degrees (counterclockwise) */
|
|
39
|
+
/** @deprecated Rotation in degrees (counterclockwise) */
|
|
40
40
|
ccwRotationOffset: number;
|
|
41
|
+
/** Rotation in degrees (counterclockwise) - output field */
|
|
42
|
+
ccwRotationDegrees?: number;
|
|
41
43
|
pads: OutputPad[];
|
|
42
44
|
}
|
|
43
45
|
interface PackInput {
|
package/dist/index.js
CHANGED
|
@@ -415,47 +415,6 @@ var getSegmentsFromPad = (pad, { padding = 0 } = {}) => {
|
|
|
415
415
|
return segments;
|
|
416
416
|
};
|
|
417
417
|
|
|
418
|
-
// lib/PackSolver/computeGlobalCenter.ts
|
|
419
|
-
function computeGlobalCenter(packedComponents) {
|
|
420
|
-
if (!packedComponents.length) return { x: 0, y: 0 };
|
|
421
|
-
const sum = packedComponents.reduce(
|
|
422
|
-
(acc, component) => ({
|
|
423
|
-
x: acc.x + component.center.x,
|
|
424
|
-
y: acc.y + component.center.y
|
|
425
|
-
}),
|
|
426
|
-
{ x: 0, y: 0 }
|
|
427
|
-
);
|
|
428
|
-
return {
|
|
429
|
-
x: sum.x / packedComponents.length,
|
|
430
|
-
y: sum.y / packedComponents.length
|
|
431
|
-
};
|
|
432
|
-
}
|
|
433
|
-
|
|
434
|
-
// lib/PackSolver/findBestPointForDisconnected.ts
|
|
435
|
-
function findBestPointForDisconnected({
|
|
436
|
-
outlines,
|
|
437
|
-
direction,
|
|
438
|
-
packedComponents
|
|
439
|
-
}) {
|
|
440
|
-
const points = outlines.flatMap(
|
|
441
|
-
(outline) => outline.map(([p1, p2]) => ({
|
|
442
|
-
x: (p1.x + p2.x) / 2,
|
|
443
|
-
y: (p1.y + p2.y) / 2
|
|
444
|
-
}))
|
|
445
|
-
);
|
|
446
|
-
if (!points.length) return { x: 0, y: 0 };
|
|
447
|
-
if (direction !== "nearest_to_center") {
|
|
448
|
-
const extreme = direction === "left" || direction === "down" ? Math.min : Math.max;
|
|
449
|
-
const key = direction === "left" || direction === "right" ? "x" : "y";
|
|
450
|
-
const target = extreme(...points.map((p) => p[key]));
|
|
451
|
-
return points.find((p) => p[key] === target);
|
|
452
|
-
}
|
|
453
|
-
const center = computeGlobalCenter(packedComponents);
|
|
454
|
-
return points.reduce(
|
|
455
|
-
(best, point) => Math.hypot(point.x - center.x, point.y - center.y) < Math.hypot(best.x - center.x, best.y - center.y) ? point : best
|
|
456
|
-
);
|
|
457
|
-
}
|
|
458
|
-
|
|
459
418
|
// lib/PackSolver/setPackedComponentPadCenters.ts
|
|
460
419
|
var setPackedComponentPadCenters = (packedComponent) => {
|
|
461
420
|
packedComponent.pads = packedComponent.pads.map((pad) => {
|
|
@@ -477,66 +436,6 @@ var setPackedComponentPadCenters = (packedComponent) => {
|
|
|
477
436
|
});
|
|
478
437
|
};
|
|
479
438
|
|
|
480
|
-
// lib/PackSolver/placeComponentAtPoint.ts
|
|
481
|
-
function placeComponentAtPoint({
|
|
482
|
-
component,
|
|
483
|
-
point,
|
|
484
|
-
candidateAngles,
|
|
485
|
-
checkOverlap
|
|
486
|
-
}) {
|
|
487
|
-
const evaluatedPositionShadows = [];
|
|
488
|
-
for (const angle of candidateAngles) {
|
|
489
|
-
const pads = component.pads.map((pad) => {
|
|
490
|
-
const rotatedOffset = rotatePoint(pad.offset, angle * Math.PI / 180);
|
|
491
|
-
return {
|
|
492
|
-
...pad,
|
|
493
|
-
absoluteCenter: {
|
|
494
|
-
x: point.x + rotatedOffset.x,
|
|
495
|
-
y: point.y + rotatedOffset.y
|
|
496
|
-
}
|
|
497
|
-
};
|
|
498
|
-
});
|
|
499
|
-
const candidate = {
|
|
500
|
-
...component,
|
|
501
|
-
center: point,
|
|
502
|
-
ccwRotationOffset: angle,
|
|
503
|
-
pads
|
|
504
|
-
};
|
|
505
|
-
evaluatedPositionShadows.push(candidate);
|
|
506
|
-
if (!checkOverlap(candidate)) {
|
|
507
|
-
Object.assign(component, candidate);
|
|
508
|
-
setPackedComponentPadCenters(component);
|
|
509
|
-
return evaluatedPositionShadows;
|
|
510
|
-
}
|
|
511
|
-
}
|
|
512
|
-
component.center = point;
|
|
513
|
-
component.ccwRotationOffset = 0;
|
|
514
|
-
setPackedComponentPadCenters(component);
|
|
515
|
-
return evaluatedPositionShadows;
|
|
516
|
-
}
|
|
517
|
-
|
|
518
|
-
// lib/PackSolver/placeComponentDisconnected.ts
|
|
519
|
-
function placeComponentDisconnected({
|
|
520
|
-
component,
|
|
521
|
-
outlines,
|
|
522
|
-
direction,
|
|
523
|
-
packedComponents,
|
|
524
|
-
candidateAngles,
|
|
525
|
-
checkOverlap
|
|
526
|
-
}) {
|
|
527
|
-
const targetPoint = findBestPointForDisconnected({
|
|
528
|
-
outlines,
|
|
529
|
-
direction,
|
|
530
|
-
packedComponents
|
|
531
|
-
});
|
|
532
|
-
return placeComponentAtPoint({
|
|
533
|
-
component,
|
|
534
|
-
point: targetPoint,
|
|
535
|
-
candidateAngles,
|
|
536
|
-
checkOverlap
|
|
537
|
-
});
|
|
538
|
-
}
|
|
539
|
-
|
|
540
439
|
// lib/PackSolver/sortComponentQueue.ts
|
|
541
440
|
function sortComponentQueue({
|
|
542
441
|
components,
|
|
@@ -799,26 +698,7 @@ var PhasedPackSolver = class extends BaseSolver {
|
|
|
799
698
|
(id) => networkIdsInNewPackedComponent.has(id)
|
|
800
699
|
)
|
|
801
700
|
);
|
|
802
|
-
|
|
803
|
-
this.phaseData.candidatePoints = [];
|
|
804
|
-
this.phaseData.goodCandidates = [];
|
|
805
|
-
const shadows = placeComponentDisconnected({
|
|
806
|
-
component: newPackedComponent,
|
|
807
|
-
outlines,
|
|
808
|
-
direction: disconnectedPackDirection,
|
|
809
|
-
packedComponents: this.packedComponents,
|
|
810
|
-
candidateAngles: this.getCandidateAngles(newPackedComponent),
|
|
811
|
-
checkOverlap: (comp) => this.checkOverlapWithPackedComponents(comp)
|
|
812
|
-
});
|
|
813
|
-
this.phaseData.selectedRotation = newPackedComponent;
|
|
814
|
-
this.phaseData.rotationTrials = shadows.map((s) => ({
|
|
815
|
-
...s,
|
|
816
|
-
cost: 0,
|
|
817
|
-
anchorType: "center",
|
|
818
|
-
hasOverlap: false
|
|
819
|
-
}));
|
|
820
|
-
return;
|
|
821
|
-
}
|
|
701
|
+
const isDisconnected = sharedNetworkIds.size === 0;
|
|
822
702
|
const candidatePoints = [];
|
|
823
703
|
const goodCandidates = [];
|
|
824
704
|
let smallestDistance = Number.POSITIVE_INFINITY;
|
|
@@ -827,19 +707,81 @@ var PhasedPackSolver = class extends BaseSolver {
|
|
|
827
707
|
const [p1, p2] = segment;
|
|
828
708
|
return `${p1.x.toFixed(6)},${p1.y.toFixed(6)}-${p2.x.toFixed(6)},${p2.y.toFixed(6)}`;
|
|
829
709
|
};
|
|
710
|
+
const packedClusterCenter = this.packedComponents.length > 0 ? {
|
|
711
|
+
x: this.packedComponents.reduce((sum, c) => sum + c.center.x, 0) / this.packedComponents.length,
|
|
712
|
+
y: this.packedComponents.reduce((sum, c) => sum + c.center.y, 0) / this.packedComponents.length
|
|
713
|
+
} : { x: 0, y: 0 };
|
|
830
714
|
const networkIdToAlreadyPackedSegments = /* @__PURE__ */ new Map();
|
|
831
|
-
|
|
832
|
-
const
|
|
833
|
-
|
|
834
|
-
for (const
|
|
835
|
-
|
|
836
|
-
|
|
715
|
+
if (!isDisconnected) {
|
|
716
|
+
for (const sharedNetworkId of sharedNetworkIds) {
|
|
717
|
+
const segments = [];
|
|
718
|
+
for (const packedComponent of this.packedComponents) {
|
|
719
|
+
for (const pad of packedComponent.pads) {
|
|
720
|
+
if (pad.networkId === sharedNetworkId) {
|
|
721
|
+
segments.push(...getSegmentsFromPad(pad));
|
|
722
|
+
}
|
|
837
723
|
}
|
|
838
724
|
}
|
|
725
|
+
networkIdToAlreadyPackedSegments.set(sharedNetworkId, segments);
|
|
839
726
|
}
|
|
840
|
-
networkIdToAlreadyPackedSegments.set(sharedNetworkId, segments);
|
|
841
727
|
}
|
|
842
|
-
if (
|
|
728
|
+
if (isDisconnected) {
|
|
729
|
+
for (const outline of outlines) {
|
|
730
|
+
for (const outlineSegment of outline) {
|
|
731
|
+
const [p1, p2] = outlineSegment;
|
|
732
|
+
for (let t = 0; t <= 1; t += 0.1) {
|
|
733
|
+
const sampledPoint = {
|
|
734
|
+
x: p1.x + t * (p2.x - p1.x),
|
|
735
|
+
y: p1.y + t * (p2.y - p1.y)
|
|
736
|
+
};
|
|
737
|
+
let distance = 0;
|
|
738
|
+
if (disconnectedPackDirection === "nearest_to_center") {
|
|
739
|
+
distance = Math.sqrt(
|
|
740
|
+
Math.pow(sampledPoint.x - packedClusterCenter.x, 2) + Math.pow(sampledPoint.y - packedClusterCenter.y, 2)
|
|
741
|
+
);
|
|
742
|
+
} else if (disconnectedPackDirection === "left") {
|
|
743
|
+
distance = sampledPoint.x;
|
|
744
|
+
distance += 1e-3 * Math.abs(sampledPoint.y - packedClusterCenter.y);
|
|
745
|
+
} else if (disconnectedPackDirection === "right") {
|
|
746
|
+
distance = -sampledPoint.x;
|
|
747
|
+
distance += 1e-3 * Math.abs(sampledPoint.y - packedClusterCenter.y);
|
|
748
|
+
} else if (disconnectedPackDirection === "up") {
|
|
749
|
+
distance = -sampledPoint.y;
|
|
750
|
+
distance += 1e-3 * Math.abs(sampledPoint.x - packedClusterCenter.x);
|
|
751
|
+
} else if (disconnectedPackDirection === "down") {
|
|
752
|
+
distance = sampledPoint.y;
|
|
753
|
+
distance += 1e-3 * Math.abs(sampledPoint.x - packedClusterCenter.x);
|
|
754
|
+
}
|
|
755
|
+
const point = {
|
|
756
|
+
...sampledPoint,
|
|
757
|
+
networkId: "disconnected",
|
|
758
|
+
distance
|
|
759
|
+
};
|
|
760
|
+
candidatePoints.push(point);
|
|
761
|
+
const segmentKey = getSegmentKey(outlineSegment);
|
|
762
|
+
const currentSegmentBest = segmentBestPoints.get(segmentKey);
|
|
763
|
+
if (!currentSegmentBest || distance < currentSegmentBest.distance) {
|
|
764
|
+
segmentBestPoints.set(segmentKey, {
|
|
765
|
+
point: {
|
|
766
|
+
...sampledPoint,
|
|
767
|
+
networkId: "disconnected"
|
|
768
|
+
},
|
|
769
|
+
distance
|
|
770
|
+
});
|
|
771
|
+
}
|
|
772
|
+
if (distance < smallestDistance + 1e-6) {
|
|
773
|
+
if (distance < smallestDistance - 1e-6) {
|
|
774
|
+
goodCandidates.length = 0;
|
|
775
|
+
goodCandidates.push(point);
|
|
776
|
+
smallestDistance = distance;
|
|
777
|
+
} else {
|
|
778
|
+
goodCandidates.push(point);
|
|
779
|
+
}
|
|
780
|
+
}
|
|
781
|
+
}
|
|
782
|
+
}
|
|
783
|
+
}
|
|
784
|
+
} else if (packPlacementStrategy === "minimum_sum_distance_to_network" || packPlacementStrategy === "minimum_sum_squared_distance_to_network") {
|
|
843
785
|
for (const outline of outlines) {
|
|
844
786
|
for (const outlineSegment of outline) {
|
|
845
787
|
const [p1, p2] = outlineSegment;
|
|
@@ -933,45 +875,47 @@ var PhasedPackSolver = class extends BaseSolver {
|
|
|
933
875
|
}
|
|
934
876
|
}
|
|
935
877
|
}
|
|
936
|
-
|
|
937
|
-
for (const
|
|
938
|
-
for (const
|
|
939
|
-
const
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
for (const
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
878
|
+
if (!isDisconnected) {
|
|
879
|
+
for (const sharedNetworkId of sharedNetworkIds) {
|
|
880
|
+
for (const outline of outlines) {
|
|
881
|
+
for (const outlineSegment of outline) {
|
|
882
|
+
const [p1, p2] = outlineSegment;
|
|
883
|
+
for (let t = 0; t <= 1; t += 0.2) {
|
|
884
|
+
const sampledPoint = {
|
|
885
|
+
x: p1.x + t * (p2.x - p1.x),
|
|
886
|
+
y: p1.y + t * (p2.y - p1.y)
|
|
887
|
+
};
|
|
888
|
+
let distance = 0;
|
|
889
|
+
const componentPadsOnNetwork = newPackedComponent.pads.filter(
|
|
890
|
+
(p) => p.networkId === sharedNetworkId
|
|
891
|
+
);
|
|
892
|
+
for (const _ of componentPadsOnNetwork) {
|
|
893
|
+
let minDist = Number.POSITIVE_INFINITY;
|
|
894
|
+
for (const packedComponent of this.packedComponents) {
|
|
895
|
+
for (const packedPad of packedComponent.pads) {
|
|
896
|
+
if (packedPad.networkId === sharedNetworkId) {
|
|
897
|
+
const dx = sampledPoint.x - packedPad.absoluteCenter.x;
|
|
898
|
+
const dy = sampledPoint.y - packedPad.absoluteCenter.y;
|
|
899
|
+
const dist = Math.sqrt(dx * dx + dy * dy);
|
|
900
|
+
minDist = Math.min(minDist, dist);
|
|
901
|
+
}
|
|
958
902
|
}
|
|
959
903
|
}
|
|
904
|
+
distance += minDist;
|
|
905
|
+
}
|
|
906
|
+
const point = {
|
|
907
|
+
...sampledPoint,
|
|
908
|
+
networkId: sharedNetworkId,
|
|
909
|
+
distance
|
|
910
|
+
};
|
|
911
|
+
candidatePoints.push(point);
|
|
912
|
+
if (distance < smallestDistance) {
|
|
913
|
+
smallestDistance = distance;
|
|
914
|
+
goodCandidates.length = 0;
|
|
915
|
+
goodCandidates.push(point);
|
|
916
|
+
} else if (distance === smallestDistance) {
|
|
917
|
+
goodCandidates.push(point);
|
|
960
918
|
}
|
|
961
|
-
distance += minDist;
|
|
962
|
-
}
|
|
963
|
-
const point = {
|
|
964
|
-
...sampledPoint,
|
|
965
|
-
networkId: sharedNetworkId,
|
|
966
|
-
distance
|
|
967
|
-
};
|
|
968
|
-
candidatePoints.push(point);
|
|
969
|
-
if (distance < smallestDistance) {
|
|
970
|
-
smallestDistance = distance;
|
|
971
|
-
goodCandidates.length = 0;
|
|
972
|
-
goodCandidates.push(point);
|
|
973
|
-
} else if (distance === smallestDistance) {
|
|
974
|
-
goodCandidates.push(point);
|
|
975
919
|
}
|
|
976
920
|
}
|
|
977
921
|
}
|
|
@@ -1023,6 +967,14 @@ var PhasedPackSolver = class extends BaseSolver {
|
|
|
1023
967
|
}
|
|
1024
968
|
}
|
|
1025
969
|
}
|
|
970
|
+
const isDisconnected = this.phaseData.goodCandidates.some(
|
|
971
|
+
(c) => c.networkId === "disconnected"
|
|
972
|
+
);
|
|
973
|
+
const packedClusterCenter = this.packedComponents.length > 0 ? {
|
|
974
|
+
x: this.packedComponents.reduce((sum, c) => sum + c.center.x, 0) / this.packedComponents.length,
|
|
975
|
+
y: this.packedComponents.reduce((sum, c) => sum + c.center.y, 0) / this.packedComponents.length
|
|
976
|
+
} : { x: 0, y: 0 };
|
|
977
|
+
const { disconnectedPackDirection = "nearest_to_center" } = this.packInput;
|
|
1026
978
|
const useSquaredDistance = this.packInput.packPlacementStrategy === "minimum_sum_squared_distance_to_network";
|
|
1027
979
|
for (const angle of candidateAngles) {
|
|
1028
980
|
for (const point of this.phaseData.goodCandidates) {
|
|
@@ -1045,20 +997,40 @@ var PhasedPackSolver = class extends BaseSolver {
|
|
|
1045
997
|
setPackedComponentPadCenters(trial);
|
|
1046
998
|
const hasOverlap = this.checkOverlapWithPackedComponents(trial);
|
|
1047
999
|
let cost = 0;
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1000
|
+
if (isDisconnected) {
|
|
1001
|
+
if (disconnectedPackDirection === "nearest_to_center") {
|
|
1002
|
+
cost = Math.sqrt(
|
|
1003
|
+
Math.pow(componentCenter.x - packedClusterCenter.x, 2) + Math.pow(componentCenter.y - packedClusterCenter.y, 2)
|
|
1004
|
+
);
|
|
1005
|
+
} else if (disconnectedPackDirection === "left") {
|
|
1006
|
+
cost = componentCenter.x;
|
|
1007
|
+
cost += 1e-3 * Math.abs(componentCenter.y - packedClusterCenter.y);
|
|
1008
|
+
} else if (disconnectedPackDirection === "right") {
|
|
1009
|
+
cost = -componentCenter.x;
|
|
1010
|
+
cost += 1e-3 * Math.abs(componentCenter.y - packedClusterCenter.y);
|
|
1011
|
+
} else if (disconnectedPackDirection === "up") {
|
|
1012
|
+
cost = -componentCenter.y;
|
|
1013
|
+
cost += 1e-3 * Math.abs(componentCenter.x - packedClusterCenter.x);
|
|
1014
|
+
} else if (disconnectedPackDirection === "down") {
|
|
1015
|
+
cost = componentCenter.y;
|
|
1016
|
+
cost += 1e-3 * Math.abs(componentCenter.x - packedClusterCenter.x);
|
|
1017
|
+
}
|
|
1018
|
+
} else {
|
|
1019
|
+
for (const pad of trial.pads) {
|
|
1020
|
+
let minDist = Number.POSITIVE_INFINITY;
|
|
1021
|
+
for (const packedComp of this.packedComponents) {
|
|
1022
|
+
for (const packedPad of packedComp.pads) {
|
|
1023
|
+
if (packedPad.networkId === pad.networkId) {
|
|
1024
|
+
const dx = pad.absoluteCenter.x - packedPad.absoluteCenter.x;
|
|
1025
|
+
const dy = pad.absoluteCenter.y - packedPad.absoluteCenter.y;
|
|
1026
|
+
const dist = Math.sqrt(dx * dx + dy * dy);
|
|
1027
|
+
minDist = Math.min(minDist, dist);
|
|
1028
|
+
}
|
|
1057
1029
|
}
|
|
1058
1030
|
}
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1031
|
+
if (minDist < Number.POSITIVE_INFINITY) {
|
|
1032
|
+
cost += useSquaredDistance ? minDist * minDist : minDist;
|
|
1033
|
+
}
|
|
1062
1034
|
}
|
|
1063
1035
|
}
|
|
1064
1036
|
rotationTrials.push({
|
|
@@ -1075,20 +1047,40 @@ var PhasedPackSolver = class extends BaseSolver {
|
|
|
1075
1047
|
setPackedComponentPadCenters(centerTrial);
|
|
1076
1048
|
const centerHasOverlap = this.checkOverlapWithPackedComponents(centerTrial);
|
|
1077
1049
|
let centerCost = 0;
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1050
|
+
if (isDisconnected) {
|
|
1051
|
+
if (disconnectedPackDirection === "nearest_to_center") {
|
|
1052
|
+
centerCost = Math.sqrt(
|
|
1053
|
+
Math.pow(centerTrial.center.x - packedClusterCenter.x, 2) + Math.pow(centerTrial.center.y - packedClusterCenter.y, 2)
|
|
1054
|
+
);
|
|
1055
|
+
} else if (disconnectedPackDirection === "left") {
|
|
1056
|
+
centerCost = centerTrial.center.x;
|
|
1057
|
+
centerCost += 1e-3 * Math.abs(centerTrial.center.y - packedClusterCenter.y);
|
|
1058
|
+
} else if (disconnectedPackDirection === "right") {
|
|
1059
|
+
centerCost = -centerTrial.center.x;
|
|
1060
|
+
centerCost += 1e-3 * Math.abs(centerTrial.center.y - packedClusterCenter.y);
|
|
1061
|
+
} else if (disconnectedPackDirection === "up") {
|
|
1062
|
+
centerCost = -centerTrial.center.y;
|
|
1063
|
+
centerCost += 1e-3 * Math.abs(centerTrial.center.x - packedClusterCenter.x);
|
|
1064
|
+
} else if (disconnectedPackDirection === "down") {
|
|
1065
|
+
centerCost = centerTrial.center.y;
|
|
1066
|
+
centerCost += 1e-3 * Math.abs(centerTrial.center.x - packedClusterCenter.x);
|
|
1067
|
+
}
|
|
1068
|
+
} else {
|
|
1069
|
+
for (const pad of centerTrial.pads) {
|
|
1070
|
+
let minDist = Number.POSITIVE_INFINITY;
|
|
1071
|
+
for (const packedComp of this.packedComponents) {
|
|
1072
|
+
for (const packedPad of packedComp.pads) {
|
|
1073
|
+
if (packedPad.networkId === pad.networkId) {
|
|
1074
|
+
const dx = pad.absoluteCenter.x - packedPad.absoluteCenter.x;
|
|
1075
|
+
const dy = pad.absoluteCenter.y - packedPad.absoluteCenter.y;
|
|
1076
|
+
const dist = Math.sqrt(dx * dx + dy * dy);
|
|
1077
|
+
minDist = Math.min(minDist, dist);
|
|
1078
|
+
}
|
|
1087
1079
|
}
|
|
1088
1080
|
}
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1081
|
+
if (minDist < Number.POSITIVE_INFINITY) {
|
|
1082
|
+
centerCost += useSquaredDistance ? minDist * minDist : minDist;
|
|
1083
|
+
}
|
|
1092
1084
|
}
|
|
1093
1085
|
}
|
|
1094
1086
|
rotationTrials.push({
|
|
@@ -1326,7 +1318,10 @@ var PhasedPackSolver = class extends BaseSolver {
|
|
|
1326
1318
|
return [this.packInput];
|
|
1327
1319
|
}
|
|
1328
1320
|
getResult() {
|
|
1329
|
-
return this.packedComponents
|
|
1321
|
+
return this.packedComponents.map((component) => ({
|
|
1322
|
+
...component,
|
|
1323
|
+
ccwRotationDegrees: component.ccwRotationOffset
|
|
1324
|
+
}));
|
|
1330
1325
|
}
|
|
1331
1326
|
/* ---------- small helpers ------------------------------------------------ */
|
|
1332
1327
|
getCandidateAngles(c) {
|
|
@@ -1347,7 +1342,7 @@ var pack = (input) => {
|
|
|
1347
1342
|
solver.solve();
|
|
1348
1343
|
return {
|
|
1349
1344
|
...input,
|
|
1350
|
-
components: solver.
|
|
1345
|
+
components: solver.getResult()
|
|
1351
1346
|
};
|
|
1352
1347
|
};
|
|
1353
1348
|
|
package/package.json
CHANGED