Solar System#
This tutorial makes use of Geometries and Animations to create an animated model of the Solar System, with the sun and planets represented as spheres and the asteroid belts with PointClouds.
Data for radii, orbital distances and orbital speeds is obtained from NASA, and scaled appropriately in order to visualize with maximal fidelity.
import vivid3d
import numpy as np
import pandas as pd
import math
# Making the Base Data
names = ['Sun', 'Mercury', 'Venus', 'Earth', 'Mars', 'Jupyter', 'Saturn', 'Uranus', 'Neptune']
distances = [0, 1.8, 2, 2.4, 3, 7.4, 12.6, 24.2, 38]
radii = [1, 0.05, 0.125, 0.128, 0.07, 0.35, 0.3, 0.255, 0.255]
colors = ['orange', 'coral', 'yellowgreen', 'royalblue', 'brown', 'tan', 'yellow', 'turquoise', 'cyan']
data = pd.DataFrame(list(zip(names, distances, radii, colors)), columns=['name', 'orbit', 'radius', 'color'])
data
name | orbit | radius | color | |
---|---|---|---|---|
0 | Sun | 0.0 | 1.000 | orange |
1 | Mercury | 1.8 | 0.050 | coral |
2 | Venus | 2.0 | 0.125 | yellowgreen |
3 | Earth | 2.4 | 0.128 | royalblue |
4 | Mars | 3.0 | 0.070 | brown |
5 | Jupyter | 7.4 | 0.350 | tan |
6 | Saturn | 12.6 | 0.300 | yellow |
7 | Uranus | 24.2 | 0.255 | turquoise |
8 | Neptune | 38.0 | 0.255 | cyan |
We’ll define a helper functions to help create the objects, and populate our solar_system Animation object with them:
planet_material = vivid3d.Material(1, 1, 0.9) # Planets are mostly rough surfaces
def create_solar_object(orbit, radius, color, name):
sphere = vivid3d.create_sphere([0,0,0], radius, 50, 50, color, 1, name) # creating the planetary object
a = 2 * math.pi * np.random.normal();
sphere.move([orbit * math.cos(a), 0, orbit * math.sin(a)]) # placing it randomly along its orbit
sphere.material = planet_material # setting the material
return vivid3d.Model(sphere)
# Creating the animation object:
solar_system = vivid3d.Animation()
for i, (name, orbit, radius, color) in data.iterrows():
solar_system.add_model(create_solar_object(orbit, radius, color, name))
# Our First object, the Sun, is a star and as such should also be emissive:
solar_system.frames[0].model.meshes[0].material.emission_strength = 5
- Our Solar System also has two asteroid belts:
The first is located between Mars and Jupyter, and is called The Asteroid Belt
The second is located beyond Neptune, and is called The Kuiper Belt
We will model the asteroids as a circular PointCloud:
asteroid_material = vivid3d.Material(1, .8, 0.7) # Asteroids are primarily heavy metallic elements, with a rough semi-reflective texture
def create_asteroid_field(distance, scale, count):
points = []
for i in range(count):
r = np.random.normal(distance, scale) # Modelling the asteroid belts as a normal distribution around an orbital distance
a = 2 * math.pi * np.random.normal();
z = np.random.normal(0, 0.15)
points.append([r * math.cos(a), z, r * math.sin(a)]) # Placing randomly along circle of radius r
asteroids = vivid3d.PointCloud(points, 'black')
asteroids.material = asteroid_material
return vivid3d.Model(asteroids)
# Asteroid Belt, Kuiper Belt
solar_system.add_model(create_asteroid_field(5, 0.6, 1_000)) # Populate the inner Asteroid Belt with 1,000 points between the orbits of Mars and Jupyter
solar_system.add_model(create_asteroid_field(55, 5, 5_000)) # Populate the outer Kuiper Belt with 5,000 points past the orbit of Neptune
Finally, we will animate the solar system by setting the rotate_animation property of each frame of our solar_system to the appropriate orbital speed:
rotation_speeds = [0, 10, 35, 30, 24, 13, 9.7, 7, 5.4, 2, 1]
for frame, speed in zip(solar_system.frames, rotation_speeds):
frame.rotate_animation = [0, speed, 0] # rotating around the y axis
# Slowing down the framerate
solar_system.ticks_per_second = 5
solar_system.show()