Trains on tracks with left and right pathing

This commit is contained in:
2025-02-10 03:57:57 -07:00
parent 68eec35ea2
commit 69475b1bd8
7 changed files with 269 additions and 70 deletions

View File

@@ -107,10 +107,12 @@ export class TrackSystem {
if (data.length === 0) return undefined;
const track = new TrackSystem([]);
const neighborMap = new Map<string, [string[], string[]]>();
for (const segment of data) {
track.segments.set(segment.id, TrackSegment.deserialize(segment));
neighborMap.set(segment.id, [segment.fNeighbors, segment.bNeighbors]);
}
for (const segment of track.segments.values()) {
segment.setTrack(track);
const neighbors = neighborMap.get(segment.id);
@@ -123,7 +125,7 @@ export class TrackSystem {
).filter((s) => s) as TrackSegment[];
}
}
console.log(track.segments);
return track;
}
@@ -146,7 +148,7 @@ export class TrackSystem {
if (!this.firstSegment) throw new Error("No first segment");
const rightOnlyPath = [
this.firstSegment.copy(),
...this.findRightPath(this.firstSegment),
...this.findRightPath(this.firstSegment, new Set([this.firstSegment.id])),
];
rightOnlyPath.forEach((s, i, arr) => {
@@ -157,17 +159,17 @@ export class TrackSystem {
prev.next = s;
});
console.log(rightOnlyPath);
return new Spline<TrackSegment>(rightOnlyPath);
}
*findRightPath(start: TrackSegment): Generator<TrackSegment> {
*findRightPath(
start: TrackSegment,
seen: Set<string>,
): Generator<TrackSegment> {
if (start.frontNeighbours.length === 0) {
yield start;
return;
}
let rightMost = start.frontNeighbours[0].copy();
let rightMost = start.frontNeighbours[0];
for (const segment of start.frontNeighbours) {
if (segment.id === rightMost.id) continue;
const rotatedSegment = segment.copy();
@@ -184,8 +186,39 @@ export class TrackSystem {
rightMost = segment;
}
}
if (seen.has(rightMost.id)) return;
seen.add(rightMost.id);
yield rightMost.copy();
yield* this.findRightPath(rightMost);
yield* this.findRightPath(rightMost, seen);
}
*findLeftPath(
start: TrackSegment,
seen: Set<string>,
): Generator<TrackSegment> {
if (start.frontNeighbours.length === 0) {
return;
}
let leftMost = start.frontNeighbours[0];
for (const segment of start.frontNeighbours) {
if (segment.id === leftMost.id) continue;
const rotatedSegment = segment.copy();
rotatedSegment.rotateAboutPoint(
rotatedSegment.tangent(0).heading(),
rotatedSegment.points[0],
);
const rotatedLeftMost = leftMost.copy();
rotatedLeftMost.rotateAboutPoint(
rotatedLeftMost.tangent(0).heading(),
rotatedLeftMost.points[0],
);
if (rotatedSegment.points[3].y < rotatedLeftMost.points[3].y) {
leftMost = segment;
}
}
if (seen.has(leftMost.id)) return;
seen.add(leftMost.id);
yield leftMost.copy();
yield* this.findLeftPath(leftMost, seen);
}
}
@@ -423,7 +456,6 @@ export class Spline<T extends PathSegment = PathSegment> {
const i = Math.floor(t) % this.evenPoints.length;
const a = this.evenPoints[i];
const b = this.evenPoints[(i + 1) % this.evenPoints.length];
return Vector.lerp(a, b, t % 1);
}