calculate-packing 0.0.20 → 0.0.22

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 (3) hide show
  1. package/dist/index.d.ts +211 -15
  2. package/dist/index.js +1162 -4
  3. package/package.json +1 -1
package/dist/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
- import { GraphicsObject, Point as Point$1 } from 'graphics-debug';
1
+ import { GraphicsObject, Point as Point$2 } from 'graphics-debug';
2
2
  import { CircuitJson } from 'circuit-json';
3
- import { Bounds } from '@tscircuit/math-utils';
3
+ import { Bounds, Point as Point$3 } from '@tscircuit/math-utils';
4
4
 
5
5
  type ComponentId = string;
6
6
  type PadId = string;
@@ -107,11 +107,11 @@ declare class BaseSolver {
107
107
  noisySolve(): void;
108
108
  }
109
109
 
110
- type Point = {
110
+ type Point$1 = {
111
111
  x: number;
112
112
  y: number;
113
113
  };
114
- type Segment = [Point, Point];
114
+ type Segment = [Point$1, Point$1];
115
115
 
116
116
  type PackingPhase = "idle" | "show_candidate_points" | "show_rotations" | "show_final_placement";
117
117
  interface RotationTrial extends PackedComponent {
@@ -127,11 +127,11 @@ declare class PhasedPackSolver extends BaseSolver {
127
127
  currentPhase: PackingPhase;
128
128
  currentComponent?: InputComponent;
129
129
  phaseData: {
130
- candidatePoints?: Array<Point$1 & {
130
+ candidatePoints?: Array<Point$2 & {
131
131
  networkId: NetworkId;
132
132
  distance: number;
133
133
  }>;
134
- goodCandidates?: Array<Point$1 & {
134
+ goodCandidates?: Array<Point$2 & {
135
135
  networkId: NetworkId;
136
136
  }>;
137
137
  bestDistance?: number;
@@ -140,13 +140,13 @@ declare class PhasedPackSolver extends BaseSolver {
140
140
  outlines?: Segment[][];
141
141
  };
142
142
  lastBestPointsResult?: {
143
- goodCandidates: (Point$1 & {
143
+ goodCandidates: (Point$2 & {
144
144
  networkId: NetworkId;
145
145
  })[];
146
146
  distance: number;
147
147
  };
148
148
  lastEvaluatedPositionShadows?: Array<PackedComponent>;
149
- lastCandidatePoints?: Array<Point$1 & {
149
+ lastCandidatePoints?: Array<Point$2 & {
150
150
  networkId: NetworkId;
151
151
  distance: number;
152
152
  }>;
@@ -199,18 +199,18 @@ type Rect = {
199
199
 
200
200
  type GlobalBounds = Bounds;
201
201
  declare class LargestRectOutsideOutlineFromPointSolver extends BaseSolver {
202
- fullOutline: Point[];
203
- origin: Point;
202
+ fullOutline: Point$1[];
203
+ origin: Point$1;
204
204
  globalBounds: Bounds;
205
205
  largestRect: Rect | null;
206
206
  constructor(params: {
207
- fullOutline: Point[];
208
- origin: Point;
207
+ fullOutline: Point$1[];
208
+ origin: Point$1;
209
209
  globalBounds: Bounds;
210
210
  });
211
211
  getConstructorParams(): {
212
- fullOutline: Point[];
213
- origin: Point;
212
+ fullOutline: Point$1[];
213
+ origin: Point$1;
214
214
  globalBounds: Bounds;
215
215
  };
216
216
  _setup(): void;
@@ -229,4 +229,200 @@ declare class LargestRectOutsideOutlineFromPointSolver extends BaseSolver {
229
229
  visualize(): GraphicsObject;
230
230
  }
231
231
 
232
- export { type ComponentId, type GlobalBounds, type InputComponent, type InputPad, LargestRectOutsideOutlineFromPointSolver, type NetworkId, type OutputPad, type PackInput, type PackOutput, type PackPlacementStrategy, type PackedComponent, type PadId, PhasedPackSolver, type Point, type Rect, convertCircuitJsonToPackOutput, convertPackOutputToPackInput, getGraphicsFromPackOutput, pack };
232
+ interface Point {
233
+ x: number;
234
+ y: number;
235
+ }
236
+ interface IrlsSolverParams {
237
+ /** Target points to minimize distance to */
238
+ targetPoints: Point[];
239
+ /** Initial position for the algorithm */
240
+ initialPosition: Point;
241
+ /** Optional constraint function that maps a point to the nearest valid position */
242
+ constraintFn?: (point: Point) => Point;
243
+ /** Convergence tolerance */
244
+ epsilon?: number;
245
+ /** Maximum iterations before giving up */
246
+ maxIterations?: number;
247
+ /** Whether to use squared distances (for sum of squared distances optimization) */
248
+ useSquaredDistance?: boolean;
249
+ }
250
+ /**
251
+ * IRLS (Iteratively Reweighted Least Squares) Solver using the Weiszfeld algorithm
252
+ * to find the geometric median (point that minimizes sum of distances to target points).
253
+ *
254
+ * This solver can be used as a subsolver in other optimization problems where
255
+ * you need to find the optimal position that minimizes total distance to a set of points.
256
+ */
257
+ declare class IrlsSolver extends BaseSolver {
258
+ targetPoints: Point[];
259
+ currentPosition: Point;
260
+ constraintFn?: (point: Point) => Point;
261
+ epsilon: number;
262
+ useSquaredDistance: boolean;
263
+ optimalPosition?: Point;
264
+ private readonly initialPosition;
265
+ constructor(params: IrlsSolverParams);
266
+ getConstructorParams(): IrlsSolverParams;
267
+ _setup(): void;
268
+ _step(): void;
269
+ /**
270
+ * Get the current best position
271
+ */
272
+ getBestPosition(): Point;
273
+ /**
274
+ * Calculate total distance from current position to all target points
275
+ */
276
+ getTotalDistance(position?: Point): number;
277
+ computeProgress(): number;
278
+ visualize(): GraphicsObject;
279
+ }
280
+
281
+ /**
282
+ * Given a single segment on the outline, the component's rotation, compute the
283
+ * optimal position for the rotated component (the position that minimizes the
284
+ * packStrategy, generally minimizing the sum of the distances to other pads in
285
+ * the network)
286
+ *
287
+ * To do this, we use the IRLS/Weiszfeld Weighted Least Squares algorithm, look
288
+ * at the site/algorithm-visualizations/irls-weiszfeld-algorithm.page.tsx for
289
+ * an interactive visualization of how it works.
290
+ */
291
+ declare class OutlineSegmentCandidatePointSolver extends BaseSolver {
292
+ outlineSegment: [Point$3, Point$3];
293
+ viableOutlineSegment: [Point$3, Point$3] | null;
294
+ fullOutline: [Point$3, Point$3][];
295
+ componentRotationDegrees: number;
296
+ packStrategy: "minimum_sum_squared_distance_to_network" | "minimum_sum_distance_to_network";
297
+ minGap: number;
298
+ packedComponents: PackedComponent[];
299
+ componentToPack: InputComponent;
300
+ viableBounds?: Bounds;
301
+ optimalPosition?: Point$3;
302
+ irlsSolver?: IrlsSolver;
303
+ constructor(params: {
304
+ outlineSegment: [Point$3, Point$3];
305
+ fullOutline: [Point$3, Point$3][];
306
+ componentRotationDegrees: number;
307
+ packStrategy: "minimum_sum_squared_distance_to_network" | "minimum_sum_distance_to_network";
308
+ minGap: number;
309
+ packedComponents: PackedComponent[];
310
+ componentToPack: InputComponent;
311
+ });
312
+ getConstructorParams(): ConstructorParameters<typeof OutlineSegmentCandidatePointSolver>[0];
313
+ _getPackedComponentBounds(params?: {
314
+ margin?: number;
315
+ }): Bounds;
316
+ _setup(): void;
317
+ _step(): void;
318
+ /**
319
+ * Get target points from network connections, considering the component's rotation
320
+ */
321
+ private getNetworkTargetPoints;
322
+ /**
323
+ * Project a point onto the outline segment
324
+ */
325
+ private projectPointOntoSegment;
326
+ /**
327
+ * Get rotated pads for the component being placed
328
+ */
329
+ private getRotatedComponentPads;
330
+ /**
331
+ * Create a temporary PackedComponent with the given center position and applied rotation
332
+ */
333
+ private createTemporaryPackedComponent;
334
+ /**
335
+ * Adjust position to avoid component bounds crossing to the inside of the outline
336
+ */
337
+ private adjustPositionForOutlineCollision;
338
+ /**
339
+ * Get the outward normal for the current segment by determining which side
340
+ * is farther from the outline centroid
341
+ */
342
+ private getOutwardNormal;
343
+ visualize(): GraphicsObject;
344
+ }
345
+
346
+ type Phase = "outline" | "segment_candidate" | "evaluate";
347
+ interface QueuedOutlineSegment {
348
+ segment: Segment;
349
+ availableRotations: number[];
350
+ segmentIndex: number;
351
+ fullOutline: Segment[];
352
+ }
353
+ interface CandidateResult {
354
+ segment: Segment;
355
+ rotation: number;
356
+ optimalPosition?: Point$2;
357
+ distance: number;
358
+ segmentIndex: number;
359
+ rotationIndex: number;
360
+ }
361
+ /**
362
+ * Packs a single component given a set of already packed components.
363
+ *
364
+ * Runs subsolvers and operates in several phases:
365
+ * Phase 1: Compute outline (visualization shows outline)
366
+ * Phase 2: Compute candidate point for each segment by finding the optimal
367
+ * point on each segment of the outline for each rotation-segment pair.
368
+ * (visualization shows candidate point for active segment using the
369
+ * visualize method of the OutlineSegmentCandidatePointSolver)
370
+ * Phase 3: Score the points. Show the points in visualization with a "step"
371
+ * where step=0 is the best point (lowest distance) and step=N is the
372
+ * worst point.
373
+ */
374
+ declare class SingleComponentPackSolver extends BaseSolver {
375
+ componentToPack: InputComponent;
376
+ packedComponents: PackedComponent[];
377
+ packPlacementStrategy: PackPlacementStrategy;
378
+ minGap: number;
379
+ currentPhase: Phase;
380
+ outlines: Segment[][];
381
+ queuedOutlineSegments: QueuedOutlineSegment[];
382
+ currentSegmentIndex: number;
383
+ currentRotationIndex: number;
384
+ activeSubSolver?: OutlineSegmentCandidatePointSolver | null;
385
+ candidateResults: CandidateResult[];
386
+ bestCandidate?: CandidateResult;
387
+ outputPackedComponent?: PackedComponent;
388
+ constructor(params: {
389
+ componentToPack: InputComponent;
390
+ packedComponents: PackedComponent[];
391
+ packPlacementStrategy: PackPlacementStrategy;
392
+ minGap?: number;
393
+ });
394
+ _setup(): void;
395
+ _step(): void;
396
+ private executeOutlinePhase;
397
+ private executeSegmentCandidatePhase;
398
+ private executeEvaluatePhase;
399
+ private calculateDistance;
400
+ private createPackedComponent;
401
+ visualize(): GraphicsObject;
402
+ private visualizeOutlinePhase;
403
+ private visualizeSegmentCandidatePhase;
404
+ private visualizeEvaluatePhase;
405
+ getResult(): PackedComponent | undefined;
406
+ getConstructorParams(): {
407
+ componentToPack: InputComponent;
408
+ packedComponents: PackedComponent[];
409
+ packPlacementStrategy: PackPlacementStrategy;
410
+ minGap: number;
411
+ };
412
+ }
413
+
414
+ declare class PackSolver2 extends BaseSolver {
415
+ activeSubSolver: SingleComponentPackSolver | null | undefined;
416
+ packInput: PackInput;
417
+ unpackedComponentQueue: InputComponent[];
418
+ packedComponents: PackedComponent[];
419
+ componentToPack?: InputComponent | null | undefined;
420
+ constructor(packInput: PackInput);
421
+ getConstructorParams(): PackInput;
422
+ _setup(): void;
423
+ private packFirstComponent;
424
+ _step(): void;
425
+ visualize(): GraphicsObject;
426
+ }
427
+
428
+ export { type ComponentId, type GlobalBounds, type InputComponent, type InputPad, LargestRectOutsideOutlineFromPointSolver, type NetworkId, type OutputPad, type PackInput, type PackOutput, type PackPlacementStrategy, PackSolver2, type PackedComponent, type PadId, PhasedPackSolver, type Point$1 as Point, type Rect, convertCircuitJsonToPackOutput, convertPackOutputToPackInput, getGraphicsFromPackOutput, pack };