!DOCTYPE html>
<html>
<head>
<title>GNSS Satellite Visualization v2</title>
<style>
body { margin: 0; overflow: hidden; }
canvas { width: 100%; height: 100% }
#info {
position: absolute;
top: 10px;
left: 10px;
color: white;
font-family: Arial;
font-size: 14px;
pointer-events: none;
}
.label {
position: absolute;
color: white;
font-family: Arial;
font-size: 12px;
}
</style>
</head>
<body>
<div id="info">Pohyb GNSS družic<br>Levé tlačítko myši: Rotace<br>Pravé tlačítko: Posun<br>Kolečko: Zoom</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/three@0.128.0/examples/js/controls/OrbitControls.js"></script>
<script>
let scene, camera, renderer, controls;
const EARTH_RADIUS = 5;
const SAT_SIZE = 0.1;
const satellites = [];
const constellations = [
{ name: 'GPS', color: 0xff0000, alt: 10, inc: 55, count: 8 },
{ name: 'Galileo', color: 0x0000ff, alt: 9.5, inc: 56, count: 8 },
{ name: 'GLONASS', color: 0x00ff00, alt: 10.2, inc: 64.8, count: 8 }
];
function init() {
// Inicializace scény
scene = new THREE.Scene();
// Nastavení kamery
camera = new THREE.PerspectiveCamera(75, window.innerWidth/window.innerHeight, 0.1, 1000);
camera.position.z = 25;
// Renderer
renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
// Ovládání kamery
controls = new THREE.OrbitControls(camera, renderer.domElement);
// Vytvoření Země
createEarth();
// Vytvoření družic a orbitů
createSatellites();
// Osvětlení
setupLighting();
// Hvězdné pozadí
createStarField();
// Spuštění animace
animate();
}
function createEarth() {
const earthGeometry = new THREE.SphereGeometry(EARTH_RADIUS, 32, 32);
const earthMaterial = new THREE.MeshPhongMaterial({
map: new THREE.TextureLoader().load('https://threejs.org/examples/textures/planets/earth_atmos_2048.jpg'),
bumpScale: 0.05,
specular: new THREE.Color('grey'),
shininess: 5
});
const earth = new THREE.Mesh(earthGeometry, earthMaterial);
scene.add(earth);
}
function createSatellites() {
constellations.forEach(constellation => {
for(let i = 0; i < constellation.count; i++) {
// Parametry orbity
const altitude = EARTH_RADIUS + constellation.alt;
const inclination = (Math.PI/180) * constellation.inc;
const orbitalPeriod = 12 * 3600; // 12 hodin v sekundách
const speed = (2 * Math.PI) / orbitalPeriod * 0.05; // Upraveno pro lepší vizualizaci
// Vytvoření orbity
const orbitGeometry = new THREE.RingGeometry(altitude-0.1, altitude, 64);
const orbitMaterial = new THREE.MeshBasicMaterial({
color: constellation.color,
side: THREE.DoubleSide,
transparent: true,
opacity: 0.2
});
const orbit = new THREE.Mesh(orbitGeometry, orbitMaterial);
orbit.rotation.x = inclination;
scene.add(orbit);
// Vytvoření družice
const satGeometry = new THREE.SphereGeometry(SAT_SIZE);
const satMaterial = new THREE.MeshPhongMaterial({color: constellation.color});
const satellite = new THREE.Mesh(satGeometry, satMaterial);
// Počáteční pozice
const angle = (Math.PI * 2 * i) / constellation.count;
const x = Math.cos(angle) * altitude;
const z = Math.sin(angle) * altitude;
const y = 0;
// Aplikace sklonu
const rotatedY = y * Math.cos(inclination) - z * Math.sin(inclination);
const rotatedZ = y * Math.sin(inclination) + z * Math.cos(inclination);
satellite.position.set(x, rotatedY, rotatedZ);
// Uložení družice
satellites.push({
mesh: satellite,
altitude: altitude,
speed: speed,
angle: angle,
inclination: inclination,
constellation: constellation.name,
groundTrack: createGroundTrack(constellation.color)
});
scene.add(satellite);
}
});
}
function createGroundTrack(color) {
const geometry = new THREE.BufferGeometry();
const material = new THREE.LineBasicMaterial({
color: color,
transparent: true,
opacity: 0.3
});
const line = new THREE.Line(geometry, material);
scene.add(line);
return line;
}
function updateGroundTrack(sat) {
const positions = [];
const maxPoints = 50;
// Generování bodů pro pozemní stopu
for(let i = 0; i < maxPoints; i++) {
const angle = sat.angle - (sat.speed * i);
const x = Math.cos(angle) * sat.altitude;
const z = Math.sin(angle) * sat.altitude;
const y = 0;
// Aplikace sklonu
const rotatedY = y * Math.cos(sat.inclination) - z * Math.sin(sat.inclination);
const rotatedZ = y * Math.sin(sat.inclination) + z * Math.cos(sat.inclination);
positions.push(x, rotatedY, rotatedZ);
}
sat.groundTrack.geometry.setAttribute(
'position',
new THREE.Float32BufferAttribute(positions, 3)
);
}
function updateSatellites() {
satellites.forEach(sat => {
// Aktualizace úhlu
sat.angle += sat.speed;
// Výpočet nový pozice
const x = Math.cos(sat.angle) * sat.altitude;
const z = Math.sin(sat.angle) * sat.altitude;
const y = 0;
// Aplikace sklonu dráhy
const rotatedY = y * Math.cos(sat.inclination) - z * Math.sin(sat.inclination);
const rotatedZ = y * Math.sin(sat.inclination) + z * Math.cos(sat.inclination);
// Aktualizace pozice
sat.mesh.position.set(x, rotatedY, rotatedZ);
// Aktualizace pozemní stopy
updateGroundTrack(sat);
});
}
function setupLighting() {
const light = new THREE.PointLight(0xffffff, 1.5);
light.position.set(50, 50, 50);
scene.add(light);
scene.add(new THREE.AmbientLight(0x404040));
}
function createStarField() {
const stars = new THREE.BufferGeometry();
const starVertices = [];
for(let i = 0; i < 1000; i++) {
starVertices.push(
THREE.MathUtils.randFloatSpread(200),
THREE.MathUtils.randFloatSpread(200),
THREE.MathUtils.randFloatSpread(200)
);
}
stars.setAttribute('position', new THREE.Float32BufferAttribute(starVertices, 3));
const starMaterial = new THREE.PointsMaterial({color: 0xFFFFFF, size: 0.1});
const starField = new THREE.Points(stars, starMaterial);
scene.add(starField);
}
function animate() {
requestAnimationFrame(animate);
updateSatellites();
controls.update();
renderer.render(scene, camera);
}
window.addEventListener('resize', () => {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
});
// Spustění aplikace
init();
</script>
</body>
</html
Three.js Oficiální Dokumentace](https://threejs.org/docs/)
- Základní koncepty 3D grafiky (scéna, kamera, renderer)
- Práce s geometriemi a materiály
- Osvětlení a stínování
Three.js Příklady (https://threejs.org/examples/)
- Využití `OrbitControls` pro ovládání kamery
- Tvorba planetárních textur a osvětlení
Pro optymalizaci kodu byli použity online nástroje: DeepSeek (https://www.deepseek.com/) a ChatGPT (https://chatgpt.com/)