.. DO NOT EDIT. .. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY. .. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE: .. "auto_examples/04_demos/viz_solar_system.py" .. LINE NUMBERS ARE GIVEN BELOW. .. only:: html .. note:: :class: sphx-glr-download-link-note :ref:`Go to the end ` to download the full example code. .. rst-class:: sphx-glr-example-title .. _sphx_glr_auto_examples_04_demos_viz_solar_system.py: ======================= Solar System Animation ======================= In this tutorial, we will create an animation of the solar system using textured spheres. We will also show how to manipulate the position of these sphere actors in a timer_callback function to simulate orbital motion. .. GENERATED FROM PYTHON SOURCE LINES 11-19 .. code-block:: Python import numpy as np from scipy.spatial.transform import Rotation as Rot from fury import actor, window from fury.primitive import prim_sphere from fury.ui import PlaybackPanel from fury.data import fetch_viz_textures, read_viz_textures .. GENERATED FROM PYTHON SOURCE LINES 20-21 Create a scene to start. .. GENERATED FROM PYTHON SOURCE LINES 21-24 .. code-block:: Python scene = window.Scene() .. GENERATED FROM PYTHON SOURCE LINES 25-27 Define information relevant for each planet actor including its texture name, relative position, and scale. .. GENERATED FROM PYTHON SOURCE LINES 27-93 .. code-block:: Python planets_data = [ { "filename": "8k_mercury.jpg", "position": 8, "earth_days": 58.0, "scale": (0.3, 0.3, 0.3), }, { "filename": "8k_venus_surface.jpg", "position": 10, "earth_days": 243.0, "scale": (0.76, 0.76, 0.76), }, { "filename": "1_earth_8k.jpg", "position": 12, "earth_days": 1.0, "scale": (0.8, 0.8, 0.8), }, { "filename": "8k_mars.jpg", "position": 14, "earth_days": 1.03, "scale": (0.42, 0.42, 0.42), }, { "filename": "jupiter.jpg", "position": 20, "earth_days": 0.41, "scale": (2.5, 2.5, 2.5), }, { "filename": "8k_saturn.jpg", "position": 28, "earth_days": 0.45, "scale": (2.1, 2.1, 2.1), }, { "filename": "8k_saturn_ring_alpha.png", "position": 28, "earth_days": 0.45, "scale": (3.15, 0.5, 3.15), }, { "filename": "2k_uranus.jpg", "position": 38, "earth_days": 0.72, "scale": (1.3, 1.3, 1.3), }, { "filename": "2k_neptune.jpg", "position": 49, "earth_days": 0.67, "scale": (1.25, 1.25, 1.25), }, { "filename": "8k_sun.jpg", "position": 0, "earth_days": 27.0, "scale": (6.0, 6.0, 6.0), }, ] fetch_viz_textures() .. rst-class:: sphx-glr-script-out .. code-block:: none Dataset is already in place. If you want to fetch it again please first remove the folder /Users/maharshigor/.fury/textures ({'1_earth_8k.jpg': ('https://raw.githubusercontent.com/fury-gl/fury-data/master/textures/1_earth_8k.jpg', '0D66DC62768C43D763D3288CE67128AAED27715B11B0529162DC4117F710E26F'), '2_no_clouds_8k.jpg': ('https://raw.githubusercontent.com/fury-gl/fury-data/master/textures/2_no_clouds_8k.jpg', '5CF740C72287AF7B3ACCF080C3951944ADCB1617083B918537D08CBD9F2C5465'), '5_night_8k.jpg': ('https://raw.githubusercontent.com/fury-gl/fury-data/master/textures/5_night_8k.jpg', 'DF443F3E20C7724803690A350D9F6FDB36AD8EBC011B0345FB519A8B321F680A'), 'earth.ppm': ('https://raw.githubusercontent.com/fury-gl/fury-data/master/textures/earth.ppm', '34CE9AD183D7C7B11E2F682D7EBB84C803E661BE09E01ADB887175AE60C58156'), 'jupiter.jpg': ('https://raw.githubusercontent.com/fury-gl/fury-data/master/textures/jupiter.jpg', '5DF6A384E407BD0D5F18176B7DB96AAE1EEA3CFCFE570DDCE0D34B4F0E493668'), 'masonry.bmp': ('https://raw.githubusercontent.com/fury-gl/fury-data/master/textures/masonry.bmp', '045E30B2ABFEAE6318C2CF955040C4A37E6DE595ACE809CE6766D397C0EE205D'), 'moon-8k.jpg': ('https://raw.githubusercontent.com/fury-gl/fury-data/master/textures/moon_8k.jpg', '7397A6C2CE0348E148C66EBEFE078467DDB9D0370FF5E63434D0451477624839'), '8k_mercury.jpg': ('https://raw.githubusercontent.com/fury-gl/fury-data/master/textures/8k_mercury.jpg', '5C8BD885AE3571C6BA2CD34B3446B9C6D767E314BF0EE8C1D5C147CADD388FC3'), '8k_venus_surface.jpg': ('https://raw.githubusercontent.com/fury-gl/fury-data/master/textures/8k_venus_surface.jpg', '9BC21A50577ED8AC734CDA91058724C7A741C19427AA276224CE349351432C5B'), '8k_mars.jpg': ('https://raw.githubusercontent.com/fury-gl/fury-data/master/textures/8k_mars.jpg', '4CC52149924ABC6AE507D63032F994E1D42A55CB82C09E002D1A567FF66C23EE'), '8k_saturn.jpg': ('https://raw.githubusercontent.com/fury-gl/fury-data/master/textures/8k_saturn.jpg', '0D39A4A490C87C3EDABE00A3881A29BB3418364178C79C534FE0986E97E09853'), '8k_saturn_ring_alpha.png': ('https://raw.githubusercontent.com/fury-gl/fury-data/master/textures/8k_saturn_ring_alpha.png', 'F1F826933C9FF87D64ECF0518D6256B8ED990B003722794F67E96E3D2B876AE4'), '2k_uranus.jpg': ('https://raw.githubusercontent.com/fury-gl/fury-data/master/textures/2k_uranus.jpg', 'D15239D46F82D3EA13D2B260B5B29B2A382F42F2916DAE0694D0387B1204A09D'), '2k_neptune.jpg': ('https://raw.githubusercontent.com/fury-gl/fury-data/master/textures/2k_neptune.jpg', 'CB42EA82709741D28B0AF44D8B283CBC6DBD0C521A7F0E1E1E010ADE00977DF6'), '8k_sun.jpg': ('https://raw.githubusercontent.com/fury-gl/fury-data/master/textures/8k_sun.jpg', 'F22B1CFB306DDCE72A7E3B628668A0175B745038CE6268557CB2F7F1BDF98B9D'), '1_earth_16k.jpg': ('https://raw.githubusercontent.com/fury-gl/fury-data/master/textures/1_earth_16k.jpg', '7DD1DAC926101B5D7B7F2E952E53ACF209421B5CCE57C03168BCE0AAD675998A'), 'clouds.jpg': ('https://raw.githubusercontent.com/fury-gl/fury-data/master/textures/clouds.jpg', '85043336E023C4C9394CFD6D48D257A5564B4F895BFCEC01C70E4898CC77F003')}, '/Users/maharshigor/.fury/textures') .. GENERATED FROM PYTHON SOURCE LINES 94-95 Create Textured Spheres and adding to the Scene .. GENERATED FROM PYTHON SOURCE LINES 95-124 .. code-block:: Python def make_textured_sphere(planet_file, scale, position=None): verts, faces = prim_sphere(phi=60, theta=60) norms = np.linalg.norm(verts, axis=1, keepdims=True) norms[norms == 0] = 1.0 normalized = verts / norms x = normalized[:, 0] y = normalized[:, 1] z = normalized[:, 2] # Standard Mercator mapping: # longitude u: [-pi, pi] -> [0, 1] # latitude v: [-pi/2, pi/2] -> [0, 1] u = np.arctan2(x, z) / (2.0 * np.pi) + 0.5 v = 0.5 - np.arcsin(y) / np.pi uvs = np.column_stack((u, v)) planet_actor = actor.surface(verts, faces, texture=planet_file, texture_coords=uvs) planet_actor.local.scale = scale if position is not None: planet_actor.local.position = position return planet_actor .. GENERATED FROM PYTHON SOURCE LINES 125-126 Initialize all planet actors. .. GENERATED FROM PYTHON SOURCE LINES 126-154 .. code-block:: Python planets = [] for p_data in planets_data: filename = p_data["filename"] pos = p_data["position"] earth_days = p_data["earth_days"] scale = p_data["scale"] planet_file = read_viz_textures(filename) initial_pos = [float(pos), 0.0, 0.0] actor_obj = make_textured_sphere(planet_file, scale, position=initial_pos) scene.add(actor_obj) is_ring = "saturn_ring" in filename is_sun = "sun" in filename p_info = { "filename": filename, "actor": actor_obj, "radius": float(pos), "earth_days": float(earth_days), "is_ring": is_ring, "is_sun": is_sun, } planets.append(p_info) .. GENERATED FROM PYTHON SOURCE LINES 155-157 Define Constants and util functions to calculate orbital paths and positions for the visual track lines and planet movements. .. GENERATED FROM PYTHON SOURCE LINES 157-203 .. code-block:: Python g_exponent = np.float_power(10, -11) g_constant = 6.673 * g_exponent m_exponent = 1073741824 m_constant = 1.989 * m_exponent miu = m_constant * g_constant def get_orbit_period(radius): if radius == 0.0: return 1.0 return 2.0 * np.pi * np.sqrt(np.power(radius, 3) / miu) def get_orbital_position(radius, time): if radius == 0.0: return 0.0, 0.0 orbit_period = get_orbit_period(radius) x = radius * np.cos((-2.0 * np.pi * time) / orbit_period) z = radius * np.sin((-2.0 * np.pi * time) / orbit_period) return x, z r_planets = [ float(p["radius"]) for p in planets if not p["is_sun"] and not p["is_ring"] ] def calculate_path(r_planet): planet_track = [] orbit_period = get_orbit_period(r_planet) for t in np.linspace(0.0, orbit_period, 200): x, z = get_orbital_position(r_planet, t) planet_track.append([x, 0.0, z]) return planet_track planet_tracks = [calculate_path(rplanet) for rplanet in r_planets] orbit_actor = actor.line(planet_tracks, colors=(1.0, 1.0, 1.0)) orbit_actor.local.position = (0.0, 0.0, 0.0) scene.add(orbit_actor) .. GENERATED FROM PYTHON SOURCE LINES 204-205 Initialize PlaybackPanel UI. .. GENERATED FROM PYTHON SOURCE LINES 205-283 .. code-block:: Python playback_ui = PlaybackPanel(position=(50, 50), width=700, loop=True) playback_ui.final_time = 2000.0 scene.add(playback_ui) state = {"current_time": 0.0, "rotation_speed": 1.0} def update_planet_transforms(p_info, t): actor_obj = p_info["actor"] if p_info["is_sun"]: angle_axial = (50.0 / p_info["earth_days"]) * t R_axial = Rot.from_euler("y", angle_axial, degrees=True) actor_obj.local.rotation = R_axial.as_quat() actor_obj.local.position = [0.0, 0.0, 0.0] else: x, z = get_orbital_position(p_info["radius"], t) actor_obj.local.position = [x, 0.0, z] if p_info["is_ring"]: pass else: angle_axial = (50.0 / p_info["earth_days"]) * t R_axial = Rot.from_euler("y", angle_axial, degrees=True) actor_obj.local.rotation = R_axial.as_quat() def on_progress_changed(t): state["current_time"] = t for p in planets: update_planet_transforms(p, t) def on_speed_changed(s): state["rotation_speed"] = s playback_ui.on_progress_bar_changed = on_progress_changed playback_ui.on_speed_changed = on_speed_changed def update_playback_logic(show_manager_obj=None): """Callback to sync animation state with PlaybackPanel UI.""" if playback_ui._playing: step = 1.0 * state["rotation_speed"] state["current_time"] += step if state["current_time"] > playback_ui.final_time: if playback_ui._loop: state["current_time"] = 0.0 else: state["current_time"] = playback_ui.final_time playback_ui.pause() playback_ui.current_time = state["current_time"] for p in planets: update_planet_transforms(p, state["current_time"]) if __name__ == "__main__": ############################################################################## # Start the ShowManager and Register the Callback. showm = window.ShowManager( scene=scene, size=(900, 768), title="FURY Solar System Animation" ) camera = showm.screens[0].camera camera.local.position = (-30.0, 90.0, 150.0) camera.look_at((0.0, 0.0, 0.0)) showm.register_callback(update_playback_logic, 0.01, True, "PlaybackSync", showm) showm.start() showm.snapshot(fname="viz_solar_system_animation.png") .. rst-class:: sphx-glr-horizontal * .. image-sg:: /auto_examples/04_demos/images/sphx_glr_viz_solar_system_001.gif :alt: viz solar system :srcset: /auto_examples/04_demos/images/sphx_glr_viz_solar_system_001.gif :class: sphx-glr-multi-img * .. image-sg:: /auto_examples/04_demos/images/sphx_glr_viz_solar_system_002.png :alt: viz solar system :srcset: /auto_examples/04_demos/images/sphx_glr_viz_solar_system_002.png :class: sphx-glr-multi-img .. rst-class:: sphx-glr-script-out .. code-block:: none array([[[ 0, 0, 0, 255], [ 0, 0, 0, 255], [ 0, 0, 0, 255], ..., [ 0, 0, 0, 255], [ 0, 0, 0, 255], [ 0, 0, 0, 255]], [[ 0, 0, 0, 255], [ 0, 0, 0, 255], [ 0, 0, 0, 255], ..., [ 0, 0, 0, 255], [ 0, 0, 0, 255], [ 0, 0, 0, 255]], [[ 0, 0, 0, 255], [ 0, 0, 0, 255], [ 0, 0, 0, 255], ..., [ 0, 0, 0, 255], [ 0, 0, 0, 255], [ 0, 0, 0, 255]], ..., [[ 0, 0, 0, 255], [ 0, 0, 0, 255], [ 0, 0, 0, 255], ..., [ 0, 0, 0, 255], [ 0, 0, 0, 255], [ 0, 0, 0, 255]], [[ 0, 0, 0, 255], [ 0, 0, 0, 255], [ 0, 0, 0, 255], ..., [ 0, 0, 0, 255], [ 0, 0, 0, 255], [ 0, 0, 0, 255]], [[ 0, 0, 0, 255], [ 0, 0, 0, 255], [ 0, 0, 0, 255], ..., [ 0, 0, 0, 255], [ 0, 0, 0, 255], [ 0, 0, 0, 255]]], shape=(1536, 1800, 4), dtype=uint8) .. rst-class:: sphx-glr-timing **Total running time of the script:** (0 minutes 11.930 seconds) .. _sphx_glr_download_auto_examples_04_demos_viz_solar_system.py: .. only:: html .. container:: sphx-glr-footer sphx-glr-footer-example .. container:: sphx-glr-download sphx-glr-download-jupyter :download:`Download Jupyter notebook: viz_solar_system.ipynb ` .. container:: sphx-glr-download sphx-glr-download-python :download:`Download Python source code: viz_solar_system.py ` .. container:: sphx-glr-download sphx-glr-download-zip :download:`Download zipped: viz_solar_system.zip ` .. only:: html .. rst-class:: sphx-glr-signature `Gallery generated by Sphinx-Gallery `_