├── .DS_Store ├── README.md ├── data ├── font.html ├── schema_scene.png └── universe.js ├── etoile.kra ├── etoile.png ├── satellite.blend ├── satellite.glb ├── satellite.png ├── texture_planete.jpg ├── texture_planete.kra └── universe-visualization.png /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EmilSurk/LagrangeView/5b001d9713f637822be9b2fe9adb8058db99b66b/.DS_Store -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # LagrangeView: A 3D Visualization of the James-Webb Space Telescope Orbit 2 | 3 | Universe Visualization 4 | 5 | **LagrangeView** is an educational and interactive 3D representation of the James-Webb Space Telescope's orbit around the second Lagrange point (L2) of the Earth-Sun system. This project is developed using the powerful WebGL library, Three.js, along with Blender for 3D modeling, bringing to life the celestial mechanics that keep the JWST in a stable position to observe the universe. 6 | 7 | ## Features 8 | 9 | - **3D Scene Creation**: A static 3D scene that accurately represents the Earth-Sun system, the Earth's orbit, the five Lagrange points, and the JWST's orbit around L2, complemented with randomly placed stars for cosmic ambiance. 10 | - **Texture Animation**: Using Krita and Three.js, this feature allows the simulation of Earth's rotation and the seamless movement of the JWST along its orbit. 11 | - **Satellite Modeling**: The JWST is modeled with high fidelity in Blender, using primitive shapes and smooth shading to reflect its intricate design and functionality. 12 | - **Scene Animation**: Animations that bring the JWST's orbit to life, demonstrating the satellite's rotation and revolution in the context of the larger celestial ballet of the Earth-Sun system. 13 | 14 | ## Technical Highlights 15 | 16 | - **Three.js**: Enables the creation of 3D graphics right in the browser, offering an immersive educational experience without the need for specialized software. 17 | - **Blender**: Used for detailed modeling of the JWST and texturing the celestial bodies within the scene. 18 | - **Krita**: Assists in creating high-quality textures to represent planetary surfaces and other celestial features. 19 | 20 | This project showcases the potential of combining modern web technologies with the principles of astronomy and 3D graphics to create an interactive learning tool. Whether you're a student, educator, or space enthusiast, **LagrangeView** offers a window into the mechanics of space through the lens of the James-Webb Space Telescope's journey. 21 | -------------------------------------------------------------------------------- /data/font.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 17 | 18 | 26 | 27 | 28 | 29 | 30 | 31 | 32 |

Telescope James Webb

33 | 34 |

35 | Légende : Points de Lagrange L1 (rouge), L2 (vert), L3 (bleu), L4 (jaune) et L5 (cyan) pour le système Terre-Soleil. 36 |

