@mark1russell7/packing 0.2.3 → 0.2.4
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/README.md +11 -0
- package/build/index.d.ts +60 -26
- package/build/index.d.ts.map +1 -1
- package/build/index.js +223 -15
- package/build/index.js.map +1 -1
- package/package.json +1 -1
- package/src/adapters.ts +25 -3
- package/src/index.ts +1 -1
- package/src/measures.ts +18 -7
- package/src/moves.ts +17 -3
- package/src/pack.ts +3 -1
- package/src/shelf.ts +200 -0
package/README.md
CHANGED
|
@@ -35,6 +35,17 @@ pack(rects, outer, { strategy: "skyline", sortOrder: "area-desc" });
|
|
|
35
35
|
- `packSkyline`: each rectangle goes to the lowest place where it fits. It packs around a `locked` rectangle.
|
|
36
36
|
- `packShelf`: it fills rows left to right in the sort order, and goes around each `locked` rectangle. With the sort order `input`, the rows read in your order.
|
|
37
37
|
|
|
38
|
+
Since 0.2.4, `packShelf` and the strategy `shelf` have the option `fit`. `SHELF_FITS` lists its values. Without `fit`, the shelf packing does not change.
|
|
39
|
+
|
|
40
|
+
```ts
|
|
41
|
+
pack(rects, outer, { strategy: "shelf", fit: "best" });
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
- `fit: "next"`: each rectangle uses only the open shelf. A short rectangle can also stack above a shorter rectangle.
|
|
45
|
+
- `fit: "first"`: each rectangle goes on the first shelf from the top where it fits.
|
|
46
|
+
- `fit: "best"`: each rectangle goes on the shelf with the least height left over above it.
|
|
47
|
+
- With a `fit`, the shelves open only in the free spans of each container shape. `docs/PACKER.md` tells the rules.
|
|
48
|
+
|
|
38
49
|
Both functions also work alone, in an outer rectangle with a width that you set. They do not change the width.
|
|
39
50
|
|
|
40
51
|
A `locked` rectangle keeps its position. `packSkyline` and `packShelf` put the other rectangles around it. `packRows` only keeps its position.
|
package/build/index.d.ts
CHANGED
|
@@ -142,6 +142,46 @@ interface FreeSpace {
|
|
|
142
142
|
* frame is the corner of the container, moved in by the inset and out by half the gap. `FreeSpace` tells the methods.
|
|
143
143
|
*/
|
|
144
144
|
export declare function freeSpace(input: PackInput): FreeSpace;
|
|
145
|
+
/**
|
|
146
|
+
* The rule of a shelf packing to choose the shelf of a rectangle. `packShelf` tells each rule.
|
|
147
|
+
*
|
|
148
|
+
* - `next`: only the open shelf, the last shelf that the packing opened.
|
|
149
|
+
* - `first`: the first shelf from the top where the rectangle fits.
|
|
150
|
+
* - `best`: the shelf with the least height left over above the rectangle.
|
|
151
|
+
*/
|
|
152
|
+
type ShelfFit = "next" | "first" | "best";
|
|
153
|
+
/** This constant lists each shelf fit. */
|
|
154
|
+
export declare const SHELF_FITS: readonly ShelfFit[];
|
|
155
|
+
/** The options of `packShelf` */
|
|
156
|
+
interface ShelfOptions {
|
|
157
|
+
/** The order of the rectangles before the packing. The default is `height-desc`. */
|
|
158
|
+
sortOrder?: SortOrder;
|
|
159
|
+
/**
|
|
160
|
+
* The free space of the container: `freeSpace` of the input. Without it, or when it is plain, the packer uses only the
|
|
161
|
+
* outer rectangle and the locked rectangles.
|
|
162
|
+
*/
|
|
163
|
+
space?: FreeSpace;
|
|
164
|
+
/**
|
|
165
|
+
* The rule to choose a shelf. Without it, `packShelf` packs as in 0.2.3. With it, `packShelf` uses its own shelves in
|
|
166
|
+
* each container shape, and it stacks rectangles in the strips above the shorter rectangles.
|
|
167
|
+
*/
|
|
168
|
+
fit?: ShelfFit;
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* This function packs rectangles into shelves: rows that it fills left to right in the sort order, and does not fill
|
|
172
|
+
* again. It goes around each `locked` rectangle. It sets the position of each rectangle and gives the outer rectangle.
|
|
173
|
+
*
|
|
174
|
+
* - With the sort order `input`, the rows read in the order of the array: left to right, and top to bottom.
|
|
175
|
+
* - With `height-desc` (the default), it is the classic Next-Fit Decreasing Height packing.
|
|
176
|
+
* - A rectangle goes to the first x in the row where it crosses no locked rectangle. If no such x is in the width,
|
|
177
|
+
* a new row starts under the current row.
|
|
178
|
+
* - A rectangle wider than the outer rectangle goes on its own row, at the left edge, and overflows.
|
|
179
|
+
* - It does not change the width. Without `fixedSize`, the height grows to the content. With `fixedSize`, a
|
|
180
|
+
* rectangle that does not fit is not packed: its `wasPacked` stays `false`.
|
|
181
|
+
* - With a space that is not plain, `packRowsInSpace` packs the rows into the outline of the space and around its holes.
|
|
182
|
+
* - With `fit`, `packShelvesInSpace` packs the rectangles, in each container shape. A `fit` that is not in `SHELF_FITS` throws a `RangeError`.
|
|
183
|
+
*/
|
|
184
|
+
export declare function packShelf<T>(rects: Rect<T>[], outer: Rect<T>, options?: ShelfOptions): Rect<T>;
|
|
145
185
|
/** The options of `pack` and `packRows` */
|
|
146
186
|
interface PackOptions {
|
|
147
187
|
/** The order of the rectangles before the packing. The default is `height-desc`. */
|
|
@@ -159,6 +199,8 @@ interface PackLayoutOptions extends PackOptions {
|
|
|
159
199
|
* Use `shelf` with the sort order `input` to keep the order of the array around locked rectangles.
|
|
160
200
|
*/
|
|
161
201
|
strategy?: "rows" | "skyline" | "shelf";
|
|
202
|
+
/** The rule of `shelf` to choose a shelf. Only `shelf` reads it. `ShelfOptions` tells it. Without it, `shelf` packs as in 0.2.3. */
|
|
203
|
+
fit?: ShelfFit;
|
|
162
204
|
}
|
|
163
205
|
/**
|
|
164
206
|
* This function packs rectangles into an outer rectangle of a given width with a guillotine row packing. It does
|
|
@@ -217,30 +259,6 @@ interface SkylineOptions {
|
|
|
217
259
|
* the obstacles and the locked items, thus the locked rectangles only keep their positions.
|
|
218
260
|
*/
|
|
219
261
|
export declare function packSkyline<T>(rects: Rect<T>[], outer: Rect<T>, options?: SkylineOptions): Rect<T>;
|
|
220
|
-
/** The options of `packShelf` */
|
|
221
|
-
interface ShelfOptions {
|
|
222
|
-
/** The order of the rectangles before the packing. The default is `height-desc`. */
|
|
223
|
-
sortOrder?: SortOrder;
|
|
224
|
-
/**
|
|
225
|
-
* The free space of the container: `freeSpace` of the input. Without it, or when it is plain, the packer uses only the
|
|
226
|
-
* outer rectangle and the locked rectangles.
|
|
227
|
-
*/
|
|
228
|
-
space?: FreeSpace;
|
|
229
|
-
}
|
|
230
|
-
/**
|
|
231
|
-
* This function packs rectangles into shelves: rows that it fills left to right in the sort order, and does not fill
|
|
232
|
-
* again. It goes around each `locked` rectangle. It sets the position of each rectangle and gives the outer rectangle.
|
|
233
|
-
*
|
|
234
|
-
* - With the sort order `input`, the rows read in the order of the array: left to right, and top to bottom.
|
|
235
|
-
* - With `height-desc` (the default), it is the classic Next-Fit Decreasing Height packing.
|
|
236
|
-
* - A rectangle goes to the first x in the row where it crosses no locked rectangle. If no such x is in the width,
|
|
237
|
-
* a new row starts under the current row.
|
|
238
|
-
* - A rectangle wider than the outer rectangle goes on its own row, at the left edge, and overflows.
|
|
239
|
-
* - It does not change the width. Without `fixedSize`, the height grows to the content. With `fixedSize`, a
|
|
240
|
-
* rectangle that does not fit is not packed: its `wasPacked` stays `false`.
|
|
241
|
-
* - With a space that is not plain, `packRowsInSpace` packs the rows into the outline of the space and around its holes.
|
|
242
|
-
*/
|
|
243
|
-
export declare function packShelf<T>(rects: Rect<T>[], outer: Rect<T>, options?: ShelfOptions): Rect<T>;
|
|
244
262
|
/** The options of `packFree` */
|
|
245
263
|
interface FreeWidthOptions extends PackLayoutOptions {
|
|
246
264
|
/** The target aspect: the width divided by the height. The default is 1, a square. */
|
|
@@ -387,9 +405,16 @@ interface LayoutMeasures {
|
|
|
387
405
|
"pack.overflow.rate": number;
|
|
388
406
|
"pack.overflow.area": number;
|
|
389
407
|
"pack.overflow.forced": number;
|
|
408
|
+
/** The tight lower bound of `pack.overflow.area`. `docs/MEASURES.md` defines it. */
|
|
390
409
|
"pack.overflow.forcedArea": number;
|
|
391
410
|
"pack.overflow.excess": number;
|
|
411
|
+
/**
|
|
412
|
+
* This measure is an alias of `pack.overflow.forcedArea`, with the same value.
|
|
413
|
+
*
|
|
414
|
+
* @deprecated Use `pack.overflow.forcedArea`. The alias stays until the next minor version.
|
|
415
|
+
*/
|
|
392
416
|
"pack.overflow.forcedAreaMin": number;
|
|
417
|
+
/** The overflow area above its bound: `pack.overflow.area` less `pack.overflow.forcedArea`. */
|
|
393
418
|
"pack.overflow.excessArea": number;
|
|
394
419
|
"pack.search.widths": number;
|
|
395
420
|
"pack.search.ms": number;
|
|
@@ -416,6 +441,8 @@ interface MeasureOptions {
|
|
|
416
441
|
* - A share of an area from 0 to 1 has 0.005. A guard has its tolerance.
|
|
417
442
|
* - An area and a ratio of lengths have `{ rel: 0.01 }`: 1% of the larger value.
|
|
418
443
|
* - The time has no minimum effect, because the times of CI change each time.
|
|
444
|
+
* - `pack.overflow.forcedAreaMin` is a deprecated alias of `pack.overflow.forcedArea`. Its spec is the same, except the id.
|
|
445
|
+
* The alias stays until the next minor version.
|
|
419
446
|
*/
|
|
420
447
|
export declare const MEASURE_SPECS: Readonly<Record<MeasureId, MeasureSpec>>;
|
|
421
448
|
/**
|
|
@@ -427,7 +454,8 @@ export declare const MEASURE_SPECS: Readonly<Record<MeasureId, MeasureSpec>>;
|
|
|
427
454
|
* - The time `pack.search.ms` comes from the trace. It is not part of the determinism rule.
|
|
428
455
|
* - The overflow measures count each id once. `pack.overflow.forced` is the lower bound of `overflowBound`.
|
|
429
456
|
* - `pack.overflow.excess` is the overflow less the forced overflow. A container with no fixed side gives 0 for both.
|
|
430
|
-
* - `pack.overflow.
|
|
457
|
+
* - `pack.overflow.forcedArea` is a lower bound of the overflow area. `pack.overflow.excessArea` is the overflow area above it.
|
|
458
|
+
* - `pack.overflow.forcedAreaMin` is a deprecated alias of `pack.overflow.forcedArea`, with the same value.
|
|
431
459
|
*
|
|
432
460
|
* @example
|
|
433
461
|
* ```ts
|
|
@@ -587,6 +615,11 @@ interface LayoutStrategyOptions {
|
|
|
587
615
|
sortOrder: SortOrder;
|
|
588
616
|
/** The number of widths that the first pass of the size search `log-sweep` tries. */
|
|
589
617
|
samples: number;
|
|
618
|
+
/**
|
|
619
|
+
* The rule of `shelf` to choose a shelf: `next`, `first` or `best`. Only `shelf` reads it. Without it, `shelf` packs
|
|
620
|
+
* as in 0.2.3. With it, the trace also counts `move.firstFit` and `move.bestFit`.
|
|
621
|
+
*/
|
|
622
|
+
fit?: ShelfFit;
|
|
590
623
|
}
|
|
591
624
|
/** The options of the strategy `push`. */
|
|
592
625
|
interface PushStrategyOptions {
|
|
@@ -609,6 +642,7 @@ export declare const skyline: Strategy<LayoutStrategyOptions>;
|
|
|
609
642
|
/**
|
|
610
643
|
* The strategy `shelf` uses `packShelf`: rows filled left to right, around the locked items and the fixed obstacles.
|
|
611
644
|
* With the sort order `input`, the rows keep the rank order. Turnable items, groups and item shapes throw `UnsupportedCell`.
|
|
645
|
+
* The option `fit` selects a shelf rule of roadmap item k21: `next`, `first` or `best`. The default has no `fit`.
|
|
612
646
|
*/
|
|
613
647
|
export declare const shelf: Strategy<LayoutStrategyOptions>;
|
|
614
648
|
/**
|
|
@@ -837,5 +871,5 @@ interface Corpus {
|
|
|
837
871
|
* `RangeError` for an unknown generator, a different version or 2 inputs with the same id.
|
|
838
872
|
*/
|
|
839
873
|
export declare function corpus(name: string, specs: readonly CorpusSpec[]): Corpus;
|
|
840
|
-
export { type Cell, type ChangeMeasures, type ContainerTest, type Corpus, type CorpusCell, type CorpusEntry, type CorpusGenerator, type CorpusManifest, type CorpusSpec, type CountScale, DEFAULT_TOLERANCE, type Dimension, type DimensionValue, type Direction, EPS, type EdgeCase, type EdgeCaseParams, type FreeSpace, type FreeSpan, type FreeWidthOptions, type FreeWidthResult, type FreeWidthTry, type GeneratedInput, type GeneratorParams, type GeneratorStamp, type Item, type LayoutContainer, type LayoutEdge, type LayoutInput, type LayoutMeasures, type LayoutStrategyOptions, type Margin, type MeasureFamily, type MeasureId, type MeasureOptions, type MeasureSpec, type MetricsOptions, type Obstacle, type ObstacleLayout, type PackContext, type PackHard, type PackInput, type PackLayoutOptions, type PackOptions, type PackOutput, type PackingMetrics, type Placement, type Port, type PushOptions, type PushStrategyOptions, RECORD_EPS, type RectGridParams, type RectScatteredParams, type Region, type ShelfOptions, type Side, type Sides, type SizeDistribution, type SizeSearch, type SkylineOptions, type SortOrder, type SpaceRect, type StageTrace, type Strategy, type Supports, type Tolerance, type UiParams, checkInput, turnPoint, turnPort, turnRegion };
|
|
874
|
+
export { type Cell, type ChangeMeasures, type ContainerTest, type Corpus, type CorpusCell, type CorpusEntry, type CorpusGenerator, type CorpusManifest, type CorpusSpec, type CountScale, DEFAULT_TOLERANCE, type Dimension, type DimensionValue, type Direction, EPS, type EdgeCase, type EdgeCaseParams, type FreeSpace, type FreeSpan, type FreeWidthOptions, type FreeWidthResult, type FreeWidthTry, type GeneratedInput, type GeneratorParams, type GeneratorStamp, type Item, type LayoutContainer, type LayoutEdge, type LayoutInput, type LayoutMeasures, type LayoutStrategyOptions, type Margin, type MeasureFamily, type MeasureId, type MeasureOptions, type MeasureSpec, type MetricsOptions, type Obstacle, type ObstacleLayout, type PackContext, type PackHard, type PackInput, type PackLayoutOptions, type PackOptions, type PackOutput, type PackingMetrics, type Placement, type Port, type PushOptions, type PushStrategyOptions, RECORD_EPS, type RectGridParams, type RectScatteredParams, type Region, type ShelfFit, type ShelfOptions, type Side, type Sides, type SizeDistribution, type SizeSearch, type SkylineOptions, type SortOrder, type SpaceRect, type StageTrace, type Strategy, type Supports, type Tolerance, type UiParams, checkInput, turnPoint, turnPort, turnRegion };
|
|
841
875
|
//# sourceMappingURL=index.d.ts.map
|
package/build/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","names":["Item","Sides","ContractMeasureSpec","Direction","ContainerTest","PackHard","LayoutContainer","LayoutEdge","LayoutInput"],"sources":["../src/vector.ts","../src/rect.ts","../src/order.ts","../src/contract.ts","../src/space.ts","../src/
|
|
1
|
+
{"version":3,"file":"index.d.ts","names":["Item","Sides","ContractMeasureSpec","Direction","ContainerTest","PackHard","LayoutContainer","LayoutEdge","LayoutInput"],"sources":["../src/vector.ts","../src/rect.ts","../src/order.ts","../src/contract.ts","../src/space.ts","../src/shelf.ts","../src/pack.ts","../src/skyline.ts","../src/free.ts","../src/push.ts","../src/metrics.ts","../src/measures.ts","../src/strategy.ts","../src/adapters.ts","../src/convert.ts","../src/registry.ts","../src/check.ts","../src/layout-input.ts","../src/generators.ts","../src/corpus.ts"],"mappings":"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"}
|
package/build/index.js
CHANGED
|
@@ -138,16 +138,23 @@ var Rect = class {
|
|
|
138
138
|
}
|
|
139
139
|
};
|
|
140
140
|
// src/moves.ts
|
|
141
|
-
/** The id of the characteristic move of each strategy. The trace of each strategy has its id, also with the count 0. */
|
|
141
|
+
/** The id of the characteristic move of each strategy and of each shelf fit. The trace of each strategy has its id, also with the count 0. */
|
|
142
142
|
const MOVES = Object.freeze({
|
|
143
143
|
/** A rectangle that the gap fill of `packRow` places in a gap of a row: under a shorter neighbor, or at the row break. */
|
|
144
144
|
rows: "move.gapFill",
|
|
145
|
-
/**
|
|
145
|
+
/**
|
|
146
|
+
* A rectangle that `packShelf` puts on an open shelf with a taller rectangle. The strip above it stays empty. With a
|
|
147
|
+
* `fit`, the move is a rectangle in the strip above a shorter rectangle of a shelf.
|
|
148
|
+
*/
|
|
146
149
|
shelf: "move.stack",
|
|
147
150
|
/** A rectangle that the skyline puts in a lower window, not in the leftmost window where it fits. */
|
|
148
151
|
skyline: "move.lowerWindow",
|
|
149
152
|
/** A rectangle that a push cascade moves. */
|
|
150
|
-
push: "move.cascade"
|
|
153
|
+
push: "move.cascade",
|
|
154
|
+
/** A rectangle that a shelf fit puts on a shelf that is not the open shelf. The open shelf is the last shelf that the packing opened. */
|
|
155
|
+
firstFit: "move.firstFit",
|
|
156
|
+
/** A rectangle that the fit `best` puts on a shelf that is not the first shelf where it fits. */
|
|
157
|
+
bestFit: "move.bestFit"
|
|
151
158
|
});
|
|
152
159
|
const counts = /* @__PURE__ */ new Map();
|
|
153
160
|
/** This function adds `n` to the count of a move. */
|
|
@@ -775,6 +782,12 @@ function freeSpace(input) {
|
|
|
775
782
|
return spaceOf(input, buildFrame(input));
|
|
776
783
|
}
|
|
777
784
|
// src/shelf.ts
|
|
785
|
+
/** This constant lists each shelf fit. */
|
|
786
|
+
const SHELF_FITS = [
|
|
787
|
+
"next",
|
|
788
|
+
"first",
|
|
789
|
+
"best"
|
|
790
|
+
];
|
|
778
791
|
/**
|
|
779
792
|
* This function gives the first x from `start` where a rectangle of width `w` crosses no obstacle in the band from
|
|
780
793
|
* `top` to `bottom`.
|
|
@@ -809,8 +822,10 @@ function nextTop(obstacles, top, bottom) {
|
|
|
809
822
|
* - It does not change the width. Without `fixedSize`, the height grows to the content. With `fixedSize`, a
|
|
810
823
|
* rectangle that does not fit is not packed: its `wasPacked` stays `false`.
|
|
811
824
|
* - With a space that is not plain, `packRowsInSpace` packs the rows into the outline of the space and around its holes.
|
|
825
|
+
* - With `fit`, `packShelvesInSpace` packs the rectangles, in each container shape. A `fit` that is not in `SHELF_FITS` throws a `RangeError`.
|
|
812
826
|
*/
|
|
813
827
|
function packShelf(rects, outer, options = {}) {
|
|
828
|
+
if (options.fit !== void 0) return packShelvesInSpace(rects, outer, options.sortOrder ?? "height-desc", options.fit, options.space);
|
|
814
829
|
if (options.space !== void 0 && !options.space.plain) return packRowsInSpace(rects, outer, options.sortOrder ?? "height-desc", options.space);
|
|
815
830
|
const width = outer.size.x;
|
|
816
831
|
const obstacles = [];
|
|
@@ -973,6 +988,181 @@ function packRowsInSpace(rects, outer, order, space) {
|
|
|
973
988
|
if (!outer.fixedSize) outer.size.y = Math.max(outer.size.y, contentBottom);
|
|
974
989
|
return outer;
|
|
975
990
|
}
|
|
991
|
+
/**
|
|
992
|
+
* This function packs rectangles into shelves with a fit: `next`, `first` or `best`. `packShelf` uses it when its
|
|
993
|
+
* options have a `fit`. It sets the position of each rectangle and gives the outer rectangle.
|
|
994
|
+
*
|
|
995
|
+
* - A shelf opens at the bottom edge of the last shelf, at the first x where the rectangle fits in the free space.
|
|
996
|
+
* When no x fits, the shelf steps down to `nextY` of the space, as an empty row of `packRowsInSpace` does.
|
|
997
|
+
* - The first rectangle of a shelf sets its height. A rectangle goes on the floor of a shelf at its cursor, or into
|
|
998
|
+
* the strip above a shorter rectangle of the shelf. The strip is the move `move.stack`.
|
|
999
|
+
* - The fit `next` uses only the open shelf: the last shelf that the packing opened. The fit `first` uses the first
|
|
1000
|
+
* shelf from the top where the rectangle fits. The fit `best` uses the place with the least height left over.
|
|
1001
|
+
* - In a shelf, the rectangle takes the place with the least height left over. A tie goes to a strip, from left to right.
|
|
1002
|
+
* - When no shelf has a place, the last shelf grows for a taller rectangle, if it fits. Else a new shelf opens.
|
|
1003
|
+
* - A rectangle wider than the outer rectangle overflows. Without `fixedSize`, it goes on a closed shelf of its own at the left edge.
|
|
1004
|
+
* - Each place is in the free space and crosses no locked rectangle. Without a space, the outer rectangle and the
|
|
1005
|
+
* locked rectangles give the free space.
|
|
1006
|
+
*/
|
|
1007
|
+
function packShelvesInSpace(rects, outer, order, fit, space) {
|
|
1008
|
+
if (!SHELF_FITS.includes(fit)) throw new RangeError(`The shelf fit "${String(fit)}" is not one of ${SHELF_FITS.join(", ")}.`);
|
|
1009
|
+
const width = outer.size.x;
|
|
1010
|
+
const ox = outer.position.x;
|
|
1011
|
+
const oy = outer.position.y;
|
|
1012
|
+
const limit = outer.fixedSize ? outer.size.y : Infinity;
|
|
1013
|
+
const obstacles = [];
|
|
1014
|
+
let contentBottom = 0;
|
|
1015
|
+
for (const rect of rects) {
|
|
1016
|
+
if (!rect.locked) continue;
|
|
1017
|
+
rect.wasPacked = true;
|
|
1018
|
+
const left = rect.position.x - ox;
|
|
1019
|
+
const top = rect.position.y - oy;
|
|
1020
|
+
obstacles.push({
|
|
1021
|
+
left,
|
|
1022
|
+
top,
|
|
1023
|
+
right: left + rect.size.x,
|
|
1024
|
+
bottom: top + rect.size.y
|
|
1025
|
+
});
|
|
1026
|
+
contentBottom = Math.max(contentBottom, top + rect.size.y);
|
|
1027
|
+
}
|
|
1028
|
+
const whole = [{
|
|
1029
|
+
start: 0,
|
|
1030
|
+
end: Infinity
|
|
1031
|
+
}];
|
|
1032
|
+
const place = (start, w, top, h) => {
|
|
1033
|
+
const spans = space === void 0 ? whole : space.band(top + oy, top + h + oy).map((s) => ({
|
|
1034
|
+
start: s.start - ox,
|
|
1035
|
+
end: s.end - ox
|
|
1036
|
+
}));
|
|
1037
|
+
return placeInBand(obstacles, spans, start, w, top, top + h);
|
|
1038
|
+
};
|
|
1039
|
+
const stepDown = (top, w, h) => Math.min(space === void 0 ? Infinity : space.nextY(top + oy, top + h + oy, w) - oy, nextTop(obstacles, top, top + h));
|
|
1040
|
+
const spotsOn = (shelf, w, h, grow) => {
|
|
1041
|
+
const ceiling = shelf.top + shelf.height;
|
|
1042
|
+
const spots = [];
|
|
1043
|
+
if (!grow) {
|
|
1044
|
+
for (const strip of shelf.strips) if (w <= strip.w && strip.bottom + h <= ceiling) spots.push({
|
|
1045
|
+
shelf,
|
|
1046
|
+
x: strip.x,
|
|
1047
|
+
y: strip.bottom,
|
|
1048
|
+
left: ceiling - strip.bottom - h,
|
|
1049
|
+
strip
|
|
1050
|
+
});
|
|
1051
|
+
}
|
|
1052
|
+
const tall = grow ? h > shelf.height && shelf.top + h <= limit : h <= shelf.height;
|
|
1053
|
+
if (Number.isFinite(shelf.cursor) && tall) spots.push({
|
|
1054
|
+
shelf,
|
|
1055
|
+
x: shelf.cursor,
|
|
1056
|
+
y: shelf.top,
|
|
1057
|
+
left: grow ? 0 : shelf.height - h,
|
|
1058
|
+
...grow ? { grow } : {}
|
|
1059
|
+
});
|
|
1060
|
+
return spots.toSorted((a, b) => a.left - b.left);
|
|
1061
|
+
};
|
|
1062
|
+
const verify = (spot, w, h) => {
|
|
1063
|
+
const x = place(spot.x, w, spot.y, h);
|
|
1064
|
+
if (spot.strip !== void 0) return x === spot.x ? spot : void 0;
|
|
1065
|
+
return x + w <= width ? {
|
|
1066
|
+
...spot,
|
|
1067
|
+
x
|
|
1068
|
+
} : void 0;
|
|
1069
|
+
};
|
|
1070
|
+
const firstOn = (shelf, w, h) => {
|
|
1071
|
+
for (const spot of spotsOn(shelf, w, h, false)) {
|
|
1072
|
+
const found = verify(spot, w, h);
|
|
1073
|
+
if (found !== void 0) return found;
|
|
1074
|
+
}
|
|
1075
|
+
};
|
|
1076
|
+
const shelves = [];
|
|
1077
|
+
for (const rect of rects.toSorted(compareRects(order))) {
|
|
1078
|
+
if (rect.wasPacked) continue;
|
|
1079
|
+
const w = rect.size.x;
|
|
1080
|
+
const h = rect.size.y;
|
|
1081
|
+
if (!(w > 0 && h > 0)) continue;
|
|
1082
|
+
const open = shelves.at(-1);
|
|
1083
|
+
const floor = open === void 0 ? 0 : open.top + open.height;
|
|
1084
|
+
if (w > width) {
|
|
1085
|
+
if (outer.fixedSize) continue;
|
|
1086
|
+
let top = floor;
|
|
1087
|
+
while (firstFreeX(obstacles, 0, w, top, top + h) !== 0) {
|
|
1088
|
+
const next = nextTop(obstacles, top, top + h);
|
|
1089
|
+
if (!Number.isFinite(next)) break;
|
|
1090
|
+
top = next;
|
|
1091
|
+
}
|
|
1092
|
+
rect.position.set(ox, top + oy);
|
|
1093
|
+
rect.wasPacked = true;
|
|
1094
|
+
shelves.push({
|
|
1095
|
+
top,
|
|
1096
|
+
height: h,
|
|
1097
|
+
cursor: Infinity,
|
|
1098
|
+
strips: []
|
|
1099
|
+
});
|
|
1100
|
+
contentBottom = Math.max(contentBottom, top + h);
|
|
1101
|
+
continue;
|
|
1102
|
+
}
|
|
1103
|
+
let spot;
|
|
1104
|
+
let firstShelf;
|
|
1105
|
+
if (fit === "best") {
|
|
1106
|
+
for (const s of shelves.flatMap((shelf) => spotsOn(shelf, w, h, false)).toSorted((a, b) => a.left - b.left)) {
|
|
1107
|
+
spot = verify(s, w, h);
|
|
1108
|
+
if (spot !== void 0) break;
|
|
1109
|
+
}
|
|
1110
|
+
if (spot !== void 0) firstShelf = shelves.find((shelf) => shelf === spot.shelf || firstOn(shelf, w, h) !== void 0);
|
|
1111
|
+
} else for (const shelf of fit === "next" ? shelves.slice(-1) : shelves) {
|
|
1112
|
+
spot = firstOn(shelf, w, h);
|
|
1113
|
+
if (spot !== void 0) break;
|
|
1114
|
+
}
|
|
1115
|
+
if (spot === void 0 && open !== void 0) {
|
|
1116
|
+
const grown = spotsOn(open, w, h, true)[0];
|
|
1117
|
+
if (grown !== void 0) spot = verify(grown, w, h);
|
|
1118
|
+
}
|
|
1119
|
+
if (spot === void 0) {
|
|
1120
|
+
let top = floor;
|
|
1121
|
+
let x = place(0, w, top, h);
|
|
1122
|
+
while (!(x + w <= width) && top + h <= limit) {
|
|
1123
|
+
const next = stepDown(top, w, h);
|
|
1124
|
+
if (!Number.isFinite(next)) break;
|
|
1125
|
+
top = next;
|
|
1126
|
+
x = place(0, w, top, h);
|
|
1127
|
+
}
|
|
1128
|
+
if (!(x + w <= width) || top + h > limit) continue;
|
|
1129
|
+
const shelf = {
|
|
1130
|
+
top,
|
|
1131
|
+
height: h,
|
|
1132
|
+
cursor: x,
|
|
1133
|
+
strips: []
|
|
1134
|
+
};
|
|
1135
|
+
shelves.push(shelf);
|
|
1136
|
+
spot = {
|
|
1137
|
+
shelf,
|
|
1138
|
+
x,
|
|
1139
|
+
y: top,
|
|
1140
|
+
left: 0
|
|
1141
|
+
};
|
|
1142
|
+
} else {
|
|
1143
|
+
if (spot.shelf !== open) countMove(MOVES.firstFit);
|
|
1144
|
+
if (firstShelf !== void 0 && spot.shelf !== firstShelf) countMove(MOVES.bestFit);
|
|
1145
|
+
}
|
|
1146
|
+
const { shelf } = spot;
|
|
1147
|
+
rect.position.set(spot.x + ox, spot.y + oy);
|
|
1148
|
+
rect.wasPacked = true;
|
|
1149
|
+
if (spot.strip !== void 0) {
|
|
1150
|
+
countMove(MOVES.shelf);
|
|
1151
|
+
spot.strip.bottom = spot.y + h;
|
|
1152
|
+
} else {
|
|
1153
|
+
shelf.cursor = spot.x + w;
|
|
1154
|
+
shelf.strips.push({
|
|
1155
|
+
x: spot.x,
|
|
1156
|
+
w,
|
|
1157
|
+
bottom: spot.y + h
|
|
1158
|
+
});
|
|
1159
|
+
if (spot.grow === true) shelf.height = h;
|
|
1160
|
+
}
|
|
1161
|
+
contentBottom = Math.max(contentBottom, spot.y + h);
|
|
1162
|
+
}
|
|
1163
|
+
if (!outer.fixedSize) outer.size.y = Math.max(outer.size.y, contentBottom);
|
|
1164
|
+
return outer;
|
|
1165
|
+
}
|
|
976
1166
|
// src/skyline.ts
|
|
977
1167
|
/**
|
|
978
1168
|
* This function finds the lowest window of width `rw` on a skyline. For each `x` in `[0, width - rw]`, the height
|
|
@@ -1993,6 +2183,8 @@ const REL = Object.freeze({ rel: .01 });
|
|
|
1993
2183
|
* - A share of an area from 0 to 1 has 0.005. A guard has its tolerance.
|
|
1994
2184
|
* - An area and a ratio of lengths have `{ rel: 0.01 }`: 1% of the larger value.
|
|
1995
2185
|
* - The time has no minimum effect, because the times of CI change each time.
|
|
2186
|
+
* - `pack.overflow.forcedAreaMin` is a deprecated alias of `pack.overflow.forcedArea`. Its spec is the same, except the id.
|
|
2187
|
+
* The alias stays until the next minor version.
|
|
1996
2188
|
*/
|
|
1997
2189
|
const MEASURE_SPECS = Object.freeze({
|
|
1998
2190
|
"pack.area": spec("pack.area", "density", "square units", "lower", 0, Infinity, REL),
|
|
@@ -2125,7 +2317,8 @@ function traceSum(output, id) {
|
|
|
2125
2317
|
* - The time `pack.search.ms` comes from the trace. It is not part of the determinism rule.
|
|
2126
2318
|
* - The overflow measures count each id once. `pack.overflow.forced` is the lower bound of `overflowBound`.
|
|
2127
2319
|
* - `pack.overflow.excess` is the overflow less the forced overflow. A container with no fixed side gives 0 for both.
|
|
2128
|
-
* - `pack.overflow.
|
|
2320
|
+
* - `pack.overflow.forcedArea` is a lower bound of the overflow area. `pack.overflow.excessArea` is the overflow area above it.
|
|
2321
|
+
* - `pack.overflow.forcedAreaMin` is a deprecated alias of `pack.overflow.forcedArea`, with the same value.
|
|
2129
2322
|
*
|
|
2130
2323
|
* @example
|
|
2131
2324
|
* ```ts
|
|
@@ -2170,7 +2363,7 @@ function measure(input, output, options = {}) {
|
|
|
2170
2363
|
}
|
|
2171
2364
|
const bound = overflowBound(input);
|
|
2172
2365
|
const overflowArea = itemArea > 0 ? unplacedArea / itemArea : 0;
|
|
2173
|
-
const
|
|
2366
|
+
const forcedArea = itemArea > 0 ? Math.min(1, bound.area / itemArea) : 0;
|
|
2174
2367
|
return {
|
|
2175
2368
|
"pack.area": hullArea,
|
|
2176
2369
|
"pack.fill": fill,
|
|
@@ -2184,10 +2377,10 @@ function measure(input, output, options = {}) {
|
|
|
2184
2377
|
"pack.overflow.rate": input.items.length > 0 ? unplaced.size / input.items.length : 0,
|
|
2185
2378
|
"pack.overflow.area": overflowArea,
|
|
2186
2379
|
"pack.overflow.forced": bound.forced,
|
|
2187
|
-
"pack.overflow.forcedArea":
|
|
2380
|
+
"pack.overflow.forcedArea": forcedArea,
|
|
2188
2381
|
"pack.overflow.excess": Math.max(0, unplaced.size - bound.forced),
|
|
2189
|
-
"pack.overflow.forcedAreaMin":
|
|
2190
|
-
"pack.overflow.excessArea": excessAreaOf(overflowArea,
|
|
2382
|
+
"pack.overflow.forcedAreaMin": forcedArea,
|
|
2383
|
+
"pack.overflow.excessArea": excessAreaOf(overflowArea, forcedArea),
|
|
2191
2384
|
"pack.search.widths": traceSum(output, "pack.search.widths"),
|
|
2192
2385
|
"pack.search.ms": traceSum(output, "pack.search.ms")
|
|
2193
2386
|
};
|
|
@@ -2196,8 +2389,8 @@ function measure(input, output, options = {}) {
|
|
|
2196
2389
|
* This function gives the overflow area above its lower bound. A value from `-AREA_NOISE` to 0 becomes 0. A value below
|
|
2197
2390
|
* `-AREA_NOISE` stays, because it shows a bug of the bound or of the packer.
|
|
2198
2391
|
*/
|
|
2199
|
-
function excessAreaOf(overflowArea,
|
|
2200
|
-
const excess = overflowArea -
|
|
2392
|
+
function excessAreaOf(overflowArea, forcedArea) {
|
|
2393
|
+
const excess = overflowArea - forcedArea;
|
|
2201
2394
|
return excess < 0 && excess >= -1e-9 ? 0 : excess;
|
|
2202
2395
|
}
|
|
2203
2396
|
/**
|
|
@@ -2544,16 +2737,28 @@ function supportsOf(cells) {
|
|
|
2544
2737
|
mode: [...cells.mode]
|
|
2545
2738
|
};
|
|
2546
2739
|
}
|
|
2740
|
+
/** This function gives the fit of the options of a strategy: only `shelf` reads it. */
|
|
2741
|
+
function fitOf(id, options) {
|
|
2742
|
+
return id === "shelf" && options.fit !== void 0 ? { fit: options.fit } : {};
|
|
2743
|
+
}
|
|
2744
|
+
/** This function gives the move counts of the trace of a strategy: its own move, and the moves of a shelf fit. */
|
|
2745
|
+
function movesOf(id, fit) {
|
|
2746
|
+
const out = { [MOVES[id]]: moveCount(MOVES[id]) };
|
|
2747
|
+
if (fit.fit !== void 0) for (const move of [MOVES.firstFit, MOVES.bestFit]) out[move] = moveCount(move);
|
|
2748
|
+
return out;
|
|
2749
|
+
}
|
|
2547
2750
|
/** This function packs an input with a fixed size or a fixed width with one strategy of `pack`. */
|
|
2548
2751
|
function packFixedWidth(id, input, options) {
|
|
2549
2752
|
const start = now();
|
|
2550
2753
|
const frame = buildFrame(input);
|
|
2551
2754
|
const rects = rectsOf(frame);
|
|
2755
|
+
const fit = fitOf(id, options);
|
|
2552
2756
|
clearMoves();
|
|
2553
2757
|
if (frame.w > 0) pack(rects, outerOf(frame), {
|
|
2554
2758
|
strategy: id,
|
|
2555
2759
|
sortOrder: options.sortOrder,
|
|
2556
|
-
space: spaceOf(input, frame)
|
|
2760
|
+
space: spaceOf(input, frame),
|
|
2761
|
+
...fit
|
|
2557
2762
|
});
|
|
2558
2763
|
const output = readFrame(input, frame, []);
|
|
2559
2764
|
return {
|
|
@@ -2563,7 +2768,7 @@ function packFixedWidth(id, input, options) {
|
|
|
2563
2768
|
ms: now() - start,
|
|
2564
2769
|
measures: {
|
|
2565
2770
|
"pack.overflow": output.overflow.length,
|
|
2566
|
-
|
|
2771
|
+
...movesOf(id, fit)
|
|
2567
2772
|
}
|
|
2568
2773
|
}]
|
|
2569
2774
|
};
|
|
@@ -2622,6 +2827,7 @@ const skyline = layoutStrategy("skyline", "skyline", ["skyline-bl"], {
|
|
|
2622
2827
|
/**
|
|
2623
2828
|
* The strategy `shelf` uses `packShelf`: rows filled left to right, around the locked items and the fixed obstacles.
|
|
2624
2829
|
* With the sort order `input`, the rows keep the rank order. Turnable items, groups and item shapes throw `UnsupportedCell`.
|
|
2830
|
+
* The option `fit` selects a shelf rule of roadmap item k21: `next`, `first` or `best`. The default has no `fit`.
|
|
2625
2831
|
*/
|
|
2626
2832
|
const shelf = layoutStrategy("shelf", "shelf", ["shelf-nf", "shelf-nfdh"], {
|
|
2627
2833
|
obstacleMove: ["fixed"],
|
|
@@ -2647,13 +2853,15 @@ const logSweep = {
|
|
|
2647
2853
|
};
|
|
2648
2854
|
const start = now();
|
|
2649
2855
|
const frame = buildFrame(input);
|
|
2856
|
+
const fit = fitOf(id, o);
|
|
2650
2857
|
const result = packFree(rectsOf(frame), new Rect(), {
|
|
2651
2858
|
strategy: id,
|
|
2652
2859
|
sortOrder: o.sortOrder,
|
|
2653
2860
|
space: spaceOf(input, frame),
|
|
2654
2861
|
samples: o.samples,
|
|
2655
2862
|
aspect: input.container.aspect ?? 1,
|
|
2656
|
-
aspectWeight: input.container.aspectWeight ?? 1
|
|
2863
|
+
aspectWeight: input.container.aspectWeight ?? 1,
|
|
2864
|
+
...fit
|
|
2657
2865
|
});
|
|
2658
2866
|
const ms = now() - start;
|
|
2659
2867
|
const runs = result.tried.length + 1;
|
|
@@ -2672,7 +2880,7 @@ const logSweep = {
|
|
|
2672
2880
|
ms: ms / runs,
|
|
2673
2881
|
measures: {
|
|
2674
2882
|
"pack.overflow": output.overflow.length,
|
|
2675
|
-
|
|
2883
|
+
...movesOf(id, fit)
|
|
2676
2884
|
}
|
|
2677
2885
|
}]
|
|
2678
2886
|
};
|
|
@@ -3923,6 +4131,6 @@ function corpus(name, specs) {
|
|
|
3923
4131
|
inputs
|
|
3924
4132
|
};
|
|
3925
4133
|
}
|
|
3926
|
-
export { DEFAULT_TOLERANCE, EPS, MEASURE_SPECS, RECORD_EPS, Rect, SORT_ORDERS, UnsupportedCell, Vector, aspectError, assertSupported, canonicalJson, cards, cellOf, checkHard, checkInput, compareRects, corpus, countCell, createContext, dashboard, edgeCases, fnv1a32, freeSpace, fromRects, gallery, generator, generators, hashInput, isDeterministic, logSweep, lowestWindow, marginOf, measure, measureChange, medianRatio, mulberry32, pack, packFree, packRows, packShelf, packSkyline, packWith, packingMetrics, pairedRatio, push, pushCascade, quantile, rectGrid, rectScattered, round3, roundMeasures, rows, shelf, skyline, strategies, strategy, supportsCell, tailShare, toPackInput, toRects, turnItem, turnPoint, turnPort, turnRegion, unsupportedOf, wordCloud };
|
|
4134
|
+
export { DEFAULT_TOLERANCE, EPS, MEASURE_SPECS, RECORD_EPS, Rect, SHELF_FITS, SORT_ORDERS, UnsupportedCell, Vector, aspectError, assertSupported, canonicalJson, cards, cellOf, checkHard, checkInput, compareRects, corpus, countCell, createContext, dashboard, edgeCases, fnv1a32, freeSpace, fromRects, gallery, generator, generators, hashInput, isDeterministic, logSweep, lowestWindow, marginOf, measure, measureChange, medianRatio, mulberry32, pack, packFree, packRows, packShelf, packSkyline, packWith, packingMetrics, pairedRatio, push, pushCascade, quantile, rectGrid, rectScattered, round3, roundMeasures, rows, shelf, skyline, strategies, strategy, supportsCell, tailShare, toPackInput, toRects, turnItem, turnPoint, turnPort, turnRegion, unsupportedOf, wordCloud };
|
|
3927
4135
|
|
|
3928
4136
|
//# sourceMappingURL=index.js.map
|