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.
Files changed (2) hide show
  1. package/dist/index.js +70 -2
  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: { x: 0, y: 0 },
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
- if (!tooCloseToObstacles) {
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
@@ -2,7 +2,7 @@
2
2
  "name": "calculate-packing",
3
3
  "main": "dist/index.js",
4
4
  "type": "module",
5
- "version": "0.0.48",
5
+ "version": "0.0.50",
6
6
  "description": "Calculate a packing layout with support for different strategy configurations",
7
7
  "scripts": {
8
8
  "start": "cosmos",