Animation de l’effet d’Eötvös
Cette page décrit l’effet d’Eötvös et son effet sur les mesures gravimétriques navales ou aéroportées. Elle montre également comment créer des cartes avec Python et comment convertir une série d’images en vidéo au format .mp4
.
L’effet Eötvös en gravimétrie
La Terre est en rotation autour de son axe et les objets situés à sa surface ressentent une accélération centrifuge. L’accélération centrifuge est perpendiculaire à l’axe de rotation de la Terre et pointe vers l’extérieur. Elle atteint une valeur maximale à l’équateur et est nulle aux pôles.
Deux véhicules qui partent du même endroit sur la surface terrestre et se déplacent à la même vitesse dans des directions opposées auront l’apparence de se déplacer à des vitesses très différentes quand on se place dans un référentiel externe à la Terre en rotation. On peut voir cet effet sur la vidéo suivante. Le code utilisé pour créer cette vidéo est détaillés plus bas.
Comme la vitesse des véhicules est inférieure à la vitesse de rotation de la Terre le véhicule bleu semble se déplacer très rapidement, alors que le véhicule rouge semble reculer! Conséquemment le véhicule bleu ressent une accélération centrifuge supérieure au véhicule rouge.
Cet effet n’est pas négligeable quand on prend des mesures gravimétriques sur un véhicule en mouvement, comme un bateau ou dans un aéronef. Il est important de comprendre cet effet pour apporter les corrections nécessaires aux données gravimétriques.
Animation avec Python
Importation des modules
import os
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.basemap import Basemap
from tqdm import tqdm # progress bar for creating the frames
Définition des paramètres du vidéo
# Define a temporary directory to hold the frames
# and a path for output video
tmp_dir = "./tmp/"
delete_tmp_after = True # flag to delete the frames after rendering
out_path = "./eotvos-effect-video.mp4"
# Choose colors for the map
ocean_map = plt.get_cmap('ocean')(230)
earth_map = plt.get_cmap('gist_earth')(150)
# Set the min and max view angles for the video
lat_view_angles = [15, 15]
lon_view_angles = [360, -360]
rotation_steps = 360 # 1 frame per degree
rotations = 10 # do 10 full rotations
# Parameters for video rendering
fps = 20
bitrate = '10M'
Fonction pour créer les images
def main():
"""Draws frames of a rotation Earth with moving
vehicules along latitude lines and converts to video.
"""
os.makedirs(tmp_dir, exist_ok=True)
# Allow update of figures in real-time
plt.ion()
fig, ax = plt.subplots(figsize=(9, 6))
# Define view angles for the Earth
lat_vec = np.linspace(lat_view_angles[0], lat_view_angles[1],
rotation_steps, endpoint=False)
lon_vec = np.linspace(lon_view_angles[0], lon_view_angles[1],
rotation_steps, endpoint=False)
# Concatenate to do multiple rotations
lat_vec = np.concatenate([lat_vec for x in range(rotations)])
lon_vec = np.concatenate([lon_vec for x in range(rotations)])
# Define line vectors for the vehicules
x1 = lon_vec.copy()//2 # veh1
y1 = np.linspace(0, 90, len(lat_vec)) # slides to north pole
x2 = -x1 # veh2 goes opposite direction
y2 = np.linspace(0, -90, len(lat_vec)) # slides to south pole
# Loop through the view angles
for i in tqdm(range(rotations*rotation_steps)):
# Clear current axes
plt.cla()
m = Basemap(projection='ortho',
lat_0=lat_vec[i], lon_0=lon_vec[i])
# Add features on the map
m.drawmapboundary(fill_color=ocean_map)
m.fillcontinents(color=earth_map, lake_color=ocean_map)
m.drawcoastlines()
m.drawcountries()
# Draw the vehicule lines
m.plot(*m(x1[:i+1], y1[:i+1]), 'C3-', lw=2)
m.plot(*m(x1[i], y1[i]), color='C3', marker='<')
m.plot(*m(x2[:i+1], y2[:i+1]), 'C0-', lw=2)
m.plot(*m(x2[i], y2[i]), color='C0', marker='>')
# Save frames
plt.savefig(f'{tmp_dir}fig{i:03d}.png', dpi=96)
plt.close()
Lancer la simulation et convertir en mp4
if __name__ == "__main__":
# Create frames
main()
# Clean up previous run and prepare temporary folder
if os.path.exists(out_path):
os.system(f"rm {out_path}")
# Use ffmpeg to convert frames to mp4
command = (f"ffmpeg -r {fps} -i {tmp_dir}fig%03d.png "
f"-c:v libx264 -b {bitrate} {out_path}")
if os.system(command):
raise RuntimeError('program {} failed!'.format(command))
# Clean up if needed
if os.path.exists(tmp_dir) and delete_tmp_after:
os.system(f"rm -r {tmp_dir}")