Add fixed constellation inspection mode
This commit is contained in:
parent
344fa08dbb
commit
4e01c768c9
2 changed files with 96 additions and 12 deletions
|
|
@ -1219,6 +1219,7 @@ const ctx = canvas.getContext('2d');
|
||||||
|
|
||||||
let obsLat = -24.72, obsLon = -53.74; // Toledo-PR; sobrescrito pela config
|
let obsLat = -24.72, obsLon = -53.74; // Toledo-PR; sobrescrito pela config
|
||||||
let showConstellations = false;
|
let showConstellations = false;
|
||||||
|
let constellationPreviewId = null;
|
||||||
const constellationArtImages = new Map();
|
const constellationArtImages = new Map();
|
||||||
if (typeof CONSTELLATIONS !== 'undefined') {
|
if (typeof CONSTELLATIONS !== 'undefined') {
|
||||||
for (const constellation of CONSTELLATIONS) {
|
for (const constellation of CONSTELLATIONS) {
|
||||||
|
|
@ -1485,12 +1486,16 @@ function constellationArtTransform(source, target) {
|
||||||
return [a, b, -b, a, e, f];
|
return [a, b, -b, a, e, f];
|
||||||
}
|
}
|
||||||
|
|
||||||
function drawConstellationArt(c, constellation, lst, W, horizonPx) {
|
function drawConstellationArt(c, constellation, lst, W, horizonPx, previewProjector) {
|
||||||
const art = constellation.art;
|
const art = constellation.art;
|
||||||
const imageEntry = constellationArtImages.get(constellation.id);
|
const imageEntry = constellationArtImages.get(constellation.id);
|
||||||
if (!art || !imageEntry || !imageEntry.render) return;
|
if (!art || !imageEntry || !imageEntry.render) return;
|
||||||
|
|
||||||
const target = art.anchors.map(anchor => {
|
const target = art.anchors.map(anchor => {
|
||||||
|
if (previewProjector) {
|
||||||
|
const sc = previewProjector(anchor.sky);
|
||||||
|
return { x: sc.x, y: sc.y, alt: ALT_TOP / 2 };
|
||||||
|
}
|
||||||
const aa = altAz(anchor.sky[0], anchor.sky[1], lst);
|
const aa = altAz(anchor.sky[0], anchor.sky[1], lst);
|
||||||
const daz = ((aa.az - VIEW_AZ) % 360 + 540) % 360 - 180;
|
const daz = ((aa.az - VIEW_AZ) % 360 + 540) % 360 - 180;
|
||||||
return {
|
return {
|
||||||
|
|
@ -1541,31 +1546,66 @@ function drawConstellationArt(c, constellation, lst, W, horizonPx) {
|
||||||
c.restore();
|
c.restore();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function makeConstellationPreviewProjector(constellation, W, horizonPx) {
|
||||||
|
const centerRa = constellation.label ? constellation.label[0] : 0;
|
||||||
|
const centerDec = constellation.label ? constellation.label[1] : 0;
|
||||||
|
const flatten = point => {
|
||||||
|
const dra = ((point[0] - centerRa) % 360 + 540) % 360 - 180;
|
||||||
|
return [dra * Math.cos(centerDec * DEG), point[1] - centerDec];
|
||||||
|
};
|
||||||
|
const points = constellation.lines.flat().map(flatten);
|
||||||
|
const xs = points.map(p => p[0]), ys = points.map(p => p[1]);
|
||||||
|
const minX = Math.min(...xs), maxX = Math.max(...xs);
|
||||||
|
const minY = Math.min(...ys), maxY = Math.max(...ys);
|
||||||
|
const scale = Math.min(
|
||||||
|
W * 0.34 / Math.max(1, maxX - minX),
|
||||||
|
horizonPx * 0.48 / Math.max(1, maxY - minY)
|
||||||
|
);
|
||||||
|
const midX = (minX + maxX) / 2, midY = (minY + maxY) / 2;
|
||||||
|
const screenX = W / 2, screenY = horizonPx * 0.42;
|
||||||
|
return point => {
|
||||||
|
const p = flatten(point);
|
||||||
|
return { x: screenX + (p[0] - midX) * scale,
|
||||||
|
y: screenY - (p[1] - midY) * scale };
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
/* Figuras convencionais dos 12 signos zodiacais, ancoradas em RA/Dec J2000.
|
/* Figuras convencionais dos 12 signos zodiacais, ancoradas em RA/Dec J2000.
|
||||||
Arte, linhas e estrelas reais ficam sobrepostas nesta ordem. */
|
Arte, linhas e estrelas reais ficam sobrepostas nesta ordem. */
|
||||||
function drawConstellations(c, lst, W, H, horizonPx) {
|
function drawConstellations(c, lst, W, H, horizonPx) {
|
||||||
if (!showConstellations || typeof CONSTELLATIONS === 'undefined') return;
|
if (!showConstellations || typeof CONSTELLATIONS === 'undefined') return;
|
||||||
const rankAlpha = [0, 0.52, 0.38, 0.25];
|
const rankAlpha = [0, 0.52, 0.38, 0.25];
|
||||||
const rankWidth = [0, 1.35, 1.05, 0.82];
|
const rankWidth = [0, 1.35, 1.05, 0.82];
|
||||||
|
const preview = constellationPreviewId
|
||||||
|
? CONSTELLATIONS.find(item => item.id === constellationPreviewId)
|
||||||
|
: null;
|
||||||
|
const visible = preview ? [preview] : CONSTELLATIONS;
|
||||||
|
const previewProjector = preview
|
||||||
|
? makeConstellationPreviewProjector(preview, W, horizonPx)
|
||||||
|
: null;
|
||||||
|
const projectPoint = point => {
|
||||||
|
if (previewProjector) return previewProjector(point);
|
||||||
|
const aa = altAz(point[0], point[1], lst);
|
||||||
|
return skyToScreen(aa.alt, aa.az, W, horizonPx);
|
||||||
|
};
|
||||||
|
|
||||||
c.save();
|
c.save();
|
||||||
c.lineCap = 'round';
|
c.lineCap = 'round';
|
||||||
c.lineJoin = 'round';
|
c.lineJoin = 'round';
|
||||||
c.shadowColor = 'rgba(60,185,255,0.65)';
|
c.shadowColor = 'rgba(60,185,255,0.65)';
|
||||||
c.shadowBlur = 7;
|
c.shadowBlur = 7;
|
||||||
for (const constellation of CONSTELLATIONS) {
|
for (const constellation of visible) {
|
||||||
drawConstellationArt(c, constellation, lst, W, horizonPx);
|
drawConstellationArt(c, constellation, lst, W, horizonPx, previewProjector);
|
||||||
}
|
}
|
||||||
for (const constellation of CONSTELLATIONS) {
|
for (const constellation of visible) {
|
||||||
const rank = Math.max(1, Math.min(3, constellation.rank || 3));
|
const rank = Math.max(1, Math.min(3, constellation.rank || 3));
|
||||||
c.strokeStyle = `rgba(105,205,255,${rankAlpha[rank]})`;
|
c.strokeStyle = `rgba(105,205,255,${preview ? 0.82 : rankAlpha[rank]})`;
|
||||||
c.lineWidth = rankWidth[rank];
|
c.lineWidth = preview ? 2.1 : rankWidth[rank];
|
||||||
for (const line of constellation.lines) {
|
for (const line of constellation.lines) {
|
||||||
c.beginPath();
|
c.beginPath();
|
||||||
let previous = null;
|
let previous = null;
|
||||||
for (const point of line) {
|
for (const point of line) {
|
||||||
const aa = altAz(point[0], point[1], lst);
|
const sc = projectPoint(point);
|
||||||
const sc = skyToScreen(aa.alt, aa.az, W, horizonPx);
|
|
||||||
if (!sc) {
|
if (!sc) {
|
||||||
previous = null;
|
previous = null;
|
||||||
continue;
|
continue;
|
||||||
|
|
@ -1583,6 +1623,22 @@ function drawConstellations(c, lst, W, H, horizonPx) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (preview) {
|
||||||
|
const seen = new Set();
|
||||||
|
c.shadowColor = 'rgba(160,225,255,0.95)';
|
||||||
|
c.shadowBlur = 9;
|
||||||
|
c.fillStyle = 'rgba(225,245,255,0.96)';
|
||||||
|
for (const point of preview.lines.flat()) {
|
||||||
|
const key = point.join(',');
|
||||||
|
if (seen.has(key)) continue;
|
||||||
|
seen.add(key);
|
||||||
|
const sc = projectPoint(point);
|
||||||
|
c.beginPath();
|
||||||
|
c.arc(sc.x, sc.y, Math.max(2.4, H * 0.0018), 0, Math.PI * 2);
|
||||||
|
c.fill();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Todos os signos recebem nome; colisões na tela ainda são evitadas. */
|
/* Todos os signos recebem nome; colisões na tela ainda são evitadas. */
|
||||||
c.shadowBlur = 5;
|
c.shadowBlur = 5;
|
||||||
c.font = `${Math.max(10, Math.round(H * 0.0105))}px ui-monospace, monospace`;
|
c.font = `${Math.max(10, Math.round(H * 0.0105))}px ui-monospace, monospace`;
|
||||||
|
|
@ -1590,10 +1646,9 @@ function drawConstellations(c, lst, W, H, horizonPx) {
|
||||||
c.textBaseline = 'middle';
|
c.textBaseline = 'middle';
|
||||||
c.fillStyle = 'rgba(170,225,255,0.66)';
|
c.fillStyle = 'rgba(170,225,255,0.66)';
|
||||||
const occupied = [];
|
const occupied = [];
|
||||||
for (const constellation of CONSTELLATIONS) {
|
for (const constellation of visible) {
|
||||||
if (!constellation.label) continue;
|
if (!constellation.label) continue;
|
||||||
const aa = altAz(constellation.label[0], constellation.label[1], lst);
|
const sc = projectPoint(constellation.label);
|
||||||
const sc = skyToScreen(aa.alt, aa.az, W, horizonPx);
|
|
||||||
if (!sc || sc.y < 24 || sc.y > horizonPx - 18) continue;
|
if (!sc || sc.y < 24 || sc.y > horizonPx - 18) continue;
|
||||||
const width = c.measureText(constellation.name).width + 14;
|
const width = c.measureText(constellation.name).width + 14;
|
||||||
const box = { x1: sc.x - width / 2, y1: sc.y - 9,
|
const box = { x1: sc.x - width / 2, y1: sc.y - 9,
|
||||||
|
|
@ -1601,7 +1656,7 @@ function drawConstellations(c, lst, W, H, horizonPx) {
|
||||||
if (occupied.some(o => box.x1 < o.x2 && box.x2 > o.x1 &&
|
if (occupied.some(o => box.x1 < o.x2 && box.x2 > o.x1 &&
|
||||||
box.y1 < o.y2 && box.y2 > o.y1)) continue;
|
box.y1 < o.y2 && box.y2 > o.y1)) continue;
|
||||||
occupied.push(box);
|
occupied.push(box);
|
||||||
c.fillText(constellation.name, sc.x, sc.y);
|
c.fillText(preview ? `Prévia: ${constellation.name}` : constellation.name, sc.x, sc.y);
|
||||||
}
|
}
|
||||||
c.restore();
|
c.restore();
|
||||||
}
|
}
|
||||||
|
|
@ -1627,6 +1682,23 @@ let constellationsFileVal = null;
|
||||||
.finally(() => setTimeout(pollConstellationsFile, 800));
|
.finally(() => setTimeout(pollConstellationsFile, 800));
|
||||||
})();
|
})();
|
||||||
|
|
||||||
|
/* Modo de inspeção temporário: centraliza um único signo sem alterar suas
|
||||||
|
coordenadas internas. Controlado por preview-constellation.sh. */
|
||||||
|
let constellationPreviewFileVal = null;
|
||||||
|
(function pollConstellationPreviewFile() {
|
||||||
|
fetch('file:///tmp/skeledance-constellation-preview?t=' + Date.now())
|
||||||
|
.then(r => r.text())
|
||||||
|
.then(t => {
|
||||||
|
const v = t.trim();
|
||||||
|
if (v === constellationPreviewFileVal) return;
|
||||||
|
constellationPreviewFileVal = v;
|
||||||
|
constellationPreviewId = CONSTELLATIONS.some(item => item.id === v) ? v : null;
|
||||||
|
projectSky();
|
||||||
|
})
|
||||||
|
.catch(() => {})
|
||||||
|
.finally(() => setTimeout(pollConstellationPreviewFile, 800));
|
||||||
|
})();
|
||||||
|
|
||||||
/* ── Passo de projeção: recalcula posições de tela (a cada 30s o céu gira
|
/* ── Passo de projeção: recalcula posições de tela (a cada 30s o céu gira
|
||||||
~0.125°, imperceptível). Camada estática (Via Láctea + estrelas fracas)
|
~0.125°, imperceptível). Camada estática (Via Láctea + estrelas fracas)
|
||||||
é pré-renderizada fora da tela; só as brilhantes cintilam por frame.
|
é pré-renderizada fora da tela; só as brilhantes cintilam por frame.
|
||||||
|
|
|
||||||
12
preview-constellation.sh
Executable file
12
preview-constellation.sh
Executable file
|
|
@ -0,0 +1,12 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
STATE_FILE=/tmp/skeledance-constellation-preview
|
||||||
|
SIGN=${1:-Vir}
|
||||||
|
|
||||||
|
if [ "$SIGN" = "off" ]; then
|
||||||
|
printf 'off\n' > "$STATE_FILE"
|
||||||
|
printf 'Prévia de constelação desativada\n'
|
||||||
|
else
|
||||||
|
printf '%s\n' "$SIGN" > "$STATE_FILE"
|
||||||
|
printf 'Prévia fixa: %s\n' "$SIGN"
|
||||||
|
fi
|
||||||
Loading…
Add table
Add a link
Reference in a new issue