Related
If you run the code you will see that I'm displaying contour lines for the Momentum Capacity (variable AM - Contour Line Plot) for different diameters. What I wish to do is to display the 2.0 contour line for different RPM values, while keeping the current X and Y axes.
Currently, RPM is a fixed value with which I compute AM. If for example, I increase the RPM, the 2.0 contour line will move "up", and "down" if I decrease it. I wish to display this variation in 2.0 contour line positioning. In the end, I want the graph to have a 4000 RPM 2.0 line, then a 4500 RPM 2.0 line, then a 5000 RPM 2.0 line, and so on.
Any advice is greatly appreciated! Thank you!
import numpy as np
import matplotlib.pyplot as plt
from pylab import meshgrid
"""
________________________________________________________________________________________________________________________
Functions
________________________________________________________________________________________________________________________
"""
def mm2m(value):
return value * 10 ** (-3)
def m2mm(value):
return value * 10 ** 3
def rpm2rad(value):
return value * 2 * np.pi / 60
def get_percentage_diff(previous, current):
try:
percentage = abs(previous - current) / max(previous, current) * 100
except ZeroDivisionError:
percentage = float('inf')
if current < previous:
percentage = - percentage
return percentage
def angular_momentum(d1, d2):
R1 = d1 / 2
R2 = d2 / 2
V = (np.pi * R1 ** 2 - np.pi * R2 ** 2) * width
M = rho * V
inertia = 1 / 2 * M * (R1 ** 2 + R2 ** 2)
omega = rpm2rad(RPM)
return inertia * omega
def angular_momentum_test(inertia, rpm):
omega = rpm2rad(rpm)
return inertia * omega
def get_inertia(d1, d2, w):
R1 = d1 / 2
R2 = d2 / 2
V = (np.pi * R1 ** 2 - np.pi * R2 ** 2) * w
M = rho * V
return 1 / 2 * M * (R1 ** 2 + R2 ** 2)
def angular_momentum_rod(d1, d2):
R1 = d1 / 2
R2 = d2 / 2
V = (np.pi * R1 ** 2 - np.pi * R2 ** 2) * rod_width
M = rho * V
inertia = 1 / 2 * M * (R1 ** 2 + R2 ** 2)
omega = rpm2rad(RPM)
return inertia * omega
"""
________________________________________________________________________________________________________________________
Input
________________________________________________________________________________________________________________________
"""
RPM = 6000
rho = 2700
width = mm2m(50)
rod_width = mm2m(250)
rod_diameter = mm2m(10)
"""
________________________________________________________________________________________________________________________
Calculation
________________________________________________________________________________________________________________________
"""
D1 = mm2m(np.arange(100, 150, 1))
D2 = mm2m(np.arange(50, 140, 1))
X, Y = meshgrid(D1, D2)
AM = angular_momentum(X, Y) + angular_momentum_rod(rod_diameter, 0)
# Testing Values
OD = mm2m(145)
ID = mm2m(80)
test_width = mm2m(60)
test_RPM = 6000
I_test = get_inertia(OD, ID, test_width) * 10 ** 6
AM_test = angular_momentum_test(I_test / 10 ** 6, test_RPM) + angular_momentum_rod(rod_diameter, 0)
Inventor_I_Value = 3190.667
# rod_I_test = get_inertia(mm2m(10),0,mm2m(250)) * 10 ** 6
"""
________________________________________________________________________________________________________________________
Printing
________________________________________________________________________________________________________________________
"""
print("The momentum capacity is: ", AM_test, " [Nms]\n")
print("The moment of inertia is: ", I_test,
" [Nmm2] , diff: {} \n".format(get_percentage_diff(I_test, Inventor_I_Value)))
# print(rod_I_test)
"""
________________________________________________________________________________________________________________________
Plotting
________________________________________________________________________________________________________________________
"""
plt.figure(figsize=(10, 10), dpi=300)
ctr = plt.contour(X, Y, AM, np.arange(0, 10, 0.5), colors='k')
fil = plt.contourf(X, Y, AM, levels=200, cmap="turbo")
plt.grid(True, which='both', zorder=1, alpha=0.69, linewidth=0.75,linestyle='-')
plt.text(0.102, 0.132, " Width = {} [mm] \n \u03C1 = {} [kg/m3]\n RPM = {} ".format(m2mm(width), rho, RPM), style='normal',
bbox={'facecolor': 'white', 'alpha': 1, 'pad': 10})
plt.minorticks_on()
plt.xlabel("Outer Diameter [m]")
plt.ylabel("Inner Diameter [m]")
plt.title("Flywheel Momentum Capacity [Nms]")
plt.clabel(ctr)
plt.colorbar(fil)
plt.savefig('Flywheel_Momentum_Capacity.png')
plt.tight_layout()
plt.show()
The key is to set levels=[2] inside the plt.contour call.
I'm going to give you a recipe. Start by creating two lists with the same number of elements
RPMS = [4500, 5000, 5500, 6000]
colors = ["r", "g", "b", "k"]
Loop over each RPM, do the computation and plot it:
# this are needed to create a legend when using contour
from matplotlib.lines import Line2D
labels, artists = [], []
plt.figure(figsize=(10, 10), dpi=300)
for RPM, col in zip(RPMS, colors):
# do the computations
# plotting
plt.contour(X, Y, AM_, np.arange(0, 10, 0.5), levels=[2], colors=col)
labels.append(str(RPM))
artists.append(Line2D([0, 1], [0, 0], color=col))
# create a legend
plt.legend(artists, labels)
# all other customizations
I want to use Python/Matplotlib/Basemap to draw a map and shade a circle that lies within a given distance of a specified point, similar to this (Map generated by the Great Circle Mapper - copyright © Karl L. Swartz.):
I can get the map to generate as follows:
from mpl_toolkits.basemap import Basemap
import numpy as np
import matplotlib.pyplot as plt
# create new figure, axes instances.
fig,ax = plt.subplots()
# setup Mercator map projection.
m = Basemap(
llcrnrlat=47.0,
llcrnrlon=-126.62,
urcrnrlat=50.60,
urcrnrlon=-119.78,
rsphere=(6378137.00,6356752.3142),
resolution='i',
projection='merc',
lat_0=49.290,
lon_0=-123.117,
)
# Latitudes and longitudes of locations of interest
coords = dict()
coords['SEA'] = [47.450, -122.309]
# Plot markers and labels on map
for key in coords:
lon, lat = coords[key]
x,y = m(lat, lon)
m.plot(x, y, 'bo', markersize=5)
plt.text(x+10000, y+5000, key, color='k')
# Draw in coastlines
m.drawcoastlines()
m.fillcontinents()
m.fillcontinents(color='grey',lake_color='aqua')
m.drawmapboundary(fill_color='aqua')
plt.show()
which generates the map:
Now I would like to create a great circle around a specified point, such as the top map.
My attempt is a function that takes the map object, a center coordinate pair and a distance, and creates two curves and then shade between them, something like:
def shaded_great_circle(map_, lat_0, lon_0, dist=100, alpha=0.2): # dist specified in nautical miles
dist = dist * 1852 # Convert distance to nautical miles
lat = np.linspace(lat_0-dist/2, lat_0+dist/2,50)
lon = # Somehow find these points
# Create curve for longitudes above lon_0
# Create curve for longitudes below lon_0
# Shade region between above two curves
where I have commented what I want to do, but am not sure how to do it.
I have tried a few ways to do this, but what has me confused is that all inputs to the map are coordinates measured in degrees, whereas I want to specify points in length, and have that converted to latitude/longitude points to plot. I think this is related to data as lat/lon in degrees versus map projection coordinates.
Any nudges in the right direction would be appreciated
Thanks
In the end I had to implement this manually.
In short, I used an equation given here to calculate the coordinates given an
initial starting point and a radial to calculate points around 360 degrees, and then plot a line through these points. I don't really need the shading part, so I haven't implemented that yet.
I thought this is a useful feature so here is how I implemented it:
from mpl_toolkits.basemap import Basemap
import numpy as np
import matplotlib.pyplot as plt
def calc_new_coord(lat1, lon1, rad, dist):
"""
Calculate coordinate pair given starting point, radial and distance
Method from: http://www.geomidpoint.com/destination/calculation.html
"""
flat = 298.257223563
a = 2 * 6378137.00
b = 2 * 6356752.3142
# Calculate the destination point using Vincenty's formula
f = 1 / flat
sb = np.sin(rad)
cb = np.cos(rad)
tu1 = (1 - f) * np.tan(lat1)
cu1 = 1 / np.sqrt((1 + tu1*tu1))
su1 = tu1 * cu1
s2 = np.arctan2(tu1, cb)
sa = cu1 * sb
csa = 1 - sa * sa
us = csa * (a * a - b * b) / (b * b)
A = 1 + us / 16384 * (4096 + us * (-768 + us * (320 - 175 * us)))
B = us / 1024 * (256 + us * (-128 + us * (74 - 47 * us)))
s1 = dist / (b * A)
s1p = 2 * np.pi
while (abs(s1 - s1p) > 1e-12):
cs1m = np.cos(2 * s2 + s1)
ss1 = np.sin(s1)
cs1 = np.cos(s1)
ds1 = B * ss1 * (cs1m + B / 4 * (cs1 * (- 1 + 2 * cs1m * cs1m) - B / 6 * \
cs1m * (- 3 + 4 * ss1 * ss1) * (-3 + 4 * cs1m * cs1m)))
s1p = s1
s1 = dist / (b * A) + ds1
t = su1 * ss1 - cu1 * cs1 * cb
lat2 = np.arctan2(su1 * cs1 + cu1 * ss1 * cb, (1 - f) * np.sqrt(sa * sa + t * t))
l2 = np.arctan2(ss1 * sb, cu1 * cs1 - su1 * ss1 * cb)
c = f / 16 * csa * (4 + f * (4 - 3 * csa))
l = l2 - (1 - c) * f * sa * (s1 + c * ss1 * (cs1m + c * cs1 * (-1 + 2 * cs1m * cs1m)))
d = np.arctan2(sa, -t)
finaltc = d + 2 * np.pi
backtc = d + np.pi
lon2 = lon1 + l
return (np.rad2deg(lat2), np.rad2deg(lon2))
def shaded_great_circle(m, lat_0, lon_0, dist=100, alpha=0.2, col='k'): # dist specified in nautical miles
dist = dist * 1852 # Convert distance to nautical miles
theta_arr = np.linspace(0, np.deg2rad(360), 100)
lat_0 = np.deg2rad(lat_0)
lon_0 = np.deg2rad(lon_0)
coords_new = []
for theta in theta_arr:
coords_new.append(calc_new_coord(lat_0, lon_0, theta, dist))
lat = [item[0] for item in coords_new]
lon = [item[1] for item in coords_new]
x, y = m(lon, lat)
m.plot(x, y, col)
# setup Mercator map projection.
m = Basemap(
llcrnrlat=45.0,
llcrnrlon=-126.62,
urcrnrlat=50.60,
urcrnrlon=-119.78,
rsphere=(6378137.00,6356752.3142),
resolution='i',
projection='merc',
lat_0=49.290,
lon_0=-123.117,
)
# Latitudes and longitudes of locations of interest
coords = dict()
coords['SEA'] = [47.450, -122.309]
# Plot markers and labels on map
for key in coords:
lon, lat = coords[key]
x,y = m(lat, lon)
m.plot(x, y, 'bo', markersize=5)
plt.text(x+10000, y+5000, key, color='k')
# Draw in coastlines
m.drawcoastlines()
m.fillcontinents()
m.fillcontinents(color='grey',lake_color='aqua')
m.drawmapboundary(fill_color='aqua')
# Draw great circle
shaded_great_circle(m, 47.450, -122.309, 100, col='k') # Distance specified in nautical miles, i.e. 100 nmi in this case
plt.show()
Running this should give you (with 100 nautical mile circle around Seattle):
I am trying to make a plot of a projectile motion of a mass which is under the effect of gravitational, buoyancy and drag force. Basically, I want to show effects of the buoyancy and drag force on flight distance, flight time and velocity change on plotting.
import matplotlib.pyplot as plt
import numpy as np
V_initial = 30 # m/s
theta = np.pi/6 # 30
g = 3.711
m =1
C = 0.47
r = 0.5
S = np.pi*pow(r, 2)
ro_mars = 0.0175
t_flight = 2*(V_initial*np.sin(theta)/g)
t = np.linspace(0, t_flight, 200)
# Drag force
Ft = 0.5*C*S*ro_mars*pow(V_initial, 2)
# Buoyant Force
Fb = ro_mars*g*(4/3*np.pi*pow(r, 3))
x_loc = []
y_loc = []
for time in t:
x = V_initial*time*np.cos(theta)
y = V_initial*time*np.sin(theta) - (1/2)*g*pow(time, 2)
x_loc.append(x)
y_loc.append(y)
x_vel = []
y_vel = []
for time in t:
vx = V_initial*np.cos(theta)
vy = V_initial*np.sin(theta) - g*time
x_vel.append(vx)
y_vel.append(vy)
v_ch = [pow(i**2+ii**2, 0.5) for i in x_vel for ii in y_vel]
tau = []
for velocity in v_ch:
Ft = 0.5*C*S*ro_mars*pow(velocity, 2)
tau.append(Ft)
buoy = []
for velocity in v_ch:
Fb = ro_mars*g*(4/3*np.pi*pow(r, 3))
buoy.append(Fb)
after this point, I couldn't figure out how to plot to a projectile motion under this forces. In other words, I'm trying to compare the projectile motion of the mass under three circumstances
Mass only under the effect of gravity
Mass under the effect of gravity and air resistance
Mass under the effect of gravity, air resistance, and buoyancy
You must calculate each location based on the sum of forces at the given time. For this it is better to start from calculating the net force at any time and using this to calculate the acceleration, velocity and then position. For the following calculations, it is assumed that buoyancy and gravity are constant (which is not true in reality but the effect of their variability is negligible in this case), it is also assumed that the initial position is (0,0) though this can be trivially changed to any initial position.
F_x = tau_x
F_y = tau_y + bouyancy + gravity
Where tau_x and tau_y are the drag forces in the x and y directions, respectively. The velocities, v_x and v_y, are then given by
v_x = v_x + (F_x / (2 * m)) * dt
v_y = v_y + (F_y / (2 * m)) * dt
So the x and y positions, r_x and r_y, at any time t are given by the summation of
r_x = r_x + v_x * dt
r_y = r_y + v_y * dt
In both cases this must be evaluated from 0 to t for some dt where dt * n = t if n is the number of steps in summation.
r_x = r_x + V_i * np.cos(theta) * dt + (F_x / (2 * m)) * dt**2
r_y = r_y + V_i * np.sin(theta) * dt + (F_y / (2 * m)) * dt**2
The entire calculation can actually be done in two lines,
r_x = r_x + V_i * np.cos(theta) * dt + (tau_x / (2 * m)) * dt**2
r_y = r_y + V_i * np.sin(theta) * dt + ((tau_y + bouyancy + gravity) / (2 * m)) * dt**2
Except that v_x and v_y require updating at every time step. To loop over this and calculate the x and y positions across a range of times you can simply follow the below (edited) example.
The following code includes corrections to prevent negative y positions, since the given value of g is for the surface or Mars I assume this is appropriate - when you hit zero y and try to keep going you may end up with a rapid unscheduled disassembly, as we physicists call it.
Edit
In response to the edited question, the following example has been modified to plot all three cases requested - gravity, gravity plus drag, and gravity plus drag and buoyancy. Plot setup code has also been added
Complete example (edited)
import numpy as np
import matplotlib.pyplot as plt
def projectile(V_initial, theta, bouyancy=True, drag=True):
g = 9.81
m = 1
C = 0.47
r = 0.5
S = np.pi*pow(r, 2)
ro_mars = 0.0175
time = np.linspace(0, 100, 10000)
tof = 0.0
dt = time[1] - time[0]
bouy = ro_mars*g*(4/3*np.pi*pow(r, 3))
gravity = -g * m
V_ix = V_initial * np.cos(theta)
V_iy = V_initial * np.sin(theta)
v_x = V_ix
v_y = V_iy
r_x = 0.0
r_y = 0.0
r_xs = list()
r_ys = list()
r_xs.append(r_x)
r_ys.append(r_y)
# This gets a bit 'hand-wavy' but as dt -> 0 it approaches the analytical solution.
# Just make sure you use sufficiently small dt (dt is change in time between steps)
for t in time:
F_x = 0.0
F_y = 0.0
if (bouyancy == True):
F_y = F_y + bouy
if (drag == True):
F_y = F_y - 0.5*C*S*ro_mars*pow(v_y, 2)
F_x = F_x - 0.5*C*S*ro_mars*pow(v_x, 2) * np.sign(v_y)
F_y = F_y + gravity
r_x = r_x + v_x * dt + (F_x / (2 * m)) * dt**2
r_y = r_y + v_y * dt + (F_y / (2 * m)) * dt**2
v_x = v_x + (F_x / m) * dt
v_y = v_y + (F_y / m) * dt
if (r_y >= 0.0):
r_xs.append(r_x)
r_ys.append(r_y)
else:
tof = t
r_xs.append(r_x)
r_ys.append(r_y)
break
return r_xs, r_ys, tof
v = 30
theta = np.pi/4
fig = plt.figure(figsize=(8,4), dpi=300)
r_xs, r_ys, tof = projectile(v, theta, True, True)
plt.plot(r_xs, r_ys, 'g:', label="Gravity, Buoyancy, and Drag")
r_xs, r_ys, tof = projectile(v, theta, False, True)
plt.plot(r_xs, r_ys, 'b:', label="Gravity and Drag")
r_xs, r_ys, tof = projectile(v, theta, False, False)
plt.plot(r_xs, r_ys, 'k:', label="Gravity")
plt.title("Trajectory", fontsize=14)
plt.xlabel("Displacement in x-direction (m)")
plt.ylabel("Displacement in y-direction (m)")
plt.ylim(bottom=0.0)
plt.legend()
plt.show()
Note that this preserves and returns the time-of-flight in the variable tof.
Using vector notation, and odeint.
import numpy as np
from scipy.integrate import odeint
import scipy.constants as SPC
import matplotlib.pyplot as plt
V_initial = 30 # m/s
theta = np.pi/6 # 30
g = 3.711
m = 1 # I assume this is your mass
C = 0.47
r = 0.5
ro_mars = 0.0175
t_flight = 2*(V_initial*np.sin(theta)/g)
t = np.linspace(0, t_flight, 200)
pos0 = [0, 0]
v0 = [np.cos(theta) * V_initial, np.sin(theta) * V_initial]
def f(vector, t, C, r, ro_mars, apply_bouyancy=True, apply_resistance=True):
x, y, x_prime, y_prime = vector
# volume and surface
V = np.pi * 4/3 * r**3
S = np.pi*pow(r, 2)
# net weight bouyancy
if apply_bouyancy:
Fb = (ro_mars * V - m) * g *np.array([0,1])
else:
Fb = -m * g * np.array([0,1])
# velocity vector
v = np.array([x_prime, y_prime])
# drag force - corrected to be updated based on current velocity
# Ft = -0.5*C*S*ro_mars*pow(V_initial, 2)
if apply_resistance:
Ft = -0.5*C*S*ro_mars* v *np.linalg.norm(v)
else:
Ft = np.array([0, 0])
# resulting acceleration
x_prime2, y_prime2 = (Fb + Ft) / m
return x_prime, y_prime, x_prime2, y_prime2
sol = odeint(f, pos0 + v0 , t, args=(C, r, ro_mars))
plt.plot(sol[:,0], sol[:, 1], 'g', label='tray')
plt.legend(loc='best')
plt.xlabel('x')
plt.ylabel('y')
plt.grid()
plt.show()
Note that I corrected your drag force to use the actual (not initial) velocity, I do not know if that was your mistake or it was on purpose.
Also please check the documentation for odeint to understand better how to turn a second order ODE (like the one in your problem) to a first order vector ODE.
To remove air resistance or bouyancy, set apply_bouyancy and apply_resistance to True or False by adding them to the args=(...)
I have an iterative model in Python which generates at signal using a function which contains a derivative. As the model iterates the signal becomes noisy - I suspect it may be an issue with computing the numerical derivative. I've tried to smooth this by applying a low-pass filter, convolving the noisy signal with a Gaussian kernel. I use the code snippet:
nw = 256
std = 40
window = gaussian(nw, std, sym=True)
filtered = convolve(current, window, mode='same') / np.sum(window)
where current is my signal, and gaussian and convolve have been imported from scipy. This seems to give a slight improvement, and the first 2 or 3 iterations appear very smooth. However, after that the signal becomes extremely noisy again, despite the fact that the low-pass filter is positioned inside the iterative loop.
Can anyone suggest where I might be going wrong or how I could better tackle this problem? Thanks.
EDIT: As suggested I've included the code I'm using below. At 5 iterations the noise on the signal is clearly apparent.
import numpy as np
from scipy import special
import matplotlib.pyplot as plt
from scipy.integrate import odeint
from scipy.signal import convolve
from scipy.signal import gaussian
# Constants
B = 426400E-9 # tesla
R = 71723E3
Rkm = R / 1000.
Omega = 1.75e-4 #8.913E-4 # rads/s
period = (2. * np.pi / Omega) / 3600. # Gets period in hours
Bj = 2.0 * B
mdot = 1000.
sigmapstar = 0.05
# Create rhoe array
rho0 = 5.* R
rho1 = 100. * R
rhoe = np.linspace(rho0, rho1, 2.E5)
# Define flux function and z component of equatorial field strength
Fe = B * R**3 / rhoe
Bze = B * (R/rhoe)**3
def derivs(u, rhoe, p):
"""Computes the derivative"""
wOmegaJ = u
Bj, sigmapstar, mdot, B, R = p
# Compute the derivative of w/omegaJ wrt rhoe (**Fe and Bjz have been subbed)
dwOmegaJ = (((8.0*np.pi*sigmapstar*B**2 * (R**6)) / (mdot * rhoe**5)) \
*(1.0-wOmegaJ) - (2.*wOmegaJ/rhoe))
res = dwOmegaJ
return res
its = 5 # number of iterations to perform
i = 0
# Loop to iterate
while i < its:
# Define the initial condition of rigid corotation
wOmegaJ_0 = 1
params = [Bj, sigmapstar, mdot, B, R]
init = wOmegaJ_0
# Compute numerical solution to Hill eqn
u = odeint(derivs, init, rhoe, args=(params,))
wOmega = u[:,0]
# Calculate I_rho
i_rho = 8. * np.pi * sigmapstar * Omega * Fe * ( 1. - wOmega)
dx = rhoe[1] - rhoe[0]
differential = np.gradient(i_rho, dx)
jpara = 1. * differential / (4 * np.pi * rhoe * Bze )
jpari = 2. * B * para
# Remove infinity and NaN values)
jpari[~np.isfinite(jpari)] = 0.0
# Convolve to smooth curve
nw = 256
std = 40
window = gaussian(nw, std, sym=True)
filtered = convolve(jpari, window, mode='same') /np.sum(window)
jpari = filtered
# Pedersen conductivity as function of jpari
sigmapstar0 = 0.05
jstar = 0.01e-6
jstarstar = 0.25e-6
s1 = 0.1e6#0.1e6 # (Am^-2)^-1
s2 = 9.9e6 # (Am^-2)^-1
n = 8.
# Calculate news sigmapstar. Realistic conductivity
sigmapstarNew = sigmapstar0 + 0.5 * (s1 + s2/(1 + (jpari/jstarstar)**n)**(1./n)) * (np.sqrt(jpari**2 + jstar**2) + jpari)
sigmapstarNew = sigmapstarNew
diff = np.abs(sigmapstar - sigmapstarNew) / sigmapstar * 100
diff = max(diff)
sigmapstar = 0.5* sigmapstar + 0.5* sigmapstarNew # Weighted averaging
i += 1
print diff
# Plot jpari
ax = plt.subplot(111)
ax.plot(rhoe/R, jpari * 1e6)
ax.axhline(0, ls=':')
ax.set_xlabel(r'$\rho_e / R_{UCD}$')
ax.set_ylabel(r'$j_{\parallel i} $ / $ \mu$ A m$^{-2}$')
ax.set_xlim([0,80])
ax.set_ylim(-0.01,0.01)
plt.locator_params(nbins=5)
plt.draw()
plt.show()
How can I add a marking along a plot at the position of -20 degrees true anomaly and 103 degrees true anomaly?
What I have is a trajectory of a space craft along a hyperbolic path around Earth where I solved for the time it took to fly between the true anomalies. Unfortunately, I don't know way to mark a position at a specified angle on the path.
I know I can do
initial = pylab.Circle((location), radius = 10, color = '#000000')
final = ....
but what do I put for the location coordinates? Is there a way to do this without the brute force method of solving for the coordinates?
import numpy as np
import pylab
a = -35000 # the semi-major axis of the hyperbolic trajectory
e = 1.2 # the eccentricity
nu0 = -20 * np.pi / 180 # initial anomaly
nuf = 103 * np.pi / 180 # final anomaly
F0 = 2 * np.arctanh(np.sqrt((e - 1) / (e + 1)) * np.tan(nu0 / 2))
Ff = 2 * np.arctanh(np.sqrt((e - 1) / (e + 1)) * np.tan(nuf / 2))
M0 = e * np.sinh(F0) - F0
Mf = e * np.sinh(Ff) - Ff
n = np.sqrt(398600.0 / -a ** 3) # the mean motion
deltat = (Mf - M0) / n # change of time in secs
hours = deltat / 3600
h = np.sqrt(a * 398600 * (1 - e ** 2))
def r(nu):
return h ** 2 / (398600 * (1 + e * np.cos(nu)))
rt = r(nu)
ext = [np.argmin(rt), np.argmax(rt)]
rt[ext] = np.nan
nu = np.linspace(0, 2 * np.pi, 500000)
fig = pylab.figure()
ax = fig.add_subplot(111, aspect = 'equal')
earth = pylab.Circle((0, 0), radius = 6378, color = 'blue')
ax.add_patch(earth)
ax.plot(rt * np.cos(nu), rt * np.sin(nu), 'r')
pylab.axis([-70000, 10000, -40000, 40000])
pylab.show()