@mark1russell7/highways 0.9.0 → 0.9.2
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 +69 -1
- package/build/index.d.ts +420 -9
- package/build/index.d.ts.map +1 -1
- package/build/index.js +4361 -2002
- package/build/index.js.map +1 -1
- package/package.json +2 -2
- package/src/bench/compare.ts +13 -1
- package/src/bench/measures/curves.ts +55 -1
- package/src/bench/measures/groups.ts +71 -0
- package/src/bench/measures/index.ts +1 -0
- package/src/bench/measures/levels.ts +24 -0
- package/src/bench/measures/room.ts +106 -1
- package/src/bench/measures/symmetry.ts +114 -0
- package/src/bench/screen/exercise.ts +5 -0
- package/src/bench/screen/forms.ts +14 -3
- package/src/bench/screen/measures.ts +40 -3
- package/src/bench/screen/screen.ts +40 -5
- package/src/bench/suite.ts +10 -2
- package/src/highways/fixtures.test-util.ts +13 -0
- package/src/highways/follow.ts +3 -2
- package/src/highways/free-lines.ts +141 -0
- package/src/highways/gaps/index.ts +85 -0
- package/src/highways/index.ts +6 -0
- package/src/highways/interchanges/index.ts +231 -0
- package/src/highways/search/index.ts +170 -0
- package/src/highways/snap.ts +4 -2
- package/src/highways/steiner/index.ts +215 -0
- package/src/highways/streets/index.ts +78 -0
- package/src/model.ts +127 -4
- package/src/routers/attraction/index.ts +61 -0
- package/src/routers/corners.ts +15 -8
- package/src/routers/frames.ts +136 -0
- package/src/routers/index.ts +3 -1
- package/src/routers/plugs.ts +3 -2
- package/src/routers/sections.ts +3 -2
- package/src/routers/shared.ts +70 -7
- package/src/routers/straight.ts +3 -2
- package/src/routers/trunks.ts +3 -2
- package/src/strategies/builtins.ts +56 -1
- package/src/strategies/schemas.ts +69 -0
package/README.md
CHANGED
|
@@ -26,6 +26,55 @@ const result = cornersRouter({ name: "corners" }).route(graph);
|
|
|
26
26
|
// Each route is a polyline: result.routes[0].points
|
|
27
27
|
```
|
|
28
28
|
|
|
29
|
+
### Plugs
|
|
30
|
+
|
|
31
|
+
A node can have `ports`, and an end of an edge can name one of them in `port`. Each plug has one of these forms:
|
|
32
|
+
|
|
33
|
+
| Form | The place of the plug |
|
|
34
|
+
|---|---|
|
|
35
|
+
| `{ id }` | The router picks the side and the point. |
|
|
36
|
+
| `{ id, side }` | The router picks the point on that side. |
|
|
37
|
+
| `{ id, at }` | The plug is fixed at `at`, relative to the top-left corner of the box. |
|
|
38
|
+
| `{ id, side, along }` | The plug is fixed at the side start plus `along` times the side length. |
|
|
39
|
+
|
|
40
|
+
- `along` goes from 0 to 1. The start of `north` and `south` is the left end. The start of `east` and `west` is the top end.
|
|
41
|
+
- When the box gets taller or wider, a plug with `along` keeps its fraction of the side.
|
|
42
|
+
- `resolvePorts(graph)` gives each plug with `along` a fixed `at`. Each router calls it at the start of `route`.
|
|
43
|
+
- The arithmetic is the arithmetic of `portPoint` of `@mark1russell7/layout-contract`. `portOffset` calls it.
|
|
44
|
+
- `resolvePorts` throws a `RangeError` for a bad `along`. A bad value is not finite or is outside 0 to 1. A plug with `along` also needs a `side` and has no `at`.
|
|
45
|
+
- In an input file, such a plug has `side` and `along`, with no `x` and no `y`.
|
|
46
|
+
|
|
47
|
+
```ts
|
|
48
|
+
const node = { id: "a", box: { x: 0, y: 0, w: 80, h: 40 }, ports: [{ id: "out", side: "east", along: 0.25 }] };
|
|
49
|
+
// The plug "out" is at (80, 10). With h = 120, it is at (80, 30).
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
### Frames
|
|
53
|
+
|
|
54
|
+
A node can name a frame node in `parent`. A frame is a node that holds other nodes, for example a card that holds rows.
|
|
55
|
+
|
|
56
|
+
- An inner edge goes from a plug of a frame to a node in the frame. `splitFrames(graph)` finds the inner edges.
|
|
57
|
+
- The router `corners` routes each inner edge inside its frame. The route stays in the box of the frame, smaller by the option `frameInset`.
|
|
58
|
+
- The route goes around the other nodes of the frame. It leaves the plug of the wall into the frame, along the normal of the wall.
|
|
59
|
+
- Each inner route has the id of its frame in `Route.frame`. The inner routes come after the outer routes.
|
|
60
|
+
- Each other router gives no route for an inner edge. To route both, use your outer router, then `corners` for the inner routes.
|
|
61
|
+
- An outer edge to a plug of the frame routes as before. The outer route and the inner route meet at the plug.
|
|
62
|
+
- The default of `frameInset` is the margin of the router.
|
|
63
|
+
- A parent that names no node, or a cycle of parents, makes each router throw a `RangeError`.
|
|
64
|
+
- The option `outside` sets the rule for a node box outside the box of its frame:
|
|
65
|
+
- `throw` (the default) throws a `RangeError`.
|
|
66
|
+
- `skip` gives no route to the edges of that node.
|
|
67
|
+
- `clamp` cuts the box to the bounds of the frame.
|
|
68
|
+
|
|
69
|
+
```ts
|
|
70
|
+
const nodes = [
|
|
71
|
+
{ id: "card", box: { x: 0, y: 0, w: 240, h: 200 }, ports: [{ id: "in", side: "west", along: 0.25 }] },
|
|
72
|
+
{ id: "row", parent: "card", box: { x: 20, y: 120, w: 200, h: 24 } },
|
|
73
|
+
];
|
|
74
|
+
const edges = [{ id: "inner", source: { node: "row" }, target: { node: "card", port: "in" } }];
|
|
75
|
+
const inner = cornersRouter({ name: "corners" }).route({ nodes, edges }).routes; // inner[0].frame is "card"
|
|
76
|
+
```
|
|
77
|
+
|
|
29
78
|
## Curve types
|
|
30
79
|
|
|
31
80
|
A router gives polylines. The curve layer turns a polyline into a curve of a type. The polyline can come from any router, from a lane of `laneRoutes` or from a link of a zoom level.
|
|
@@ -453,6 +502,11 @@ The step `highway` decides which edges share a way. It gives a plan, not routes.
|
|
|
453
502
|
| `consensus` | The consensus of HWY-035. The finders vote on the pairs of edges, and the pairs that most finders agree on stay. |
|
|
454
503
|
| `p-hub` | The p-hub median of HWY-041. The p-median of the plugs gives the hubs, and the links between two hubs become highways. |
|
|
455
504
|
| `scale-space` | The scale space of HWY-053. Only the clusters that live over a long range of scales get highways. |
|
|
505
|
+
| `steiner` | The Steiner trees of HWY-036. Each group of edges gets one rectilinear tree around the boxes, and the shared parts of the tree become highways. |
|
|
506
|
+
| `gaps` | The gap highways of HWY-057. A free line in a gap between boxes holds a highway when enough edges can ride it. |
|
|
507
|
+
| `streets` | The orthogonal streets of HWY-058. A greedy set cover picks the free horizontal and vertical lines that carry the most edge length. |
|
|
508
|
+
| `search` | The local search of HWY-059. It adds, drops and changes the highways of a start plan, and it keeps the plan with the best score. |
|
|
509
|
+
| `interchanges` | The interchanges of HWY-060. An edge can change from one highway to another at an interchange, where two spines come near. |
|
|
456
510
|
|
|
457
511
|
The strategy `corridors` joins two ways when they share a long length. The length is `BREAK_EVEN` times the lane width or more, and the share `rho` of the shorter way or more.
|
|
458
512
|
The strategies `meet`, `weiszfeld`, `stubs`, `zipper`, `level-links`, `lanes`, `divided` and `crossbars` change the plan of the option `from`: `shared-ways` (the default), `corridors` or `none`.
|
|
@@ -518,6 +572,16 @@ const shared = stableOrderStrategy(routerStrategies.shared);
|
|
|
518
572
|
const result = repairStrategy(shared).run(graph); // The router `shared+stable+repair`.
|
|
519
573
|
```
|
|
520
574
|
|
|
575
|
+
### The router `attraction`
|
|
576
|
+
|
|
577
|
+
The router `attraction` is opt-in. It is not in `STRATEGIES`, so the default outputs do not change.
|
|
578
|
+
|
|
579
|
+
- `attractionRouter(options)` gives the negotiated attraction of HWY-044, and `attractionStrategy` is its router strategy.
|
|
580
|
+
- Each pass after the first routes each edge again. A link that many edges used in the passes before gets a lower cost.
|
|
581
|
+
- The options are `passes` (1 to 10), `attraction` (0 to 1), `capacityWeight` (0 to 10) and `laneWidth` (1 to 12).
|
|
582
|
+
- A capacity term raises the cost of a link when its users are more than its width holds.
|
|
583
|
+
- With 1 pass, `attraction: 0` and `capacityWeight: 0`, the routes are the routes of `shared`.
|
|
584
|
+
|
|
521
585
|
### The portfolio router
|
|
522
586
|
|
|
523
587
|
The router `portfolio` is opt-in. It is not in `STRATEGIES`, so the default outputs do not change. [`PORTFOLIO.md`](../../docs/research/PORTFOLIO.md#the-portfolio-router-portfolio-api) gives its tables.
|
|
@@ -621,10 +685,14 @@ The [note on the measures](https://github.com/mark1russell7/highways/blob/main/d
|
|
|
621
685
|
| R11 | `plugSpacing`: the gaps between the plugs of each side |
|
|
622
686
|
| B1, B4 | `inkSaved`, `ambiguity` |
|
|
623
687
|
| C1, C2, C3 | `g1Defect`, `g2Defect`, `bendingEnergy` |
|
|
688
|
+
| C4, C8 | `curvatureVariation`, `curveDeviation` |
|
|
689
|
+
| Z5 | `levelRatio`: the largest ratio of the item counts of two levels, and the spread of the ratios |
|
|
624
690
|
| Z6, Z7, Z8 | `nestingFaults`, `positionStability`, `orderStability` |
|
|
625
691
|
| Z10 | `changeGraph` makes a seeded small change, and `routeStability` compares the routes |
|
|
626
692
|
| G1, G2, G8, G9 | `modularity`, `cutShare`, `treeCost`, `groupStability` |
|
|
627
|
-
|
|
|
693
|
+
| G4, G5, G7 | `groupFill`, `itemOverlaps`, `silhouette` |
|
|
694
|
+
| M2, M3, M5 | `roomOrderFaults`, `boxDisplacement`, `distanceDistortion` |
|
|
695
|
+
| H3 | `routeSymmetry`: the share of the routes that a mirror or a half turn of the board keeps |
|
|
628
696
|
|
|
629
697
|
A quadratic measure examines a seeded sample above its limit, so the values of a large board are estimates.
|
|
630
698
|
|