121 lines
3.3 KiB
JavaScript
121 lines
3.3 KiB
JavaScript
const canvas = document.getElementById("simCanvas");
|
|
const ctx = canvas.getContext("2d");
|
|
|
|
const WIDTH = 700;
|
|
const HEIGHT = 700;
|
|
const CENTER = { x: WIDTH / 2, y: HEIGHT / 2 };
|
|
const RADIUS = 260;
|
|
|
|
let TAG_COUNT = 36;
|
|
let TAG_STEP = 360 / TAG_COUNT;
|
|
|
|
let telescopeAngle = 0.0;
|
|
let domeAngle = TAG_STEP / 2; // aktuelle Position
|
|
let targetDomeAngle = domeAngle;
|
|
let slotWidth = 20.0;
|
|
|
|
let domeSpeed = 1.0; // ° pro Frame
|
|
let state = "IDLE"; // "IDLE" oder "MOVING"
|
|
|
|
function angleDiff(target, source) {
|
|
let d = (target - source + 180) % 360 - 180;
|
|
return d;
|
|
}
|
|
function getTagIndex(angle) {
|
|
return Math.floor((angle % 360) / TAG_STEP);
|
|
}
|
|
function tagToAngle(idx) {
|
|
return idx * TAG_STEP + TAG_STEP / 2;
|
|
}
|
|
|
|
// Tastatursteuerung
|
|
document.addEventListener("keydown", (e) => {
|
|
if (e.key === "ArrowLeft") telescopeAngle = (telescopeAngle - 2.5 + 360) % 360;
|
|
if (e.key === "ArrowRight") telescopeAngle = (telescopeAngle + 2.5) % 360;
|
|
});
|
|
|
|
function update() {
|
|
let diff = angleDiff(telescopeAngle, domeAngle);
|
|
let halfSlot = slotWidth / 2;
|
|
let moveDir = "STOP";
|
|
|
|
if (state === "IDLE") {
|
|
// Prüfen, ob Teleskop aus Schlitz läuft
|
|
if (diff > halfSlot) {
|
|
// CW-Bewegung → Kuppel muss eine Spaltbreite weiter drehen
|
|
targetDomeAngle = (domeAngle + slotWidth) % 360;
|
|
state = "MOVING";
|
|
} else if (diff < -halfSlot) {
|
|
// CCW-Bewegung → Kuppel muss eine Spaltbreite zurück
|
|
targetDomeAngle = (domeAngle - slotWidth + 360) % 360;
|
|
state = "MOVING";
|
|
}
|
|
}
|
|
|
|
if (state === "MOVING") {
|
|
let delta = angleDiff(targetDomeAngle, domeAngle);
|
|
if (Math.abs(delta) > domeSpeed) {
|
|
domeAngle = (domeAngle + Math.sign(delta) * domeSpeed + 360) % 360;
|
|
moveDir = Math.sign(delta) > 0 ? "+" : "-";
|
|
} else {
|
|
domeAngle = targetDomeAngle;
|
|
state = "IDLE";
|
|
}
|
|
}
|
|
|
|
let activeTag = getTagIndex(domeAngle);
|
|
draw(activeTag, diff, moveDir);
|
|
requestAnimationFrame(update);
|
|
}
|
|
|
|
function draw(activeTag, diff, moveDir) {
|
|
ctx.clearRect(0, 0, WIDTH, HEIGHT);
|
|
|
|
// Tags
|
|
for (let i = 0; i < TAG_COUNT; i++) {
|
|
let a = (-2 * Math.PI * i) / TAG_COUNT;
|
|
let x = CENTER.x + Math.cos(a) * RADIUS;
|
|
let y = CENTER.y + Math.sin(a) * RADIUS;
|
|
ctx.beginPath();
|
|
ctx.arc(x, y, i === activeTag ? 6 : 3, 0, 2 * Math.PI);
|
|
ctx.fillStyle = i === activeTag ? "green" : "black";
|
|
ctx.fill();
|
|
}
|
|
|
|
// Spaltbogen
|
|
let midAngle = -domeAngle * (Math.PI / 180);
|
|
let half = (slotWidth / 2) * (Math.PI / 180);
|
|
ctx.beginPath();
|
|
ctx.strokeStyle = "blue";
|
|
ctx.lineWidth = 12;
|
|
ctx.arc(CENTER.x, CENTER.y, RADIUS, midAngle - half, midAngle + half);
|
|
ctx.stroke();
|
|
|
|
// Teleskop
|
|
let tx = CENTER.x + Math.cos((-telescopeAngle * Math.PI) / 180) * (RADIUS - 60);
|
|
let ty = CENTER.y + Math.sin((-telescopeAngle * Math.PI) / 180) * (RADIUS - 60);
|
|
ctx.beginPath();
|
|
ctx.moveTo(CENTER.x, CENTER.y);
|
|
ctx.lineTo(tx, ty);
|
|
ctx.strokeStyle = "red";
|
|
ctx.lineWidth = 6;
|
|
ctx.stroke();
|
|
ctx.beginPath();
|
|
ctx.arc(tx, ty, 8, 0, 2 * Math.PI);
|
|
ctx.fillStyle = "red";
|
|
ctx.fill();
|
|
|
|
// Debug
|
|
document.getElementById("debug").textContent =
|
|
`Telescope: ${telescopeAngle.toFixed(1)}°\n` +
|
|
`Dome: ${domeAngle.toFixed(1)}°\n` +
|
|
`Target: ${targetDomeAngle.toFixed(1)}°\n` +
|
|
`Diff: ${diff.toFixed(2)}°\n` +
|
|
`Active Tag: ${activeTag}\n` +
|
|
`Move: ${moveDir}\n` +
|
|
`State: ${state}`;
|
|
}
|
|
|
|
// Start
|
|
update();
|