Add mass driver station system with Lagrange point placement

- Lagrange point computation (L1-L5) for any Sun-planet pair in Rust
- Station generation: auto-place at Lagrange points by priority (inner → outer planets)
- Station panel UI: count slider (5-50), launch velocity slider (5-100 km/s) with info tooltip
- Blue diamond markers on 2D canvas with labels when zoomed in
- Active station list in sidebar (Earth L1, Mars L2, Jupiter L4, etc.)
- WASM API: generate_stations(), get_station_positions(), get_station_names()
- Station positions update every frame (co-rotating with planets at Lagrange points)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-04-08 12:00:36 -07:00
parent 067ef1f557
commit a2daa2d617
10 changed files with 449 additions and 25 deletions

View File

@@ -17,6 +17,9 @@ export class SolarSystem2DRenderer {
private positions: Float64Array = new Float64Array(0);
private velocities: Float64Array = new Float64Array(0);
private orbitPoints: Map<number, Float64Array> = new Map();
private stationPositions: Float64Array = new Float64Array(0);
private stationNames: string[] = [];
private showStations: boolean = true;
private isDragging = false;
private lastMouse = { x: 0, y: 0 };
private animFrameId: number = 0;
@@ -77,6 +80,12 @@ export class SolarSystem2DRenderer {
this.orbitPoints.set(bodyId, points);
}
updateStations(positions: Float64Array, names: string[], visible: boolean) {
this.stationPositions = positions;
this.stationNames = names;
this.showStations = visible;
}
render() {
const { canvas, ctx } = this;
const dpr = window.devicePixelRatio || 1;
@@ -115,6 +124,15 @@ export class SolarSystem2DRenderer {
}
}
// Draw stations
if (this.showStations && this.stationPositions.length > 0) {
for (let i = 0; i < this.stationNames.length; i++) {
const x = this.stationPositions[i * 3];
const y = this.stationPositions[i * 3 + 1];
this.drawStation(x, y, this.stationNames[i]);
}
}
// Scale indicator
this.drawScaleBar(rect.width, rect.height);
}
@@ -269,6 +287,32 @@ export class SolarSystem2DRenderer {
ctx.fillText(info.name, sx + size + 4, sy + 3);
}
private drawStation(xAU: number, yAU: number, name: string) {
const ctx = this.ctx;
const [sx, sy] = this.auToScreen(xAU, yAU);
// Diamond shape
const s = 3;
ctx.fillStyle = 'rgba(74, 158, 255, 0.6)';
ctx.strokeStyle = 'rgba(74, 158, 255, 0.8)';
ctx.lineWidth = 1;
ctx.beginPath();
ctx.moveTo(sx, sy - s);
ctx.lineTo(sx + s, sy);
ctx.lineTo(sx, sy + s);
ctx.lineTo(sx - s, sy);
ctx.closePath();
ctx.fill();
ctx.stroke();
// Label (only show when zoomed in enough)
if (this.getScale() > 50) {
ctx.fillStyle = 'rgba(74, 158, 255, 0.5)';
ctx.font = '8px monospace';
ctx.fillText(name, sx + s + 3, sy + 3);
}
}
private drawScaleBar(w: number, h: number) {
const ctx = this.ctx;
const scale = this.getScale();