plotboilerplate 1.17.1 → 1.19.0
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 +63 -6
- package/dist/index.esm.js +278 -60
- package/dist/index.esm.js.map +1 -1
- package/dist/index.esm.min.js +1 -1
- package/dist/index.esm.min.js.map +1 -1
- package/dist/plotboilerplate.browser.min.js +1 -1
- package/dist/plotboilerplate.browser.min.js.map +1 -1
- package/dist/plotboilerplate.js +276 -58
- package/dist/plotboilerplate.min.js +1 -1
- package/package.json +1 -1
- package/src/cjs/Bounds.d.ts +11 -1
- package/src/cjs/Bounds.js +13 -1
- package/src/cjs/Bounds.js.map +1 -1
- package/src/cjs/Circle.d.ts +36 -2
- package/src/cjs/Circle.js +81 -1
- package/src/cjs/Circle.js.map +1 -1
- package/src/cjs/CubicBezierCurve.d.ts +20 -3
- package/src/cjs/CubicBezierCurve.js +25 -2
- package/src/cjs/CubicBezierCurve.js.map +1 -1
- package/src/cjs/Line.d.ts +46 -4
- package/src/cjs/Line.js +60 -3
- package/src/cjs/Line.js.map +1 -1
- package/src/cjs/MouseHandler.d.ts +3 -2
- package/src/cjs/MouseHandler.js +16 -14
- package/src/cjs/MouseHandler.js.map +1 -1
- package/src/cjs/PlotBoilerplate.d.ts +4 -2
- package/src/cjs/PlotBoilerplate.js +44 -28
- package/src/cjs/PlotBoilerplate.js.map +1 -1
- package/src/cjs/Polygon.js +1 -1
- package/src/cjs/Polygon.js.map +1 -1
- package/src/cjs/Vector.d.ts +14 -3
- package/src/cjs/Vector.js +21 -2
- package/src/cjs/Vector.js.map +1 -1
- package/src/cjs/draw.d.ts +4 -1
- package/src/cjs/draw.js +15 -6
- package/src/cjs/draw.js.map +1 -1
- package/src/cjs/interfaces/additionals.d.ts +95 -0
- package/src/cjs/interfaces/additionals.js +3 -0
- package/src/cjs/interfaces/additionals.js.map +1 -0
- package/src/cjs/interfaces/core.d.ts +4 -0
- package/src/cjs/interfaces/core.js +1 -0
- package/src/cjs/interfaces/core.js.map +1 -1
- package/src/cjs/interfaces/index.d.ts +1 -0
- package/src/cjs/interfaces/index.js +1 -0
- package/src/cjs/interfaces/index.js.map +1 -1
- package/src/cjs/utils/algorithms/arrayShuffle.d.ts +8 -0
- package/src/cjs/utils/algorithms/arrayShuffle.js +15 -0
- package/src/cjs/utils/algorithms/arrayShuffle.js.map +1 -0
- package/src/cjs/utils/algorithms/detectPaths.d.ts +20 -0
- package/src/cjs/utils/algorithms/detectPaths.js +169 -0
- package/src/cjs/utils/algorithms/detectPaths.js.map +1 -0
- package/src/cjs/utils/datastructures/GenericPath.d.ts +75 -0
- package/src/cjs/utils/datastructures/GenericPath.js +105 -0
- package/src/cjs/utils/datastructures/GenericPath.js.map +1 -0
- package/src/cjs/utils/datastructures/GirihTile.d.ts +1 -1
- package/src/esm/Bounds.d.ts +11 -1
- package/src/esm/Bounds.js +13 -1
- package/src/esm/Bounds.js.map +1 -1
- package/src/esm/Circle.d.ts +36 -2
- package/src/esm/Circle.js +81 -1
- package/src/esm/Circle.js.map +1 -1
- package/src/esm/CubicBezierCurve.d.ts +20 -3
- package/src/esm/CubicBezierCurve.js +25 -2
- package/src/esm/CubicBezierCurve.js.map +1 -1
- package/src/esm/Line.d.ts +46 -4
- package/src/esm/Line.js +60 -3
- package/src/esm/Line.js.map +1 -1
- package/src/esm/MouseHandler.d.ts +3 -2
- package/src/esm/MouseHandler.js +16 -14
- package/src/esm/MouseHandler.js.map +1 -1
- package/src/esm/PlotBoilerplate.d.ts +4 -2
- package/src/esm/PlotBoilerplate.js +44 -28
- package/src/esm/PlotBoilerplate.js.map +1 -1
- package/src/esm/Polygon.js +1 -1
- package/src/esm/Polygon.js.map +1 -1
- package/src/esm/Vector.d.ts +13 -2
- package/src/esm/Vector.js +23 -4
- package/src/esm/Vector.js.map +1 -1
- package/src/esm/draw.d.ts +4 -1
- package/src/esm/draw.js +15 -6
- package/src/esm/draw.js.map +1 -1
- package/src/esm/interfaces/additionals.d.ts +95 -0
- package/src/esm/interfaces/additionals.js +2 -0
- package/src/esm/interfaces/additionals.js.map +1 -0
- package/src/esm/interfaces/core.d.ts +4 -0
- package/src/esm/interfaces/core.js +1 -0
- package/src/esm/interfaces/core.js.map +1 -1
- package/src/esm/interfaces/index.d.ts +1 -0
- package/src/esm/interfaces/index.js +1 -0
- package/src/esm/interfaces/index.js.map +1 -1
- package/src/esm/utils/algorithms/arrayShuffle.d.ts +8 -0
- package/src/esm/utils/algorithms/arrayShuffle.js +11 -0
- package/src/esm/utils/algorithms/arrayShuffle.js.map +1 -0
- package/src/esm/utils/algorithms/detectPaths.d.ts +20 -0
- package/src/esm/utils/algorithms/detectPaths.js +165 -0
- package/src/esm/utils/algorithms/detectPaths.js.map +1 -0
- package/src/esm/utils/datastructures/GenericPath.d.ts +75 -0
- package/src/esm/utils/datastructures/GenericPath.js +100 -0
- package/src/esm/utils/datastructures/GenericPath.js.map +1 -0
- package/src/esm/utils/datastructures/GirihTile.d.ts +1 -1
- package/src/ts/Bounds.ts +14 -1
- package/src/ts/Circle.ts +92 -2
- package/src/ts/CubicBezierCurve.ts +29 -4
- package/src/ts/Line.ts +70 -6
- package/src/ts/MouseHandler.ts +16 -15
- package/src/ts/PlotBoilerplate.ts +47 -32
- package/src/ts/Polygon.ts +1 -1
- package/src/ts/Vector.ts +24 -4
- package/src/ts/draw.ts +15 -6
- package/src/ts/interfaces/additionals.ts +105 -0
- package/src/ts/interfaces/core.ts +2 -0
- package/src/ts/interfaces/index.ts +1 -0
- package/src/ts/utils/algorithms/arrayShuffle.ts +11 -0
- package/src/ts/utils/algorithms/detectPaths.ts +195 -0
- package/src/ts/utils/datastructures/GenericPath.ts +113 -0
- package/src/ts/utils/datastructures/GirihTile.ts +1 -1
- package/changelog.md +0 -722
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A function to detect connected paths on the plane given by a random set of segments.
|
|
3
|
+
*
|
|
4
|
+
* Note that is algorithm operates IN PLACE and will ALTER your INPUT array.
|
|
5
|
+
*
|
|
6
|
+
* @author Ikaros Kappler
|
|
7
|
+
* @version 1.0.0
|
|
8
|
+
* @date 2022-10-17
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import { Path, PathSegment } from "../../interfaces";
|
|
12
|
+
import { GenericPath } from "../datastructures/GenericPath";
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* An interface/datascructure for keeping track of visited path segments.
|
|
16
|
+
*/
|
|
17
|
+
interface Visitation {
|
|
18
|
+
visited: boolean;
|
|
19
|
+
hasPredecessor: boolean;
|
|
20
|
+
hasSuccessor: boolean;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* A private helper function that initializes the visitation tracking and reverses
|
|
25
|
+
* dangling path ends to connect them with preceding paths.
|
|
26
|
+
*
|
|
27
|
+
* Note that this function alters those dangling path segments IN PLACE!
|
|
28
|
+
*
|
|
29
|
+
* @param segments
|
|
30
|
+
* @param epsilon
|
|
31
|
+
* @returns
|
|
32
|
+
*/
|
|
33
|
+
const initVisitationArray = (segments: Array<PathSegment>, epsilon: number): Array<Visitation> => {
|
|
34
|
+
const result: Array<Visitation> = []; // { visited: false, hasPredecessor: false }
|
|
35
|
+
for (var i = 0; i < segments.length; i++) {
|
|
36
|
+
result.push({ visited: false, hasPredecessor: false, hasSuccessor: false });
|
|
37
|
+
for (var j = 0; j < segments.length; j++) {
|
|
38
|
+
if (i === j) {
|
|
39
|
+
continue;
|
|
40
|
+
}
|
|
41
|
+
if (
|
|
42
|
+
segments[i].getStartPoint().distance(segments[j].getEndPoint()) < epsilon ||
|
|
43
|
+
segments[i].getStartPoint().distance(segments[j].getStartPoint()) < epsilon
|
|
44
|
+
) {
|
|
45
|
+
result[i].hasPredecessor = true;
|
|
46
|
+
}
|
|
47
|
+
if (
|
|
48
|
+
segments[i].getEndPoint().distance(segments[j].getEndPoint()) < epsilon ||
|
|
49
|
+
segments[i].getEndPoint().distance(segments[j].getStartPoint()) < epsilon
|
|
50
|
+
) {
|
|
51
|
+
result[i].hasSuccessor = true;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
// After first initialization make sure that no loose path ends are dangling around
|
|
56
|
+
// if the affected path segment has a predecessor (but nu successor).
|
|
57
|
+
//
|
|
58
|
+
// Revert those segments. This makes the actual detection algorithm much easier.
|
|
59
|
+
for (var i = 0; i < segments.length; i++) {
|
|
60
|
+
if (!result[i].hasSuccessor && result[i].hasPredecessor) {
|
|
61
|
+
segments[i] = segments[i].reverse();
|
|
62
|
+
result[i].hasPredecessor = false;
|
|
63
|
+
result[i].hasSuccessor = true;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
return result;
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Find the next unvisited path segment (private helper function).
|
|
71
|
+
*
|
|
72
|
+
* There is a special order: starting path segments (those without any predecessor)
|
|
73
|
+
* will be preferred. If no more open paths are available (no starting path segments),
|
|
74
|
+
* then no more unvisited paths are available or all remaining paths are loops (without
|
|
75
|
+
* determined start/end).
|
|
76
|
+
*
|
|
77
|
+
* Doing this keeps us from the need to run a final loop to connect detected sub paths.
|
|
78
|
+
*
|
|
79
|
+
* @param {Array<PathSegment>} segments - The path segments to search in.
|
|
80
|
+
* @param { Array<Visitation>} isSegmentVisited
|
|
81
|
+
* @returns {number} The index of the next unvisited path segment or -1 if no more are available.
|
|
82
|
+
*/
|
|
83
|
+
const locateUnvisitedSegment = (segments: Array<PathSegment>, isSegmentVisited: Array<Visitation>): number => {
|
|
84
|
+
// First run: detect beginnings
|
|
85
|
+
for (var i = 0; i < segments.length; i++) {
|
|
86
|
+
if (!isSegmentVisited[i].hasPredecessor && !isSegmentVisited[i].visited) {
|
|
87
|
+
return i;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
// Second run: if no beginnings exist -> use inner path segment
|
|
91
|
+
for (var i = 0; i < segments.length; i++) {
|
|
92
|
+
if (!isSegmentVisited[i].visited) {
|
|
93
|
+
return i;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
return -1;
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Get the next adjacent path segment to the given (current) segment. This is a private
|
|
101
|
+
* helper function.
|
|
102
|
+
*
|
|
103
|
+
* Note that the function will revert the adjacent path segment if required, so the next
|
|
104
|
+
* starting point 'equals' the current ending point.
|
|
105
|
+
*
|
|
106
|
+
* The visitation tracker will be updated if the adjacent segment was found.
|
|
107
|
+
*
|
|
108
|
+
* @param {Array<PathSegment>} segments - The total set of available path segments (visited and invisited).
|
|
109
|
+
* @param {Array<Visitation>} isSegmentVisited - A tracker of visited path segments so far.
|
|
110
|
+
* @param {PathSegment} currentSegment - The current path segment to find the adjacent segment for.
|
|
111
|
+
* @param {number} epsilon - The epsilon to use to detect 'equal' start/end points. Must be >= 0.
|
|
112
|
+
* @returns {PathSegment | null} The next adjacent path segment of null if no such exists.
|
|
113
|
+
*/
|
|
114
|
+
const getAdjacentSegment = (
|
|
115
|
+
segments: Array<PathSegment>,
|
|
116
|
+
isSegmentVisited: Array<Visitation>,
|
|
117
|
+
currentSegment: PathSegment,
|
|
118
|
+
epsilon: number
|
|
119
|
+
): PathSegment | null => {
|
|
120
|
+
for (var j = 0; j < segments.length; j++) {
|
|
121
|
+
if (isSegmentVisited[j].visited) {
|
|
122
|
+
continue;
|
|
123
|
+
}
|
|
124
|
+
var nextSegment = segments[j];
|
|
125
|
+
// [start]---[end] [start]---[end]
|
|
126
|
+
if (currentSegment.getEndPoint().distance(nextSegment.getStartPoint()) < epsilon) {
|
|
127
|
+
isSegmentVisited[j].visited = true;
|
|
128
|
+
return nextSegment;
|
|
129
|
+
}
|
|
130
|
+
// [start]---[end] [end]---[start]
|
|
131
|
+
else if (currentSegment.getEndPoint().distance(nextSegment.getEndPoint()) < epsilon) {
|
|
132
|
+
isSegmentVisited[j].visited = true;
|
|
133
|
+
return nextSegment.reverse();
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
return null;
|
|
137
|
+
};
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* A private helper function to find the adjacent full path for the given path segment,
|
|
141
|
+
* considering the current path segment is a starting segment (or one inside a loop).
|
|
142
|
+
*
|
|
143
|
+
* @param {Array<PathSegment>} segments - The total set of available path segments.
|
|
144
|
+
* @param { Array<Visitation>} isSegmentVisited - A tracker to determine which segments have already been visited.
|
|
145
|
+
* @param {number} currentSegmentIndex - The index of the current segments to find the containing path for.
|
|
146
|
+
* @param {number} epsilon - The epsilon to use to determine 'equal' path points. Must be >= 0.
|
|
147
|
+
* @returns {GenericPath} The dected path which consists at least of the current path segment.
|
|
148
|
+
*/
|
|
149
|
+
const detectAdjacentPath = (
|
|
150
|
+
segments: Array<PathSegment>,
|
|
151
|
+
isSegmentVisited: Array<Visitation>,
|
|
152
|
+
currentSegmentIndex: number,
|
|
153
|
+
epsilon: number
|
|
154
|
+
): GenericPath => {
|
|
155
|
+
var currentSegment: PathSegment | null = segments[currentSegmentIndex];
|
|
156
|
+
isSegmentVisited[currentSegmentIndex].visited = true;
|
|
157
|
+
const path = new GenericPath(currentSegment); // { segments: [currentSegment], reverse };
|
|
158
|
+
|
|
159
|
+
var i: number = 0;
|
|
160
|
+
// A safety break if something goes wrong
|
|
161
|
+
while (i < segments.length && currentSegment) {
|
|
162
|
+
currentSegment = getAdjacentSegment(segments, isSegmentVisited, currentSegment, epsilon);
|
|
163
|
+
if (currentSegment) {
|
|
164
|
+
path.segments.push(currentSegment);
|
|
165
|
+
}
|
|
166
|
+
i++;
|
|
167
|
+
}
|
|
168
|
+
return path;
|
|
169
|
+
};
|
|
170
|
+
|
|
171
|
+
/**
|
|
172
|
+
* Run a path detection on the given set of path segments.
|
|
173
|
+
*
|
|
174
|
+
* Note that the array and some path segments may be altered (like reversal) IN PLACE.
|
|
175
|
+
*
|
|
176
|
+
* @param {Array<PathSegment>} segments - The total set (array) of available path segments.
|
|
177
|
+
* @param {number=1.0} epsilon - (optional) An epsilon to use to tell if two plane points should be considered 'equal'.
|
|
178
|
+
* @returns {Array<GenericPath>} An array containing all detected path (consisting of adjacent path segments of the original set).
|
|
179
|
+
*/
|
|
180
|
+
export const detectPaths = (segments: Array<PathSegment>, epsilon?: number): Array<Path> => {
|
|
181
|
+
const eps = typeof epsilon === "undefined" || epsilon < 0 ? 1.0 : epsilon;
|
|
182
|
+
const isSegmentVisited: Array<Visitation> = initVisitationArray(segments, eps);
|
|
183
|
+
const resultPaths: Array<GenericPath> = [];
|
|
184
|
+
var nextSegmentIndex: number = -1;
|
|
185
|
+
var i = 0;
|
|
186
|
+
while ((nextSegmentIndex = locateUnvisitedSegment(segments, isSegmentVisited)) !== -1 && i < segments.length) {
|
|
187
|
+
isSegmentVisited[nextSegmentIndex].visited = true;
|
|
188
|
+
// A safety break (to avoid infinited loops during development).
|
|
189
|
+
i++;
|
|
190
|
+
const path = detectAdjacentPath(segments, isSegmentVisited, nextSegmentIndex, eps);
|
|
191
|
+
i += path.getSegmentCount() - 1;
|
|
192
|
+
resultPaths.push(path);
|
|
193
|
+
}
|
|
194
|
+
return resultPaths;
|
|
195
|
+
};
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @author Ikaros Kappler
|
|
3
|
+
* @version 1.0.0
|
|
4
|
+
* @date 2022-10-17
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { Path, PathSegment } from "../../interfaces/additionals";
|
|
8
|
+
import { Vertex } from "../../Vertex";
|
|
9
|
+
|
|
10
|
+
export class GenericPath implements Path {
|
|
11
|
+
segments: Array<PathSegment>;
|
|
12
|
+
|
|
13
|
+
constructor(startSegment: PathSegment) {
|
|
14
|
+
this.segments = [startSegment];
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Get the number of segments in this path.
|
|
19
|
+
*
|
|
20
|
+
* @method getSegmentCount
|
|
21
|
+
* @memberof Path
|
|
22
|
+
* @return {number} The number (integer) of path segments.
|
|
23
|
+
*/
|
|
24
|
+
getSegmentCount(): number {
|
|
25
|
+
return this.segments.length;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Get the path segment at the given index.
|
|
30
|
+
*
|
|
31
|
+
* @method getSegmentAt
|
|
32
|
+
* @memberof Path
|
|
33
|
+
* @return {PathSegment} The paths segment at the given index.
|
|
34
|
+
*/
|
|
35
|
+
getSegmentAt(index: number): PathSegment {
|
|
36
|
+
return this.segments[index];
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Create a deep clone of this path.
|
|
41
|
+
*
|
|
42
|
+
* @method clone
|
|
43
|
+
* @memberof Path
|
|
44
|
+
* @return {Path} A deep clone/copy of this path.
|
|
45
|
+
*/
|
|
46
|
+
clone(): GenericPath {
|
|
47
|
+
const newPath = new GenericPath(this.segments[this.segments.length - 1].clone().reverse());
|
|
48
|
+
for (var i = this.segments.length - 2; i >= 0; i--) {
|
|
49
|
+
newPath.segments.push(this.segments[i].clone().reverse());
|
|
50
|
+
}
|
|
51
|
+
return newPath;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Reverse this path (swap start and end and thus – the direction) in-place.
|
|
56
|
+
*
|
|
57
|
+
* @method reverse
|
|
58
|
+
* @memberof Path
|
|
59
|
+
* @return {PathSegment} This path instance.
|
|
60
|
+
*/
|
|
61
|
+
reverse() {
|
|
62
|
+
const newSegments: Array<PathSegment> = [];
|
|
63
|
+
for (var i = this.segments.length - 1; i >= 0; i--) {
|
|
64
|
+
newSegments.push(this.segments[i].reverse());
|
|
65
|
+
}
|
|
66
|
+
this.segments = newSegments;
|
|
67
|
+
return this;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Get the start point of this path segment.
|
|
72
|
+
*
|
|
73
|
+
* @method getStartPoint
|
|
74
|
+
* @memberof PathSegment
|
|
75
|
+
* @return {Vertex} The start point of this path segment.
|
|
76
|
+
*/
|
|
77
|
+
getStartPoint(): Vertex {
|
|
78
|
+
return this.segments[0].getStartPoint();
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Get the end point of this path segment.
|
|
83
|
+
*
|
|
84
|
+
* @method getEndPoint
|
|
85
|
+
* @memberof PathSegment
|
|
86
|
+
* @return {Vertex} The end point of this path segment.
|
|
87
|
+
*/
|
|
88
|
+
getEndPoint(): Vertex {
|
|
89
|
+
return this.segments[this.segments.length - 1].getEndPoint();
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Get the tangent's end point at the start point of this segment.
|
|
94
|
+
*
|
|
95
|
+
* @method getStartTangent
|
|
96
|
+
* @memberof PathSegment
|
|
97
|
+
* @return {Vertex} The end point of the starting point's tangent.
|
|
98
|
+
*/
|
|
99
|
+
getStartTangent(): Vertex {
|
|
100
|
+
return this.segments[0].getStartTangent();
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* Get the tangent's end point at the end point of this segment.
|
|
105
|
+
*
|
|
106
|
+
* @method getEndTangent
|
|
107
|
+
* @memberof PathSegment
|
|
108
|
+
* @return {Vertex} The end point of the ending point's tangent.
|
|
109
|
+
*/
|
|
110
|
+
getEndTangent(): Vertex {
|
|
111
|
+
return this.segments[this.segments.length - 1].getEndTangent();
|
|
112
|
+
}
|
|
113
|
+
}
|
|
@@ -319,7 +319,7 @@ export abstract class GirihTile extends Polygon {
|
|
|
319
319
|
* @param {Polygon} neighbourTile - The polygon (or tile) you want to find adjacency for at the specified edge.
|
|
320
320
|
* @return {Polygon|null} the passed tile itself if adjacency was found, null otherwise.
|
|
321
321
|
*/
|
|
322
|
-
transformTilePositionToAdjacency<P extends Polygon>(baseEdgeIndex: number, neighbourTile: P): P {
|
|
322
|
+
transformTilePositionToAdjacency<P extends Polygon>(baseEdgeIndex: number, neighbourTile: P): P | null {
|
|
323
323
|
// Find the position for that tile to match (might not exist)
|
|
324
324
|
// { edgeIndex:number, offset:XYCoords }
|
|
325
325
|
var adjacency = this.findAdjacentTilePosition(baseEdgeIndex, neighbourTile);
|