@mark1russell7/highways 0.1.2 → 0.1.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 +109 -0
- package/build/index.d.ts +468 -1
- package/build/index.d.ts.map +1 -1
- package/build/index.js +1882 -255
- package/build/index.js.map +1 -1
- package/package.json +2 -1
- package/src/bench/curves.ts +98 -0
- package/src/bench/links.ts +191 -0
- package/src/bench/room.ts +122 -0
- package/src/bench/run.ts +28 -0
- package/src/cases.ts +139 -0
- package/src/curves/arc/index.ts +71 -0
- package/src/curves/index.ts +48 -0
- package/src/curves/model.ts +64 -0
- package/src/curves/rounded/index.ts +60 -0
- package/src/curves/sample.ts +73 -0
- package/src/curves/space.ts +91 -0
- package/src/curves/spline/index.ts +77 -0
- package/src/curves/straight/index.ts +7 -0
- package/src/grid.ts +61 -2
- package/src/index.ts +6 -0
- package/src/levels.ts +151 -14
- package/src/room/index.ts +334 -0
- package/src/routers/sections.ts +33 -6
- package/src/visibility.ts +334 -92
package/README.md
ADDED
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
# @mark1russell7/highways
|
|
2
|
+
|
|
3
|
+
`@mark1russell7/highways` routes the edges of large graphs. It knows no renderer. It takes boxes and edges, and it gives polylines and zoom levels.
|
|
4
|
+
|
|
5
|
+
The [repository README](https://github.com/mark1russell7/highways#readme) tells the idea, the routers and the benchmark. The [site](https://mark1russell7.github.io/highways/) shows a live map.
|
|
6
|
+
|
|
7
|
+
## Install
|
|
8
|
+
|
|
9
|
+
```sh
|
|
10
|
+
pnpm add @mark1russell7/highways
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Route a graph
|
|
14
|
+
|
|
15
|
+
```ts
|
|
16
|
+
import { cornersRouter, type Graph } from "@mark1russell7/highways";
|
|
17
|
+
|
|
18
|
+
const graph: Graph = {
|
|
19
|
+
nodes: [
|
|
20
|
+
{ id: "a", box: { x: 0, y: 0, w: 80, h: 40 } },
|
|
21
|
+
{ id: "b", box: { x: 240, y: 120, w: 80, h: 40 } },
|
|
22
|
+
],
|
|
23
|
+
edges: [{ id: "ab", source: { node: "a" }, target: { node: "b" } }],
|
|
24
|
+
};
|
|
25
|
+
const result = cornersRouter({ name: "corners" }).route(graph);
|
|
26
|
+
// Each route is a polyline: result.routes[0].points
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## Curve types
|
|
30
|
+
|
|
31
|
+
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.
|
|
32
|
+
|
|
33
|
+
| Type | Curve | Ends |
|
|
34
|
+
|---|---|---|
|
|
35
|
+
| `straight` | The polyline as it is. | As the polyline. |
|
|
36
|
+
| `rounded` | A quadratic Bezier curve at each corner, as `roundCorners` draws it. The `radius` sets the size of the corners. | The first and the last legs stay. |
|
|
37
|
+
| `spline` | A centripetal Catmull-Rom spline through each point. It does not overshoot or make loops in a piece. The `tension` goes from 0 (the spline) to 1 (the polyline). | With `startNormal` and `endNormal`, the curve leaves and enters each plug along its normal. |
|
|
38
|
+
| `arc` | A circular arc at each corner, tangent to the two legs. On horizontal and vertical legs, each arc is a quarter circle. | The first and the last legs stay. |
|
|
39
|
+
|
|
40
|
+
The output is a list of segments: `move`, `line`, `cubic` and `arc`. A renderer maps them to SVG path data, to canvas calls or to the vertices of a mesh.
|
|
41
|
+
|
|
42
|
+
- `curveOf(points, options)` gives the segments of a curve. The `type` of `options` selects the curve type.
|
|
43
|
+
- `toSvgPath(segments, digits = 2)` writes the segments as SVG path data.
|
|
44
|
+
- `sampleCurve(segments, tolerance = 0.5)` gives a polyline within `tolerance` of the curve, for hit tests and measures.
|
|
45
|
+
- `curveSpace(boxes)` makes the free space of a board one time. With `space`, a curve goes through no box that its polyline avoids.
|
|
46
|
+
|
|
47
|
+
Where the full curve goes through a box, the free space makes the curve smaller. It shrinks the radius of a corner, or the tangents of a piece of a spline. A corner with no clear radius stays sharp. A piece of a spline with no clear tangent is its straight leg.
|
|
48
|
+
|
|
49
|
+
```ts
|
|
50
|
+
import { curveOf, curveSpace, nearestSide, SIDE_NORMAL, toSvgPath } from "@mark1russell7/highways";
|
|
51
|
+
|
|
52
|
+
const space = curveSpace(graph.nodes.map((n) => n.box));
|
|
53
|
+
const box = new Map(graph.nodes.map((n) => [n.id, n.box]));
|
|
54
|
+
for (const route of result.routes) {
|
|
55
|
+
const edge = graph.edges.find((e) => e.id === route.edge)!;
|
|
56
|
+
const p = route.points;
|
|
57
|
+
const curve = curveOf(p, {
|
|
58
|
+
type: "spline",
|
|
59
|
+
startNormal: SIDE_NORMAL[nearestSide(box.get(edge.source.node)!, p[0]!)],
|
|
60
|
+
endNormal: SIDE_NORMAL[nearestSide(box.get(edge.target.node)!, p[p.length - 1]!)],
|
|
61
|
+
space,
|
|
62
|
+
});
|
|
63
|
+
const d = toSvgPath(curve); // The data of an SVG path element: "M 80 20 C ..."
|
|
64
|
+
}
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
A canvas draws an `arc` segment with `ctx.arc(center.x, center.y, radius, start, start + sweep, sweep < 0)`.
|
|
68
|
+
|
|
69
|
+
Each type has its own function too: `straightCurve`, `roundedCurve`, `splineCurve` and `arcCurve`.
|
|
70
|
+
|
|
71
|
+
The benchmark compares each curve type to the polylines of each router, on the fixtures of 100 nodes or fewer. It counts the curves that go through a box, with and without the free space. It also gives the ratio of the lengths.
|
|
72
|
+
|
|
73
|
+
## Room for the links
|
|
74
|
+
|
|
75
|
+
A host layout can pack the boxes of a far view in a grid, with no gap between them. Then the links have no channel, and they go through the boxes. The router knows the room that the links need. The room functions give that room, and they can open the gaps.
|
|
76
|
+
|
|
77
|
+
- `roomDemand(items, links, options)` gives the gaps of the board. A gap is a boundary between two columns (`axis: "x"`) or two rows (`axis: "y"`). Each gap has its current `width`, its `lanes` and its `need`.
|
|
78
|
+
- The need of a gap is `gutter + lanes × spacing`, and not less than its current width. The default gutter is 8, and the default spacing is 4.
|
|
79
|
+
- With the method `routes`, the default, the function opens each gap to the gutter and routes the links one time. The lanes of a gap are the most routes that go along it side by side.
|
|
80
|
+
- With the method `lines`, the lanes of a gap are the straight lines between the centers of the boxes that cross the gap.
|
|
81
|
+
- `openGaps(items, gaps)` moves each box by the growth of each gap before it. The boxes keep their size, their order and their alignment, so a grid stays a grid.
|
|
82
|
+
- `makeRoom(items, links, options)` gives the gaps and the open board. `maxGrowth` limits the growth of the board on each axis, as a share of its size.
|
|
83
|
+
- `roomLinks(graph)` gives the links of a graph, with the count of the edges of each pair.
|
|
84
|
+
|
|
85
|
+
The host layout still packs the boxes. These functions do not place a box. They only open the gaps between the boxes.
|
|
86
|
+
|
|
87
|
+
```ts
|
|
88
|
+
import { cornersRouter, makeRoom, roomLinks } from "@mark1russell7/highways";
|
|
89
|
+
|
|
90
|
+
const room = makeRoom(graph.nodes, roomLinks(graph), { gutter: 8, spacing: 4 });
|
|
91
|
+
// Each gap tells its axis, its place `at`, its `width`, its `lanes` and its `need`.
|
|
92
|
+
const open = { nodes: room.items, edges: graph.edges };
|
|
93
|
+
const result = cornersRouter({ name: "corners" }).route(open);
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
The benchmark measures the board `packedGridBoard`: 96 touching boxes and 132 links, at gutter 8 and spacing 4. The links are the links of the far view. A lane route of the router `sections` gets a lane of 4 units for each edge of a shared segment.
|
|
97
|
+
|
|
98
|
+
| Board | Area | Through | Crossings | Mean detour | Worst detour | Lane routes through a box |
|
|
99
|
+
|---|---:|---:|---:|---:|---:|---:|
|
|
100
|
+
| Packed | 1.00 | 62 | 162 | 1.12 | 1.48 | 94 |
|
|
101
|
+
| Gutter only | 1.13 | 0 | 345 | 1.34 | 2.38 | 10 |
|
|
102
|
+
| Method `routes` | 1.50 | 0 | 276 | 1.32 | 2.09 | 2 |
|
|
103
|
+
| Method `lines` | 3.80 | 0 | 382 | 1.20 | 1.47 | 5 |
|
|
104
|
+
|
|
105
|
+
On the packed board, the links are short only because they go through the boxes. The method `routes` is the default, because it gives the fewest crossings for its area.
|
|
106
|
+
|
|
107
|
+
## License
|
|
108
|
+
|
|
109
|
+
MIT
|
package/build/index.d.ts
CHANGED
|
@@ -70,6 +70,11 @@ export declare class Grid<T> {
|
|
|
70
70
|
query(b: Box, visit: (item: T) => void): void;
|
|
71
71
|
/** This method gives each item whose buckets come within `margin` of the segment `ab` to `visit`, one time each. */
|
|
72
72
|
querySegment(a: Point, b: Point, margin: number, visit: (item: T) => void): void;
|
|
73
|
+
/**
|
|
74
|
+
* This method tells if `test` gives true for an item whose buckets come within `margin` of the segment `ab`.
|
|
75
|
+
* It gives the items in the order of `querySegment`, and it stops at the first item that passes the test.
|
|
76
|
+
*/
|
|
77
|
+
someSegment(a: Point, b: Point, margin: number, test: (item: T) => boolean): boolean;
|
|
73
78
|
}
|
|
74
79
|
/** This function gives the bounding box of the segment `ab`. */
|
|
75
80
|
export declare function segmentBounds(a: Point, b: Point): Box;
|
|
@@ -211,6 +216,45 @@ export declare const FIXTURES: readonly FixtureSpec[];
|
|
|
211
216
|
* Node boxes do not overlap, and a gap of 12 units stays between them.
|
|
212
217
|
*/
|
|
213
218
|
export declare function makeFixture(spec: FixtureSpec): Graph;
|
|
219
|
+
/**
|
|
220
|
+
* A board of made-up data that shows one known defect of the routes or of the zoom levels.
|
|
221
|
+
* The benchmark races the routers on each case, and the measures of `measureLinks` give a number for the defect.
|
|
222
|
+
*/
|
|
223
|
+
export interface CaseBoard {
|
|
224
|
+
readonly name: string;
|
|
225
|
+
/** The defect that the board shows, in a few words. */
|
|
226
|
+
readonly defect: string;
|
|
227
|
+
/** This function makes the graph. The same function always gives the same graph. */
|
|
228
|
+
readonly make: () => Graph;
|
|
229
|
+
}
|
|
230
|
+
/**
|
|
231
|
+
* This function makes a dense board: 150 nodes in tight clusters. At the far view, the boxes of the groups overlap.
|
|
232
|
+
* Then a level link starts or ends in a group that another group covers.
|
|
233
|
+
*/
|
|
234
|
+
export declare function denseGroupsBoard(): Graph;
|
|
235
|
+
/**
|
|
236
|
+
* This function makes a board of three rows of 32 cards. Each card links to the next card of its row.
|
|
237
|
+
* Forty long links join cards far apart. The hub of a section is near the middle of its cards.
|
|
238
|
+
* So a long link climbs to hubs behind its source or past its target, and comes back.
|
|
239
|
+
*/
|
|
240
|
+
export declare function hubChainBoard(): Graph;
|
|
241
|
+
/**
|
|
242
|
+
* This function makes a board of 32 groups in 8 columns and 4 rows. Each group has 4 cards in a square.
|
|
243
|
+
* The cards of a group link in a chain, and 96 random links join cards of two groups.
|
|
244
|
+
* On a level with many groups, some level links go around the outer edge of the board.
|
|
245
|
+
*/
|
|
246
|
+
export declare function manyGroupsBoard(): Graph;
|
|
247
|
+
/**
|
|
248
|
+
* This function makes the far view of a board after a host layout packs it.
|
|
249
|
+
* The board has 96 boxes of one size in a grid of 12 columns and 8 rows.
|
|
250
|
+
* The boxes touch, with no gap between them. Each box links to a box near it, and 48 long links join boxes far apart.
|
|
251
|
+
* The links have no channel between the boxes. The roadmap item ROOM measures this board before and after `makeRoom`.
|
|
252
|
+
*
|
|
253
|
+
* The board is not in `CASES`, because the digests of the router fix the output on each board of `CASES`.
|
|
254
|
+
*/
|
|
255
|
+
export declare function packedGridBoard(): Graph;
|
|
256
|
+
/** The case boards of the benchmark. Each board has a few hundred nodes at most, so the benchmark races them on each run. */
|
|
257
|
+
export declare const CASES: readonly CaseBoard[];
|
|
214
258
|
/** A plug: the point where a route leaves or enters a node, and the outward normal of its side. */
|
|
215
259
|
export interface Plug {
|
|
216
260
|
readonly point: Point;
|
|
@@ -261,6 +305,160 @@ export declare function inflectionCurve(p0: Point, normal: Point, target: Point,
|
|
|
261
305
|
* The curve starts and ends at most `radius` from the vertex, and at most half of each segment. The ends of the polyline stay.
|
|
262
306
|
*/
|
|
263
307
|
export declare function roundCorners(p: readonly Point[], radius: number, steps?: number): Point[];
|
|
308
|
+
/**
|
|
309
|
+
* A type of curve for a route.
|
|
310
|
+
*
|
|
311
|
+
* - `straight`: the polyline as it is.
|
|
312
|
+
* - `rounded`: a quadratic Bezier curve at each corner, as `roundCorners` draws it.
|
|
313
|
+
* - `spline`: a centripetal Catmull-Rom spline through the points. It does not overshoot or make loops.
|
|
314
|
+
* - `arc`: a circular arc at each corner, tangent to the two legs.
|
|
315
|
+
*/
|
|
316
|
+
export type CurveType = "straight" | "rounded" | "spline" | "arc";
|
|
317
|
+
/** The curve types, in the order of the benchmark. */
|
|
318
|
+
export declare const CURVE_TYPES: readonly CurveType[];
|
|
319
|
+
/** The start of a curve: the pen goes to `to` and draws nothing. */
|
|
320
|
+
export interface MoveSegment {
|
|
321
|
+
readonly kind: "move";
|
|
322
|
+
readonly to: Point;
|
|
323
|
+
}
|
|
324
|
+
/** A straight line from the end of the segment before to `to`. */
|
|
325
|
+
export interface LineSegment {
|
|
326
|
+
readonly kind: "line";
|
|
327
|
+
readonly to: Point;
|
|
328
|
+
}
|
|
329
|
+
/** A cubic Bezier curve from the end of the segment before to `to`, with the control points `c1` and `c2`. */
|
|
330
|
+
export interface CubicSegment {
|
|
331
|
+
readonly kind: "cubic";
|
|
332
|
+
readonly c1: Point;
|
|
333
|
+
readonly c2: Point;
|
|
334
|
+
readonly to: Point;
|
|
335
|
+
}
|
|
336
|
+
/**
|
|
337
|
+
* A circular arc from the end of the segment before to `to`. The arc has its center at `center` and the radius `radius`.
|
|
338
|
+
* It starts at the angle `start` and turns by `sweep` radians. A positive `sweep` turns from the x axis to the y axis.
|
|
339
|
+
* On a canvas, `ctx.arc(center.x, center.y, radius, start, start + sweep, sweep < 0)` draws it.
|
|
340
|
+
*/
|
|
341
|
+
export interface ArcSegment {
|
|
342
|
+
readonly kind: "arc";
|
|
343
|
+
readonly center: Point;
|
|
344
|
+
readonly radius: number;
|
|
345
|
+
readonly start: number;
|
|
346
|
+
readonly sweep: number;
|
|
347
|
+
readonly to: Point;
|
|
348
|
+
}
|
|
349
|
+
/**
|
|
350
|
+
* A segment of a curve. A curve is a list of segments: one `move` first, then lines, cubic curves and arcs.
|
|
351
|
+
* A renderer maps the list to SVG path data, to canvas calls or to the vertices of a mesh.
|
|
352
|
+
*/
|
|
353
|
+
export type CurveSegment = MoveSegment | LineSegment | CubicSegment | ArcSegment;
|
|
354
|
+
/** This function gives the points of a polyline without the points that are nearer than `eps` to the point before them. */
|
|
355
|
+
export declare function distinctPoints(points: readonly Point[], eps?: number): Point[];
|
|
356
|
+
/**
|
|
357
|
+
* The free space of a board: the boxes that a curve must not go through.
|
|
358
|
+
* Make it one time for a board with `curveSpace`, and give it to each call of `curveOf`.
|
|
359
|
+
*/
|
|
360
|
+
interface CurveSpace {
|
|
361
|
+
/** The boxes of the board. */
|
|
362
|
+
readonly boxes: readonly Box[];
|
|
363
|
+
/** The tolerance of the samples of a curve, in units of the plane. */
|
|
364
|
+
readonly tolerance: number;
|
|
365
|
+
/**
|
|
366
|
+
* This method tells if the polyline `q` goes through a box that the polyline `p` does not go through.
|
|
367
|
+
* A polyline goes through a box when a part of it longer than `TOLERANCE` is inside the box made smaller by `TOLERANCE`.
|
|
368
|
+
*/
|
|
369
|
+
addsHit(q: readonly Point[], p: readonly Point[]): boolean;
|
|
370
|
+
}
|
|
371
|
+
/**
|
|
372
|
+
* This function makes the free space of a board from its boxes. The boxes are the nodes, or the items of a zoom level.
|
|
373
|
+
* The curves sample each piece within `tolerance` of the curve for the test.
|
|
374
|
+
*/
|
|
375
|
+
export declare function curveSpace(boxes: readonly Box[], tolerance?: number): CurveSpace;
|
|
376
|
+
/**
|
|
377
|
+
* This function gives a polyline that follows the curve. The distance from each part of the curve to the polyline is `tolerance` or less.
|
|
378
|
+
* The polyline starts at the point of the `move` and goes through the end of each segment.
|
|
379
|
+
* Hit tests, measures and renderers that draw only lines use this polyline.
|
|
380
|
+
*/
|
|
381
|
+
export declare function sampleCurve(segments: readonly CurveSegment[], tolerance?: number): Point[];
|
|
382
|
+
/** This function gives the point at the parameter `t` of the cubic Bezier curve with the control points `p0`, `p1`, `p2` and `p3`. */
|
|
383
|
+
export declare function cubicAt(p0: Point, p1: Point, p2: Point, p3: Point, t: number): Point;
|
|
384
|
+
/**
|
|
385
|
+
* This function writes the segments as the data of an SVG path: the commands `M`, `L`, `C` and `A`.
|
|
386
|
+
* Each number has at most `digits` digits after the point.
|
|
387
|
+
*/
|
|
388
|
+
export declare function toSvgPath(segments: readonly CurveSegment[], digits?: number): string;
|
|
389
|
+
/** This function gives the polyline as it is: one `move` to the first point and one `line` to each other point. */
|
|
390
|
+
export declare function straightCurve(points: readonly Point[]): CurveSegment[];
|
|
391
|
+
/** The options of `roundedCurve`. */
|
|
392
|
+
interface RoundedOptions {
|
|
393
|
+
/** The largest distance from a corner to the start and to the end of its curve. The default is 12. */
|
|
394
|
+
readonly radius?: number;
|
|
395
|
+
/** The boxes that the curve must not go through. Without it, each corner gets the full radius. */
|
|
396
|
+
readonly space?: CurveSpace;
|
|
397
|
+
}
|
|
398
|
+
/**
|
|
399
|
+
* This function rounds each inner vertex of a polyline with a quadratic Bezier curve, as `roundCorners` does.
|
|
400
|
+
* The curve of a corner starts and ends at most `radius` from the vertex, and at most half of each leg. The ends of the polyline stay.
|
|
401
|
+
* The function gives each quadratic curve as the same cubic curve. With `space`, it makes the radius of a corner smaller until the curve
|
|
402
|
+
* goes through no box that the polyline avoids.
|
|
403
|
+
*/
|
|
404
|
+
export declare function roundedCurve(points: readonly Point[], options?: RoundedOptions): CurveSegment[];
|
|
405
|
+
/** The options of `splineCurve`. */
|
|
406
|
+
interface SplineOptions {
|
|
407
|
+
/**
|
|
408
|
+
* The tension of the spline, from 0 to 1. The value 0 gives the centripetal Catmull-Rom spline, and 1 gives the polyline.
|
|
409
|
+
* The default is 0.
|
|
410
|
+
*/
|
|
411
|
+
readonly tension?: number;
|
|
412
|
+
/** The outward normal of the plug at the first point. With it, the curve leaves the first point along this normal. */
|
|
413
|
+
readonly startNormal?: Point;
|
|
414
|
+
/** The outward normal of the plug at the last point. With it, the curve comes into the last point against this normal. */
|
|
415
|
+
readonly endNormal?: Point;
|
|
416
|
+
/** The boxes that the curve must not go through. Without it, each piece gets the full tangents. */
|
|
417
|
+
readonly space?: CurveSpace;
|
|
418
|
+
}
|
|
419
|
+
/**
|
|
420
|
+
* This function draws a centripetal Catmull-Rom spline through the points of a polyline (Yuksel, Schaefer and Keyser, 2011).
|
|
421
|
+
* Each piece between two points is one cubic Bezier curve. The centripetal knots keep the curve free of cusps and loops in a piece.
|
|
422
|
+
* The curve goes through each point. Its tangent at a point keeps one direction on the two sides of the point.
|
|
423
|
+
*
|
|
424
|
+
* With `space`, the function makes the tangents of a piece shorter until the piece goes through no box that its leg avoids.
|
|
425
|
+
* A piece with no tangent is the straight leg.
|
|
426
|
+
*/
|
|
427
|
+
export declare function splineCurve(points: readonly Point[], options?: SplineOptions): CurveSegment[];
|
|
428
|
+
/** The options of `arcCurve`. */
|
|
429
|
+
interface ArcOptions {
|
|
430
|
+
/** The largest radius of the arc at a corner. The default is 12. */
|
|
431
|
+
readonly radius?: number;
|
|
432
|
+
/** The boxes that the curve must not go through. Without it, each corner gets the largest radius that fits on its legs. */
|
|
433
|
+
readonly space?: CurveSpace;
|
|
434
|
+
}
|
|
435
|
+
/**
|
|
436
|
+
* This function puts a circular arc at each inner vertex of a polyline. The arc is tangent to the two legs of its corner.
|
|
437
|
+
* The tangent points stay on the first half of each leg, so the ends of the polyline stay.
|
|
438
|
+
* With `space`, the function makes the radius of a corner smaller until the arc goes through no box that the polyline avoids.
|
|
439
|
+
* On a polyline with only horizontal and vertical legs, each arc is a quarter circle.
|
|
440
|
+
*/
|
|
441
|
+
export declare function arcCurve(points: readonly Point[], options?: ArcOptions): CurveSegment[];
|
|
442
|
+
/** The options of `curveOf`. Each type reads only the options that it uses. */
|
|
443
|
+
export interface CurveOptions {
|
|
444
|
+
readonly type: CurveType;
|
|
445
|
+
/** The types `rounded` and `arc` read this radius of the corners. The default is 12. */
|
|
446
|
+
readonly radius?: number;
|
|
447
|
+
/** The type `spline` reads this tension, from 0 to 1. The default is 0. */
|
|
448
|
+
readonly tension?: number;
|
|
449
|
+
/** The type `spline` leaves the first point along this outward normal of its plug. */
|
|
450
|
+
readonly startNormal?: Point;
|
|
451
|
+
/** The type `spline` comes into the last point against this outward normal of its plug. */
|
|
452
|
+
readonly endNormal?: Point;
|
|
453
|
+
/** The boxes that the curve must not go through, from `curveSpace`. The type `straight` does not read it. */
|
|
454
|
+
readonly space?: CurveSpace;
|
|
455
|
+
}
|
|
456
|
+
/**
|
|
457
|
+
* This function gives the curve of a route: a polyline of a router, a lane of `laneRoutes` or a link of a zoom level.
|
|
458
|
+
* The curve starts at the first point and ends at the last point of the polyline.
|
|
459
|
+
* The output is a list of segments for any renderer. `toSvgPath` writes it as SVG path data, and `sampleCurve` gives points.
|
|
460
|
+
*/
|
|
461
|
+
export declare function curveOf(points: readonly Point[], options: CurveOptions): CurveSegment[];
|
|
264
462
|
/** The nodes as obstacles, with a grid for fast tests. */
|
|
265
463
|
export declare class Obstacles {
|
|
266
464
|
#private;
|
|
@@ -268,11 +466,30 @@ export declare class Obstacles {
|
|
|
268
466
|
constructor(nodes: readonly Node[], cell: number);
|
|
269
467
|
/** This method tells if the segment `ab` stays out of each box, made larger by `pad`. The nodes in `skip` do not count. */
|
|
270
468
|
clear(a: Point, b: Point, pad: number, skip?: ReadonlySet<Node>): boolean;
|
|
469
|
+
/**
|
|
470
|
+
* This method gives a node whose box, made larger by `pad`, the segment `ab` goes into, or `undefined` when the segment is clear.
|
|
471
|
+
* The nodes in `skip` do not count. The test stops at the first such node.
|
|
472
|
+
*/
|
|
473
|
+
hit(a: Point, b: Point, pad: number, skip?: ReadonlySet<Node>): Node | undefined;
|
|
271
474
|
/** This method tells if the polyline stays out of each box, made larger by `pad`. The nodes in `skip` do not count. */
|
|
272
475
|
clearPath(p: readonly Point[], pad: number, skip?: ReadonlySet<Node>): boolean;
|
|
476
|
+
/** This method gives each node whose bucket the box touches to `visit`. A node can be outside the box. */
|
|
477
|
+
query(box: Box, visit: (n: Node) => void): void;
|
|
273
478
|
/** This method tells if the point is inside a box, made larger by `pad`. The node `skip` does not count. */
|
|
274
479
|
inside(p: Point, pad: number, skip?: Node): boolean;
|
|
275
480
|
}
|
|
481
|
+
/** A free point at an end of a search of `CornerGraph.pathAmong`, and the cost to reach it. */
|
|
482
|
+
export interface Terminal {
|
|
483
|
+
readonly point: Point;
|
|
484
|
+
readonly cost: number;
|
|
485
|
+
}
|
|
486
|
+
/** A path of `CornerGraph.pathAmong`: its points, the index of its first point in `from`, the index of its last point in `to`, and its cost. */
|
|
487
|
+
export interface Among {
|
|
488
|
+
readonly points: Point[];
|
|
489
|
+
readonly from: number;
|
|
490
|
+
readonly to: number;
|
|
491
|
+
readonly cost: number;
|
|
492
|
+
}
|
|
276
493
|
/** The options of the corner graph. */
|
|
277
494
|
export interface CornerGraphOptions {
|
|
278
495
|
/** The distance from a box to its corners. */
|
|
@@ -284,6 +501,11 @@ export interface CornerGraphOptions {
|
|
|
284
501
|
* The lattice links groups of nodes across empty space. Without it, the nearest corners of a group are all in that group.
|
|
285
502
|
*/
|
|
286
503
|
readonly lattice?: number;
|
|
504
|
+
/**
|
|
505
|
+
* With `cones`, each corner also links to the nearest corner that it can see in each of four cones around the axes.
|
|
506
|
+
* Then a path can go along a long corridor between rows or columns of boxes. The default is false.
|
|
507
|
+
*/
|
|
508
|
+
readonly cones?: boolean;
|
|
287
509
|
}
|
|
288
510
|
/**
|
|
289
511
|
* A sparse visibility graph. Its vertices are the corners of the boxes, made larger by `margin`.
|
|
@@ -309,6 +531,11 @@ export declare class CornerGraph {
|
|
|
309
531
|
* It must give at least `floor` × `d`, so that the estimate of A* stays below the true cost.
|
|
310
532
|
*/
|
|
311
533
|
path(from: Point, to: Point, cost?: (i: number, j: number, d: number) => number, floor?: number): Point[] | undefined;
|
|
534
|
+
/**
|
|
535
|
+
* This method gives the shortest path from a point of `from` to a point of `to`, or `undefined` when the graph has none.
|
|
536
|
+
* The cost of a path includes the costs of its two points. One search finds the path, so this method is faster than a call of `path` for each pair.
|
|
537
|
+
*/
|
|
538
|
+
pathAmong(from: readonly Terminal[], to: readonly Terminal[]): Among | undefined;
|
|
312
539
|
/** This method removes the vertices that a later vertex makes needless: from each vertex, it goes to the farthest vertex in view. */
|
|
313
540
|
pull(p: readonly Point[], lookahead?: number): Point[];
|
|
314
541
|
}
|
|
@@ -498,6 +725,8 @@ interface SectionsOptions extends WayOptions, SectionOptions {
|
|
|
498
725
|
* Each way from hub to hub is found one time, so all the edges on it share its points.
|
|
499
726
|
* The edges in one section of the lowest level go straight around the nodes.
|
|
500
727
|
*
|
|
728
|
+
* An edge skips a hub that takes it away from its target. A way that still goes out and back gives way to the direct way.
|
|
729
|
+
*
|
|
501
730
|
* The result gives one zoom level for each depth of the tree.
|
|
502
731
|
* A link of a level goes from the boundary of one item to the boundary of the other, around the other items.
|
|
503
732
|
*/
|
|
@@ -543,6 +772,90 @@ export declare function splitPoint(start: Point, targets: readonly Point[], spli
|
|
|
543
772
|
export declare function trunksRouter(options: TrunksOptions): Router;
|
|
544
773
|
/** The routers that the benchmark races. */
|
|
545
774
|
export declare const ROUTERS: readonly Router[];
|
|
775
|
+
/** An item with a box: a node of a graph, an item of a level or a box of a host layout. */
|
|
776
|
+
export interface Boxed {
|
|
777
|
+
readonly id: string;
|
|
778
|
+
readonly box: Box;
|
|
779
|
+
}
|
|
780
|
+
/** A link between two boxes. For a bundled link, `count` is the number of its edges. The default count is 1. */
|
|
781
|
+
export interface RoomLink {
|
|
782
|
+
readonly source: string;
|
|
783
|
+
readonly target: string;
|
|
784
|
+
readonly count?: number;
|
|
785
|
+
}
|
|
786
|
+
/**
|
|
787
|
+
* A gap of a board: a boundary of the sweep over the left or top edges of the boxes.
|
|
788
|
+
* On the axis `x`, the gap is a vertical channel between two columns. On the axis `y`, it is a horizontal channel between two rows.
|
|
789
|
+
*/
|
|
790
|
+
export interface Gap {
|
|
791
|
+
readonly axis: "x" | "y";
|
|
792
|
+
/** The place of the gap in the order of the gaps on its axis, from 0. */
|
|
793
|
+
readonly index: number;
|
|
794
|
+
/** The coordinate where the boxes after the gap start, on the axis of the gap. */
|
|
795
|
+
readonly at: number;
|
|
796
|
+
/** The ids of the boxes that end at the near side of the gap. */
|
|
797
|
+
readonly before: readonly string[];
|
|
798
|
+
/** The ids of the boxes that start at the far side of the gap, at `at`. */
|
|
799
|
+
readonly after: readonly string[];
|
|
800
|
+
/** The current width of the gap: the distance from the nearest box edge before the gap to `at`. */
|
|
801
|
+
readonly width: number;
|
|
802
|
+
/** The number of lanes that the links need in the gap. */
|
|
803
|
+
readonly lanes: number;
|
|
804
|
+
/** The width that the gap needs: at least the current width, and at least `gutter + lanes × spacing`. */
|
|
805
|
+
readonly need: number;
|
|
806
|
+
}
|
|
807
|
+
/** The ways that `roomDemand` finds the lanes of each gap. */
|
|
808
|
+
export type RoomMethod = "routes" | "lines";
|
|
809
|
+
/** The options of `roomDemand` and `makeRoom`. */
|
|
810
|
+
export interface RoomOptions {
|
|
811
|
+
/** The smallest width of each gap. The default is 8. */
|
|
812
|
+
readonly gutter?: number;
|
|
813
|
+
/** The width of one lane: the distance between two lines that run side by side. The default is 4. */
|
|
814
|
+
readonly spacing?: number;
|
|
815
|
+
/**
|
|
816
|
+
* The largest growth of the board on each axis, as a share of its size. The default is `Infinity`.
|
|
817
|
+
* When the lanes need more, each gap gets its gutter, and the lanes share the rest in proportion.
|
|
818
|
+
*/
|
|
819
|
+
readonly maxGrowth?: number;
|
|
820
|
+
/**
|
|
821
|
+
* The way to find the lanes. The default is `routes`.
|
|
822
|
+
* With `routes`, the function routes the links one time on the board with each gap open to the gutter.
|
|
823
|
+
* The lanes of a gap are the most routes that run along the gap side by side.
|
|
824
|
+
* With `lines`, the lanes of a gap are the straight lines between the centers of the boxes that cross the gap.
|
|
825
|
+
*/
|
|
826
|
+
readonly method?: RoomMethod;
|
|
827
|
+
/** The router of the method `routes`. Without it, the links go as the links of a zoom level (`levelLinks`), with the margin `gutter / 2`. */
|
|
828
|
+
readonly router?: Router;
|
|
829
|
+
/** With `count`, a link takes one lane for each of its edges. With `link`, the default, a link takes one lane. */
|
|
830
|
+
readonly lanes?: "link" | "count";
|
|
831
|
+
/** Two box edges nearer than this distance make one boundary of the sweep. The default is 0.5. */
|
|
832
|
+
readonly snap?: number;
|
|
833
|
+
}
|
|
834
|
+
/** The demand of a board and the board with its gaps open. */
|
|
835
|
+
export interface Room<T extends Boxed> {
|
|
836
|
+
readonly gaps: readonly Gap[];
|
|
837
|
+
readonly items: T[];
|
|
838
|
+
}
|
|
839
|
+
/**
|
|
840
|
+
* This function gives the gaps of a board. A sweep over each axis sorts the left (or top) edges of the boxes.
|
|
841
|
+
* Each distinct edge after the first is a gap. The `lanes` of each gap are 0, and its `need` is its current width.
|
|
842
|
+
*/
|
|
843
|
+
export declare function boardGaps(items: readonly Boxed[], snap?: number): Gap[];
|
|
844
|
+
/**
|
|
845
|
+
* This function moves the boxes apart, so that each gap gets the width `need`. The boxes keep their size, their order and their alignment.
|
|
846
|
+
* A box moves by the sum of the growth of each gap at or before its left (or top) edge. Thus a grid stays a grid.
|
|
847
|
+
* The function moves no box nearer to another box, so it makes no overlap.
|
|
848
|
+
*/
|
|
849
|
+
export declare function openGaps<T extends Boxed>(items: readonly T[], gaps: readonly Gap[], snap?: number): T[];
|
|
850
|
+
/**
|
|
851
|
+
* This function gives the room that the links need in each gap of the board.
|
|
852
|
+
* The lanes of a gap come from the `method` of the options. The need of a gap is `gutter + lanes × spacing`, and not less than its current width.
|
|
853
|
+
*/
|
|
854
|
+
export declare function roomDemand(items: readonly Boxed[], links: readonly RoomLink[], options?: RoomOptions): Gap[];
|
|
855
|
+
/** This function gives the demand of the board and the board with each gap open to its need. */
|
|
856
|
+
export declare function makeRoom<T extends Boxed>(items: readonly T[], links: readonly RoomLink[], options?: RoomOptions): Room<T>;
|
|
857
|
+
/** This function gives the links between the nodes of a graph, with the count of the edges of each pair. A loop does not count. */
|
|
858
|
+
export declare function roomLinks(graph: Graph): RoomLink[];
|
|
546
859
|
/** A broken hard rule. A correct router has none. */
|
|
547
860
|
export interface Violation {
|
|
548
861
|
readonly rule: "complete" | "ends-at-plugs" | "fixed-plugs" | "no-pass-through" | "counts-sum" | "link-ends" | "bundle-trunk" | "run-shared";
|
|
@@ -605,6 +918,83 @@ export interface Stability {
|
|
|
605
918
|
}
|
|
606
919
|
/** This function measures how much the routes changed between two results. */
|
|
607
920
|
export declare function measureStability(before: Result, after: Result): Stability;
|
|
921
|
+
/**
|
|
922
|
+
* The faults of a set of links: the routes of the edges, or the links of one zoom level.
|
|
923
|
+
* Each value counts links, except `worstDetour`. Lower is better for each value.
|
|
924
|
+
*/
|
|
925
|
+
export interface LinkFaults {
|
|
926
|
+
/** The number of links that the measure examined. */
|
|
927
|
+
readonly links: number;
|
|
928
|
+
/**
|
|
929
|
+
* The number of links that go through the inside of a box that is not one of their two ends.
|
|
930
|
+
* A segment goes through a box when a part of it longer than `TOLERANCE` is inside the box made smaller by `TOLERANCE`.
|
|
931
|
+
*/
|
|
932
|
+
readonly through: number;
|
|
933
|
+
/**
|
|
934
|
+
* The number of links that go out and back. The distance from a point of the link to its last point grows after the nearest approach.
|
|
935
|
+
* A link goes out and back when this growth is more than `BACKTRACK_SHARE` of the distance between its ends, and more than `BACKTRACK_MIN` units.
|
|
936
|
+
*/
|
|
937
|
+
readonly backtrack: number;
|
|
938
|
+
/** The largest ratio of the length of a link to the distance between its ends. Links with ends nearer than 1 unit do not count. */
|
|
939
|
+
readonly worstDetour: number;
|
|
940
|
+
/**
|
|
941
|
+
* The number of links with a point outside the bounding box of all the boxes, made larger by `slack`.
|
|
942
|
+
* Both ends of a link are always in that bounding box, so such a link goes around the outer edge of the board.
|
|
943
|
+
*/
|
|
944
|
+
readonly outside: number;
|
|
945
|
+
}
|
|
946
|
+
/** The faults of the links of one zoom level. */
|
|
947
|
+
export interface LevelFaults extends LinkFaults {
|
|
948
|
+
readonly depth: number;
|
|
949
|
+
/** The number of items of the level. */
|
|
950
|
+
readonly items: number;
|
|
951
|
+
/** The number of items that hold more than one node. */
|
|
952
|
+
readonly groups: number;
|
|
953
|
+
/** The number of pairs of items whose boxes overlap by more than `TOLERANCE` on each axis. */
|
|
954
|
+
readonly overlaps: number;
|
|
955
|
+
}
|
|
956
|
+
/** The options of the link measures. */
|
|
957
|
+
export interface LinkFaultOptions {
|
|
958
|
+
/** A link that goes farther than this distance outside the bounding box of all the boxes counts in `outside`. The default is 24. */
|
|
959
|
+
readonly slack?: number;
|
|
960
|
+
}
|
|
961
|
+
/** A link goes out and back when its distance to its target grows by more than this share of the distance between its ends. */
|
|
962
|
+
export declare const BACKTRACK_SHARE = .25;
|
|
963
|
+
/** A link goes out and back only when its distance to its target grows by more than this number of units. */
|
|
964
|
+
export declare const BACKTRACK_MIN = 40;
|
|
965
|
+
/** The default `slack` of `LinkFaultOptions`. */
|
|
966
|
+
export declare const OUTSIDE_SLACK = 24;
|
|
967
|
+
/** A link from one box to another box, as `measureLinks` sees it. */
|
|
968
|
+
export interface MeasuredLink {
|
|
969
|
+
readonly source: string;
|
|
970
|
+
readonly target: string;
|
|
971
|
+
readonly points: readonly Point[];
|
|
972
|
+
}
|
|
973
|
+
/**
|
|
974
|
+
* This function gives the largest growth of the distance to the last point of a polyline.
|
|
975
|
+
* The growth at a vertex is its distance to the last point, less the nearest approach of the polyline before that vertex.
|
|
976
|
+
*/
|
|
977
|
+
export declare function backtrackOf(p: readonly Point[]): number;
|
|
978
|
+
/** This function tells if the polyline `p` goes out and back: `backtrackOf(p)` is more than `BACKTRACK_MIN` and more than `BACKTRACK_SHARE` of the span. */
|
|
979
|
+
export declare function goesOutAndBack(p: readonly Point[]): boolean;
|
|
980
|
+
/**
|
|
981
|
+
* This function measures the faults of links between boxes. The map `boxes` gives the box of each end.
|
|
982
|
+
* The bounding box of `outside` is the bounding box of all the boxes of the map.
|
|
983
|
+
*/
|
|
984
|
+
export declare function measureLinks(boxes: ReadonlyMap<string, Box>, links: readonly MeasuredLink[], options?: LinkFaultOptions): LinkFaults;
|
|
985
|
+
/** This function measures the faults of the routes of a result. The ends of a route are the nodes of its edge. */
|
|
986
|
+
export declare function measureRouteFaults(graph: Graph, result: Result, options?: LinkFaultOptions): LinkFaults;
|
|
987
|
+
/** This function counts the pairs of boxes that overlap by more than `TOLERANCE` on each axis. */
|
|
988
|
+
export declare function countOverlaps(boxes: readonly Box[]): number;
|
|
989
|
+
/** This function measures the faults of the links of one zoom level. The items of the level are the boxes. */
|
|
990
|
+
export declare function measureLevel(level: Level, options?: LinkFaultOptions): LevelFaults;
|
|
991
|
+
/**
|
|
992
|
+
* This function measures the faults of each zoom level of a result that has groups: the levels of the far view.
|
|
993
|
+
* A level of single nodes only is the near view. Its links are routes, and `measureRouteFaults` measures them.
|
|
994
|
+
*/
|
|
995
|
+
export declare function measureLevelFaults(result: Result, options?: LinkFaultOptions): LevelFaults[];
|
|
996
|
+
/** This function adds the faults of several levels: it sums the counts and keeps the largest `worstDetour`. */
|
|
997
|
+
export declare function sumFaults(list: readonly LinkFaults[]): LinkFaults;
|
|
608
998
|
/** One row of the benchmark: one router on one fixture. */
|
|
609
999
|
export interface BenchRow {
|
|
610
1000
|
readonly router: string;
|
|
@@ -619,6 +1009,10 @@ export interface BenchRow {
|
|
|
619
1009
|
/** The first violations, for the report. */
|
|
620
1010
|
readonly sample: readonly Violation[];
|
|
621
1011
|
readonly quality: Quality;
|
|
1012
|
+
/** The faults of the routes of the edges (`measureRouteFaults`). */
|
|
1013
|
+
readonly faults: LinkFaults;
|
|
1014
|
+
/** The faults of each zoom level with groups (`measureLevelFaults`). The list is empty for a router without levels. */
|
|
1015
|
+
readonly levelFaults: readonly LevelFaults[];
|
|
622
1016
|
}
|
|
623
1017
|
/** The options of a benchmark run. */
|
|
624
1018
|
export interface BenchOptions {
|
|
@@ -636,5 +1030,78 @@ export declare function sameData(a: unknown, b: unknown): boolean;
|
|
|
636
1030
|
export declare function benchOne(router: Router, fixture: string, graph: Graph, repeat?: number): BenchRow;
|
|
637
1031
|
/** This function writes the rows as a Markdown table. */
|
|
638
1032
|
export declare function formatTable(rows: readonly BenchRow[]): string;
|
|
639
|
-
|
|
1033
|
+
/**
|
|
1034
|
+
* This function writes the faults of the rows as a Markdown table: the routes first, then the sum of the levels with groups.
|
|
1035
|
+
* A router without such levels gets a dash in the columns of the levels.
|
|
1036
|
+
*/
|
|
1037
|
+
export declare function formatFaults(rows: readonly BenchRow[]): string;
|
|
1038
|
+
/** One row of the benchmark of the curves: one curve type on the routes of one router on one fixture. */
|
|
1039
|
+
export interface CurveBenchRow {
|
|
1040
|
+
readonly router: string;
|
|
1041
|
+
readonly fixture: string;
|
|
1042
|
+
readonly type: CurveType;
|
|
1043
|
+
/** The number of routes. */
|
|
1044
|
+
readonly links: number;
|
|
1045
|
+
/** The number of polylines that go through a box that is not one of their ends (`measureLinks`). */
|
|
1046
|
+
readonly through: number;
|
|
1047
|
+
/** The number of curves without a free space that go through such a box. */
|
|
1048
|
+
readonly free: number;
|
|
1049
|
+
/** The number of curves with the free space of the nodes (`curveSpace`) that go through such a box. */
|
|
1050
|
+
readonly clamped: number;
|
|
1051
|
+
/** The ratio of the length of all curves with the free space to the length of all polylines. */
|
|
1052
|
+
readonly length: number;
|
|
1053
|
+
/** The time to make all curves with the free space, in milliseconds. */
|
|
1054
|
+
readonly ms: number;
|
|
1055
|
+
}
|
|
1056
|
+
/** The options of `benchCurves`. */
|
|
1057
|
+
export interface CurveBenchOptions {
|
|
1058
|
+
/** The radius of the types `rounded` and `arc`. The default is 12. */
|
|
1059
|
+
readonly radius?: number;
|
|
1060
|
+
/** The tolerance of the samples of the curves. The default is 0.25. */
|
|
1061
|
+
readonly tolerance?: number;
|
|
1062
|
+
}
|
|
1063
|
+
/**
|
|
1064
|
+
* This function routes a graph with a router and makes each curve type of each route.
|
|
1065
|
+
* It counts the curves that go through a box, with and without the free space, and it compares their length to the polylines.
|
|
1066
|
+
* The type `spline` leaves each plug along the normal of the nearest side of its node.
|
|
1067
|
+
*/
|
|
1068
|
+
export declare function benchCurves(router: Router, fixture: string, graph: Graph, options?: CurveBenchOptions): CurveBenchRow[];
|
|
1069
|
+
/** This function writes the rows of `benchCurves` as a Markdown table. */
|
|
1070
|
+
export declare function formatCurves(rows: readonly CurveBenchRow[]): string;
|
|
1071
|
+
/** One row of the benchmark of the room: one state of a board, packed or open, and the measures of its links. */
|
|
1072
|
+
export interface RoomBenchRow {
|
|
1073
|
+
readonly fixture: string;
|
|
1074
|
+
/** The state of the board: `packed`, `gutter` (each gap open to the gutter only), or a method of `roomDemand`. */
|
|
1075
|
+
readonly board: string;
|
|
1076
|
+
/** The area of the bounding box of the boxes, as a share of the area of the packed board. */
|
|
1077
|
+
readonly area: number;
|
|
1078
|
+
/** The faults of the links of the far view (`levelLinks` with each box as one item). */
|
|
1079
|
+
readonly faults: LinkFaults;
|
|
1080
|
+
/** The crossings of the links of the far view (`measureQuality`). */
|
|
1081
|
+
readonly crossings: number;
|
|
1082
|
+
/** The ink of the links of the far view. */
|
|
1083
|
+
readonly ink: number;
|
|
1084
|
+
/** The mean detour of the links of the far view. */
|
|
1085
|
+
readonly detour: number;
|
|
1086
|
+
/**
|
|
1087
|
+
* The number of lane routes of the router `sections` that go through a box. Each shared segment opens to one lane for each edge,
|
|
1088
|
+
* at the spacing of the options (`laneRoutes`).
|
|
1089
|
+
*/
|
|
1090
|
+
readonly laneThrough: number;
|
|
1091
|
+
/** The time of `makeRoom`, in milliseconds. It is 0 for the packed board. */
|
|
1092
|
+
readonly ms: number;
|
|
1093
|
+
}
|
|
1094
|
+
/**
|
|
1095
|
+
* This function measures the links of one board. It measures the links of the far view, with each node of the graph as one item of a level.
|
|
1096
|
+
* It also measures the lane routes of the router `sections` at the lane width `spacing`.
|
|
1097
|
+
*/
|
|
1098
|
+
export declare function measureBoard(graph: Graph, spacing: number): Omit<RoomBenchRow, "fixture" | "board" | "area" | "ms">;
|
|
1099
|
+
/**
|
|
1100
|
+
* This function measures a packed board, the board with each gap open to the gutter only, and the board that `makeRoom` opens with each method.
|
|
1101
|
+
* The options of `makeRoom` are the same for each method, except `method`.
|
|
1102
|
+
*/
|
|
1103
|
+
export declare function benchRoom(fixture: string, graph: Graph, options?: RoomOptions): RoomBenchRow[];
|
|
1104
|
+
/** This function writes the rows of `benchRoom` as a Markdown table. */
|
|
1105
|
+
export declare function formatRoom(rows: readonly RoomBenchRow[]): string;
|
|
1106
|
+
export type { ArcOptions, CornersOptions, CurveSpace, RoundedOptions, SectionsOptions, SharedOptions, SplineOptions, TrunksOptions };
|
|
640
1107
|
//# sourceMappingURL=index.d.ts.map
|