Align constellation art with mirrored sky charts

This commit is contained in:
vini 2026-07-19 14:35:51 -03:00
parent 4e01c768c9
commit 6843e1fc33

View file

@ -1470,20 +1470,35 @@ function constellationArtTransform(source, target) {
.map(v => v / source.length); .map(v => v / source.length);
const qc = target.reduce((p, v) => [p[0] + v.x, p[1] + v.y], [0, 0]) const qc = target.reduce((p, v) => [p[0] + v.x, p[1] + v.y], [0, 0])
.map(v => v / target.length); .map(v => v / target.length);
let dot = 0, cross = 0, energy = 0; let dot = 0, cross = 0, mirrorA = 0, mirrorB = 0, energy = 0;
for (let i = 0; i < source.length; i++) { for (let i = 0; i < source.length; i++) {
const px = source[i][0] - pc[0], py = source[i][1] - pc[1]; const px = source[i][0] - pc[0], py = source[i][1] - pc[1];
const qx = target[i].x - qc[0], qy = target[i].y - qc[1]; const qx = target[i].x - qc[0], qy = target[i].y - qc[1];
dot += px * qx + py * qy; dot += px * qx + py * qy;
cross += px * qy - py * qx; cross += px * qy - py * qx;
mirrorA += px * qx - py * qy;
mirrorB += py * qx + px * qy;
energy += px * px + py * py; energy += px * px + py * py;
} }
if (energy < 1e-6) return null; if (energy < 1e-6) return null;
const a = dot / energy; const candidate = (a, b, c, d) => {
const b = cross / energy; const e = qc[0] - a * pc[0] - c * pc[1];
const e = qc[0] - a * pc[0] + b * pc[1]; const f = qc[1] - b * pc[0] - d * pc[1];
const f = qc[1] - b * pc[0] - a * pc[1]; const matrix = [a, b, c, d, e, f];
return [a, b, -b, a, e, f]; const error = source.reduce((sum, p, i) => {
const dx = a * p[0] + c * p[1] + e - target[i].x;
const dy = b * p[0] + d * p[1] + f - target[i].y;
return sum + dx * dx + dy * dy;
}, 0);
return { matrix, error };
};
const rotate = candidate(dot / energy, cross / energy,
-cross / energy, dot / energy);
/* Ao observar a esfera por dentro, várias cartas precisam inverter a
orientação leste/oeste. Esta alternativa inclui a reflexão sem shear. */
const reflect = candidate(mirrorA / energy, mirrorB / energy,
mirrorB / energy, -mirrorA / energy);
return (reflect.error < rotate.error ? reflect : rotate).matrix;
} }
function drawConstellationArt(c, constellation, lst, W, horizonPx, previewProjector) { function drawConstellationArt(c, constellation, lst, W, horizonPx, previewProjector) {