Pionier 10 drin

This commit is contained in:
2026-04-12 10:09:22 +02:00
parent 911b67e9e8
commit 8aa599b3bf
2 changed files with 260 additions and 4 deletions
+252 -3
View File
@@ -11,6 +11,7 @@ $trackedCometsForJs = [];
$voyager1TrackForJs = [];
$voyager2TrackForJs = [];
$newHorizonsTrackForJs = [];
$pioneer10TrackForJs = [];
$pdo = null;
$spacecraftOptionsForJs = [];
@@ -279,10 +280,12 @@ if ($pdo instanceof PDO) {
$voyager1TrackForJs = loadSpacecraftTrackFromDatabase($pdo, 'voyager1');
$voyager2TrackForJs = loadSpacecraftTrackFromDatabase($pdo, 'voyager2');
$newHorizonsTrackForJs = loadSpacecraftTrackFromDatabase($pdo, 'new_horizons');
$pioneer10TrackForJs = loadSpacecraftTrackFromDatabase($pdo, 'pioneer10');
} catch (Throwable $e) {
$voyager1TrackForJs = [];
$voyager2TrackForJs = [];
$newHorizonsTrackForJs = [];
$pioneer10TrackForJs = [];
}
}
@@ -295,6 +298,9 @@ if ($voyager2TrackForJs !== []) {
if ($newHorizonsTrackForJs !== []) {
$spacecraftOptionsForJs[] = ['key' => 'new_horizons', 'label' => 'New Horizons'];
}
if ($pioneer10TrackForJs !== []) {
$spacecraftOptionsForJs[] = ['key' => 'pioneer10', 'label' => 'Pioneer 10'];
}
$pageTitle = 'Sonnensystem - AstroTools';
$bodyClass = 'solarsystem-page';
@@ -498,6 +504,7 @@ const SPACECRAFT_OPTIONS = <?= json_encode($spacecraftOptionsForJs, JSON_UNESCAP
const VOYAGER1_TRACK = <?= json_encode($voyager1TrackForJs, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES) ?>;
const VOYAGER2_TRACK = <?= json_encode($voyager2TrackForJs, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES) ?>;
const NEW_HORIZONS_TRACK = <?= json_encode($newHorizonsTrackForJs, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES) ?>;
const PIONEER10_TRACK = <?= json_encode($pioneer10TrackForJs, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES) ?>;
const JUPITER_MIN_VISIBLE_SIZE = 1.42;
const MOON_DISPLAY_DISTANCE_MULTIPLIER = 2200;
@@ -582,6 +589,8 @@ let voyager2Objects = null;
let voyager2LabelElement = null;
let newHorizonsObjects = null;
let newHorizonsLabelElement = null;
let pioneer10Objects = null;
let pioneer10LabelElement = null;
let voyagerModelTemplatePromise = null;
let voyagerModelTemplate = null;
const planetDynamicsCache = new Map();
@@ -602,6 +611,7 @@ let selectedSpacecraftKeys = spacecraftCheckboxes
let focusedVoyager1 = false;
let focusedVoyager2 = false;
let focusedNewHorizons = false;
let focusedPioneer10 = false;
let simDate = new Date();
let lastAnimationTime = performance.now();
let orbitRefreshCursor = 0;
@@ -944,6 +954,50 @@ function getNewHorizonsPosition(date) {
return null;
}
function getPioneer10Position(date) {
if (!Array.isArray(PIONEER10_TRACK) || PIONEER10_TRACK.length === 0) {
return null;
}
const targetMs = date.getTime();
if (targetMs <= Number(PIONEER10_TRACK[0].timestampMs)) {
return PIONEER10_TRACK[0];
}
const lastIndex = PIONEER10_TRACK.length - 1;
if (targetMs >= Number(PIONEER10_TRACK[lastIndex].timestampMs)) {
return PIONEER10_TRACK[lastIndex];
}
for (let index = 0; index < lastIndex; index += 1) {
const left = PIONEER10_TRACK[index];
const right = PIONEER10_TRACK[index + 1];
const leftMs = Number(left.timestampMs);
const rightMs = Number(right.timestampMs);
if (targetMs < leftMs || targetMs > rightMs) {
continue;
}
const span = Math.max(rightMs - leftMs, 1);
const factor = (targetMs - leftMs) / span;
const xAu = Number(left.xAu) + ((Number(right.xAu) - Number(left.xAu)) * factor);
const yAu = Number(left.yAu) + ((Number(right.yAu) - Number(left.yAu)) * factor);
const zAu = Number(left.zAu) + ((Number(right.zAu) - Number(left.zAu)) * factor);
const distanceAu = Math.hypot(xAu, yAu, zAu);
return {
timestampMs: targetMs,
dateTdb: String(left.dateTdb || ''),
xAu,
yAu,
zAu,
distanceAu,
};
}
return null;
}
const MINOR_PLANET_COLOR_PALETTE = [
{ line: '#ff6b6b', body: '#ff5a5a', emissive: '#d63b3b' },
{ line: '#ff5252', body: '#ff4747', emissive: '#c62828' },
@@ -1203,6 +1257,7 @@ function clearFocus() {
focusedVoyager1 = false;
focusedVoyager2 = false;
focusedNewHorizons = false;
focusedPioneer10 = false;
cameraTarget.set(0, 0, 0);
camRadiusTarget = camRadius;
document.querySelectorAll('.solarsystem-planet-chip').forEach((button) => {
@@ -1406,6 +1461,33 @@ function updateNewHorizonsInfoPanel() {
document.getElementById('solarInfoType').textContent = 'Raumsonde | JPL Horizons CSV';
}
function updatePioneer10InfoPanel() {
const position = getPioneer10Position(simDate);
if (!position) {
infoPanel.hidden = true;
return;
}
const earthPosition = getHelioPosition('Earth', simDate);
const earthDistanceAu = Math.hypot(
position.xAu - earthPosition.x,
position.yAu - earthPosition.y,
position.zAu - earthPosition.z
);
infoPanel.hidden = false;
document.getElementById('solarInfoName').textContent = 'Pioneer 10';
document.getElementById('solarInfoName').style.color = '#f3a86f';
document.getElementById('solarInfoDistanceAu').textContent = `${Number(position.distanceAu).toFixed(3)} AU`;
document.getElementById('solarInfoDistanceKm').textContent = `${(Number(position.distanceAu) * AU_IN_KM).toFixed(0).replace(/\B(?=(\d{3})+(?!\d))/g, '.')} km`;
document.getElementById('solarInfoEarthDistanceAu').textContent = `${earthDistanceAu.toFixed(3)} AU`;
document.getElementById('solarInfoEarthDistanceKm').textContent = `${(earthDistanceAu * AU_IN_KM).toFixed(0).replace(/\B(?=(\d{3})+(?!\d))/g, '.')} km`;
document.getElementById('solarInfoMagnitude').textContent = '--';
document.getElementById('solarInfoPeriod').textContent = '--';
document.getElementById('solarInfoAxis').textContent = '--';
document.getElementById('solarInfoType').textContent = 'Raumsonde | JPL Horizons CSV';
}
function focusPlanet(key) {
focusedPlanetKey = key;
focusedMinorPlanetId = null;
@@ -1413,6 +1495,7 @@ function focusPlanet(key) {
focusedVoyager1 = false;
focusedVoyager2 = false;
focusedNewHorizons = false;
focusedPioneer10 = false;
document.querySelectorAll('.solarsystem-planet-chip').forEach((button) => {
button.classList.toggle('is-focused', button.dataset.planet === key);
});
@@ -1457,6 +1540,13 @@ function buildLabels() {
newHorizonsLabelElement.style.color = '#ff9fd6';
newHorizonsLabelElement.hidden = true;
labelsLayer.appendChild(newHorizonsLabelElement);
pioneer10LabelElement = document.createElement('div');
pioneer10LabelElement.className = 'solarsystem-planet-label';
pioneer10LabelElement.textContent = 'Pioneer 10';
pioneer10LabelElement.style.color = '#f3a86f';
pioneer10LabelElement.hidden = true;
labelsLayer.appendChild(pioneer10LabelElement);
}
function ensureVoyager1Objects() {
@@ -1722,6 +1812,101 @@ function updateNewHorizonsVisual() {
}
}
function ensurePioneer10Objects() {
if (pioneer10Objects || !Array.isArray(PIONEER10_TRACK) || PIONEER10_TRACK.length === 0) {
return;
}
const orbitLine = new THREE.Line(
new THREE.BufferGeometry(),
new THREE.LineBasicMaterial({
color: new THREE.Color('#f3a86f'),
transparent: true,
opacity: 0.8,
})
);
orbitLine.visible = showOrbits;
scene.add(orbitLine);
const mesh = new THREE.Mesh(
new THREE.SphereGeometry(0.28, 20, 20),
new THREE.MeshStandardMaterial({
color: new THREE.Color('#f7c49c'),
emissive: new THREE.Color('#bc6a2e'),
emissiveIntensity: 0.45,
roughness: 0.45,
metalness: 0.7,
})
);
mesh.userData.baseScale = 1;
mesh.userData.minScaleMultiplier = 1.8;
scene.add(mesh);
pioneer10Objects = { orbitLine, mesh, labelElement: pioneer10LabelElement };
}
function rebuildPioneer10Track() {
ensurePioneer10Objects();
if (!pioneer10Objects) {
return;
}
const positions = [];
PIONEER10_TRACK.forEach((entry) => {
const display = toDisplayPosition({
x: Number(entry.xAu),
y: Number(entry.yAu),
z: Number(entry.zAu),
r: Math.max(Number(entry.distanceAu), 1e-9),
});
positions.push(display.x, display.y, display.z);
});
pioneer10Objects.orbitLine.geometry.dispose();
pioneer10Objects.orbitLine.geometry = new THREE.BufferGeometry();
pioneer10Objects.orbitLine.geometry.setAttribute('position', new THREE.Float32BufferAttribute(positions, 3));
pioneer10Objects.orbitLine.visible = showOrbits;
}
function updatePioneer10Visual() {
ensurePioneer10Objects();
if (!pioneer10Objects) {
return;
}
if (!isSpacecraftSelected('pioneer10')) {
pioneer10Objects.mesh.visible = false;
pioneer10Objects.orbitLine.visible = false;
if (pioneer10Objects.labelElement) {
pioneer10Objects.labelElement.hidden = true;
}
return;
}
const position = getPioneer10Position(simDate);
if (!position) {
pioneer10Objects.mesh.visible = false;
pioneer10Objects.orbitLine.visible = false;
if (pioneer10Objects.labelElement) {
pioneer10Objects.labelElement.hidden = true;
}
return;
}
pioneer10Objects.mesh.visible = true;
pioneer10Objects.mesh.position.copy(toDisplayPosition({
x: Number(position.xAu),
y: Number(position.yAu),
z: Number(position.zAu),
r: Math.max(Number(position.distanceAu), 1e-9),
}));
pioneer10Objects.orbitLine.visible = showOrbits;
if (focusedPioneer10) {
updatePioneer10InfoPanel();
}
}
function syncSpacecraftObjects() {
const selectedSpacecraftSet = getSelectedSpacecraftSet();
@@ -1752,6 +1937,15 @@ function syncSpacecraftObjects() {
}
}
if (pioneer10Objects) {
const isSelected = selectedSpacecraftSet.has('pioneer10');
pioneer10Objects.mesh.visible = isSelected && pioneer10Objects.mesh.visible;
pioneer10Objects.orbitLine.visible = isSelected && showOrbits && pioneer10Objects.orbitLine.visible;
if (!isSelected && pioneer10Objects.labelElement) {
pioneer10Objects.labelElement.hidden = true;
}
}
if (focusedVoyager1 && !selectedSpacecraftSet.has('voyager1')) {
clearFocus();
}
@@ -1761,6 +1955,9 @@ function syncSpacecraftObjects() {
if (focusedNewHorizons && !selectedSpacecraftSet.has('new_horizons')) {
clearFocus();
}
if (focusedPioneer10 && !selectedSpacecraftSet.has('pioneer10')) {
clearFocus();
}
}
function ensureMoonObjects() {
@@ -2559,6 +2756,10 @@ function updateBodyDisplayScales() {
if (newHorizonsObjects && newHorizonsObjects.mesh && newHorizonsObjects.mesh.visible) {
applyMinimumDisplayScale(newHorizonsObjects.mesh, 260, 10);
}
if (pioneer10Objects && pioneer10Objects.mesh && pioneer10Objects.mesh.visible) {
applyMinimumDisplayScale(pioneer10Objects.mesh, 260, 10);
}
}
function updateLabels() {
@@ -2684,6 +2885,20 @@ function updateLabels() {
}
}
}
if (pioneer10Objects && pioneer10LabelElement) {
pioneer10LabelElement.hidden = !showLabels || !pioneer10Objects.mesh.visible;
if (!pioneer10LabelElement.hidden) {
const projectedPioneer10 = pioneer10Objects.mesh.position.clone().project(camera);
if (projectedPioneer10.z > 1) {
pioneer10LabelElement.style.opacity = '0';
} else {
pioneer10LabelElement.style.opacity = '1';
pioneer10LabelElement.style.left = `${(projectedPioneer10.x * 0.5 + 0.5) * stageWrap.clientWidth}px`;
pioneer10LabelElement.style.top = `${(-projectedPioneer10.y * 0.5 + 0.5) * stageWrap.clientHeight}px`;
}
}
}
}
function pickPlanet(clientX, clientY) {
@@ -2716,6 +2931,7 @@ function pickPlanet(clientX, clientY) {
focusedVoyager1 = false;
focusedVoyager2 = false;
focusedNewHorizons = false;
focusedPioneer10 = false;
document.querySelectorAll('.solarsystem-planet-chip').forEach((button) => {
button.classList.remove('is-focused');
});
@@ -2740,6 +2956,7 @@ function pickPlanet(clientX, clientY) {
focusedVoyager1 = false;
focusedVoyager2 = false;
focusedNewHorizons = false;
focusedPioneer10 = false;
document.querySelectorAll('.solarsystem-planet-chip').forEach((button) => {
button.classList.remove('is-focused');
});
@@ -2758,6 +2975,7 @@ function pickPlanet(clientX, clientY) {
focusedVoyager1 = true;
focusedVoyager2 = false;
focusedNewHorizons = false;
focusedPioneer10 = false;
document.querySelectorAll('.solarsystem-planet-chip').forEach((button) => {
button.classList.remove('is-focused');
});
@@ -2775,6 +2993,7 @@ function pickPlanet(clientX, clientY) {
focusedVoyager1 = false;
focusedVoyager2 = true;
focusedNewHorizons = false;
focusedPioneer10 = false;
document.querySelectorAll('.solarsystem-planet-chip').forEach((button) => {
button.classList.remove('is-focused');
});
@@ -2792,6 +3011,7 @@ function pickPlanet(clientX, clientY) {
focusedVoyager1 = false;
focusedVoyager2 = false;
focusedNewHorizons = true;
focusedPioneer10 = false;
document.querySelectorAll('.solarsystem-planet-chip').forEach((button) => {
button.classList.remove('is-focused');
});
@@ -2800,6 +3020,24 @@ function pickPlanet(clientX, clientY) {
}
}
if (pioneer10Objects && pioneer10Objects.mesh.visible) {
const pioneer10Hits = raycaster.intersectObject(pioneer10Objects.mesh, true);
if (pioneer10Hits.length > 0) {
focusedPlanetKey = null;
focusedMinorPlanetId = null;
focusedCometId = null;
focusedVoyager1 = false;
focusedVoyager2 = false;
focusedNewHorizons = false;
focusedPioneer10 = true;
document.querySelectorAll('.solarsystem-planet-chip').forEach((button) => {
button.classList.remove('is-focused');
});
updatePioneer10InfoPanel();
return;
}
}
if (hits.length === 0) {
clearFocus();
return;
@@ -2916,6 +3154,9 @@ function attachUiHandlers() {
if (newHorizonsObjects) {
newHorizonsObjects.orbitLine.visible = showOrbits;
}
if (pioneer10Objects) {
pioneer10Objects.orbitLine.visible = showOrbits;
}
if (moonOrbitLine) {
moonOrbitLine.visible = showOrbits;
}
@@ -2966,7 +3207,7 @@ function attachUiHandlers() {
});
updateMinorPlanetSummary();
if (selectedMinorPlanetIds.length === 0 && !focusedPlanetKey && focusedMinorPlanetId === null && focusedCometId === null && !focusedVoyager1 && !focusedVoyager2 && !focusedNewHorizons) {
if (selectedMinorPlanetIds.length === 0 && !focusedPlanetKey && focusedMinorPlanetId === null && focusedCometId === null && !focusedVoyager1 && !focusedVoyager2 && !focusedNewHorizons && !focusedPioneer10) {
infoPanel.hidden = true;
}
});
@@ -2989,7 +3230,7 @@ function attachUiHandlers() {
updateCometSummary();
if (selectedCometIds.length === 0 && !focusedPlanetKey && focusedMinorPlanetId === null && focusedCometId === null) {
if (!focusedVoyager1 && !focusedVoyager2 && !focusedNewHorizons) {
if (!focusedVoyager1 && !focusedVoyager2 && !focusedNewHorizons && !focusedPioneer10) {
infoPanel.hidden = true;
}
}
@@ -3005,7 +3246,7 @@ function attachUiHandlers() {
syncSpacecraftObjects();
updateSpacecraftSummary();
if (!focusedPlanetKey && focusedMinorPlanetId === null && focusedCometId === null && !focusedVoyager1 && !focusedVoyager2 && !focusedNewHorizons) {
if (!focusedPlanetKey && focusedMinorPlanetId === null && focusedCometId === null && !focusedVoyager1 && !focusedVoyager2 && !focusedNewHorizons && !focusedPioneer10) {
infoPanel.hidden = true;
}
});
@@ -3030,6 +3271,7 @@ function animate() {
updateVoyager1Visual();
updateVoyager2Visual();
updateNewHorizonsVisual();
updatePioneer10Visual();
// Aim shadow light from sun toward Saturn
const saturnMesh = planetMeshes.get('Saturn');
@@ -3082,6 +3324,11 @@ function animate() {
updateNewHorizonsInfoPanel();
}
if (focusedPioneer10 && pioneer10Objects && pioneer10Objects.mesh.visible) {
cameraTarget.lerp(pioneer10Objects.mesh.position, 0.06);
updatePioneer10InfoPanel();
}
camRadius += (camRadiusTarget - camRadius) * 0.18;
updateCamera();
updateBodyDisplayScales();
@@ -3227,6 +3474,8 @@ async function initSolarSystem() {
rebuildVoyager2Track();
ensureNewHorizonsObjects();
rebuildNewHorizonsTrack();
ensurePioneer10Objects();
rebuildPioneer10Track();
syncSpacecraftObjects();
attachPointerControls();
attachUiHandlers();
+8 -1
View File
@@ -5,7 +5,7 @@ ini_set('display_errors', '1');
error_reporting(E_ALL);
const AU_IN_KM = 149597870.7;
const IMPORT_END_TIME = '2046-04-12 00:00:00';
const IMPORT_END_TIME = '2049-12-31 00:00:00';
$config = require __DIR__ . '/../../config/database.php';
$dsn = sprintf(
@@ -71,6 +71,13 @@ $missions = [
'start_time' => '2006-01-19 19:52:00',
'dense_stop_time' => '2017-10-19 19:52:00',
],
[
'key' => 'pioneer10',
'name' => 'Pioneer 10',
'command' => "'-23'",
'start_time' => '1972-03-03 02:56:00',
'dense_stop_time' => '1986-11-03 02:56:00',
],
];
function fetchHorizonsResult(array $extraParams): string