37 | 41 | 45 | 49 | 50 | AmbientLight 51 | 52 | -------------------------------------------------------------------------------- /data/schema_scene.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EmilSurk/LagrangeView/5b001d9713f637822be9b2fe9adb8058db99b66b/data/schema_scene.png -------------------------------------------------------------------------------- /data/universe.js: -------------------------------------------------------------------------------- 1 | 2 | "use strict"; 3 | import * as THREE from 'three'; 4 | import { ArcballControls } from 'three/addons/controls/ArcballControls.js'; 5 | import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js'; 6 | 7 | 8 | let scene, camera, renderer, earth, pyramid; // Bases pour le rendu Three.js 9 | let controls; // Pour l'interaction avec la souris 10 | let canvas; // Le canevas où est dessinée la scène 11 | let ambient_light; 12 | let camera_light; 13 | let last_render = Date.now(); 14 | 15 | 16 | // VARIABLES POUR LA TERRE 17 | let earth_orbit_radius = 1; // Définissez le rayon de l'orbite de la Terre 18 | let earth_angle = 0; // Angle initial de la Terre 19 | let earth_orbit_speed = 0.005; // La vitesse de rotation de la Terre autour du soleil 20 | let earth_self_rotation_speed = 0.005; // Vous pouvez ajuster cette valeur pour contrôler la vitesse 21 | let earthTexture; 22 | 23 | // VARIABLES POUR LES PYRAMIDES 24 | let pyramid_orbit_speed = 0.005; // Vitesse de rotation de la pyramide autour de la Terre 25 | let pyramids = []; // Nouvelle structure pour suivre les pyramides 26 | let pyramid_model; 27 | 28 | // VARIABLES POUR LE SATELLITE 29 | let satellite_orbit_radius = earth_orbit_radius / 8; 30 | let satellite_angle = 0; // Angle initial du satellite autour de la Terre 31 | let satellite_orbit_speed = 0.01; // Vitesse de rotation du satellite autour de la Terre 32 | let satellite; // Variable globale pour le satellite 33 | 34 | // VARIABLES POUR L'ORBITE DU SATELLITE 35 | let satelliteOrbit; 36 | let L2_orbit_angle = 0; // Angle initial de l'orbite 37 | const L2_orbit_speed = 0.005; // Vitesse de rotation de l'orbite 38 | 39 | // VARIBLES POUR LES ETOILES 40 | let starsPositions; 41 | let starTexture; 42 | 43 | // VARIABLES CONTENANT LES COORDONNES DES POINTS DE LAGRANGE 44 | let L1_position; 45 | let L2_position; 46 | let L3_position; 47 | let L4_position; 48 | let L5_position; 49 | 50 | 51 | /* Création de la scène 3D */ 52 | function createScene() { 53 | // Initialiser une nouvelle scène Three.js 54 | scene = new THREE.Scene(); 55 | // Définir la couleur d'arrière-plan de la scène en noir 56 | scene.background = new THREE.Color(0, 0, 0); 57 | 58 | // Appeler la fonction pour dessiner les étoiles dans la scène 59 | draw_stars(); 60 | 61 | // Dessiner le soleil et l'ajouter à la scène 62 | const sun = draw_sun(); 63 | scene.add(sun); 64 | 65 | // Dessiner l'orbite de la planète et l'ajouter à la scène 66 | const orbit = draw_orbit(); 67 | scene.add(orbit); 68 | 69 | // Dessiner la Terre et l'ajouter à la scène 70 | earth = draw_earth(); 71 | scene.add(earth); 72 | 73 | // Ajouter une source de lumière directionnelle à la scène 74 | add_light(); 75 | 76 | // Dessiner les points de Lagrange et la seconde orbite (verte) autour du point L2 77 | draw_lagrange_points(); 78 | 79 | // Initialiser et ajouter l'orbite verte du satellite autour du point L2 à la scène 80 | satelliteOrbit = draw_orbit(0x00ff00, satellite_orbit_radius); // Couleur verte pour l'orbite 81 | satelliteOrbit.position.copy(L2_position); // Positionner cette orbite autour du point L2 82 | scene.add(satelliteOrbit); 83 | 84 | // Créer une caméra avec un champ de vision, un ratio d'aspect, et des plans de coupe 85 | camera = new THREE.PerspectiveCamera(45, canvas.width / canvas.height, 0.1, 100); 86 | // Positionner la caméra dans la scène 87 | camera.position.x = 2; 88 | camera.position.y = 2; 89 | camera.position.z = 1; 90 | // Orienter la caméra vers le centre de la scène 91 | camera.lookAt(0, 0, 0); 92 | // Ajouter la caméra à la scène 93 | scene.add(camera); 94 | 95 | // Ajouter une lumière ambiante à la scène 96 | ambient_light = new THREE.AmbientLight("white", 0.0); 97 | scene.add(ambient_light); 98 | 99 | // Ajouter une lumière directionnelle et l'attacher à la caméra 100 | camera_light = new THREE.DirectionalLight("white", 0.0); 101 | camera.add(camera_light); 102 | } 103 | 104 | 105 | function generate_randomStars() { 106 | // TODO: générer les positions des étoiles 107 | let stars = []; 108 | for (let i = 0; i < 100; i++) { // Generer 100 etoiles 109 | let radius = 1 + Math.random(); // Rayon entre 1 et 2 110 | let theta = Math.random() * Math.PI * 2; // Angle du theta 111 | let phi = Math.acos((Math.random() * 2) - 1); // Angle phi pour une distribution uniforme sur la sphère 112 | let x = radius * Math.sin(phi) * Math.cos(theta); 113 | let y = radius * Math.sin(phi) * Math.sin(theta); 114 | let z = radius * Math.cos(phi); 115 | stars.push(new THREE.Vector3(x, y, z)); 116 | } 117 | return stars; 118 | } 119 | 120 | function generate_pyramid_IFS(){ 121 | // Coordonnées des sommets d'un tétraèdre (pyramide à base triangulaire) 122 | // IFS est utilisé ici pour définir une structure géométrique répétitive. 123 | // Chaque sommet est défini par ses coordonnées x, y, z dans l'espace 3D. 124 | const vertices = new Float32Array([ 125 | Math.sqrt(8/9), 0, -1/3, // v1 126 | -Math.sqrt(2/9), Math.sqrt(2/3), -1/3, // v2 127 | -Math.sqrt(2/9), -Math.sqrt(2/3), -1/3, // v3 128 | 0, 0, 1 // v4 129 | ]); 130 | 131 | // Indices des triangles formant les faces de la pyramide 132 | // Les indices sont des références aux points dans le tableau de sommets. 133 | // Chaque groupe de trois indices définit une face triangulaire de la pyramide. 134 | const indices = new Uint16Array([ 135 | 0, 1, 2, // Face 1: Utilise les sommets 1 (v1), 2 (v2) et 3 (v3) 136 | 0, 2, 3, // Face 2: Utilise les sommets 1 (v1), 3 (v3) et 4 (v4) 137 | 0, 3, 1, // Face 3: Utilise les sommets 1 (v1), 4 (v4) et 2 (v2) 138 | 1, 3, 2 // Base: Utilise les sommets 2 (v2), 4 (v4) et 3 (v3) 139 | ]); 140 | 141 | const geometry = new THREE.BufferGeometry(); 142 | geometry.setIndex(new THREE.BufferAttribute(indices, 1)); 143 | geometry.setAttribute('position', new THREE.BufferAttribute(vertices, 3)); 144 | 145 | // Calcul des vecteurs normaux pour chaque face de la pyramide 146 | // Chaque normale est calculée en utilisant le produit vectoriel des arêtes de chaque face 147 | const normals = new Float32Array([ 148 | // normal = (B - A) x (C - A) puis normalisation 149 | 150 | // Normale de la face 1 (calculée à partir des sommets v1, v2, v3) 151 | // Produit vectoriel des vecteurs (v2-v1) et (v3-v1), puis normalisation du résultat 152 | // ici la normale est [0, 0, 1], car la face est parallèle au plan XY 153 | 0.0, 0.0, 1.0, // Normale de la face 1 154 | 155 | // Normale de la face 2 (calculée à partir des sommets v1, v3, v4) 156 | // Produit vectoriel des vecteurs (v3-v1) et (v4-v1), puis normalisation du résultat 157 | // Le résultat [-0.48666, 0.81110, -0.32444] est la normale unitaire de cette face 158 | -0.48666426339228763, 0.8111071056538127, -0.3244428422615251, // Normale de la face 2 159 | 160 | // Normale de la face 3 (calculée à partir des sommets v1, v4, v2) 161 | // Produit vectoriel des vecteurs (v4-v1) et (v2-v1), puis normalisation du résultat 162 | // Le résultat [-0.48666, -0.81110, -0.32444] est la normale unitaire de cette face 163 | -0.48666426339228763, -0.8111071056538127, -0.3244428422615251, // Normale de la face 3 164 | 165 | // Normale de la base (calculée à partir des sommets v2, v4, v3) 166 | // Produit vectoriel des vecteurs (v4-v2) et (v3-v2), puis normalisation du résultat 167 | // Le résultat [0.98639, 0, -0.16439] est la normale unitaire de cette face 168 | 0.9863939238321436, 0.0, -0.1643989873053573 // Normale de la base 169 | ]); 170 | 171 | // Assigner les normaux calculés à la géométrie 172 | geometry.setAttribute('normal', new THREE.BufferAttribute(normals, 3)); 173 | 174 | // Utilisation de MeshPhongMaterial qui réagit à la lumière 175 | const material = new THREE.MeshBasicMaterial({ 176 | color: 0xffffff, // Couleur de base 177 | emissive: 0x111111, // Faible couleur d'émission pour un léger effet lumineux 178 | 179 | }); 180 | 181 | let model = { geometry, material }; 182 | 183 | return model; 184 | } 185 | 186 | 187 | function draw_lagrange_points() { 188 | const pyramidSize = new THREE.Vector3(0.03, 0.03, 0.03); // Définir la taille de la pyramide 189 | const sunPosition = new THREE.Vector3(0, 0, 0); // Le Soleil est au centre de la scene 190 | 191 | pyramids.push({ 192 | mesh: draw_pyramid(pyramid_model, "red", L1_position, pyramidSize), 193 | orbitRadius: 0.7, 194 | orbitSpeed: pyramid_orbit_speed, 195 | angle: 0, // Theta = 0 196 | orbitCenter: sunPosition 197 | }); 198 | 199 | pyramids.push({ 200 | mesh: draw_pyramid(pyramid_model, "green", L2_position, pyramidSize), 201 | orbitRadius: 1.3, 202 | orbitSpeed: pyramid_orbit_speed, 203 | angle: 0, // Theta = 0 204 | orbitCenter: sunPosition 205 | }); 206 | 207 | pyramids.push({ 208 | mesh: draw_pyramid(pyramid_model, "blue", L3_position, pyramidSize), 209 | orbitRadius: 1.0, 210 | orbitSpeed: pyramid_orbit_speed, 211 | angle: Math.PI, // Theta = 180 degrees 212 | orbitCenter: sunPosition 213 | }); 214 | 215 | pyramids.push({ 216 | mesh: draw_pyramid(pyramid_model, "yellow", L4_position, pyramidSize), 217 | orbitRadius: 1.0, 218 | orbitSpeed: pyramid_orbit_speed, 219 | angle: Math.PI / 3, // Theta = 60 degrees 220 | orbitCenter: sunPosition 221 | }); 222 | 223 | pyramids.push({ 224 | mesh: draw_pyramid(pyramid_model, "cyan", L5_position, pyramidSize), 225 | orbitRadius: 1.0, 226 | orbitSpeed: pyramid_orbit_speed, 227 | angle: -Math.PI / 3, // Theta = -60 degrees equivalent de 5 * Math.PI / 3 228 | orbitCenter: sunPosition 229 | }); 230 | } 231 | 232 | // Cette fonction aide à convertir les coordonnées polaires (r, theta) en coordonnées cartésiennes 233 | function polarToCartesian(r, theta) { 234 | return new THREE.Vector3(r * Math.cos(theta), 0, r * Math.sin(theta)); 235 | } 236 | 237 | function draw_pyramid(model, color, position, size) { 238 | // Cloner le matériau du modèle de la pyramide pour créer une instance unique 239 | const pyramidMaterial = model.material.clone(); 240 | // Définir la couleur du matériau de la pyramide en fonction de l'argument 'color' 241 | pyramidMaterial.color.set(color); 242 | // Créer un mesh (forme 3D) pour la pyramide en utilisant la géométrie et le matériau spécifiés 243 | const pyramid = new THREE.Mesh(model.geometry, pyramidMaterial); 244 | // Régler l'échelle de la pyramide en fonction de l'argument 'size' 245 | pyramid.scale.set(size.x, size.y, size.z); 246 | // Positionner la pyramide dans la scène en fonction de l'argument 'position' 247 | pyramid.position.set(position.x, position.y, position.z); 248 | 249 | // Ajouter la pyramide à la scène globale 250 | scene.add(pyramid); 251 | 252 | // Retourner la pyramide pour pouvoir l'utiliser ailleurs dans le code 253 | return pyramid; 254 | } 255 | 256 | 257 | function draw_sun() { 258 | const geometry = new THREE.SphereGeometry(0.1, 32, 32); // Sphere avec le rayon de 0.5 259 | 260 | const yellow = new THREE.Color(0xffff00); // Couleur jaune 261 | const orange = new THREE.Color(0xffa500); // Couleur orange 262 | 263 | // Interpoler entre jaune et orange 264 | const colorMix = yellow.lerp(orange, 0.5); // facteur d'interpolation (0.5 pour un mélange égal) 265 | const material = new THREE.MeshBasicMaterial({ color: colorMix }); // Materiau jaune sans illumination 266 | const sun = new THREE.Mesh(geometry, material); 267 | 268 | return sun; 269 | } 270 | 271 | function draw_earth() { 272 | // Créer le matériau de la Terre avec la texture appliquée 273 | const earthMaterial = new THREE.MeshLambertMaterial({ 274 | map: earthTexture // Utilise la texture importe chargée pour la Terre 275 | }); 276 | // Créer la géométrie sphérique de la Terre 277 | const earthGeometry = new THREE.SphereGeometry(0.1, 32, 32); // Rayon de 0.1, 32 segments en latitude et longitude 278 | // Créer le mesh de la Terre en utilisant la géométrie et le matériau 279 | const earthMesh = new THREE.Mesh(earthGeometry, earthMaterial); 280 | // Définir la position de la Terre sur son orbite 281 | earthMesh.position.set(1, 0, 0); // Position sur l'axe X à 1, Y et Z à 0 282 | 283 | // Retourner le mesh de la Terre pour utilisation dans d'autres parties du code 284 | return earthMesh; 285 | } 286 | 287 | 288 | 289 | function draw_stars() { 290 | // Création d'un matériau pour les étoiles avec la texture étoile chargée 291 | const starsMaterial = new THREE.PointsMaterial({ 292 | size: 0.03, // Définir la taille des points représentant les étoiles 293 | map: starTexture, // Utiliser la texture étoile chargée 294 | sizeAttenuation: true, // Activer l'atténuation de la taille en fonction de la distance 295 | }); 296 | 297 | // Création de la géométrie pour les étoiles 298 | const starsGeometry = new THREE.BufferGeometry(); 299 | // Transformer la liste des positions des étoiles en un attribut de position pour la géométrie 300 | const positionAttribute = new THREE.Float32BufferAttribute(starsPositions.flatMap(star => [star.x, star.y, star.z]), 3); 301 | starsGeometry.setAttribute('position', positionAttribute); // Assigner les positions des étoiles 302 | 303 | // Création de l'objet Points représentant l'ensemble des étoiles 304 | const stars = new THREE.Points(starsGeometry, starsMaterial); 305 | 306 | // Ajout de l'objet Points à la scène pour afficher les étoiles 307 | scene.add(stars); 308 | } 309 | 310 | 311 | 312 | function draw_orbit(orbitColor = 0xffffff, orbitRadius = 1) { 313 | // Création d'un tableau pour stocker les points de l'orbite 314 | const points = []; 315 | // Boucle pour générer un cercle de points représentant l'orbite 316 | for (let i = 0; i <= 360; i++) { 317 | let rad = THREE.MathUtils.degToRad(i); // Conversion degrés en radians 318 | // Calcul et ajout des points de l'orbite dans le plan x-z 319 | points.push(new THREE.Vector3(orbitRadius * Math.cos(rad), 0, orbitRadius * Math.sin(rad))); 320 | } 321 | 322 | // Création de la géométrie à partir des points de l'orbite 323 | const geometry = new THREE.BufferGeometry().setFromPoints(points); 324 | // Création du matériau pour le tracé de l'orbite 325 | const material = new THREE.LineBasicMaterial({ color: orbitColor }); 326 | // Création de l'objet Line pour représenter l'orbite 327 | const orbit = new THREE.Line(geometry, material); 328 | 329 | // Retourner l'objet Line représentant l'orbite 330 | return orbit; 331 | } 332 | 333 | 334 | function add_light() { 335 | const light = new THREE.PointLight(0xffffff, 1, 100); 336 | light.position.set(0, 0, 0); // La lumière vient du soleil 337 | 338 | scene.add(light); 339 | } 340 | 341 | 342 | function animate() { 343 | // Ajout d'une lumière de point de vue 344 | let camera_light_intensity = document.getElementById("toggleViewlight").checked; 345 | if (camera_light_intensity) { 346 | camera_light.intensity = 1.0; 347 | } else { 348 | camera_light.intensity = 0.0; 349 | } 350 | 351 | // Ajout d'une lumière ambiante 352 | let ambient_light_intensity = document.getElementById("controlAmbientLight").value; 353 | ambient_light.intensity = ambient_light_intensity/ 100; 354 | 355 | // Affichage du gizmo pour l'interaction avec la souris 356 | let acrball_gizmo = document.getElementById("toggleGizmo"); 357 | if (acrball_gizmo.checked) { 358 | controls.setGizmosVisible(true); 359 | } else { 360 | controls.setGizmosVisible(false); 361 | } 362 | 363 | // Contrôle de l'animation 364 | let run_animation = document.getElementById("toggleAnimation"); 365 | if (run_animation.checked) { 366 | // Mise à jour de l'angle de la Terre 367 | earth.rotateY(earth_self_rotation_speed); 368 | earth_angle += earth_orbit_speed; 369 | // Conversion en coordonnees cartesiennes 370 | earth.position.x = earth_orbit_radius * Math.cos(earth_angle); 371 | earth.position.z = earth_orbit_radius * Math.sin(earth_angle); 372 | 373 | // Mise à jour de l'angle de l'orbite de L2 autour du soleil 374 | L2_orbit_angle += L2_orbit_speed; 375 | 376 | // Calculer la nouvelle position de L2 autour du soleil 377 | const satelliteOrbit_x = L2_position.x * Math.cos(L2_orbit_angle); 378 | const satelliteOrbit_z = L2_position.x * Math.sin(L2_orbit_angle); 379 | 380 | // Mettre à jour la position de l'orbite verte pour qu'elle suive L2 tout en tournant autour de son propre centre 381 | satelliteOrbit.position.set(satelliteOrbit_x, 0, satelliteOrbit_z); 382 | 383 | // Mettre à jour l'angle et la position du satellite 384 | if (satellite) { // Vérifier si le satellite a été chargé 385 | satellite_angle += satellite_orbit_speed; // Mettre à jour l'angle du satellite 386 | 387 | const satelliteX = satelliteOrbit_x + satellite_orbit_radius * Math.cos(satellite_angle); 388 | const satelliteZ = satelliteOrbit_z + satellite_orbit_radius * Math.sin(satellite_angle); 389 | 390 | // Définir la nouvelle position du satellite 391 | satellite.position.set(satelliteX, 0, satelliteZ); 392 | } 393 | 394 | // Pour chaque pyramide dans le tableau pyramides 395 | pyramids.forEach((pyramidData) => { 396 | // Incrémenter l'angle de la pyramide en fonction de sa vitesse orbitale 397 | pyramidData.angle += pyramidData.orbitSpeed; 398 | 399 | // Convertir l'angle en coordonnées cartésiennes par rapport au centre de l'orbite 400 | // Calculer la position x de la pyramide en fonction de son rayon orbital et de son angle actuel 401 | let pyramidX = pyramidData.orbitCenter.x + pyramidData.orbitRadius * Math.cos(pyramidData.angle); 402 | // Calculer la position z de la pyramide de la même manière 403 | let pyramidZ = pyramidData.orbitCenter.z + pyramidData.orbitRadius * Math.sin(pyramidData.angle); 404 | 405 | // Mettre à jour la position de la pyramide avec les nouvelles coordonnées x et z 406 | pyramidData.mesh.position.set(pyramidX, pyramidData.mesh.position.y, pyramidZ); 407 | }); 408 | 409 | } 410 | last_render = Date.now(); 411 | requestAnimationFrame(animate); 412 | renderer.render(scene, camera); 413 | 414 | } 415 | 416 | function init() { 417 | try { 418 | canvas = document.getElementById("canvas"); 419 | 420 | renderer = new THREE.WebGLRenderer({canvas: canvas, antialias: true}); 421 | renderer.setSize( canvas.clientWidth, canvas.clientHeight ); 422 | document.body.appendChild(renderer.domElement); 423 | 424 | 425 | } 426 | catch (e) { 427 | document.getElementById("canvas-holder").innerHTML="

