.. DO NOT EDIT. .. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY. .. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE: .. "auto_examples/01_introductory/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_01_introductory_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 itertools import numpy as np from fury import actor, io, ui, utils, window from fury.data import fetch_viz_textures, read_viz_icons, read_viz_textures .. GENERATED FROM PYTHON SOURCE LINES 20-21 Create a scene to start. .. GENERATED FROM PYTHON SOURCE LINES 21-38 .. code-block:: Python scene = window.Scene() # Create a panel and the start/pause buttons panel = ui.Panel2D(size=(300, 100), color=(1, 1, 1), align='right') panel.center = (400, 50) pause_button = ui.Button2D(icon_fnames=[('square', read_viz_icons(fname='pause2.png'))]) start_button = ui.Button2D(icon_fnames=[('square', read_viz_icons(fname='play3.png'))]) # Add the buttons on the panel panel.add_element(pause_button, (0.25, 0.33)) panel.add_element(start_button, (0.66, 0.33)) .. GENERATED FROM PYTHON SOURCE LINES 39-41 Define information relevant for each planet actor including its texture name, relative position, and scale. .. GENERATED FROM PYTHON SOURCE LINES 41-96 .. code-block:: Python planets_data = [ { 'filename': '8k_mercury.jpg', 'position': 7, 'earth_days': 58, 'scale': (0.4, 0.4, 0.4), }, { 'filename': '8k_venus_surface.jpg', 'position': 9, 'earth_days': 243, 'scale': (0.6, 0.6, 0.6), }, { 'filename': '1_earth_8k.jpg', 'position': 11, 'earth_days': 1, 'scale': (0.4, 0.4, 0.4), }, { 'filename': '8k_mars.jpg', 'position': 13, 'earth_days': 1, 'scale': (0.8, 0.8, 0.8), }, {'filename': 'jupiter.jpg', 'position': 16, 'earth_days': 0.41, 'scale': (2, 2, 2)}, { 'filename': '8k_saturn.jpg', 'position': 19, 'earth_days': 0.45, 'scale': (2, 2, 2), }, { 'filename': '8k_saturn_ring_alpha.png', 'position': 19, 'earth_days': 0.45, 'scale': (3, 0.5, 3), }, { 'filename': '2k_uranus.jpg', 'position': 22, 'earth_days': 0.70, 'scale': (1, 1, 1), }, { 'filename': '2k_neptune.jpg', 'position': 25, 'earth_days': 0.70, 'scale': (1, 1, 1), }, {'filename': '8k_sun.jpg', 'position': 0, 'earth_days': 27, 'scale': (5, 5, 5)}, ] 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/skoudoro/.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/skoudoro/.fury/textures') .. GENERATED FROM PYTHON SOURCE LINES 97-101 To take advantage of the previously defined data structure we are going to create an auxiliary function that will load and apply the respective texture, set its respective properties (relative position and scale), and add the actor to a previously created scene. .. GENERATED FROM PYTHON SOURCE LINES 101-128 .. code-block:: Python def init_planet(planet_data): """Initialize a planet actor. Parameters ---------- planet_data : dict The planet_data is a dictionary, and the keys are filename(texture), position and scale. Returns ------- planet_actor: actor The corresponding sphere actor with texture applied. """ planet_file = read_viz_textures(planet_data['filename']) planet_image = io.load_image(planet_file) planet_actor = actor.texture_on_sphere(planet_image) planet_actor.SetPosition(planet_data['position'], 0, 0) if planet_data['filename'] != '8k_saturn_ring_alpha.png': utils.rotate(planet_actor, (90, 1, 0, 0)) planet_actor.SetScale(planet_data['scale']) scene.add(planet_actor) return planet_actor .. GENERATED FROM PYTHON SOURCE LINES 129-132 Use the ``map`` function to create actors for each of the texture files in the ``planet_files`` list. Then, assign each actor to its corresponding actor in the list. .. GENERATED FROM PYTHON SOURCE LINES 132-147 .. code-block:: Python planet_actor_list = list(map(init_planet, planets_data)) mercury_actor = planet_actor_list[0] venus_actor = planet_actor_list[1] earth_actor = planet_actor_list[2] mars_actor = planet_actor_list[3] jupiter_actor = planet_actor_list[4] saturn_actor = planet_actor_list[5] saturn_rings_actor = planet_actor_list[6] uranus_actor = planet_actor_list[7] neptune_actor = planet_actor_list[8] sun_actor = planet_actor_list[9] .. GENERATED FROM PYTHON SOURCE LINES 148-152 Define the gravitational constant G, the orbital radii of each of the planets, and the central mass of the sun. The gravity and mass will be used to calculate the orbital position, so multiply these two together to create a new constant, which we will call miu. .. GENERATED FROM PYTHON SOURCE LINES 152-161 .. code-block:: Python g_exponent = np.float_power(10, -11) g_constant = 6.673 * g_exponent m_exponent = 1073741824 # np.power(10, 30) m_constant = 1.989 * m_exponent miu = m_constant * g_constant .. GENERATED FROM PYTHON SOURCE LINES 162-166 Let's define two functions that will help us calculate the position of each planet as it orbits around the sun: ``get_orbit_period`` and ``get_orbital_position``, using the constant miu and the orbital radii of each planet. .. GENERATED FROM PYTHON SOURCE LINES 166-179 .. code-block:: Python def get_orbit_period(radius): return 2 * np.pi * np.sqrt(np.power(radius, 3) / miu) def get_orbital_position(radius, time): orbit_period = get_orbit_period(radius) x = radius * np.cos((-2 * np.pi * time) / orbit_period) y = radius * np.sin((-2 * np.pi * time) / orbit_period) return x, y .. GENERATED FROM PYTHON SOURCE LINES 180-183 Let's define a function to rotate the planet actor axially, we'll be defining axis of each planet and angle by which it should be rotated using ``rotate_axial`` funtction .. GENERATED FROM PYTHON SOURCE LINES 183-192 .. code-block:: Python def rotate_axial(actor, time, radius): axis = (0, radius, 0) angle = 50 / time utils.rotate(actor, (angle, axis[0], axis[1], axis[2])) return angle .. GENERATED FROM PYTHON SOURCE LINES 193-194 Let's change the camera position to visualize the planets better. .. GENERATED FROM PYTHON SOURCE LINES 194-197 .. code-block:: Python scene.set_camera(position=(-20, 60, 100)) .. GENERATED FROM PYTHON SOURCE LINES 198-200 Next, create a ShowManager object. The ShowManager class is the interface between the scene, the window and the interactor. .. GENERATED FROM PYTHON SOURCE LINES 200-206 .. code-block:: Python showm = window.ShowManager( scene, size=(900, 768), reset_camera=False, order_transparent=True ) scene.add(panel) .. GENERATED FROM PYTHON SOURCE LINES 207-210 Next, let's focus on creating the animation. We can determine the duration of animation with using the ``counter``. Use itertools to avoid global variables. .. GENERATED FROM PYTHON SOURCE LINES 210-213 .. code-block:: Python counter = itertools.count() .. GENERATED FROM PYTHON SOURCE LINES 214-216 Define one new function to use in ``timer_callback`` to update the planet positions ``update_planet_position``. .. GENERATED FROM PYTHON SOURCE LINES 216-224 .. code-block:: Python def update_planet_position(r_planet, planet_actor, cnt): pos_planet = get_orbital_position(r_planet, cnt) planet_actor.SetPosition(pos_planet[0], 0, pos_planet[1]) return pos_planet .. GENERATED FROM PYTHON SOURCE LINES 225-227 ``calculate_path`` function is for calculating the path/orbit of every planet. .. GENERATED FROM PYTHON SOURCE LINES 227-237 .. code-block:: Python def calculate_path(r_planet, c): planet_track = [ [get_orbital_position(r_planet, i)[0], 0, get_orbital_position(r_planet, i)[1]] for i in range(c) ] return planet_track .. GENERATED FROM PYTHON SOURCE LINES 238-243 First we are making a list that will contain radius from `planets_data`. Here we are not taking the radius of orbit/path for sun and saturn ring. `planet_actors` will contain all the planet actors. `r_times` will contain time taken (in days) by the planets to rotate around itself. .. GENERATED FROM PYTHON SOURCE LINES 243-271 .. code-block:: Python r_planets = [ p_data['position'] for p_data in planets_data if 'sun' not in p_data['filename'] if 'saturn_ring' not in p_data['filename'] ] planet_actors = [ mercury_actor, venus_actor, earth_actor, mars_actor, jupiter_actor, saturn_actor, uranus_actor, neptune_actor, ] sun_data = { 'actor': sun_actor, 'position': planets_data[9]['position'], 'earth_days': planets_data[9]['earth_days'], } r_times = [p_data['earth_days'] for p_data in planets_data] .. GENERATED FROM PYTHON SOURCE LINES 272-273 Here we are calculating and updating the path/orbit before animation starts. .. GENERATED FROM PYTHON SOURCE LINES 273-276 .. code-block:: Python planet_tracks = [calculate_path(rplanet, rplanet * 85) for rplanet in r_planets] .. GENERATED FROM PYTHON SOURCE LINES 277-279 This is for orbit visualization. We are using line actor for orbits. After creating an actor we add it to the scene. .. GENERATED FROM PYTHON SOURCE LINES 279-283 .. code-block:: Python orbit_actor = actor.line(planet_tracks, colors=(1, 1, 1), linewidth=0.1) scene.add(orbit_actor) .. GENERATED FROM PYTHON SOURCE LINES 284-288 Define the ``timer_callback`` function, which controls what events happen at certain times, using the counter. Update the position of each planet actor using ``update_planet_position,`` assigning the x and y values of each planet's position with the newly calculated ones. .. GENERATED FROM PYTHON SOURCE LINES 288-311 .. code-block:: Python def timer_callback(_obj, _event): cnt = next(counter) showm.render() # Rotating the sun actor rotate_axial(sun_actor, sun_data['earth_days'], 1) for r_planet, p_actor, r_time in zip(r_planets, planet_actors, r_times): # if the planet is saturn then we also need to update the position # of its rings. if p_actor == saturn_actor: pos_saturn = update_planet_position(19, saturn_actor, cnt) saturn_rings_actor.SetPosition(pos_saturn[0], 0, pos_saturn[1]) else: update_planet_position(r_planet, p_actor, cnt) rotate_axial(p_actor, r_time, r_planet) if cnt == 2000: showm.exit() .. GENERATED FROM PYTHON SOURCE LINES 312-313 We add a callback to each button to perform some action. .. GENERATED FROM PYTHON SOURCE LINES 313-327 .. code-block:: Python def start_animation(i_ren, _obj, _button): showm.add_timer_callback(True, 10, timer_callback) def pause_animation(i_ren, _obj, _button): showm.destroy_timers() start_button.on_left_mouse_button_clicked = start_animation pause_button.on_left_mouse_button_clicked = pause_animation .. GENERATED FROM PYTHON SOURCE LINES 328-329 Watch the planets orbit the sun in your new animation! .. GENERATED FROM PYTHON SOURCE LINES 329-335 .. code-block:: Python showm.add_timer_callback(True, 10, timer_callback) showm.start() window.record(showm.scene, size=(900, 768), out_path='viz_solar_system_animation.png') .. image-sg:: /auto_examples/01_introductory/images/sphx_glr_viz_solar_system_001.png :alt: viz solar system :srcset: /auto_examples/01_introductory/images/sphx_glr_viz_solar_system_001.png :class: sphx-glr-single-img .. rst-class:: sphx-glr-timing **Total running time of the script:** (0 minutes 31.865 seconds) .. _sphx_glr_download_auto_examples_01_introductory_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 ` .. only:: html .. rst-class:: sphx-glr-signature `Gallery generated by Sphinx-Gallery `_