tight curve, nearest segment

This commit is contained in:
Emmaline Autumn 2025-02-23 13:13:28 -07:00
parent 2176f67413
commit 3aea38f9f4
6 changed files with 100 additions and 11 deletions

View File

@ -48,6 +48,7 @@ const _fullDebug: Debug = {
bogies: false, bogies: false,
angles: false, angles: false,
aabb: false, aabb: false,
segment: false,
}; };
const storedDebug = JSON.parse(localStorage.getItem("debug") || "0"); const storedDebug = JSON.parse(localStorage.getItem("debug") || "0");

View File

@ -14,6 +14,8 @@ import {
SBendLeft, SBendLeft,
SBendRight, SBendRight,
StraightTrack, StraightTrack,
TightBankLeft,
TightBankRight,
WideBankLeft, WideBankLeft,
WideBankRight, WideBankRight,
} from "../../track/shapes.ts"; } from "../../track/shapes.ts";
@ -285,6 +287,8 @@ export class EditTrackState extends State<States> {
new BankRight(), new BankRight(),
new WideBankLeft(), new WideBankLeft(),
new WideBankRight(), new WideBankRight(),
new TightBankLeft(),
new TightBankRight(),
]); ]);
const inputManager = getContextItem<InputManager>("inputManager"); const inputManager = getContextItem<InputManager>("inputManager");

View File

@ -85,7 +85,10 @@ export class RunningState extends State<States> {
// this.activeTr0ain = train; // this.activeTr0ain = train;
// const trainCount = 1000; // const trainCount = 1000;
// for (let i = 0; i < trainCount; i++) { // for (let i = 0; i < trainCount; i++) {
// const train = new Train(track.path, [new LargeLady(), new Tender()]); // const train = new Train(track.path, [
// new LargeLady(),
// new LargeLadyTender(),
// ]);
// ctx.trains.push(train); // ctx.trains.push(train);
// } // }

View File

@ -88,6 +88,58 @@ export class WideBankLeft extends TrackSegment {
]); ]);
} }
} }
export class TightBankLeft extends TrackSegment {
constructor(start?: Vector) {
start = start || new Vector(100, 100);
const p1 = start.copy();
const p2 = start.copy();
const p3 = start.copy();
const p4 = start.copy();
const scale = 61.57;
p2.add(new Vector(1, 0).mult(scale));
p3.set(p2);
const dirToP3 = Vector.fromAngle(-Math.PI / 12).mult(scale);
p3.add(dirToP3);
p4.set(p3);
const dirToP4 = Vector.fromAngle(-Math.PI / 6).mult(scale);
p4.add(dirToP4);
super([
p1,
p2,
p3,
p4,
]);
}
}
export class TightBankRight extends TrackSegment {
constructor(start?: Vector) {
start = start || new Vector(100, 100);
const p1 = start.copy();
const p2 = start.copy();
const p3 = start.copy();
const p4 = start.copy();
const scale = 61.57;
p2.add(new Vector(1, 0).mult(scale));
p3.set(p2);
const dirToP3 = Vector.fromAngle(Math.PI / 12).mult(scale);
p3.add(dirToP3);
p4.set(p3);
const dirToP4 = Vector.fromAngle(Math.PI / 6).mult(scale);
p4.add(dirToP4);
super([
p1,
p2,
p3,
p4,
]);
}
}
export class WideBankRight extends TrackSegment { export class WideBankRight extends TrackSegment {
constructor(start?: Vector) { constructor(start?: Vector) {
start = start || new Vector(100, 100); start = start || new Vector(100, 100);

View File

@ -2,12 +2,14 @@ import { Doodler, Point, Vector } from "@bearmetal/doodler";
import { ComplexPath, PathSegment } from "../math/path.ts"; import { ComplexPath, PathSegment } from "../math/path.ts";
import { getContextItem, setDefaultContext } from "../lib/context.ts"; import { getContextItem, setDefaultContext } from "../lib/context.ts";
import { clamp } from "../math/clamp.ts"; import { clamp } from "../math/clamp.ts";
import { Debuggable } from "../lib/debuggable.ts";
export class TrackSystem { export class TrackSystem extends Debuggable {
private _segments: Map<string, TrackSegment> = new Map(); private _segments: Map<string, TrackSegment> = new Map();
private doodler: Doodler; private doodler: Doodler;
constructor(segments: TrackSegment[]) { constructor(segments: TrackSegment[]) {
super("track");
this.doodler = getContextItem<Doodler>("doodler"); this.doodler = getContextItem<Doodler>("doodler");
for (const segment of segments) { for (const segment of segments) {
this._segments.set(segment.id, segment); this._segments.set(segment.id, segment);
@ -26,6 +28,19 @@ export class TrackSystem {
return this._segments.values().toArray().pop(); return this._segments.values().toArray().pop();
} }
getNearestSegment(pos: Vector) {
let minDistance = Infinity;
let nearestSegment: TrackSegment | undefined;
for (const segment of this._segments.values()) {
const distance = segment.getDistanceTo(pos);
if (distance < minDistance) {
minDistance = distance;
nearestSegment = segment;
}
}
return nearestSegment;
}
optimize(percent: number) { optimize(percent: number) {
console.log("Optimizing track", percent * 100 / 4); console.log("Optimizing track", percent * 100 / 4);
for (const segment of this._segments.values()) { for (const segment of this._segments.values()) {
@ -85,6 +100,15 @@ export class TrackSystem {
// } // }
} }
override debugDraw(): void {
const debug = getContextItem("debug");
if (debug.track) {
for (const segment of this._segments.values()) {
segment.drawAABB();
}
}
}
ends: Map<TrackSegment, [End, End]> = new Map(); ends: Map<TrackSegment, [End, End]> = new Map();
endArray: End[] = []; endArray: End[] = [];
@ -293,6 +317,10 @@ export class TrackSegment extends PathSegment {
this.update(); this.update();
} }
getDistanceTo(pos: Vector) {
return Vector.dist(this.aabb.center, pos);
}
updateAABB() { updateAABB() {
let minX = Infinity; let minX = Infinity;
let maxX = -Infinity; let maxX = -Infinity;
@ -435,15 +463,15 @@ export class TrackSegment extends PathSegment {
// color: "red", // color: "red",
// weight: 3, // weight: 3,
// }); // });
const debug = getContextItem("debug"); }
if (debug.track) {
this.doodler.drawRect(this.aabb.pos, this.aabb.width, this.aabb.height, { drawAABB() {
color: "lime", this.doodler.drawRect(this.aabb.pos, this.aabb.width, this.aabb.height, {
}); color: "lime",
this.doodler.drawCircle(this.aabb.center, 2, { });
color: "cyan", this.doodler.drawCircle(this.aabb.center, 2, {
}); color: "cyan",
} });
} }
serialize(): SerializedTrackSegment { serialize(): SerializedTrackSegment {

View File

@ -18,6 +18,7 @@ declare global {
type Debug = { type Debug = {
track: boolean; track: boolean;
segment: boolean;
train: boolean; train: boolean;
car: boolean; car: boolean;
path: boolean; path: boolean;