@mark1russell7/highways 0.0.0-stage → 0.1.1

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/src/ways.ts ADDED
@@ -0,0 +1,67 @@
1
+ import { inflectionCurve, roundCorners } from "./curves.ts";
2
+ import type { Point } from "./geom.ts";
3
+ import type { Node } from "./model.ts";
4
+ import type { Plug } from "./plugs.ts";
5
+ import { CornerGraph, Obstacles } from "./visibility.ts";
6
+
7
+ /** The options of a way finder. */
8
+ export interface WayOptions {
9
+ /** The distance from a box to the corners of the graph. The default is 5. */
10
+ readonly margin?: number;
11
+ /** The number of visible neighbours of each corner. The default is 8. */
12
+ readonly k?: number;
13
+ /** With `smooth`, a way in clear view uses the inflection rule, and the other ways get round corners. */
14
+ readonly smooth?: boolean;
15
+ }
16
+
17
+ /**
18
+ * The ways around the nodes of one graph. A way leaves a plug along its normal.
19
+ * It goes a shortest way (A*) through the corner graph, without the needless corners. It enters the other plug along its normal.
20
+ */
21
+ export class WayFinder {
22
+ readonly obstacles: Obstacles;
23
+ readonly corners: CornerGraph;
24
+ readonly margin: number;
25
+ readonly #smooth: boolean;
26
+
27
+ /** This constructor makes the obstacles and the corner graph of the nodes. */
28
+ constructor(nodes: readonly Node[], options: WayOptions = {}) {
29
+ this.margin = options.margin ?? 5;
30
+ this.#smooth = options.smooth ?? false;
31
+ this.obstacles = new Obstacles(nodes, 180);
32
+ this.corners = new CornerGraph(nodes, this.obstacles, { margin: this.margin, k: options.k ?? 8 });
33
+ }
34
+
35
+ /** This method gives the point at `margin` from the plug, along its normal. */
36
+ out(p: Plug): Point {
37
+ return { x: p.point.x + p.normal.x * this.margin, y: p.point.y + p.normal.y * this.margin };
38
+ }
39
+
40
+ /** This method gives a way from plug to plug. Without a way in the graph, it gives the straight line. */
41
+ between(ps: Plug, pt: Plug, ends: ReadonlySet<Node>): Point[] {
42
+ if (this.#smooth) {
43
+ const curve = inflectionCurve(ps.point, ps.normal, pt.point);
44
+ if (this.obstacles.clearPath(curve, this.margin / 2, ends)) return curve;
45
+ }
46
+ const way = this.corners.path(this.out(ps), this.out(pt));
47
+ if (!way) return [ps.point, pt.point];
48
+ const poly = [ps.point, ...this.corners.pull(way), pt.point];
49
+ if (this.#smooth) {
50
+ const round = roundCorners(poly, this.margin);
51
+ if (this.obstacles.clearPath(round, 0, ends)) return round;
52
+ }
53
+ return poly;
54
+ }
55
+
56
+ /** This method gives a way from a plug to a free point, or `undefined` when the graph has none. */
57
+ fromPlug(ps: Plug, to: Point): Point[] | undefined {
58
+ const way = this.corners.path(this.out(ps), to);
59
+ return way && [ps.point, ...this.corners.pull(way)];
60
+ }
61
+
62
+ /** This method gives a way from a free point to a plug, or `undefined` when the graph has none. */
63
+ toPlug(from: Point, pt: Plug): Point[] | undefined {
64
+ const way = this.corners.path(from, this.out(pt));
65
+ return way && [...this.corners.pull(way), pt.point];
66
+ }
67
+ }
package/README.md DELETED
@@ -1,3 +0,0 @@
1
- # Temporary Holding Version
2
-
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.