Sorry, an error occurred:
" + 428 | e + "

"; 429 | return; 430 | } 431 | 432 | // Initialisation de la scène 433 | starsPositions = generate_randomStars(); 434 | pyramid_model = generate_pyramid_IFS(); 435 | 436 | L1_position = new THREE.Vector3(0.7, 0, 0); // r = 0.7, theta = 0 437 | L2_position = new THREE.Vector3(1.3, 0, 0); // r = 1.3, theta = 0 438 | L3_position = new THREE.Vector3(-1.0, 0, 0); // r = 1.0, theta = 180 439 | L4_position = polarToCartesian(1.0, THREE.MathUtils.degToRad(60)); // r = 1.0, theta = 60 440 | L5_position = polarToCartesian(1.0, THREE.MathUtils.degToRad(-60)); // r = 1.0, theta = -60 441 | 442 | const textureLoader = new THREE.TextureLoader(); 443 | // Charger la texture pour les étoiles 444 | starTexture = textureLoader.load('../tp2_etoile.png'); 445 | // Charger la texture pour la Terre 446 | earthTexture = textureLoader.load('../tp2_texture_planete.jpg'); 447 | 448 | const loader = new GLTFLoader(); 449 | 450 | // Charger le modèle 3D du satellite 451 | loader.load('../tp2_satellite.glb', function (gltf) { 452 | // Réduire la taille du modèle 453 | gltf.scene.scale.set(0.01, 0.01, 0.01); 454 | // Définir la position du satellite près de L2 455 | gltf.scene.position.copy(new THREE.Vector3(L2_position.x + satellite_orbit_radius, 0, 0)); 456 | // Ajuster la rotation du satellite pour qu'il soit aligné correctement 457 | gltf.scene.rotation.x = -(Math.PI / 2); 458 | // Stocker la scène du satellite dans la variable globale 'satellite' 459 | satellite = gltf.scene; 460 | // Ajouter le modèle du satellite à la scène près de L2 461 | scene.add(satellite); 462 | }, undefined, function (error) { 463 | // Afficher les erreurs de chargement dans la console 464 | console.error(error); 465 | }); 466 | 467 | 468 | // Création de la scène 3D 469 | createScene(); 470 | 471 | // Ajout de l'interactivité avec la souris 472 | controls = new ArcballControls(camera, canvas, scene); 473 | controls.setGizmosVisible(false); 474 | 475 | // Animation de la scèene (appelée toutes les 30 ms) 476 | animate(); 477 | } 478 | 479 | init(); -------------------------------------------------------------------------------- /etoile.kra: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EmilSurk/LagrangeView/5b001d9713f637822be9b2fe9adb8058db99b66b/etoile.kra -------------------------------------------------------------------------------- /etoile.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EmilSurk/LagrangeView/5b001d9713f637822be9b2fe9adb8058db99b66b/etoile.png -------------------------------------------------------------------------------- /satellite.blend: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EmilSurk/LagrangeView/5b001d9713f637822be9b2fe9adb8058db99b66b/satellite.blend -------------------------------------------------------------------------------- /satellite.glb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EmilSurk/LagrangeView/5b001d9713f637822be9b2fe9adb8058db99b66b/satellite.glb -------------------------------------------------------------------------------- /satellite.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EmilSurk/LagrangeView/5b001d9713f637822be9b2fe9adb8058db99b66b/satellite.png -------------------------------------------------------------------------------- /texture_planete.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EmilSurk/LagrangeView/5b001d9713f637822be9b2fe9adb8058db99b66b/texture_planete.jpg -------------------------------------------------------------------------------- /texture_planete.kra: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EmilSurk/LagrangeView/5b001d9713f637822be9b2fe9adb8058db99b66b/texture_planete.kra -------------------------------------------------------------------------------- /universe-visualization.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EmilSurk/LagrangeView/5b001d9713f637822be9b2fe9adb8058db99b66b/universe-visualization.png --------------------------------------------------------------------------------