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:

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()