calculate-packing 0.0.48 → 0.0.50
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.js +70 -2
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -2196,6 +2196,11 @@ var SingleComponentPackSolver = class extends BaseSolver {
|
|
|
2196
2196
|
return distance2 + 1e-6 < this.minGap;
|
|
2197
2197
|
});
|
|
2198
2198
|
});
|
|
2199
|
+
let outsideBounds = false;
|
|
2200
|
+
if (this.bounds) {
|
|
2201
|
+
const componentBounds = getComponentBounds(candidateComponent, 0);
|
|
2202
|
+
outsideBounds = componentBounds.minX < this.bounds.minX || componentBounds.maxX > this.bounds.maxX || componentBounds.minY < this.bounds.minY || componentBounds.maxY > this.bounds.maxY;
|
|
2203
|
+
}
|
|
2199
2204
|
let outsideBoundaryOutline = false;
|
|
2200
2205
|
if (this.boundaryOutline && this.boundaryOutline.length >= 3) {
|
|
2201
2206
|
const componentBounds = getComponentBounds(candidateComponent, 0);
|
|
@@ -2231,6 +2236,17 @@ var SingleComponentPackSolver = class extends BaseSolver {
|
|
|
2231
2236
|
rotationIndex: this.currentRotationIndex,
|
|
2232
2237
|
gapDistance: minObstacleGapDistance
|
|
2233
2238
|
});
|
|
2239
|
+
} else if (outsideBounds) {
|
|
2240
|
+
this.rejectedCandidates.push({
|
|
2241
|
+
segment: queuedSegment.segment,
|
|
2242
|
+
rotation,
|
|
2243
|
+
optimalPosition,
|
|
2244
|
+
distance,
|
|
2245
|
+
segmentIndex: queuedSegment.segmentIndex,
|
|
2246
|
+
rotationIndex: this.currentRotationIndex,
|
|
2247
|
+
gapDistance: -1
|
|
2248
|
+
// Special marker for bounds violation
|
|
2249
|
+
});
|
|
2234
2250
|
} else if (outsideBoundaryOutline) {
|
|
2235
2251
|
this.rejectedCandidates.push({
|
|
2236
2252
|
segment: queuedSegment.segment,
|
|
@@ -2503,6 +2519,38 @@ gap_distance=${candidate.gapDistance}`,
|
|
|
2503
2519
|
|
|
2504
2520
|
// lib/PackSolver2/PackSolver2.ts
|
|
2505
2521
|
import { computeDistanceBetweenBoxes as computeDistanceBetweenBoxes3 } from "@tscircuit/math-utils";
|
|
2522
|
+
|
|
2523
|
+
// lib/math/getPolygonCentroid.ts
|
|
2524
|
+
function getPolygonCentroid(points) {
|
|
2525
|
+
if (points.length < 3) {
|
|
2526
|
+
const sumX = points.reduce((sum, p) => sum + p.x, 0);
|
|
2527
|
+
const sumY = points.reduce((sum, p) => sum + p.y, 0);
|
|
2528
|
+
return { x: sumX / points.length, y: sumY / points.length };
|
|
2529
|
+
}
|
|
2530
|
+
let signedArea = 0;
|
|
2531
|
+
let cx = 0;
|
|
2532
|
+
let cy = 0;
|
|
2533
|
+
for (let i = 0; i < points.length; i++) {
|
|
2534
|
+
const p1 = points[i];
|
|
2535
|
+
const p2 = points[(i + 1) % points.length];
|
|
2536
|
+
const crossProduct = p1.x * p2.y - p2.x * p1.y;
|
|
2537
|
+
signedArea += crossProduct;
|
|
2538
|
+
cx += (p1.x + p2.x) * crossProduct;
|
|
2539
|
+
cy += (p1.y + p2.y) * crossProduct;
|
|
2540
|
+
}
|
|
2541
|
+
signedArea *= 0.5;
|
|
2542
|
+
const area = Math.abs(signedArea);
|
|
2543
|
+
if (area < 1e-10) {
|
|
2544
|
+
const sumX = points.reduce((sum, p) => sum + p.x, 0);
|
|
2545
|
+
const sumY = points.reduce((sum, p) => sum + p.y, 0);
|
|
2546
|
+
return { x: sumX / points.length, y: sumY / points.length };
|
|
2547
|
+
}
|
|
2548
|
+
cx /= 6 * signedArea;
|
|
2549
|
+
cy /= 6 * signedArea;
|
|
2550
|
+
return { x: cx, y: cy };
|
|
2551
|
+
}
|
|
2552
|
+
|
|
2553
|
+
// lib/PackSolver2/PackSolver2.ts
|
|
2506
2554
|
var PackSolver2 = class extends BaseSolver {
|
|
2507
2555
|
packInput;
|
|
2508
2556
|
unpackedComponentQueue = [];
|
|
@@ -2526,9 +2574,13 @@ var PackSolver2 = class extends BaseSolver {
|
|
|
2526
2574
|
}
|
|
2527
2575
|
packFirstComponent() {
|
|
2528
2576
|
const firstComponentToPack = this.unpackedComponentQueue.shift();
|
|
2577
|
+
let initialPosition = { x: 0, y: 0 };
|
|
2578
|
+
if (this.packInput.boundaryOutline && this.packInput.boundaryOutline.length >= 3) {
|
|
2579
|
+
initialPosition = getPolygonCentroid(this.packInput.boundaryOutline);
|
|
2580
|
+
}
|
|
2529
2581
|
const newPackedComponent = {
|
|
2530
2582
|
...firstComponentToPack,
|
|
2531
|
-
center:
|
|
2583
|
+
center: initialPosition,
|
|
2532
2584
|
ccwRotationOffset: 0,
|
|
2533
2585
|
pads: firstComponentToPack.pads.map((p) => ({
|
|
2534
2586
|
...p,
|
|
@@ -2553,7 +2605,23 @@ var PackSolver2 = class extends BaseSolver {
|
|
|
2553
2605
|
return distance + 1e-6 < this.packInput.minGap;
|
|
2554
2606
|
});
|
|
2555
2607
|
});
|
|
2556
|
-
|
|
2608
|
+
let outsideBoundaryOutline = false;
|
|
2609
|
+
if (this.packInput.boundaryOutline && this.packInput.boundaryOutline.length >= 3) {
|
|
2610
|
+
const componentBounds = getComponentBounds(newPackedComponent, 0);
|
|
2611
|
+
const allPadsInside = newPackedComponent.pads.every(
|
|
2612
|
+
(pad) => isPointInPolygon(pad.absoluteCenter, this.packInput.boundaryOutline)
|
|
2613
|
+
);
|
|
2614
|
+
const cornersInside = [
|
|
2615
|
+
{ x: componentBounds.minX, y: componentBounds.minY },
|
|
2616
|
+
{ x: componentBounds.minX, y: componentBounds.maxY },
|
|
2617
|
+
{ x: componentBounds.maxX, y: componentBounds.minY },
|
|
2618
|
+
{ x: componentBounds.maxX, y: componentBounds.maxY }
|
|
2619
|
+
].every(
|
|
2620
|
+
(corner) => isPointInPolygon(corner, this.packInput.boundaryOutline)
|
|
2621
|
+
);
|
|
2622
|
+
outsideBoundaryOutline = !allPadsInside || !cornersInside;
|
|
2623
|
+
}
|
|
2624
|
+
if (!tooCloseToObstacles && !outsideBoundaryOutline) {
|
|
2557
2625
|
this.packedComponents.push(newPackedComponent);
|
|
2558
2626
|
return;
|
|
2559
2627
|
}
|
package/package.json
CHANGED