1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104
| #!/usr/bin/python
# -*- coding: utf-8 -*-
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
import numpy as np
class SimulatedEarth:
# -----------------------------------------------------
# VARIABLES
# -----------------------------------------------------
def __init__(self):
self.ax = None
self.width = 8
self.height = 8
self.radius = 1.8
self.meridians_number = 24
self.parallels_number = 18
# ---------------------------------------------------------
# CONFIGURING THE WINDOW
# ---------------------------------------------------------
def create_figure(self):
""" The window is configured """
fig = plt.figure(figsize=(self.width, self.height))
self.ax = fig.add_subplot(111, projection='3d')
""" Grids, axis and graduations are removed """
self.ax.grid(False)
self.ax.set_axis_off()
""" Axis is configured with a uniform scale """
self.ax.set_box_aspect([1, 1, 1])
v = 2.1
self.ax.set_xlim([-v, v])
self.ax.set_ylim([-v, v])
self.ax.set_zlim([-v, v])
# ---------------------------------------------------------
# COMPUTING MERIDIANS AND PARALLELS
#
# - θ is the 3D polar angle relative to z-axis
# - ϕ is the 3D azimuthal angle relative to the x-axis
# ---------------------------------------------------------
def plot_circle_on_sphere(self, great_circle, angle, num_points):
angle = np.radians(angle)
if great_circle == "meridians":
''' Coordinates of meridians '''
theta = np.linspace(0, np.pi, num_points) # Polar angle
phi = angle # Azimuthal angle
x = self.radius * np.cos(phi) * np.sin(theta)
y = self.radius * np.sin(phi) * np.sin(theta)
z = self.radius * np.cos(theta)
else:
''' Coordinates of parallels '''
theta = angle # Angle polaire
phi = np.linspace(0, 2 * np.pi, num_points) # Azimuthal angle
r = self.radius * np.cos(theta) # Circle's radius
x = r * np.cos(phi)
y = r * np.sin(phi)
z = np.dot(self.radius * np.sin(theta), np.ones(np.shape(x))) # Circle's elevation
self.plot_points( x, y, z)
# -----------------------------------------------------
# PLOTTING MERIDIANS AND PARALLELS
# -----------------------------------------------------
def plot_points(self, x, y, z):
self.ax.plot(x, y, z, color="blue", linewidth=0.5)
# =========================================================
# MAIN PROCEDURE
# =========================================================
if __name__ == "__main__":
S = SimulatedEarth()
S.create_figure()
for latitude in range(-90, 90, 10):
S.plot_circle_on_sphere("parallels", latitude, S.meridians_number) # Plotting paralleles
for longitude in range(0, 360, 15):
S.plot_circle_on_sphere("meridians",longitude, S.parallels_number) # Plotting meridians
plt.show() |