primo commit

This commit is contained in:
2026-08-29 00:34:41 +02:00
parent d65038a4e7
commit 5412ff621d
10 changed files with 2308 additions and 2 deletions
+380
View File
@@ -0,0 +1,380 @@
<!DOCTYPE html>
<html lang="it">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Alpha Centauri</title>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body { overflow: hidden; background: #000; }
canvas { display: block; }
#info {
position: fixed;
top: 10px;
left: 10px;
color: rgba(255,255,255,0.5);
font-family: monospace;
font-size: 12px;
pointer-events: none;
}
</style>
</head>
<body>
<canvas id="alpha"></canvas>
<div id="info">Alpha Centauri — Simulazione</div>
<script>
// === SISTEMA ALPHA CENTAURI — JavaScript ===
let tempo = 0;
// Stelle del sistema triplo
const stelle = [
{
nome: "Alpha Cen A",
tipo: "G2V",
colore: "#fff4e0",
raggio: 18,
asseMaggiore: 175,
eccentricita: 0.517,
velocita: 0.0125,
angoloIniziale: 0,
massa: "1.1 M☉",
coloreTesto: "rgba(255,244,224,0.8)",
},
{
nome: "Alpha Cen B",
tipo: "K1V",
colore: "#ffcc66",
raggio: 14,
asseMaggiore: 215,
eccentricita: 0.517,
velocita: 0.0125,
angoloIniziale: Math.PI,
massa: "0.907 M☉",
coloreTesto: "rgba(255,204,102,0.8)",
},
{
nome: "Proxima Cen",
tipo: "M5.5Ve",
colore: "#cc4422",
raggio: 10,
asseMaggiore: 650,
eccentricita: 0.509,
velocita: 0.00091,
angoloIniziale: Math.PI * 0.7,
massa: "0.122 M☉",
coloreTesto: "rgba(255,150,100,0.8)",
},
];
// Pianeti: [stella_ospite, dati_pianeta]
const pianeti = [
// === SU ALPHA CENTAURI B ===
[
1,
{
nome: "Alpha Cen Ab",
raggio: 7,
asseMaggiore: 55,
eccentricita: 0.02,
velocita: 1.63,
colore: "#5a8ab5",
angoli: [0],
dettagli: [
{ tipo: "oceano", colore: "#3a6a9a", x: -2, y: -1, r: 3 },
{ tipo: "continente", colore: "#4a8a4a", x: 2, y: 1, r: 2.5 },
{ tipo: "nuvola", colore: "rgba(255,255,255,0.25)", x: 0, y: -2, r: 1.5 },
],
},
],
// === SU PROXIMA CENTAURI ===
[
2,
{
nome: "Proxima d",
raggio: 3,
asseMaggiore: 30,
eccentricita: 0.04,
velocita: 2.094,
colore: "#6b7b8d",
angoli: [0],
dettagli: [
{ tipo: "superficie", colore: "#5a6a7a", x: -1, y: -1, r: 1.5 },
{ tipo: "superficie", colore: "#7a8a9a", x: 1, y: 1, r: 1 },
],
},
],
[
2,
{
nome: "Proxima b",
raggio: 8,
asseMaggiore: 50,
eccentricita: 0.11,
velocita: 0.959,
colore: "#4a90d9",
angoli: [0],
dettagli: [
{ tipo: "oceano", colore: "#2a5a8a", x: -3, y: -2, r: 4 },
{ tipo: "continente", colore: "#3a7a3a", x: 2, y: 1, r: 3 },
{ tipo: "continente", colore: "#4a8a4a", x: -1, y: 3, r: 2.5 },
{ tipo: "nuvola", colore: "rgba(255,255,255,0.3)", x: 0, y: -3, r: 2 },
],
},
],
[
2,
{
nome: "Proxima c",
raggio: 14,
asseMaggiore: 200,
eccentricita: 0.04,
velocita: 0.00559,
colore: "#c8944a",
angoli: [0],
raggiMondi: [35, 55, 75],
coloriMondi: ["#d4c4a4", "#b4a484", "#948464"],
nomiMondi: ["Candidate-m1", "Candidate-m2", "Candidate-m3"],
velocitaMondi: [8, 4, 2.5],
anelli: true,
dettagli: [
{ tipo: "banda", colore: "#a8743a", y: -4 },
{ tipo: "banda", colore: "#b8844a", y: 0 },
{ tipo: "banda", colore: "#98642a", y: 4 },
],
},
],
];
const canvas = document.getElementById("alpha");
const ctx = canvas.getContext("2d");
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
// Stelle di sfondo
const stelleSfondo = [];
for (let i = 0; i < 300; i++) {
stelleSfondo.push({
x: Math.random() * canvas.width,
y: Math.random() * canvas.height,
r: Math.random() * 1.2,
a: Math.random() * 0.5 + 0.2,
});
}
function disegnaStelle() {
stelleSfondo.forEach((s) => {
ctx.fillStyle = `rgba(255,255,255,${s.a})`;
ctx.beginPath();
ctx.arc(s.x, s.y, s.r, 0, Math.PI * 2);
ctx.fill();
});
}
function disegnaStella(stella, x, y) {
// Glow differenziato per tipo
if (stella.tipo === "G2V") {
const g = ctx.createRadialGradient(x, y, stella.raggio * 0.5, x, y, stella.raggio * 5);
g.addColorStop(0, "#fff8e0");
g.addColorStop(0.2, "#ffdd44");
g.addColorStop(0.5, "rgba(255,221,68,0.2)");
g.addColorStop(1, "rgba(255,200,0,0)");
ctx.fillStyle = g;
} else if (stella.tipo === "K1V") {
const g = ctx.createRadialGradient(x, y, stella.raggio * 0.5, x, y, stella.raggio * 4);
g.addColorStop(0, "#ffe0a0");
g.addColorStop(0.2, "#ffaa44");
g.addColorStop(0.5, "rgba(255,170,68,0.2)");
g.addColorStop(1, "rgba(255,150,0,0)");
ctx.fillStyle = g;
} else {
const g = ctx.createRadialGradient(x, y, stella.raggio * 0.3, x, y, stella.raggio * 4);
g.addColorStop(0, "rgba(255,100,50,0.8)");
g.addColorStop(0.2, "rgba(200,50,20,0.4)");
g.addColorStop(0.5, "rgba(150,30,10,0.1)");
g.addColorStop(1, "rgba(100,20,5,0)");
ctx.fillStyle = g;
}
ctx.beginPath();
ctx.arc(x, y, stella.raggio * 5, 0, Math.PI * 2);
ctx.fill();
ctx.fillStyle = stella.colore;
ctx.shadowColor = stella.colore;
ctx.shadowBlur = stella.raggio * 2;
ctx.beginPath();
ctx.arc(x, y, stella.raggio, 0, Math.PI * 2);
ctx.fill();
ctx.shadowBlur = 0;
}
function disegnaAnelli(cx, cy, raggio) {
ctx.strokeStyle = "rgba(210, 180, 140, 0.4)";
ctx.lineWidth = 3;
ctx.beginPath();
ctx.ellipse(cx, cy, raggio * 2.0, raggio * 0.5, 0, 0, Math.PI * 2);
ctx.stroke();
ctx.strokeStyle = "rgba(190, 160, 120, 0.25)";
ctx.lineWidth = 2;
ctx.beginPath();
ctx.ellipse(cx, cy, raggio * 2.4, raggio * 0.6, 0, 0, Math.PI * 2);
ctx.stroke();
}
function disegnaOrbita(cx, cy, a, b) {
ctx.strokeStyle = "rgba(255,255,255,0.06)";
ctx.lineWidth = 1;
ctx.setLineDash([3, 3]);
ctx.beginPath();
ctx.ellipse(cx, cy, a, b, 0, 0, Math.PI * 2);
ctx.stroke();
ctx.setLineDash([]);
}
function disegnaDettaglioPianeta(dettagli, x, y, raggio) {
dettagli.forEach((d) => {
ctx.fillStyle = d.colore;
ctx.beginPath();
ctx.arc(x + (d.x || 0), y + (d.y || 0), d.r || 1, 0, Math.PI * 2);
ctx.fill();
});
}
function disegnaCorpo(c, stellaX, stellaY, angolo) {
const a = c.asseMaggiore;
const b = a * Math.sqrt(1 - c.eccentricita * c.eccentricita);
const x = stellaX + a * Math.cos(angolo);
const y = stellaY + b * Math.sin(angolo);
disegnaOrbita(stellaX, stellaY, a, b);
if (c.anelli) {
disegnaAnelli(x, y, c.raggio);
}
ctx.fillStyle = c.colore;
ctx.beginPath();
ctx.arc(x, y, c.raggio, 0, Math.PI * 2);
ctx.fill();
if (c.dettagli) {
disegnaDettaglioPianeta(c.dettagli, x, y, c.raggio);
}
if (c.raggiMondi && c.coloriMondi) {
const coloriM = c.coloriMondi;
c.raggiMondi.forEach((raggioM, i) => {
const velocitaM = c.velocitaMondi?.[i] ?? 3;
const angoloM = angolo + (c.angoli?.[i] || 0) + tempo * velocitaM;
const mx = stellaX + Math.cos(angoloM) * raggioM;
const my = stellaY + Math.sin(angoloM) * raggioM;
ctx.strokeStyle = "rgba(255,255,255,0.04)";
ctx.lineWidth = 0.5;
ctx.setLineDash([2, 2]);
ctx.beginPath();
ctx.arc(stellaX, stellaY, raggioM, 0, Math.PI * 2);
ctx.stroke();
ctx.setLineDash([]);
ctx.fillStyle = coloriM[i];
ctx.beginPath();
ctx.arc(mx, my, 2, 0, Math.PI * 2);
ctx.fill();
ctx.fillStyle = "rgba(255,255,255,0.3)";
ctx.font = "7px monospace";
ctx.fillText(c.nomiMondi?.[i] || "", mx + 3, my - 3);
});
}
ctx.fillStyle = "rgba(255,255,255,0.6)";
ctx.font = "11px monospace";
ctx.fillText(c.nome, x + c.raggio + 5, y - 5);
}
function disegnaLineaTraStelle(x1, y1, x2, y2) {
ctx.strokeStyle = "rgba(255,255,255,0.03)";
ctx.lineWidth = 1;
ctx.setLineDash([5, 10]);
ctx.beginPath();
ctx.moveTo(x1, y1);
ctx.lineTo(x2, y2);
ctx.stroke();
ctx.setLineDash([]);
}
function animazione() {
ctx.fillStyle = "#000010";
ctx.fillRect(0, 0, canvas.width, canvas.height);
disegnaStelle();
const cx = canvas.width / 2;
const cy = canvas.height / 2;
// Calcola posizioni stelle relative al baricentro
const posizioniStelle = [];
stelle.forEach((s) => {
const a = s.asseMaggiore;
const b = a * Math.sqrt(1 - s.eccentricita * s.eccentricita);
const angolo = tempo * s.velocita + s.angoloIniziale;
const x = cx + a * Math.cos(angolo);
const y = cy + b * Math.sin(angolo);
posizioniStelle.push({ x, y });
});
// Calcola baricentro del triangolo formato dalle tre stelle
const baricentroX = (posizioniStelle[0].x + posizioniStelle[1].x + posizioniStelle[2].x) / 3;
const baricentroY = (posizioniStelle[0].y + posizioniStelle[1].y + posizioniStelle[2].y) / 3;
// Offset per centrare tutto il sistema sul canvas
const offsetX = baricentroX - cx;
const offsetY = baricentroY - cy;
// Linea tra Alpha Cen A e B
disegnaLineaTraStelle(
posizioniStelle[0].x - offsetX,
posizioniStelle[0].y - offsetY,
posizioniStelle[1].x - offsetX,
posizioniStelle[1].y - offsetY
);
// Disegna stelle
stelle.forEach((s, i) => {
disegnaStella(s, posizioniStelle[i].x - offsetX, posizioniStelle[i].y - offsetY);
});
// Pianeti
pianeti.forEach(([stellaIdx, p]) => {
const angolo = tempo * p.velocita;
disegnaCorpo(p, posizioniStelle[stellaIdx].x - offsetX, posizioniStelle[stellaIdx].y - offsetY, angolo);
});
ctx.fillStyle = "rgba(255,255,255,0.4)";
ctx.font = "10px monospace";
ctx.fillText(
"Alpha Centauri — Sistema triplo (4.37 anni luce) | A+B orbita: 79.9 anni | Proxima orbita: 547 anni",
10,
canvas.height - 10
);
tempo += 0.005;
requestAnimationFrame(animazione);
}
window.addEventListener("resize", () => {
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
});
animazione();
</script>
</body>
</html>
+445
View File
@@ -0,0 +1,445 @@
// === SISTEMA ALPHA CENTAURI — Simulazione TypeScript ===
// Sistema triplo: Alpha Cen A + Alpha Cen B + Proxima Centauri
// Distanza totale: 4.37 anni luce dalla Terra
interface CorpoCeleste {
nome: string;
raggio: number;
asseMaggiore: number;
eccentricita: number;
velocita: number;
colore: string;
angoli?: number[];
raggiMondi?: number[];
coloriMondi?: string[];
nomiMondi?: string[];
velocitaMondi?: number[];
anelli?: boolean;
dettagli?: Dettaglio[];
}
interface Dettaglio {
tipo: string;
colore: string;
x?: number;
y?: number;
r?: number;
}
const canvas = document.getElementById("alpha") as HTMLCanvasElement;
const ctx = canvas.getContext("2d")!;
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
// === DATI ASTROFISICI ===
// Alpha Centauri A (Rigil Kentaurus): G2V, 1.1 M☉, 1.221 R☉
// Alpha Centauri B (Toliman): K1V, 0.907 M☉, 0.863 R☉
// Orbita A-B: a=23.4 UA, e=0.517, P=79.91 anni
// Proxima Centauri: M5.5Ve, 0.122 M☉
// Orbita Proxima: a~125 UA, e~0.509, P~547 anni
// === PIANETI CONFERMATI ===
// Alpha Cen Bb: 0.011 M⊕, 3.236 giorni, 0.064 UA (controverso)
// Alpha Cen Ab: 1.1 M⊕, 224 giorni, ~1.25 UA (confermato HARPS 2012)
// Proxima d: 0.26 M⊕, 5.122 giorni, 0.029 UA (2022)
// Proxima b: 1.07 M⊕, 11.186 giorni, 0.0485 UA (2016)
// Proxima c: ~7 M⊕, ~5.28 anni, ~1.489 UA (2019)
let tempo = 0;
// Stelle del sistema triplo
interface Stella {
nome: string;
tipo: string;
colore: string;
raggio: number;
asseMaggiore: number;
eccentricita: number;
velocita: number;
angoloIniziale: number;
massa: string;
coloreTesto: string;
}
const stelle: Stella[] = [
{
nome: "Alpha Cen A",
tipo: "G2V",
colore: "#fff4e0",
raggio: 18,
asseMaggiore: 175,
eccentricita: 0.517,
velocita: 0.0125, // P=79.91 anni → scala
angoloIniziale: 0,
massa: "1.1 M☉",
coloreTesto: "rgba(255,244,224,0.8)",
},
{
nome: "Alpha Cen B",
tipo: "K1V",
colore: "#ffcc66",
raggio: 14,
asseMaggiore: 215,
eccentricita: 0.517,
velocita: 0.0125,
angoloIniziale: Math.PI, // opposto ad A
massa: "0.907 M☉",
coloreTesto: "rgba(255,204,102,0.8)",
},
{
nome: "Proxima Cen",
tipo: "M5.5Ve",
colore: "#cc4422",
raggio: 10,
asseMaggiore: 650,
eccentricita: 0.509,
velocita: 0.00091, // P=547 anni → scala
angoloIniziale: Math.PI * 0.7,
massa: "0.122 M☉",
coloreTesto: "rgba(255,150,100,0.8)",
},
];
// Pianeti: [stella_ospite, dati_pianeta]
type Pianeta = [number, CorpoCeleste];
const pianeti: Pianeta[] = [
// === SU ALPHA CENTAURI B ===
[
1, // Alpha Cen B
{
nome: "Alpha Cen Ab",
raggio: 7,
asseMaggiore: 55,
eccentricita: 0.02,
velocita: 1.63, // 224 giorni → scala: 10s orbita
colore: "#5a8ab5",
angoli: [0],
dettagli: [
{ tipo: "oceano", colore: "#3a6a9a", x: -2, y: -1, r: 3 },
{ tipo: "continente", colore: "#4a8a4a", x: 2, y: 1, r: 2.5 },
{ tipo: "nuvola", colore: "rgba(255,255,255,0.25)", x: 0, y: -2, r: 1.5 },
],
},
],
// === SU PROXIMA CENTAURI ===
[
2, // Proxima Centauri
{
nome: "Proxima d",
raggio: 3,
asseMaggiore: 30,
eccentricita: 0.04,
velocita: 2.094, // 10 secondi orbita
colore: "#6b7b8d",
angoli: [0],
dettagli: [
{ tipo: "superficie", colore: "#5a6a7a", x: -1, y: -1, r: 1.5 },
{ tipo: "superficie", colore: "#7a8a9a", x: 1, y: 1, r: 1 },
],
},
],
[
2,
{
nome: "Proxima b",
raggio: 8,
asseMaggiore: 50,
eccentricita: 0.11,
velocita: 0.959, // ~22 secondi orbita
colore: "#4a90d9",
angoli: [0],
dettagli: [
{ tipo: "oceano", colore: "#2a5a8a", x: -3, y: -2, r: 4 },
{ tipo: "continente", colore: "#3a7a3a", x: 2, y: 1, r: 3 },
{ tipo: "continente", colore: "#4a8a4a", x: -1, y: 3, r: 2.5 },
{ tipo: "nuvola", colore: "rgba(255,255,255,0.3)", x: 0, y: -3, r: 2 },
],
},
],
[
2,
{
nome: "Proxima c",
raggio: 14,
asseMaggiore: 200,
eccentricita: 0.04,
velocita: 0.00559, // ~62 minuti orbita
colore: "#c8944a",
angoli: [0],
raggiMondi: [35, 55, 75],
coloriMondi: ["#d4c4a4", "#b4a484", "#948464"],
nomiMondi: ["Candidate-m1", "Candidate-m2", "Candidate-m3"],
velocitaMondi: [8, 4, 2.5],
anelli: true,
dettagli: [
{ tipo: "banda", colore: "#a8743a", y: -4 },
{ tipo: "banda", colore: "#b8844a", y: 0 },
{ tipo: "banda", colore: "#98642a", y: 4 },
],
},
],
];
// === FUNZIONI DI DISEGNO ===
function disegnaStelle() {
stelleSfondo.forEach((s) => {
ctx.fillStyle = `rgba(255,255,255,${s.a})`;
ctx.beginPath();
ctx.arc(s.x, s.y, s.r, 0, Math.PI * 2);
ctx.fill();
});
}
function disegnaStella(stella: Stella, x: number, y: number) {
// Glow
const grad = ctx.createRadialGradient(x, y, stella.raggio * 0.3, x, y, stella.raggio * 4);
grad.addColorStop(0, stella.colore);
grad.addColorStop(0.3, stella.colore.replace(")", ",0.5)").replace("#", "rgba(").replace(/(..)(..)(..)/, (m, r, g, b) => {
const red = parseInt(r, 16);
const green = parseInt(g, 16);
const blue = parseInt(b, 16);
return `rgba(${red},${green},${blue}`;
}) + ",0.3)");
grad.addColorStop(1, "rgba(0,0,0,0)");
// Glow semplificato per tipo di stella
if (stella.tipo === "G2V") {
// Gialla come il Sole
const g = ctx.createRadialGradient(x, y, stella.raggio * 0.5, x, y, stella.raggio * 5);
g.addColorStop(0, "#fff8e0");
g.addColorStop(0.2, "#ffdd44");
g.addColorStop(0.5, "rgba(255,221,68,0.2)");
g.addColorStop(1, "rgba(255,200,0,0)");
ctx.fillStyle = g;
} else if (stella.tipo === "K1V") {
// Arancione
const g = ctx.createRadialGradient(x, y, stella.raggio * 0.5, x, y, stella.raggio * 4);
g.addColorStop(0, "#ffe0a0");
g.addColorStop(0.2, "#ffaa44");
g.addColorStop(0.5, "rgba(255,170,68,0.2)");
g.addColorStop(1, "rgba(255,150,0,0)");
ctx.fillStyle = g;
} else {
// Rossa (Proxima)
const g = ctx.createRadialGradient(x, y, stella.raggio * 0.3, x, y, stella.raggio * 4);
g.addColorStop(0, "rgba(255,100,50,0.8)");
g.addColorStop(0.2, "rgba(200,50,20,0.4)");
g.addColorStop(0.5, "rgba(150,30,10,0.1)");
g.addColorStop(1, "rgba(100,20,5,0)");
ctx.fillStyle = g;
}
ctx.beginPath();
ctx.arc(x, y, stella.raggio * 5, 0, Math.PI * 2);
ctx.fill();
// Stella
ctx.fillStyle = stella.colore;
ctx.shadowColor = stella.colore;
ctx.shadowBlur = stella.raggio * 2;
ctx.beginPath();
ctx.arc(x, y, stella.raggio, 0, Math.PI * 2);
ctx.fill();
ctx.shadowBlur = 0;
}
function disegnaAnelli(cx: number, cy: number, raggio: number) {
ctx.strokeStyle = "rgba(210, 180, 140, 0.4)";
ctx.lineWidth = 3;
ctx.beginPath();
ctx.ellipse(cx, cy, raggio * 2.0, raggio * 0.5, 0, 0, Math.PI * 2);
ctx.stroke();
ctx.strokeStyle = "rgba(190, 160, 120, 0.25)";
ctx.lineWidth = 2;
ctx.beginPath();
ctx.ellipse(cx, cy, raggio * 2.4, raggio * 0.6, 0, 0, Math.PI * 2);
ctx.stroke();
}
function disegnaOrbita(cx: number, cy: number, a: number, b: number) {
ctx.strokeStyle = "rgba(255,255,255,0.06)";
ctx.lineWidth = 1;
ctx.setLineDash([3, 3]);
ctx.beginPath();
ctx.ellipse(cx, cy, a, b, 0, 0, Math.PI * 2);
ctx.stroke();
ctx.setLineDash([]);
}
function disegnaDettaglioPianeta(
dettagli: Dettaglio[],
x: number,
y: number,
raggio: number
) {
dettagli.forEach((d) => {
ctx.fillStyle = d.colore;
ctx.beginPath();
ctx.arc(x + (d.x || 0), y + (d.y || 0), d.r || 1, 0, Math.PI * 2);
ctx.fill();
});
}
function disegnaCorpo(
c: CorpoCeleste,
stellaX: number,
stellaY: number,
angolo: number
) {
const a = c.asseMaggiore;
const b = a * Math.sqrt(1 - c.eccentricita * c.eccentricita);
const x = stellaX + a * Math.cos(angolo);
const y = stellaY + b * Math.sin(angolo);
// Orbita
disegnaOrbita(stellaX, stellaY, a, b);
// Anelli
if (c.anelli) {
disegnaAnelli(x, y, c.raggio);
}
// Pianeta
ctx.fillStyle = c.colore;
ctx.beginPath();
ctx.arc(x, y, c.raggio, 0, Math.PI * 2);
ctx.fill();
// Dettagli
if (c.dettagli) {
disegnaDettaglioPianeta(c.dettagli, x, y, c.raggio);
}
// Lune
if (c.raggiMondi && c.coloriMondi) {
const coloriM = c.coloriMondi;
c.raggiMondi.forEach((raggioM, i) => {
const velocitaM = c.velocitaMondi?.[i] ?? 3;
const angoloM = angolo + (c.angoli?.[i] || 0) + tempo * velocitaM;
const mx = stellaX + Math.cos(angoloM) * raggioM;
const my = stellaY + Math.sin(angoloM) * raggioM;
ctx.strokeStyle = "rgba(255,255,255,0.04)";
ctx.lineWidth = 0.5;
ctx.setLineDash([2, 2]);
ctx.beginPath();
ctx.arc(stellaX, stellaY, raggioM, 0, Math.PI * 2);
ctx.stroke();
ctx.setLineDash([]);
ctx.fillStyle = coloriM[i];
ctx.beginPath();
ctx.arc(mx, my, 2, 0, Math.PI * 2);
ctx.fill();
ctx.fillStyle = "rgba(255,255,255,0.3)";
ctx.font = "7px monospace";
ctx.fillText(c.nomiMondi?.[i] || "", mx + 3, my - 3);
});
}
// Etichetta
ctx.fillStyle = "rgba(255,255,255,0.6)";
ctx.font = "11px monospace";
ctx.fillText(c.nome, x + c.raggio + 5, y - 5);
}
function disegnaLineaTraStelle(x1: number, y1: number, x2: number, y2: number) {
ctx.strokeStyle = "rgba(255,255,255,0.03)";
ctx.lineWidth = 1;
ctx.setLineDash([5, 10]);
ctx.beginPath();
ctx.moveTo(x1, y1);
ctx.lineTo(x2, y2);
ctx.stroke();
ctx.setLineDash([]);
}
function animazione() {
// Sfondo
ctx.fillStyle = "#000010";
ctx.fillRect(0, 0, canvas.width, canvas.height);
// Stelle
disegnaStelle();
// Centro del sistema (baricentro A-B)
const cx = canvas.width / 2;
const cy = canvas.height / 2;
// Calcola posizioni stelle relative al baricentro
const posizioniStelle: { x: number; y: number }[] = [];
stelle.forEach((s) => {
const a = s.asseMaggiore;
const b = a * Math.sqrt(1 - s.eccentricita * s.eccentricita);
const angolo = tempo * s.velocita + s.angoloIniziale;
const x = cx + a * Math.cos(angolo);
const y = cy + b * Math.sin(angolo);
posizioniStelle.push({ x, y });
});
// Calcola baricentro del triangolo formato dalle tre stelle
const baricentroX = (posizioniStelle[0].x + posizioniStelle[1].x + posizioniStelle[2].x) / 3;
const baricentroY = (posizioniStelle[0].y + posizioniStelle[1].y + posizioniStelle[2].y) / 3;
// Offset per centrare tutto il sistema sul canvas
const offsetX = baricentroX - cx;
const offsetY = baricentroY - cy;
// Linea tra Alpha Cen A e B
disegnaLineaTraStelle(
posizioniStelle[0].x - offsetX,
posizioniStelle[0].y - offsetY,
posizioniStelle[1].x - offsetX,
posizioniStelle[1].y - offsetY
);
// Disegna stelle
stelle.forEach((s, i) => {
disegnaStella(s, posizioniStelle[i].x - offsetX, posizioniStelle[i].y - offsetY);
});
// Pianeti
pianeti.forEach(([stellaIdx, p]) => {
const angolo = tempo * p.velocita;
disegnaCorpo(p, posizioniStella[stellaIdx].x - offsetX, posizioniStelle[stellaIdx].y - offsetY, angolo);
});
// Info
ctx.fillStyle = "rgba(255,255,255,0.4)";
ctx.font = "10px monospace";
ctx.fillText(
"Alpha Centauri — Sistema triplo (4.37 anni luce) | A+B orbita: 79.9 anni | Proxima orbita: 547 anni",
10,
canvas.height - 10
);
tempo += 0.005;
requestAnimationFrame(animazione);
}
// Stelle di sfondo
const stelleSfondo: { x: number; y: number; r: number; a: number }[] = [];
for (let i = 0; i < 300; i++) {
stelleSfondo.push({
x: Math.random() * canvas.width,
y: Math.random() * canvas.height,
r: Math.random() * 1.2,
a: Math.random() * 0.5 + 0.2,
});
}
// Resize
window.addEventListener("resize", () => {
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
});
// Avvia
animazione();
+24
View File
@@ -0,0 +1,24 @@
#!/bin/bash
# 1. Chromium in modalità app, senza vero fullscreen, dimensionato allo schermo
chromium index.html \
--window-position=0,0 --window-size=1920,1080 \
--disable-infobars --noerrdialogs --disable-session-crashed-bubble &
sleep 3
# 2. Trova l'ID finestra
WID=$(xdotool search --sync --onlyvisible --class "chromium" | head -1)
# 3. Riposiziona/ridimensiona per sicurezza
xdotool windowmove "$WID" 0 0
xdotool windowsize "$WID" 1920 1080
# 4. Marcala come finestra "desktop" e mandala in fondo allo stack
wmctrl -i -r "$WID" -b add,below
wmctrl -i -r "$WID" -b add,sticky,skip_taskbar,skip_pager
xprop -id "$WID" -f _NET_WM_WINDOW_TYPE 32a \
-set _NET_WM_WINDOW_TYPE _NET_WM_WINDOW_TYPE_DESKTOP
# 5. Forza nemo-desktop a ridisegnarsi sopra (necessario spesso su Mint)
killall nemo-desktop 2>/dev/null
nemo-desktop &
+455
View File
@@ -0,0 +1,455 @@
// === SISTEMA SOLARE - Simulazione TypeScript ===
interface CorpoCeleste {
nome: string;
raggio: number;
asseMaggiore: number;
eccentricita: number;
velocita: number;
colore: string;
angoli?: number[];
raggiMondi?: number[];
coloriMondi?: string[];
nomiMondi?: string[];
velocitaMondi?: number[];
anelli?: boolean;
}
const canvas = document.getElementById("sistema") as HTMLCanvasElement;
const ctx = canvas.getContext("2d")!;
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
// === COMETA DI HALLEY ===
// Periodo: ~75.3 anni | Eccentricità: 0.967 | Inclinazione: 162° (retrograda)
// Perielio: 0.586 UA | Afelio: 35.1 UA | Semiasse maggiore: 17.8 UA
interface ParticellaCoda {
distanza: number;
larghezza: number;
angoloOffset: number;
opacita: number;
}
interface Cometa {
nome: string;
asseMaggiore: number;
eccentricita: number;
velocita: number;
angoloIniziale: number;
angoloOrbita: number;
coda: ParticellaCoda[];
}
const cometaHalley: Cometa = {
nome: "Halley",
asseMaggiore: 267, // ~17.8 UA in scala
eccentricita: 0.967,
velocita: 0.00084, // P=75.3 anni → scala
angoloIniziale: Math.PI * 0.45, // posizione iniziale
angoloOrbita: Math.PI * 0.85, // rotazione ellisse (simula inclinazione)
coda: [], // particelle coda
};
// Inizializza particelle della coda
for (let i = 0; i < 60; i++) {
cometaHalley.coda.push({
distanza: i * 3,
larghezza: (60 - i) * 0.08,
angoloOffset: (Math.random() - 0.5) * 0.3,
opacita: 1 - i / 60,
});
}
const corpo: CorpoCeleste[] = [
{
nome: "Mercurio",
raggio: 4,
asseMaggiore: 60,
eccentricita: 0.206,
velocita: 4.15,
colore: "#b5b5b5",
},
{
nome: "Venere",
raggio: 7,
asseMaggiore: 90,
eccentricita: 0.007,
velocita: 1.62,
colore: "#e8cda0",
},
{
nome: "Terra",
raggio: 8,
asseMaggiore: 130,
eccentricita: 0.017,
velocita: 1.0,
colore: "#4a90d9",
angoli: [0],
raggiMondi: [18],
coloriMondi: ["#cccccc"],
nomiMondi: ["Luna"],
},
{
nome: "Marte",
raggio: 6,
asseMaggiore: 170,
eccentricita: 0.093,
velocita: 0.53,
colore: "#c1440e",
angoli: [0, 0.5],
raggiMondi: [12, 16],
coloriMondi: ["#aaaaaa", "#999999"],
nomiMondi: ["Fobos", "Deimos"],
},
{
nome: "Giove",
raggio: 20,
asseMaggiore: 240,
eccentricita: 0.049,
velocita: 0.084,
colore: "#c88b3a",
angoli: [0, 0.8, 1.6, 2.4],
raggiMondi: [30, 36, 42, 48],
coloriMondi: ["#dddddd", "#bbbbbb", "#aaaaaa", "#999999"],
nomiMondi: ["Io", "Europa", "Ganimede", "Callisto"],
},
{
nome: "Saturno",
raggio: 17,
asseMaggiore: 320,
eccentricita: 0.057,
velocita: 0.034,
colore: "#e8d191",
angoli: [0, 1.2, 2.4],
raggiMondi: [30, 38, 46],
coloriMondi: ["#cccccc", "#bbbbbb", "#aaaaaa"],
nomiMondi: ["Encelado", "Mimante", "Titano"],
anelli: true,
},
{
nome: "Urano",
raggio: 12,
asseMaggiore: 390,
eccentricita: 0.046,
velocita: 0.011,
colore: "#72b5c4",
angoli: [0, 1.5, 3.0],
raggiMondi: [20, 26, 32],
coloriMondi: ["#cccccc", "#bbbbbb", "#aaaaaa"],
nomiMondi: ["Miranda", "Ariel", "Titania"],
},
{
nome: "Nettuno",
raggio: 11,
asseMaggiore: 450,
eccentricita: 0.011,
velocita: 0.006,
colore: "#3f54ba",
angoli: [0, 1.0],
raggiMondi: [20, 26],
coloriMondi: ["#cccccc", "#bbbbbb"],
nomiMondi: ["Tritone", "Nereide"],
},
{
nome: "Plutone",
raggio: 5,
asseMaggiore: 590,
eccentricita: 0.244,
velocita: 0.004,
colore: "#a89f91",
angoli: [0, 1.2, 2.4, 3.6, 4.8],
raggiMondi: [25, 45, 65, 42, 52],
coloriMondi: ["#cccccc", "#bbbbbb", "#aaaaaa", "#999999", "#888888"],
nomiMondi: ["Caronte", "Nix", "Idra", "Cerbero", "Stige"],
velocitaMondi: [10, 2.5, 1.7, 3.2, 5.3],
},
];
let tempo = 0;
function disegnaSole(cx: number, cy: number) {
// Glow esterno
const grad = ctx.createRadialGradient(cx, cy, 10, cx, cy, 60);
grad.addColorStop(0, "#fff700");
grad.addColorStop(0.3, "#ff8c00");
grad.addColorStop(1, "rgba(255,140,0,0)");
ctx.fillStyle = grad;
ctx.beginPath();
ctx.arc(cx, cy, 60, 0, Math.PI * 2);
ctx.fill();
// Sole
ctx.fillStyle = "#ffcc00";
ctx.shadowColor = "#ff8800";
ctx.shadowBlur = 30;
ctx.beginPath();
ctx.arc(cx, cy, 25, 0, Math.PI * 2);
ctx.fill();
ctx.shadowBlur = 0;
}
function disegnaAnelliSaturno(cx: number, cy: number, raggio: number) {
ctx.strokeStyle = "rgba(210, 180, 140, 0.5)";
ctx.lineWidth = 4;
ctx.beginPath();
ctx.ellipse(cx, cy, raggio * 2.2, raggio * 0.6, 0, 0, Math.PI * 2);
ctx.stroke();
ctx.strokeStyle = "rgba(190, 160, 120, 0.3)";
ctx.lineWidth = 3;
ctx.beginPath();
ctx.ellipse(cx, cy, raggio * 2.6, raggio * 0.7, 0, 0, Math.PI * 2);
ctx.stroke();
}
function disegnaOrbita(cx: number, cy: number, a: number, b: number) {
ctx.strokeStyle = "rgba(255,255,255,0.08)";
ctx.lineWidth = 1;
ctx.beginPath();
ctx.ellipse(cx, cy, a, b, 0, 0, Math.PI * 2);
ctx.stroke();
}
function disegnaCorpo(c: CorpoCeleste, cx: number, cy: number, angolo: number) {
const a = c.asseMaggiore;
const b = a * Math.sqrt(1 - c.eccentricita * c.eccentricita);
const x = cx + a * Math.cos(angolo);
const y = cy + b * Math.sin(angolo);
// Disegna orbita ellittica
disegnaOrbita(cx, cy, a, b);
// Anelli di Saturno (dietro il pianeta)
if (c.anelli) {
disegnaAnelliSaturno(x, y, c.raggio);
}
// Pianeta
ctx.fillStyle = c.colore;
ctx.beginPath();
ctx.arc(x, y, c.raggio, 0, Math.PI * 2);
ctx.fill();
// Dettaglio Giove (fasce)
if (c.nome === "Giove") {
ctx.strokeStyle = "rgba(160, 100, 30, 0.4)";
ctx.lineWidth = 2;
for (let i = -2; i <= 2; i++) {
ctx.beginPath();
ctx.arc(x, y, c.raggio * 0.6, 0, Math.PI);
ctx.stroke();
}
// Grande macchia rossa
ctx.fillStyle = "rgba(200, 80, 50, 0.6)";
ctx.beginPath();
ctx.ellipse(x + 5, y + 3, 5, 3, 0, 0, Math.PI * 2);
ctx.fill();
}
// Dettaglio Terra (continenti)
if (c.nome === "Terra") {
ctx.fillStyle = "rgba(50, 150, 50, 0.5)";
ctx.beginPath();
ctx.arc(x - 2, y - 2, 3, 0, Math.PI * 2);
ctx.fill();
ctx.fillStyle = "rgba(50, 150, 50, 0.4)";
ctx.beginPath();
ctx.arc(x + 3, y + 2, 2, 0, Math.PI * 2);
ctx.fill();
}
// Disegna lune
if (c.raggiMondi && c.coloriMondi) {
const coloriM = c.coloriMondi;
c.raggiMondi.forEach((raggioM, i) => {
const velocitaM = c.velocitaMondi?.[i] ?? 3;
const angoloM = angolo + (c.angoli?.[i] || 0) + tempo * velocitaM;
const mx = x + Math.cos(angoloM) * raggioM;
const my = y + Math.sin(angoloM) * raggioM;
// Orbita luna (circolare per semplicità)
ctx.strokeStyle = "rgba(255,255,255,0.05)";
ctx.lineWidth = 0.5;
ctx.beginPath();
ctx.arc(x, y, raggioM, 0, Math.PI * 2);
ctx.stroke();
// Luna
ctx.fillStyle = coloriM[i];
ctx.beginPath();
ctx.arc(mx, my, 2, 0, Math.PI * 2);
ctx.fill();
// Etichetta
ctx.fillStyle = "rgba(255,255,255,0.4)";
ctx.font = "8px monospace";
ctx.fillText(c.nomiMondi?.[i] || "", mx + 4, my - 4);
});
}
// Etichetta pianeta
ctx.fillStyle = "rgba(255,255,255,0.6)";
ctx.font = "11px monospace";
ctx.fillText(c.nome, x + c.raggio + 5, y - 5);
}
function animazione() {
// Sfondo
ctx.fillStyle = "#000010";
ctx.fillRect(0, 0, canvas.width, canvas.height);
// Stelle
disegnaStelle();
const cx = canvas.width / 2;
const cy = canvas.height / 2;
// Sole
disegnaSole(cx, cy);
// Pianeti
corpo.forEach((c) => {
const angolo = tempo * c.velocita;
disegnaCorpo(c, cx, cy, angolo);
});
// === COMETA DI HALLEY ===
disegnaCometaHalley(cx, cy);
tempo += 0.005;
requestAnimationFrame(animazione);
}
// Stelle di sfondo (statiche)
const stelle: { x: number; y: number; r: number; a: number }[] = [];
for (let i = 0; i < 300; i++) {
stelle.push({
x: Math.random() * canvas.width,
y: Math.random() * canvas.height,
r: Math.random() * 1.2,
a: Math.random() * 0.5 + 0.2,
});
}
function disegnaCometaHalley(cx: number, cy: number) {
const c = cometaHalley;
const a = c.asseMaggiore;
const b = a * Math.sqrt(1 - c.eccentricita * c.eccentricita);
const angolo = tempo * c.velocita + c.angoloIniziale;
// Posizione cometa sull'orbita ellittica
const xOrbita = a * Math.cos(angolo);
const yOrbita = b * Math.sin(angolo);
// Ruota l'orbita per simulare inclinazione/retrograda
const cosA = Math.cos(c.angoloOrbita);
const sinA = Math.sin(c.angoloOrbita);
const x = cx + xOrbita * cosA - yOrbita * sinA;
const y = cy + xOrbita * sinA + yOrbita * cosA;
// Disegna orbita (ellisse ruotata)
ctx.save();
ctx.translate(cx, cy);
ctx.rotate(c.angoloOrbita);
ctx.strokeStyle = "rgba(150,200,255,0.12)";
ctx.lineWidth = 1;
ctx.setLineDash([4, 6]);
ctx.beginPath();
ctx.ellipse(0, 0, a, b, 0, Math.PI * 2);
ctx.stroke();
ctx.setLineDash([]);
ctx.restore();
// Distanza dal Sole per direzione coda
const dxSole = cx - x;
const dySole = cy - y;
const distSole = Math.sqrt(dxSole * dxSole + dySole * dySole);
const direzioneX = dxSole / distSole;
const direzioneY = dySole / distSole;
// Perielio: la cometa è più luminosa quando è vicina al Sole
const perielioDist = a * (1 - c.eccentricita); // ~9px in scala
const luminosita = Math.min(1, perielioDist / distSole);
// Coda di polvere (più larga, curva leggermente)
for (let i = 0; i < cometaHalley.coda.length; i++) {
const p = cometaHalley.coda[i];
const tailLen = p.distanza * (0.5 + luminosita * 1.5);
const tailW = p.larghezza * (0.5 + luminosita);
const angoloCoda = Math.atan2(direzioneY, direzioneX) + p.angoloOffset;
const px = x - Math.cos(angoloCoda) * tailLen;
const py = y - Math.sin(angoloCoda) * tailLen;
const alpha = p.opacita * luminosita * 0.6;
if (alpha > 0.01) {
ctx.fillStyle = `rgba(180,220,255,${alpha})`;
ctx.beginPath();
ctx.arc(px, py, tailW, 0, Math.PI * 2);
ctx.fill();
}
}
// Coda ionica (più sottile, dritta, blu)
const codaIonicaLunghezza = 40 + luminosita * 80;
const angoloIonico = Math.atan2(direzioneY, direzioneX);
for (let i = 0; i < 30; i++) {
const t = i / 30;
const ix = x - Math.cos(angoloIonico) * codaIonicaLunghezza * t;
const iy = y - Math.sin(angoloIonico) * codaIonicaLunghezza * t;
const alpha = (1 - t) * luminosita * 0.5;
if (alpha > 0.01) {
ctx.fillStyle = `rgba(100,150,255,${alpha})`;
ctx.beginPath();
ctx.arc(ix, iy, 1.5 * (1 - t), 0, Math.PI * 2);
ctx.fill();
}
}
// Coma (chioma) intorno al nucleo
if (luminosita > 0.1) {
const comaRaggio = 6 + luminosita * 12;
const comaGrad = ctx.createRadialGradient(x, y, 2, x, y, comaRaggio);
comaGrad.addColorStop(0, `rgba(200,230,255,${luminosita * 0.8})`);
comaGrad.addColorStop(0.3, `rgba(150,200,255,${luminosita * 0.3})`);
comaGrad.addColorStop(1, "rgba(100,150,255,0)");
ctx.fillStyle = comaGrad;
ctx.beginPath();
ctx.arc(x, y, comaRaggio, 0, Math.PI * 2);
ctx.fill();
}
// Nucleo della cometa
const nucleoRaggio = 2.5 + luminosita * 1.5;
ctx.fillStyle = `rgba(220,240,255,${0.5 + luminosita * 0.5})`;
ctx.shadowColor = "rgba(150,200,255,0.8)";
ctx.shadowBlur = 8 * luminosita;
ctx.beginPath();
ctx.arc(x, y, nucleoRaggio, 0, Math.PI * 2);
ctx.fill();
ctx.shadowBlur = 0;
// Etichetta
ctx.fillStyle = `rgba(180,220,255,${0.4 + luminosita * 0.4})`;
ctx.font = "10px monospace";
ctx.fillText(c.nome, x + 10, y - 8);
}
function disegnaStelle() {
stelle.forEach((s) => {
ctx.fillStyle = `rgba(255,255,255,${s.a})`;
ctx.beginPath();
ctx.arc(s.x, s.y, s.r, 0, Math.PI * 2);
ctx.fill();
});
}
// Resize
window.addEventListener("resize", () => {
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
});
// Avvia
animazione();
+353
View File
@@ -0,0 +1,353 @@
<!DOCTYPE html>
<html lang="it">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Sistema Solare</title>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body { overflow: hidden; background: #000; }
canvas { display: block; }
#info {
position: fixed;
top: 10px;
left: 10px;
color: rgba(255,255,255,0.5);
font-family: monospace;
font-size: 12px;
pointer-events: none;
}
</style>
</head>
<body>
<canvas id="sistema"></canvas>
<div id="info">Sistema Solare — Simulazione</div>
<script>
// === SISTEMA SOLARE — JavaScript (da sistema-solare.ts) ===
let tempo = 0;
// === COMETA DI HALLEY ===
// Periodo: ~75.3 anni | Eccentricità: 0.967 | Inclinazione: 162° (retrograda)
// Perielio: 0.586 UA | Afelio: 35.1 UA | Semiasse maggiore: 17.8 UA
const cometaHalley = {
nome: "Halley",
asseMaggiore: 267, // ~17.8 UA in scala
eccentricita: 0.967,
velocita: 0.00084, // P=75.3 anni → scala
angoloIniziale: Math.PI * 0.45, // posizione iniziale
angoloOrbita: Math.PI * 0.85, // rotazione ellisse (simula inclinazione)
coda: [], // particelle coda
};
// Inizializza particelle della coda
for (let i = 0; i < 60; i++) {
cometaHalley.coda.push({
distanza: i * 3,
larghezza: (60 - i) * 0.08,
angoloOffset: (Math.random() - 0.5) * 0.3,
opacita: 1 - i / 60,
});
}
const corpo = [
{ nome: "Mercurio", raggio: 4, asseMaggiore: 60, eccentricita: 0.206, velocita: 4.15, colore: "#b5b5b5" },
{ nome: "Venere", raggio: 7, asseMaggiore: 90, eccentricita: 0.007, velocita: 1.62, colore: "#e8cda0" },
{ nome: "Terra", raggio: 8, asseMaggiore: 130, eccentricita: 0.017, velocita: 1.0, colore: "#4a90d9",
angoli: [0], raggiMondi: [18], coloriMondi: ["#cccccc"], nomiMondi: ["Luna"] },
{ nome: "Marte", raggio: 6, asseMaggiore: 170, eccentricita: 0.093, velocita: 0.53, colore: "#c1440e",
angoli: [0, 0.5], raggiMondi: [12, 16], coloriMondi: ["#aaaaaa", "#999999"], nomiMondi: ["Fobos", "Deimos"] },
{ nome: "Giove", raggio: 20, asseMaggiore: 240, eccentricita: 0.049, velocita: 0.084, colore: "#c88b3a",
angoli: [0, 0.8, 1.6, 2.4], raggiMondi: [30, 36, 42, 48], coloriMondi: ["#dddddd", "#bbbbbb", "#aaaaaa", "#999999"], nomiMondi: ["Io", "Europa", "Ganimede", "Callisto"] },
{ nome: "Saturno", raggio: 17, asseMaggiore: 320, eccentricita: 0.057, velocita: 0.034, colore: "#e8d191",
angoli: [0, 1.2, 2.4], raggiMondi: [30, 38, 46], coloriMondi: ["#cccccc", "#bbbbbb", "#aaaaaa"], nomiMondi: ["Encelado", "Mimante", "Titano"], anelli: true },
{ nome: "Urano", raggio: 12, asseMaggiore: 390, eccentricita: 0.046, velocita: 0.011, colore: "#72b5c4",
angoli: [0, 1.5, 3.0], raggiMondi: [20, 26, 32], coloriMondi: ["#cccccc", "#bbbbbb", "#aaaaaa"], nomiMondi: ["Miranda", "Ariel", "Titania"] },
{ nome: "Nettuno", raggio: 11, asseMaggiore: 450, eccentricita: 0.011, velocita: 0.006, colore: "#3f54ba",
angoli: [0, 1.0], raggiMondi: [20, 26], coloriMondi: ["#cccccc", "#bbbbbb"], nomiMondi: ["Tritone", "Nereide"] },
{ nome: "Plutone", raggio: 5, asseMaggiore: 590, eccentricita: 0.244, velocita: 0.004, colore: "#a89f91",
angoli: [0, 1.2, 2.4, 3.6, 4.8], raggiMondi: [25, 45, 65, 42, 52],
coloriMondi: ["#cccccc", "#bbbbbb", "#aaaaaa", "#999999", "#888888"],
nomiMondi: ["Caronte", "Nix", "Idra", "Cerbero", "Stige"],
velocitaMondi: [10, 2.5, 1.7, 3.2, 5.3] },
];
const canvas = document.getElementById("sistema");
const ctx = canvas.getContext("2d");
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
// Stelle
const stelle = [];
for (let i = 0; i < 300; i++) {
stelle.push({
x: Math.random() * canvas.width,
y: Math.random() * canvas.height,
r: Math.random() * 1.2,
a: Math.random() * 0.5 + 0.2,
});
}
function disegnaStelle() {
stelle.forEach((s) => {
ctx.fillStyle = `rgba(255,255,255,${s.a})`;
ctx.beginPath();
ctx.arc(s.x, s.y, s.r, 0, Math.PI * 2);
ctx.fill();
});
}
function disegnaSole(cx, cy) {
const grad = ctx.createRadialGradient(cx, cy, 10, cx, cy, 60);
grad.addColorStop(0, "#fff700");
grad.addColorStop(0.3, "#ff8c00");
grad.addColorStop(1, "rgba(255,140,0,0)");
ctx.fillStyle = grad;
ctx.beginPath();
ctx.arc(cx, cy, 60, 0, Math.PI * 2);
ctx.fill();
ctx.fillStyle = "#ffcc00";
ctx.shadowColor = "#ff8800";
ctx.shadowBlur = 30;
ctx.beginPath();
ctx.arc(cx, cy, 25, 0, Math.PI * 2);
ctx.fill();
ctx.shadowBlur = 0;
}
function disegnaAnelliSaturno(cx, cy, raggio) {
ctx.strokeStyle = "rgba(210, 180, 140, 0.5)";
ctx.lineWidth = 4;
ctx.beginPath();
ctx.ellipse(cx, cy, raggio * 2.2, raggio * 0.6, 0, 0, Math.PI * 2);
ctx.stroke();
ctx.strokeStyle = "rgba(190, 160, 120, 0.3)";
ctx.lineWidth = 3;
ctx.beginPath();
ctx.ellipse(cx, cy, raggio * 2.6, raggio * 0.7, 0, 0, Math.PI * 2);
ctx.stroke();
}
function disegnaOrbita(cx, cy, a, b) {
ctx.strokeStyle = "rgba(255,255,255,0.08)";
ctx.lineWidth = 1;
ctx.beginPath();
ctx.ellipse(cx, cy, a, b, 0, 0, Math.PI * 2);
ctx.stroke();
}
function disegnaCorpo(c, cx, cy, angolo) {
const a = c.asseMaggiore;
const b = a * Math.sqrt(1 - c.eccentricita * c.eccentricita);
const x = cx + a * Math.cos(angolo);
const y = cy + b * Math.sin(angolo);
disegnaOrbita(cx, cy, a, b);
if (c.anelli) {
disegnaAnelliSaturno(x, y, c.raggio);
}
ctx.fillStyle = c.colore;
ctx.beginPath();
ctx.arc(x, y, c.raggio, 0, Math.PI * 2);
ctx.fill();
// Dettaglio Giove
if (c.nome === "Giove") {
ctx.strokeStyle = "rgba(160, 100, 30, 0.4)";
ctx.lineWidth = 2;
for (let i = -2; i <= 2; i++) {
ctx.beginPath();
ctx.arc(x, y, c.raggio * 0.6, 0, Math.PI);
ctx.stroke();
}
ctx.fillStyle = "rgba(200, 80, 50, 0.6)";
ctx.beginPath();
ctx.ellipse(x + 5, y + 3, 5, 3, 0, 0, Math.PI * 2);
ctx.fill();
}
// Dettaglio Terra
if (c.nome === "Terra") {
ctx.fillStyle = "rgba(50, 150, 50, 0.5)";
ctx.beginPath();
ctx.arc(x - 2, y - 2, 3, 0, Math.PI * 2);
ctx.fill();
ctx.fillStyle = "rgba(50, 150, 50, 0.4)";
ctx.beginPath();
ctx.arc(x + 3, y + 2, 2, 0, Math.PI * 2);
ctx.fill();
}
// Lune
if (c.raggiMondi && c.coloriMondi) {
c.raggiMondi.forEach((raggioM, i) => {
const velocitaM = c.velocitaMondi?.[i] ?? 3;
const angoloM = angolo + (c.angoli?.[i] || 0) + tempo * velocitaM;
const mx = x + Math.cos(angoloM) * raggioM;
const my = y + Math.sin(angoloM) * raggioM;
ctx.strokeStyle = "rgba(255,255,255,0.05)";
ctx.lineWidth = 0.5;
ctx.beginPath();
ctx.arc(x, y, raggioM, 0, Math.PI * 2);
ctx.stroke();
ctx.fillStyle = c.coloriMondi[i];
ctx.beginPath();
ctx.arc(mx, my, 2, 0, Math.PI * 2);
ctx.fill();
ctx.fillStyle = "rgba(255,255,255,0.4)";
ctx.font = "8px monospace";
ctx.fillText(c.nomiMondi?.[i] || "", mx + 4, my - 4);
});
}
// Etichetta
ctx.fillStyle = "rgba(255,255,255,0.6)";
ctx.font = "11px monospace";
ctx.fillText(c.nome, x + c.raggio + 5, y - 5);
}
function animazione() {
ctx.fillStyle = "#000010";
ctx.fillRect(0, 0, canvas.width, canvas.height);
disegnaStelle();
const cx = canvas.width / 2;
const cy = canvas.height / 2;
disegnaSole(cx, cy);
corpo.forEach((c) => {
const angolo = tempo * c.velocita;
disegnaCorpo(c, cx, cy, angolo);
});
// === COMETA DI HALLEY ===
disegnaCometaHalley(cx, cy);
tempo += 0.005;
requestAnimationFrame(animazione);
}
function disegnaCometaHalley(cx, cy) {
const c = cometaHalley;
const a = c.asseMaggiore;
const b = a * Math.sqrt(1 - c.eccentricita * c.eccentricita);
const angolo = tempo * c.velocita + c.angoloIniziale;
// Posizione cometa sull'orbita ellittica
const xOrbita = a * Math.cos(angolo);
const yOrbita = b * Math.sin(angolo);
// Ruota l'orbita per simulare inclinazione/retrograda
const cosA = Math.cos(c.angoloOrbita);
const sinA = Math.sin(c.angoloOrbita);
const x = cx + xOrbita * cosA - yOrbita * sinA;
const y = cy + xOrbita * sinA + yOrbita * cosA;
// Disegna orbita (ellisse ruotata)
ctx.save();
ctx.translate(cx, cy);
ctx.rotate(c.angoloOrbita);
ctx.strokeStyle = "rgba(150,200,255,0.12)";
ctx.lineWidth = 1;
ctx.setLineDash([4, 6]);
ctx.beginPath();
ctx.ellipse(0, 0, a, b, 0, 0, Math.PI * 2);
ctx.stroke();
ctx.setLineDash([]);
ctx.restore();
// Distanza dal Sole per direzione coda
const dxSole = cx - x;
const dySole = cy - y;
const distSole = Math.sqrt(dxSole * dxSole + dySole * dySole);
const direzioneX = dxSole / distSole;
const direzioneY = dySole / distSole;
// Perielio: la cometa è più luminosa quando è vicina al Sole
const perielioDist = a * (1 - c.eccentricita); // ~9px in scala
const luminosita = Math.min(1, perielioDist / distSole);
// Coda di polvere (più larga, curva leggermente)
for (let i = 0; i < cometaHalley.coda.length; i++) {
const p = cometaHalley.coda[i];
const tailLen = p.distanza * (0.5 + luminosita * 1.5);
const tailW = p.larghezza * (0.5 + luminosita);
const angoloCoda = Math.atan2(direzioneY, direzioneX) + p.angoloOffset;
const px = x - Math.cos(angoloCoda) * tailLen;
const py = y - Math.sin(angoloCoda) * tailLen;
const alpha = p.opacita * luminosita * 0.6;
if (alpha > 0.01) {
ctx.fillStyle = `rgba(180,220,255,${alpha})`;
ctx.beginPath();
ctx.arc(px, py, tailW, 0, Math.PI * 2);
ctx.fill();
}
}
// Coda ionica (più sottile, dritta, blu)
const codaIonicaLunghezza = 40 + luminosita * 80;
const angoloIonico = Math.atan2(direzioneY, direzioneX);
for (let i = 0; i < 30; i++) {
const t = i / 30;
const ix = x - Math.cos(angoloIonico) * codaIonicaLunghezza * t;
const iy = y - Math.sin(angoloIonico) * codaIonicaLunghezza * t;
const alpha = (1 - t) * luminosita * 0.5;
if (alpha > 0.01) {
ctx.fillStyle = `rgba(100,150,255,${alpha})`;
ctx.beginPath();
ctx.arc(ix, iy, 1.5 * (1 - t), 0, Math.PI * 2);
ctx.fill();
}
}
// Coma (chioma) intorno al nucleo
if (luminosita > 0.1) {
const comaRaggio = 6 + luminosita * 12;
const comaGrad = ctx.createRadialGradient(x, y, 2, x, y, comaRaggio);
comaGrad.addColorStop(0, `rgba(200,230,255,${luminosita * 0.8})`);
comaGrad.addColorStop(0.3, `rgba(150,200,255,${luminosita * 0.3})`);
comaGrad.addColorStop(1, "rgba(100,150,255,0)");
ctx.fillStyle = comaGrad;
ctx.beginPath();
ctx.arc(x, y, comaRaggio, 0, Math.PI * 2);
ctx.fill();
}
// Nucleo della cometa
const nucleoRaggio = 2.5 + luminosita * 1.5;
ctx.fillStyle = `rgba(220,240,255,${0.5 + luminosita * 0.5})`;
ctx.shadowColor = "rgba(150,200,255,0.8)";
ctx.shadowBlur = 8 * luminosita;
ctx.beginPath();
ctx.arc(x, y, nucleoRaggio, 0, Math.PI * 2);
ctx.fill();
ctx.shadowBlur = 0;
// Etichetta
ctx.fillStyle = `rgba(180,220,255,${0.4 + luminosita * 0.4})`;
ctx.font = "10px monospace";
ctx.fillText(c.nome, x + 10, y - 8);
}
window.addEventListener("resize", () => {
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
});
animazione();
</script>
</body>
</html>