just so much groundwork
This commit is contained in:
124
track/system.ts
Normal file
124
track/system.ts
Normal file
@@ -0,0 +1,124 @@
|
||||
import { Doodler, Vector } from "@bearmetal/doodler";
|
||||
import { PathSegment } from "../math/path.ts";
|
||||
import { getContextItem, setDefaultContext } from "../lib/context.ts";
|
||||
|
||||
export class TrackSystem {
|
||||
private segments: Map<string, TrackSegment> = new Map();
|
||||
private doodler: Doodler;
|
||||
|
||||
constructor(segments: TrackSegment[]) {
|
||||
this.doodler = getContextItem<Doodler>("doodler");
|
||||
for (const segment of segments) {
|
||||
this.segments.set(segment.id, segment);
|
||||
}
|
||||
}
|
||||
|
||||
draw() {
|
||||
for (const segment of this.segments.values()) {
|
||||
segment.draw();
|
||||
}
|
||||
|
||||
try {
|
||||
if (getContextItem<boolean>("showEnds")) {
|
||||
const ends = this.findEnds();
|
||||
for (const end of ends) {
|
||||
this.doodler.fillCircle(end.pos, 2, {
|
||||
color: "red",
|
||||
// weight: 3,
|
||||
});
|
||||
if (getContextItem<boolean>("debug")) {
|
||||
this.doodler.line(
|
||||
end.pos,
|
||||
end.pos.copy().add(end.tangent.copy().mult(20)),
|
||||
{
|
||||
color: "blue",
|
||||
// weight: 3,
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch {
|
||||
setDefaultContext({ showEnds: false });
|
||||
}
|
||||
}
|
||||
|
||||
findEnds() {
|
||||
const ends: { pos: Vector; segment: TrackSegment; tangent: Vector }[] = [];
|
||||
for (const segment of this.segments.values()) {
|
||||
const [a, b, c, d] = segment.points;
|
||||
{
|
||||
const tangent = Vector.sub(a, b).normalize();
|
||||
const pos = a.copy();
|
||||
ends.push({ pos, segment, tangent });
|
||||
}
|
||||
{
|
||||
const tangent = Vector.sub(d, c).normalize();
|
||||
const pos = d.copy();
|
||||
ends.push({ pos, segment, tangent });
|
||||
}
|
||||
}
|
||||
return ends;
|
||||
}
|
||||
|
||||
serialize() {
|
||||
return this.segments.values().map((s) => s.serialize()).toArray();
|
||||
}
|
||||
|
||||
static deserialize(data: any) {
|
||||
const track = new TrackSystem([]);
|
||||
for (const segment of data) {
|
||||
track.segments.set(segment.id, TrackSegment.deserialize(segment));
|
||||
}
|
||||
return track;
|
||||
}
|
||||
}
|
||||
|
||||
export class TrackSegment extends PathSegment {
|
||||
frontNeighbours: TrackSegment[] = [];
|
||||
backNeighbours: TrackSegment[] = [];
|
||||
|
||||
track?: TrackSystem;
|
||||
|
||||
doodler: Doodler;
|
||||
|
||||
id: string;
|
||||
|
||||
constructor(p: [Vector, Vector, Vector, Vector], id?: string) {
|
||||
super(p);
|
||||
this.doodler = getContextItem<Doodler>("doodler");
|
||||
this.id = id ?? crypto.randomUUID();
|
||||
}
|
||||
|
||||
setTrack(t: TrackSystem) {
|
||||
this.track = t;
|
||||
}
|
||||
|
||||
draw() {
|
||||
this.doodler.drawBezier(
|
||||
this.points[0],
|
||||
this.points[1],
|
||||
this.points[2],
|
||||
this.points[3],
|
||||
{
|
||||
strokeColor: "#ffffff50",
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
serialize() {
|
||||
return {
|
||||
p: this.points.map((p) => p.array()),
|
||||
id: this.id,
|
||||
bNeighbors: this.backNeighbours.map((n) => n.id),
|
||||
fNeighbors: this.frontNeighbours.map((n) => n.id),
|
||||
};
|
||||
}
|
||||
|
||||
static deserialize(data: any) {
|
||||
return new TrackSegment(
|
||||
data.p.map((p: [number, number, number]) => new Vector(p[0], p[1], p[2])),
|
||||
data.id,
|
||||
);
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user