{ "nbformat": 4, "nbformat_minor": 0, "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.7.3" }, "latex_envs": { "LaTeX_envs_menu_present": true, "autoclose": false, "autocomplete": true, "bibliofile": "biblio.bib", "cite_by": "apalike", "current_citInitial": 1, "eqLabelWithNumbers": true, "eqNumInitial": 1, "hotkeys": { "equation": "Ctrl-E", "itemize": "Ctrl-I" }, "labels_anchors": false, "latex_user_defs": false, "report_style_numbering": false, "user_envs_cfg": false }, "toc": { "base_numbering": 1, "nav_menu": {}, "number_sections": true, "sideBar": true, "skip_h1_title": false, "title_cell": "Table of Contents", "title_sidebar": "Contents", "toc_cell": false, "toc_position": {}, "toc_section_display": true, "toc_window_display": false }, "varInspector": { "cols": { "lenName": 16, "lenType": 16, "lenVar": 40 }, "kernels_config": { "python": { "delete_cmd_postfix": "", "delete_cmd_prefix": "del ", "library": "var_list.py", "varRefreshCmd": "print(var_dic_list())" }, "r": { "delete_cmd_postfix": ") ", "delete_cmd_prefix": "rm(", "library": "var_list.r", "varRefreshCmd": "cat(var_dic_list()) " } }, "types_to_exclude": [ "module", "function", "builtin_function_or_method", "instance", "_Feature" ], "window_display": false }, "colab": { "name": "FINAL_NOTEBOOK_BALL_AEROSPACE.ipynb", "provenance": [] } }, "cells": [ { "cell_type": "code", "metadata": { "ExecuteTime": { "end_time": "2020-05-14T20:03:58.118045Z", "start_time": "2020-05-14T20:03:58.107203Z" }, "id": "BdjqcH4Vkgrk", "outputId": "b7361d12-53b2-41b7-d951-322be8738e0c" }, "source": [ "from IPython.display import HTML, display\n", "display(HTML(\"\"))\n", "from mpl_toolkits.mplot3d import Axes3D\n", "from scipy.optimize import fsolve\n", "import matplotlib.pyplot as plt\n", "import numpy as np\n", "from interval import interval, inf, imath " ], "execution_count": null, "outputs": [ { "output_type": "display_data", "data": { "text/html": [ "" ], "text/plain": [ "" ] }, "metadata": { "tags": [] } } ] }, { "cell_type": "code", "metadata": { "ExecuteTime": { "end_time": "2020-05-14T20:03:58.515840Z", "start_time": "2020-05-14T20:03:58.497294Z" }, "id": "cuBzY0XHkgrp" }, "source": [ "def t2q(t, i, ω, Ω,\n", " a, b, H, E) : # create 3D orbit coordinates (q[0],q[1],q[2])\n", " o = [np.cos(Ω), # longitude of the ascending node\n", " np.sin(Ω)] # ... converted to its cosine and sine\n", " s = np.sin(i) # sine of inclination angle, radians\n", " j= 0\n", " l = t[j:] # shift time between plane rotation and E\n", " l = 2*np.pi*l/24/3600 # convert l to orbital plane normal-vector azimuth (radian)\n", " ν = np.array([np.cos(l)*s, # unit normal vector of orbital plane\n", " np.sin(l)*s,\n", " np.array([np.cos(i)]*len(l))]).transpose()\n", " λ = np.cross([0, 0, 1], ν) # vector orthogonal to ν and to reference North Pole\n", " λ = np.diag(np.sum(λ*λ, # normalize λ\n", " axis=1)**-.5)@λ\n", " μ = np.cross(ν, λ) # unit vector orthogonal to λ and to ν\n", " E = E - ω + np.pi/2 # eq. 39 implies E ≈ θ when 0 < e << 1\n", " x = a*np.cos(E) # eq. 20, x-coordinate list (shifted to ellipse center)\n", " y = b*np.sin(E) # eq. 21, y-coordinate list\n", " q = (np.diag(x)@λ + np.diag(y)@μ)@np.array([[o[0], -o[1], 0],\n", " [o[1], o[0], 0],\n", " [ 0, 0, 1]])\n", " return q" ], "execution_count": null, "outputs": [] }, { "cell_type": "code", "metadata": { "ExecuteTime": { "end_time": "2020-05-14T20:03:58.958185Z", "start_time": "2020-05-14T20:03:58.953322Z" }, "id": "SiuhP_lFkgrq" }, "source": [ "def swath_coverage(theta, h):\n", " swath = (2 * h * np.tan( ( (np.pi / 180) / 2 ) * theta )) \n", " return swath" ], "execution_count": null, "outputs": [] }, { "cell_type": "markdown", "metadata": { "id": "_Veq7_7qkgrq" }, "source": [ "t2q is a function that outputs a vector 𝑞 in ℝ3 . This vector is Earth centered Earth fixed (ECEF).\n", "\n", "The inputs are:\n", "\n", "t - time\n", "\n", "i - inclination angle\n", "\n", "ω - argument of perigee\n", "\n", "Ω - longitude of the ascending node\n", "\n", "a - semi-major axis\n", "\n", "b - semi-minor axis\n", "\n", "H - relative angular-momentum magnitude\n", "\n", "j - displaces a satellite in orbit\n" ] }, { "cell_type": "code", "metadata": { "ExecuteTime": { "end_time": "2020-05-14T20:08:02.333641Z", "start_time": "2020-05-14T20:08:02.316015Z" }, "id": "CPGIY4fYkgrq" }, "source": [ "\n", "# Eq. 25, https://en.wikipedia.org/wiki/Kepler_orbit#Properties_of_trajectory_equation\n", "# Note eq. 24 implies a unique E for all t and 0 < e < 1.\n", "t2E = lambda e, t : fsolve(lambda E : E - e*np.sin(E) - t, t/(1 - e))\n", "\n", "\n", "# Only used in the 2D plot of Earth reference\n", "circlexy = lambda r, θ : (r*np.cos(θ), r*np.sin(θ))\n", "\n", "# number of days we want to simulate\n", "num_days = 1\n", "\n", "# number of satellites we wish to simulate -- << 13\n", "satellites = 10\n", "\n", "# altitude in meters\n", "h = 500000\n", "\n", "# eccentricity\n", "e = .01 \n", "\n", "# np.sin takes radians ==> 83° × π/180 = 1.449 rad\n", "inclination = 1.449\n", "\n", "\n", "# mean earth radius, m https://en.wikipedia.org/wiki/Earth_radius\n", "# can be changed to 6378.1343e3 --> This value will convert to exactly\n", "# 40,075 km when evaluating coverage. The mean Earth radius will yield \n", "# a maximum of 40,035 km\n", "R = 6371.0088e3 \n", "\n", "\n", "G = 6.67430e-11 # gravitational constant, m³/(kg s²) https://en.wikipedia.org/wiki/Gravitational_constant\n", "m = [1e3, 5.9722e24] # masses of satellite, earth, kg https://en.wikipedia.org/wiki/Earth_mass\n", "N = 350 # nu. plot points\n", "α = G*sum(m) # gravitational parameter, eq. 1, m³/s²\n", "a = (R + h)/(1 - e) # eq. 35, R + minimum altitude solved for semi-major axis, m\n", "p = a*(1 - e*e) # eqs. 13--14, r(θ=π/2), θ being the true anomaly\n", "b = a*(1 - e*e)**.5 # eq. 15, semi-minor axis\n", "H = (α*p)**.5 # eq. 26, specific relative angular-momentum magnitude, m²/s\n", "P = 2*np.pi*a**1.5/α**.5 # eq. 43, orbital period for an elliptic orbit, s\n", "opd = (24*60*60) / P # roughly 16 orbits in one day -- exactly for a period of 1.5 hours\n", "orbits = (num_days)*opd # number of orbits we will simulate\n", "swath = swath_coverage(30,h) # swath based on calculation of altitude \n", "s = swath/2 " ], "execution_count": null, "outputs": [] }, { "cell_type": "code", "metadata": { "ExecuteTime": { "end_time": "2020-05-14T20:08:28.913899Z", "start_time": "2020-05-14T20:08:02.664477Z" }, "id": "Vjv4difIkgrq" }, "source": [ "\n", "q = [0]*satellites # Creating empty lists for the x,y,z cordinates, their relative times and their eccentric anomolies\n", "t = [0]*satellites \n", "E = [0]*satellites \n", "# Ω, the longitude of the ascending node will rotate by one degree every day. \n", "# This ensures that the orbital plane passes through the same time on each\n", "# day at each latitude.\n", "Ω = np.pi/4\n", "ω = 0\n", "\n", "spacer=.1021569\n", "\n", "for i in range(0,satellites): # Creating individual times lists for each of the satellies, and getting their x,y,z coordinates\n", " t[i]= np.linspace((i*(spacer*P)), ((orbits*P)+(i*(spacer*P))), 4*N)\n", " E[i] = t2E(e, H*t[0]/a/b)\n", " q[i] = t2q(t[i], inclination, ω, Ω, a, b, H, E[i])" ], "execution_count": null, "outputs": [] }, { "cell_type": "code", "metadata": { "ExecuteTime": { "end_time": "2020-05-14T20:08:29.093808Z", "start_time": "2020-05-14T20:08:28.970521Z" }, "id": "y8hqUWWykgrr" }, "source": [ "\n", "# convert for ground-tracking\n", "psi = [0]*satellites\n", "phi = [0]*satellites\n", "\n", "for i in range(0,satellites):\n", " psi[i] = np.arctan2(q[i][:,1], q[i][:,0]) # x-coordinate for groundtracking\n", " qq = np.zeros(np.size(q[i][:,2]))\n", " for j in range(0,np.size(q[i][:,2])):\n", " qq[j] = q[i][j,2] / np.sqrt( q[i][j,0]**2 + q[i][j,1]**2 + q[i][j,2]**2 )\n", " phi[i] = np.arcsin( qq ) \n", " \n", "# Converting meters to radians \n", "# 1°longitude = cos(latitude) *111.32 km\n", "# 1 rad = 57.2958°\n", "m2r = (1/111320) * (1/57.2958)" ], "execution_count": null, "outputs": [] }, { "cell_type": "code", "metadata": { "ExecuteTime": { "end_time": "2020-05-14T20:08:29.162191Z", "start_time": "2020-05-14T20:08:29.118804Z" }, "id": "LcJDCNMOkgrr" }, "source": [ "# Finding when the satellite crosses the equator\n", "# and accumulating the points to form the line\n", "\n", "# Setting up parameters needed to find area of\n", "# swath that crosses the equator\n", "x1 = ['']*satellites\n", "y1 = ['']*satellites\n", "x2 = ['']*satellites\n", "y2 = ['']*satellites\n", "t1 = ['']*satellites\n", "t2 = ['']*satellites\n", "\n", "for i in range(0,satellites):\n", " x1[i]= [];\n", " y1[i]= [];\n", " x2[i]= [];\n", " y2[i]= [];\n", " t1[i]= [];\n", " t2[i]= [];\n", " for j in range(0,np.size(phi[i])-1):\n", " if( phi[i][j] > 0 and phi[i][j+1] < 0 ) or ( phi[i][j] < 0 and phi[i][j+1] > 0 ):\n", " x1[i].append( psi[i][j] ) # x1\n", " x2[i].append( psi[i][j+1] ) # x2\n", " y1[i].append( phi[i][j] ) # y1\n", " y2[i].append( phi[i][j+1] ) # y2\n", " t1[i].append(t[i][j])\n", " t2[i].append(t[i][j+1])\n", " \n", " " ], "execution_count": null, "outputs": [] }, { "cell_type": "code", "metadata": { "ExecuteTime": { "end_time": "2020-05-14T20:08:29.205743Z", "start_time": "2020-05-14T20:08:29.190549Z" }, "id": "TWsBKMgykgrr" }, "source": [ "# Setting up parameters in order to center a point on an interpolated line at the equator\n", "# and to calculate the length of the swath crossing the equator, given our angle of \n", "# inclination\n", "u1 = ['']*satellites\n", "v1 = ['']*satellites\n", "a1 = ['']*satellites\n", "b1 = ['']*satellites\n", "te = ['']*satellites\n", "\n", "\n", "for i in range(0, satellites):\n", " u1[i]= [];\n", " v1[i]= [];\n", " a1[i]= [];\n", " b1[i]= [];\n", " te[i]= [];\n", " n= np.size(x1[i])\n", "\n", " for j in range(0, n):\n", " u1[i].append( x2[i][j] - x1[i][j] )\n", " v1[i].append( y2[i][j] - y1[i][j] ) \n", "\n", " for j in range(0, n):\n", " a1[i].append( x1[i][j] - (u1[i][j]/v1[i][j])*y1[i][j] )\n", " b1[i].append( 0 ) \n", " for j in range (0, n):\n", " te[i].append((a1[i][j]-x1[i][j])*(t2[i][j]-t1[i][j])/(x2[i][j]-x1[i][j]) + t1[i][j]) \n", " " ], "execution_count": null, "outputs": [] }, { "cell_type": "code", "metadata": { "ExecuteTime": { "end_time": "2020-05-15T00:37:59.729190Z", "start_time": "2020-05-15T00:37:59.693225Z" }, "id": "HKaAg9drkgrs" }, "source": [ "te_day = ['']*satellites #day time at the equitorial line\n", "a1_day = ['']*satellites #longitude of satellite at the specific time it crosses the equator during daytime\n", "slopeday= ['']*satellites #Finding the slope between the interpolated points for the daytime crossings\n", "l_i = 0 #Initial longitude location\n", "t_i = 0 #Intial time.\n", "seconds= 240\n", "radm = (np.pi/180)*(1/seconds) #longitude moves 1 degree every 240 second and 1 degree is np.pi/180.\n", "\n", "\n", "psi_r = (l_i + np.pi/2-t_i*radm)%(2*np.pi) #initial sunrise longitude\n", "psi_s = (l_i + 3*np.pi/2-t_i*radm)%(2*np.pi) #initial sunset longitude\n", " \n", "for i in range(0, satellites): \n", " te_day[i] = [];\n", " a1_day[i] = [];\n", " slopeday[i]= [];\n", " for j in range(0,np.size(a1[i])):\n", " if (((psi_r-te[i][j]*radm)%(2*np.pi)<= (psi_s-te[i][j]*radm)%(2*np.pi)) and ((psi_r-te[i][j]*radm)%(2*np.pi) <= a1[i][j]%(2*np.pi)<=(psi_s-te[i][j]*radm)%(2*np.pi))) or \\\n", " (((psi_r-te[i][j]*radm)%(2*np.pi) > (psi_s-te[i][j]*radm)%(2*np.pi)) and (a1[i][j]%(2*np.pi)>=(psi_r-te[i][j]*radm)%(2*np.pi) or a1[i][j]%(2*np.pi)<= (psi_s-te[i][j]*radm)%(2*np.pi))):\n", " te_day[i].append(te[i][j])\n", " a1_day[i].append(a1[i][j])\n", " slopeday[i].append((y2[i][j]-y1[i][j])/(x2[i][j]-x1[i][j]))" ], "execution_count": null, "outputs": [] }, { "cell_type": "code", "metadata": { "ExecuteTime": { "end_time": "2020-05-14T20:08:29.296936Z", "start_time": "2020-05-14T20:08:29.283585Z" }, "id": "nFba8r7ckgrs" }, "source": [ "# Calculation of the swath length given our angle\n", "# Converting meters to radians \n", "# 1°longitude = cos(latitude) *111.32 km\n", "# 1 rad = 57.2958°\n", "m2r = (1/111320) * (1/57.2958)\n", "\n", "swath_length = ['']*satellites;\n", "\n", "for i in range(0, satellites):\n", " swath_length[i] = [];\n", " \n", "\n", " for j in range(0,np.size(slopeday[i])):\n", " swath_length[i].append( s / np.sin( np.arctan( slopeday[i][j] ) ) )\n", "\n", " for k in range(0,np.size(swath_length[i])):\n", " swath_length[i][k]= swath_length[i][k] * m2r\n", "\n", "#Finding the distances to the right and left of our center point (a1_day) that the swath catches\n", "equator_catch_plus= ['']*satellites;\n", "equator_catch_minus= ['']*satellites;\n", "\n", "for i in range(0, satellites):\n", " equator_catch_plus[i]= [];\n", " equator_catch_minus[i]= [];\n", " n= np.size(a1_day[i])\n", " \n", " for j in range(0,n):\n", " equator_catch_plus[i].append( a1_day[i][j] + swath_length[i][j] )\n", " equator_catch_minus[i].append( a1_day[i][j] - swath_length[i][j] )\n", " \n", "\n" ], "execution_count": null, "outputs": [] }, { "cell_type": "code", "metadata": { "ExecuteTime": { "end_time": "2020-05-14T20:08:29.345543Z", "start_time": "2020-05-14T20:08:29.326450Z" }, "id": "Dum_a7gbkgrs", "outputId": "22918cf1-6ba1-429d-b3cb-d1dab7454df4" }, "source": [ "#TESTING TO SEE WHAT THE OPTIMAL SPACING WOULD BE BY PRINTING OUT THE INTERVALS CAUGHT AND LOOKING AT THEIR ENDPOINTS\n", "area_passed_over_eq1= ['']*satellites\n", "interval_caught1= ['']*satellites;\n", "for i in range(0, satellites):\n", " interval_caught1[i]= [];\n", " m = len(equator_catch_plus[i])\n", " for j in range(0,m):\n", " if(equator_catch_plus[i][j] <= equator_catch_minus[i][j]):\n", " interval_caught1[i].append( [ np.pi + equator_catch_plus[i][j], np.pi + equator_catch_minus[i][j] ] )\n", " else:\n", " interval_caught1[i].append( [ np.pi + equator_catch_minus[i][j], np.pi + equator_catch_plus[i][j] ] )\n", "interval_caught1\n" ], "execution_count": null, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ "[[[0.8679689010052818, 0.9107279704474043],\n", " [4.638583383184164, 4.681342061431825],\n", " [5.057042912558717, 5.099801332829942],\n", " [5.475501844391044, 5.5182602681201995],\n", " [2.9602673960322345, 3.003027001081611],\n", " [3.378728951148442, 3.4214878893832386],\n", " [3.7971888782793126, 3.839947411537684],\n", " [4.215647952298522, 4.258406341939387],\n", " [1.28461724571853, 1.3273756435296946],\n", " [1.7030761496077276, 1.7458346114296759],\n", " [2.121535409473717, 2.1642941966022056],\n", " [2.539995799357579, 2.5827551734405887],\n", " [5.889488913834182, 5.932247734924861],\n", " [0.02476326713259347, 0.06752174384805087],\n", " [0.44322225388081415, 0.48598064752847625]],\n", " [[0.9107174749532572, 0.9534765443953797],\n", " [4.681331957132139, 4.724090635379801],\n", " [5.0997914865066925, 5.1425499067779175],\n", " [5.51825041833902, 5.561008842068176],\n", " [3.00301596998021, 3.0457755750295865],\n", " [3.4214775250964182, 3.4642364633312144],\n", " [3.839937452227288, 3.8826959854856593],\n", " [4.258396526246498, 4.301154915887363],\n", " [1.3273658196665055, 1.37012421747767],\n", " [1.7458247235557038, 1.7885831853776522],\n", " [2.1642839834216923, 2.2070427705501814],\n", " [2.5827443733055544, 2.6255037473885645],\n", " [5.932237487782157, 5.974996308872836],\n", " [0.06751184108056929, 0.1102703177960267],\n", " [0.4859708278287882, 0.5287292214764503]],\n", " [[0.953466048901233, 0.9962251183433555],\n", " [4.305619627969246, 4.348378826205723],\n", " [4.724080531080115, 4.766839209327776],\n", " [5.142540060454667, 5.185298480725892],\n", " [5.560998992286995, 5.603757416016151],\n", " [3.0457645439281857, 3.0885241489775623],\n", " [3.4642260990443936, 3.50698503727919],\n", " [3.8826860261752634, 3.925444559433635],\n", " [1.3701143936144817, 1.4128727914256463],\n", " [1.7885732975036792, 1.8313317593256275],\n", " [2.2070325573696685, 2.249791344498158],\n", " [2.6254929472535307, 2.6682523213365403],\n", " [5.974986061730133, 6.017744882820812],\n", " [0.11026041502854511, 0.15301889174400252],\n", " [0.5287194017767649, 0.571477795424427]],\n", " [[0.9962146228492084, 1.0389736922913309],\n", " [4.348368201917221, 4.391127400153699],\n", " [4.766829105028091, 4.809587783275751],\n", " [5.185288634402644, 5.228047054673869],\n", " [5.603747566234972, 5.646505989964128],\n", " [3.0885131178761616, 3.131272722925538],\n", " [3.506974672992369, 3.5497336112271656],\n", " [3.925434600123239, 3.968193133381611],\n", " [1.4128629675624562, 1.4556213653736207],\n", " [1.8313218714516546, 1.874080333273603],\n", " [2.249781131317643, 2.292539918446132],\n", " [2.6682415212015056, 2.7110008952845153],\n", " [6.017734635678107, 6.0604934567687865],\n", " [0.15300898897652004, 0.19576746569197745],\n", " [0.5714679757247394, 0.6142263693724015]],\n", " [[1.0389631967971842, 1.0817222662393067],\n", " [4.391116775865197, 4.4338759741016744],\n", " [4.809577678976066, 4.852336357223727],\n", " [5.228037208350619, 5.270795628621844],\n", " [5.646496140182947, 5.689254563912103],\n", " [3.1312616918241365, 3.1740212968735135],\n", " [3.5497232469403444, 3.592482185175141],\n", " [3.968183174071214, 4.010941707329586],\n", " [1.4556115415104325, 1.498369939321597],\n", " [1.87407044539963, 1.9168289072215783],\n", " [2.2925297052656193, 2.335288492394109],\n", " [2.7109900951494814, 2.753749469232491],\n", " [6.060483209626084, 6.103242030716763],\n", " [0.19575756292449586, 0.23851603963995327],\n", " [0.6142165496727161, 0.6569749433203782]],\n", " [[1.0817117707451596, 1.124470840187282],\n", " [4.433865349813172, 4.476624548049649],\n", " [4.852326252924042, 4.895084931171702],\n", " [5.270785782298595, 5.31354420256982],\n", " [5.689244714130922, 5.732003137860078],\n", " [2.755549613128756, 2.7983083885357134],\n", " [3.174010265772112, 3.2167698708214885],\n", " [3.59247182088832, 3.6352307591231168],\n", " [4.01093174801919, 4.053690281277562],\n", " [1.4983601154584083, 1.5411185132695728],\n", " [1.9168190193476058, 1.959577481169554],\n", " [2.3352782792135947, 2.378037066342084],\n", " [6.103231783574059, 6.145990604664738],\n", " [0.23850613687247169, 0.2812646135879291],\n", " [0.6569651236206915, 0.6997235172683536]],\n", " [[1.124460344693135, 1.1672194141352574],\n", " [4.476613923761148, 4.519373121997625],\n", " [4.895074826872017, 4.937833505119678],\n", " [5.313534356246571, 5.356292776517796],\n", " [5.731993288078899, 5.7747517118080545],\n", " [2.798298187076732, 2.8410569624836888],\n", " [3.2167588397200877, 3.2595184447694643],\n", " [3.635220394836296, 3.6779793330710926],\n", " [4.053680321967166, 4.0964388552255375],\n", " [1.5411086894063835, 1.583867087217548],\n", " [1.9595675932955812, 2.0023260551175293],\n", " [2.3780268531615705, 2.4207856402900596],\n", " [6.145980357522035, 6.188739178612714],\n", " [0.2812547108204466, 0.324013187535904],\n", " [0.6997136975686664, 0.7424720912163285]],\n", " [[4.519362497709124, 4.562121695945601],\n", " [4.937823400819993, 4.980582079067654],\n", " [5.356282930194546, 5.399041350465771],\n", " [5.774741862026874, 5.817500285756029],\n", " [2.841046761024707, 2.883805536431664],\n", " [3.2595074136680635, 3.3022670187174405],\n", " [3.6779689687842714, 3.720727907019068],\n", " [4.096428895915142, 4.139187429173513],\n", " [1.165397941468358, 1.2081565366287665],\n", " [1.5838572633543593, 1.6266156611655238],\n", " [2.002316167243557, 2.045074629065505],\n", " [2.420775427109546, 2.4635342142380345],\n", " [6.188728931470011, 6.23148775256069],\n", " [0.3240032847684233, 0.36676176148388073],\n", " [0.7424622715166427, 0.7852206651643048]],\n", " [[4.5621110716571, 4.604870269893577],\n", " [4.980571974767969, 5.023330653015629],\n", " [5.399031504142521, 5.441789924413746],\n", " [5.8174904359748485, 5.860248859704004],\n", " [2.8837953349726826, 2.92655411037964],\n", " [3.3022559876160393, 3.345015592665416],\n", " [3.720717542732247, 3.763476480967044],\n", " [4.139177469863117, 4.181936003121489],\n", " [1.2081465154163333, 1.250905110576742],\n", " [1.626605837302335, 1.6693642351134996],\n", " [2.045064741191532, 2.08782320301348],\n", " [2.4635240010575217, 2.5062827881860112],\n", " [6.231477505417986, 6.274236326508665],\n", " [0.36675185871639737, 0.4095103354318548],\n", " [0.7852108454646185, 0.8279692391122806]],\n", " [[4.6048596456050745, 4.647618843841553],\n", " [5.023320548715944, 5.0660792269636055],\n", " [5.441780078090497, 5.484538498361722],\n", " [5.860239009922825, 5.902997433651981],\n", " [2.9265439089206584, 2.969302684327616],\n", " [3.3450045615640143, 3.3877641666133913],\n", " [3.763466116680222, 3.8062250549150187],\n", " [4.181926043811092, 4.224684577069464],\n", " [1.2508950893643087, 1.2936536845247173],\n", " [1.66935441125031, 1.7121128090614746],\n", " [2.0878133151395075, 2.130571776961456],\n", " [2.5062725750054975, 2.549031362133986],\n", " [-0.008959227813624793, 0.033799593277054285],\n", " [0.4095004326643741, 0.4522589093798315],\n", " [0.8279594194125939, 0.870717813060256]]]" ] }, "metadata": { "tags": [] }, "execution_count": 113 } ] }, { "cell_type": "code", "metadata": { "ExecuteTime": { "end_time": "2020-05-14T20:08:29.378280Z", "start_time": "2020-05-14T20:08:29.372603Z" }, "id": "8kcnAP4Ekgrt", "outputId": "f6eb681a-6324-4a79-925a-34a38b56ce42" }, "source": [ "#Looking at the gap or overlap between the right endpoint of the first satellite's first crossing and the left endpoint of the second satellite's first crossing\n", "overlap= interval_caught1[1][0][0]-interval_caught1[0][0][1]\n", "#Converting that gap or overlap to meters\n", "km= 40000/(2*np.pi)\n", "overlap_m=(km*overlap)*1000\n", "overlap_m" ], "execution_count": null, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ "-66.81639094819324" ] }, "metadata": { "tags": [] }, "execution_count": 114 } ] }, { "cell_type": "code", "metadata": { "ExecuteTime": { "end_time": "2020-05-14T20:08:29.421312Z", "start_time": "2020-05-14T20:08:29.405883Z" }, "id": "8VZsCb4Pkgrt" }, "source": [ "# Comparing each interval we've crossed through periods and combining\n", " # overlapping intervals. As well as offsetting the interval we've \n", " # caught so instead of looking at [-pi,pi] we look at [0,2pi]\n", " # this should be easier to convert to a scale needed to compare\n", " # with the equitorial coverage of the Earth\n", "area_passed_over_eq1= ['']*satellites\n", "\n", "for i in range(0, satellites):\n", " interval_caught1= [];\n", " m = len(equator_catch_plus[i])\n", " for j in range(0,m):\n", " if(equator_catch_plus[i][j] <= equator_catch_minus[i][j]):\n", " interval_caught1.append( [ np.pi + equator_catch_plus[i][j], np.pi + equator_catch_minus[i][j] ] )\n", " else:\n", " interval_caught1.append( [ np.pi + equator_catch_minus[i][j], np.pi + equator_catch_plus[i][j] ] ) \n", " area_passed_over_eq1[i] = interval_caught1[0]\n", " m1 = len(interval_caught1)\n", " for j in range(0,m1):\n", " area_passed_over_eq1[i] = interval( area_passed_over_eq1[i] ) | interval( interval_caught1[j] )\n", " " ], "execution_count": null, "outputs": [] }, { "cell_type": "code", "metadata": { "ExecuteTime": { "end_time": "2020-05-14T20:08:29.454403Z", "start_time": "2020-05-14T20:08:29.447892Z" }, "id": "JoZe73Ugkgru" }, "source": [ "#Looking at the distance captured in radians by each of the satellites for every day-time crossing of the equator\n", "area_covered1 = ['']* satellites;\n", "\n", "for i in range(0, satellites):\n", " area_covered1[i]= [];\n", " for j in range(0, len(area_passed_over_eq1[i])):\n", " r1 = np.cos((area_passed_over_eq1[i][j][1])-(area_passed_over_eq1[i][j][0])) \n", " area_covered1[i].append(np.arccos(r1)) \n", " " ], "execution_count": null, "outputs": [] }, { "cell_type": "code", "metadata": { "ExecuteTime": { "end_time": "2020-05-14T20:08:29.488214Z", "start_time": "2020-05-14T20:08:29.481225Z" }, "id": "_SbfLIEhkgru", "outputId": "b5b1775c-3676-4f59-dcc8-ae948ca715ab" }, "source": [ "#Creating a variable to sum up all of the coverage per satellite\n", "total_day_area_covered_bysat = ['']*satellites;\n", "\n", "for i in range(0, satellites):\n", " total_day_area_covered_bysat[i] = 0;\n", " for j in range(0, np.size(area_covered1[i])):\n", " total_day_area_covered_bysat[i] = total_day_area_covered_bysat[i] + area_covered1[i][j];\n", "total_day_area_covered_bysat " ], "execution_count": null, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ "[0.6413807701719743,\n", " 0.6413807701719796,\n", " 0.6413815787675926,\n", " 0.64138157876759,\n", " 0.6413815787675953,\n", " 0.6413809800915388,\n", " 0.6413809800915388,\n", " 0.6413805058098256,\n", " 0.6413805058098282,\n", " 0.6413805058098282]" ] }, "metadata": { "tags": [] }, "execution_count": 117 } ] }, { "cell_type": "code", "metadata": { "ExecuteTime": { "end_time": "2020-05-14T20:08:29.523100Z", "start_time": "2020-05-14T20:08:29.518165Z" }, "id": "4Nrp6zcZkgru", "outputId": "d9b02ee6-69f6-4f2e-d0c6-acf0bbde707a" }, "source": [ "#Creating a variable to hold the total day-time coverage in radians for all satellites combined \n", "total_day_coverage= 0;\n", "\n", "for i in range(0, satellites):\n", " total_day_coverage= total_day_coverage + total_day_area_covered_bysat[i];\n", " \n", "print(total_day_coverage)\n", "print(total_day_coverage/(2*np.pi))" ], "execution_count": null, "outputs": [ { "output_type": "stream", "text": [ "6.413809754259292\n", "1.0207895264413809\n" ], "name": "stdout" } ] }, { "cell_type": "markdown", "metadata": { "id": "TMqoyg_rkgru" }, "source": [ "6 Satellites\n", "Radians Covered: 3.8482872567382707\n", "Percentage Covered (Decimal): 0.6124739393474455\n", "\n", "7 Satellites\n", "Radians Covered: 4.489668236829809\n", "Percentage Covered (Decimal): 0.7145528927341384\n", "\n", "8 Satellites\n", "Radians Covered: 5.131048742639635\n", "Percentage Covered (Decimal): 0.8166317706365522\n", "\n", "9 Satellites\n", "Radians Covered:5.7724292484494635\n", "Percentage Covered (Decimal): 0.9187106485389666\n", "\n", "10 Satellites\n", "Radians Covered: 6.413809754259292\n", "Percentage Covered (Decimal): 1.0207895264413809\n", "\n", "\n" ] }, { "cell_type": "code", "metadata": { "ExecuteTime": { "end_time": "2020-05-14T20:08:34.465134Z", "start_time": "2020-05-14T20:08:34.251079Z" }, "id": "IkJlICjEkgru", "outputId": "9b5d904b-96f9-4a85-eb78-705d99321b6e" }, "source": [ "\n", "%matplotlib notebook\n", "\n", "f = plt.figure(figsize=(10,8))\n", "ax1 = f.add_subplot(1,1,1)\n", "\n", "for i in range(satellites):\n", " title = \"Satellite\" + str(i+1)\n", " ax1.plot(np.array(te_day[i])/3600,np.array(area_covered1[i]).cumsum(), '.', label=title)\n", " plt.ylim((0,1))\n", " plt.ylabel('Individual Satellite Equator coverage in radians')\n", " plt.xlabel('Time since Satellite 1 started in hours') \n", " ax1.legend(loc='center left')\n", "ax2 = ax1.twinx()\n", "title1 = \"Cumulative Coverage of All Satellites\"\n", "title2 =\"2π Full Earth Coverage during Daytime (righthand y-axis)\"\n", "ax2.plot(np.array(te_day[0])/3600, np.array(area_covered1).cumsum(axis=1).sum(axis=0), color='blue', label=title1)\n", "ax2.yaxis.label.set_color('blue')\n", "ax2.hlines(y=(2*np.pi), xmin=22, xmax=24.5, colors='r', linestyles='--', lw=2, label =title2)\n", "ax2.legend(loc='upper right')\n", "plt.ylim((0, (2*np.pi)+1))\n", "plt.ylabel('Cumulative Equator coverage in radians') \n", "ax1.set_title('Daytime Coverage of Equator Crossings within 24 hours with ' + str(i+1) + ' Satellites')\n", "ax2.spines['right'].set_color('blue')" ], "execution_count": null, "outputs": [ { "output_type": "display_data", "data": { "application/javascript": [ "/* Put everything inside the global mpl namespace */\n", "window.mpl = {};\n", "\n", "\n", "mpl.get_websocket_type = function() {\n", " if (typeof(WebSocket) !== 'undefined') {\n", " return WebSocket;\n", " } else if (typeof(MozWebSocket) !== 'undefined') {\n", " return MozWebSocket;\n", " } else {\n", " alert('Your browser does not have WebSocket support. ' +\n", " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", " 'Firefox 4 and 5 are also supported but you ' +\n", " 'have to enable WebSockets in about:config.');\n", " };\n", "}\n", "\n", "mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n", " this.id = figure_id;\n", "\n", " this.ws = websocket;\n", "\n", " this.supports_binary = (this.ws.binaryType != undefined);\n", "\n", " if (!this.supports_binary) {\n", " var warnings = document.getElementById(\"mpl-warnings\");\n", " if (warnings) {\n", " warnings.style.display = 'block';\n", " warnings.textContent = (\n", " \"This browser does not support binary websocket messages. \" +\n", " \"Performance may be slow.\");\n", " }\n", " }\n", "\n", " this.imageObj = new Image();\n", "\n", " this.context = undefined;\n", " this.message = undefined;\n", " this.canvas = undefined;\n", " this.rubberband_canvas = undefined;\n", " this.rubberband_context = undefined;\n", " this.format_dropdown = undefined;\n", "\n", " this.image_mode = 'full';\n", "\n", " this.root = $('
');\n", " this._root_extra_style(this.root)\n", " this.root.attr('style', 'display: inline-block');\n", "\n", " $(parent_element).append(this.root);\n", "\n", " this._init_header(this);\n", " this._init_canvas(this);\n", " this._init_toolbar(this);\n", "\n", " var fig = this;\n", "\n", " this.waiting = false;\n", "\n", " this.ws.onopen = function () {\n", " fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n", " fig.send_message(\"send_image_mode\", {});\n", " if (mpl.ratio != 1) {\n", " fig.send_message(\"set_dpi_ratio\", {'dpi_ratio': mpl.ratio});\n", " }\n", " fig.send_message(\"refresh\", {});\n", " }\n", "\n", " this.imageObj.onload = function() {\n", " if (fig.image_mode == 'full') {\n", " // Full images could contain transparency (where diff images\n", " // almost always do), so we need to clear the canvas so that\n", " // there is no ghosting.\n", " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", " }\n", " fig.context.drawImage(fig.imageObj, 0, 0);\n", " };\n", "\n", " this.imageObj.onunload = function() {\n", " fig.ws.close();\n", " }\n", "\n", " this.ws.onmessage = this._make_on_message_function(this);\n", "\n", " this.ondownload = ondownload;\n", "}\n", "\n", "mpl.figure.prototype._init_header = function() {\n", " var titlebar = $(\n", " '
');\n", " var titletext = $(\n", " '
');\n", " titlebar.append(titletext)\n", " this.root.append(titlebar);\n", " this.header = titletext[0];\n", "}\n", "\n", "\n", "\n", "mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n", "\n", "}\n", "\n", "\n", "mpl.figure.prototype._root_extra_style = function(canvas_div) {\n", "\n", "}\n", "\n", "mpl.figure.prototype._init_canvas = function() {\n", " var fig = this;\n", "\n", " var canvas_div = $('
');\n", "\n", " canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n", "\n", " function canvas_keyboard_event(event) {\n", " return fig.key_event(event, event['data']);\n", " }\n", "\n", " canvas_div.keydown('key_press', canvas_keyboard_event);\n", " canvas_div.keyup('key_release', canvas_keyboard_event);\n", " this.canvas_div = canvas_div\n", " this._canvas_extra_style(canvas_div)\n", " this.root.append(canvas_div);\n", "\n", " var canvas = $('');\n", " canvas.addClass('mpl-canvas');\n", " canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n", "\n", " this.canvas = canvas[0];\n", " this.context = canvas[0].getContext(\"2d\");\n", "\n", " var backingStore = this.context.backingStorePixelRatio ||\n", "\tthis.context.webkitBackingStorePixelRatio ||\n", "\tthis.context.mozBackingStorePixelRatio ||\n", "\tthis.context.msBackingStorePixelRatio ||\n", "\tthis.context.oBackingStorePixelRatio ||\n", "\tthis.context.backingStorePixelRatio || 1;\n", "\n", " mpl.ratio = (window.devicePixelRatio || 1) / backingStore;\n", "\n", " var rubberband = $('');\n", " rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n", "\n", " var pass_mouse_events = true;\n", "\n", " canvas_div.resizable({\n", " start: function(event, ui) {\n", " pass_mouse_events = false;\n", " },\n", " resize: function(event, ui) {\n", " fig.request_resize(ui.size.width, ui.size.height);\n", " },\n", " stop: function(event, ui) {\n", " pass_mouse_events = true;\n", " fig.request_resize(ui.size.width, ui.size.height);\n", " },\n", " });\n", "\n", " function mouse_event_fn(event) {\n", " if (pass_mouse_events)\n", " return fig.mouse_event(event, event['data']);\n", " }\n", "\n", " rubberband.mousedown('button_press', mouse_event_fn);\n", " rubberband.mouseup('button_release', mouse_event_fn);\n", " // Throttle sequential mouse events to 1 every 20ms.\n", " rubberband.mousemove('motion_notify', mouse_event_fn);\n", "\n", " rubberband.mouseenter('figure_enter', mouse_event_fn);\n", " rubberband.mouseleave('figure_leave', mouse_event_fn);\n", "\n", " canvas_div.on(\"wheel\", function (event) {\n", " event = event.originalEvent;\n", " event['data'] = 'scroll'\n", " if (event.deltaY < 0) {\n", " event.step = 1;\n", " } else {\n", " event.step = -1;\n", " }\n", " mouse_event_fn(event);\n", " });\n", "\n", " canvas_div.append(canvas);\n", " canvas_div.append(rubberband);\n", "\n", " this.rubberband = rubberband;\n", " this.rubberband_canvas = rubberband[0];\n", " this.rubberband_context = rubberband[0].getContext(\"2d\");\n", " this.rubberband_context.strokeStyle = \"#000000\";\n", "\n", " this._resize_canvas = function(width, height) {\n", " // Keep the size of the canvas, canvas container, and rubber band\n", " // canvas in synch.\n", " canvas_div.css('width', width)\n", " canvas_div.css('height', height)\n", "\n", " canvas.attr('width', width * mpl.ratio);\n", " canvas.attr('height', height * mpl.ratio);\n", " canvas.attr('style', 'width: ' + width + 'px; height: ' + height + 'px;');\n", "\n", " rubberband.attr('width', width);\n", " rubberband.attr('height', height);\n", " }\n", "\n", " // Set the figure to an initial 600x600px, this will subsequently be updated\n", " // upon first draw.\n", " this._resize_canvas(600, 600);\n", "\n", " // Disable right mouse context menu.\n", " $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n", " return false;\n", " });\n", "\n", " function set_focus () {\n", " canvas.focus();\n", " canvas_div.focus();\n", " }\n", "\n", " window.setTimeout(set_focus, 100);\n", "}\n", "\n", "mpl.figure.prototype._init_toolbar = function() {\n", " var fig = this;\n", "\n", " var nav_element = $('
');\n", " nav_element.attr('style', 'width: 100%');\n", " this.root.append(nav_element);\n", "\n", " // Define a callback function for later on.\n", " function toolbar_event(event) {\n", " return fig.toolbar_button_onclick(event['data']);\n", " }\n", " function toolbar_mouse_event(event) {\n", " return fig.toolbar_button_onmouseover(event['data']);\n", " }\n", "\n", " for(var toolbar_ind in mpl.toolbar_items) {\n", " var name = mpl.toolbar_items[toolbar_ind][0];\n", " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", " var image = mpl.toolbar_items[toolbar_ind][2];\n", " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", "\n", " if (!name) {\n", " // put a spacer in here.\n", " continue;\n", " }\n", " var button = $('');\n", " button.click(method_name, toolbar_event);\n", " button.mouseover(tooltip, toolbar_mouse_event);\n", " nav_element.append(button);\n", " }\n", "\n", " // Add the status bar.\n", " var status_bar = $('');\n", " nav_element.append(status_bar);\n", " this.message = status_bar[0];\n", "\n", " // Add the close button to the window.\n", " var buttongrp = $('
');\n", " var button = $('');\n", " button.click(function (evt) { fig.handle_close(fig, {}); } );\n", " button.mouseover('Stop Interaction', toolbar_mouse_event);\n", " buttongrp.append(button);\n", " var titlebar = this.root.find($('.ui-dialog-titlebar'));\n", " titlebar.prepend(buttongrp);\n", "}\n", "\n", "mpl.figure.prototype._root_extra_style = function(el){\n", " var fig = this\n", " el.on(\"remove\", function(){\n", "\tfig.close_ws(fig, {});\n", " });\n", "}\n", "\n", "mpl.figure.prototype._canvas_extra_style = function(el){\n", " // this is important to make the div 'focusable\n", " el.attr('tabindex', 0)\n", " // reach out to IPython and tell the keyboard manager to turn it's self\n", " // off when our div gets focus\n", "\n", " // location in version 3\n", " if (IPython.notebook.keyboard_manager) {\n", " IPython.notebook.keyboard_manager.register_events(el);\n", " }\n", " else {\n", " // location in version 2\n", " IPython.keyboard_manager.register_events(el);\n", " }\n", "\n", "}\n", "\n", "mpl.figure.prototype._key_event_extra = function(event, name) {\n", " var manager = IPython.notebook.keyboard_manager;\n", " if (!manager)\n", " manager = IPython.keyboard_manager;\n", "\n", " // Check for shift+enter\n", " if (event.shiftKey && event.which == 13) {\n", " this.canvas_div.blur();\n", " event.shiftKey = false;\n", " // Send a \"J\" for go to next cell\n", " event.which = 74;\n", " event.keyCode = 74;\n", " manager.command_mode();\n", " manager.handle_keydown(event);\n", " }\n", "}\n", "\n", "mpl.figure.prototype.handle_save = function(fig, msg) {\n", " fig.ondownload(fig, null);\n", "}\n", "\n", "\n", "mpl.find_output_cell = function(html_output) {\n", " // Return the cell and output element which can be found *uniquely* in the notebook.\n", " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", " // IPython event is triggered only after the cells have been serialised, which for\n", " // our purposes (turning an active figure into a static one), is too late.\n", " var cells = IPython.notebook.get_cells();\n", " var ncells = cells.length;\n", " for (var i=0; i= 3 moved mimebundle to data attribute of output\n", " data = data.data;\n", " }\n", " if (data['text/html'] == html_output) {\n", " return [cell, data, j];\n", " }\n", " }\n", " }\n", " }\n", "}\n", "\n", "// Register the function which deals with the matplotlib target/channel.\n", "// The kernel may be null if the page has been refreshed.\n", "if (IPython.notebook.kernel != null) {\n", " IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n", "}\n" ], "text/plain": [ "" ] }, "metadata": { "tags": [] } }, { "output_type": "display_data", "data": { "text/html": [ "" ], "text/plain": [ "" ] }, "metadata": { "tags": [] } }, { "output_type": "execute_result", "data": { "text/plain": [ "" ] }, "metadata": { "tags": [] }, "execution_count": 119 } ] }, { "cell_type": "code", "metadata": { "ExecuteTime": { "end_time": "2020-05-14T20:04:59.367944Z", "start_time": "2020-05-14T20:04:59.305499Z" }, "id": "XNHHIOKDkgrv", "outputId": "d0df2c85-0d20-47e5-d10d-807090c0c0e7" }, "source": [ "#ALL PLOTS FOR THE PROJECT\n", "\n", "#Plotting the orbit(s) around a fixed invisible Earth.\n", "%matplotlib notebook\n", "f = plt.figure(figsize=(20,10))\n", "ax = f.add_subplot(1,2,1,projection='3d')\n", "for i in range(0,satellites):\n", " title = \"sat\" + str(i+1) + \"-orbit\"\n", " ax.plot(q[i][:,0], q[i][:,1], q[i][:,2], label=title)\n", "ax.set_xlabel('q₁')\n", "ax.set_ylabel('q₂')\n", "ax.set_zlabel('q₃')\n", "ax.set_title('3-Dimensional Orbits for ' + str(i+1) + ' Satellites in 24 hours')\n", "ax.legend(loc='lower right')\n" ], "execution_count": null, "outputs": [ { "output_type": "display_data", "data": { "application/javascript": [ "/* Put everything inside the global mpl namespace */\n", "window.mpl = {};\n", "\n", "\n", "mpl.get_websocket_type = function() {\n", " if (typeof(WebSocket) !== 'undefined') {\n", " return WebSocket;\n", " } else if (typeof(MozWebSocket) !== 'undefined') {\n", " return MozWebSocket;\n", " } else {\n", " alert('Your browser does not have WebSocket support. ' +\n", " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", " 'Firefox 4 and 5 are also supported but you ' +\n", " 'have to enable WebSockets in about:config.');\n", " };\n", "}\n", "\n", "mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n", " this.id = figure_id;\n", "\n", " this.ws = websocket;\n", "\n", " this.supports_binary = (this.ws.binaryType != undefined);\n", "\n", " if (!this.supports_binary) {\n", " var warnings = document.getElementById(\"mpl-warnings\");\n", " if (warnings) {\n", " warnings.style.display = 'block';\n", " warnings.textContent = (\n", " \"This browser does not support binary websocket messages. \" +\n", " \"Performance may be slow.\");\n", " }\n", " }\n", "\n", " this.imageObj = new Image();\n", "\n", " this.context = undefined;\n", " this.message = undefined;\n", " this.canvas = undefined;\n", " this.rubberband_canvas = undefined;\n", " this.rubberband_context = undefined;\n", " this.format_dropdown = undefined;\n", "\n", " this.image_mode = 'full';\n", "\n", " this.root = $('
');\n", " this._root_extra_style(this.root)\n", " this.root.attr('style', 'display: inline-block');\n", "\n", " $(parent_element).append(this.root);\n", "\n", " this._init_header(this);\n", " this._init_canvas(this);\n", " this._init_toolbar(this);\n", "\n", " var fig = this;\n", "\n", " this.waiting = false;\n", "\n", " this.ws.onopen = function () {\n", " fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n", " fig.send_message(\"send_image_mode\", {});\n", " if (mpl.ratio != 1) {\n", " fig.send_message(\"set_dpi_ratio\", {'dpi_ratio': mpl.ratio});\n", " }\n", " fig.send_message(\"refresh\", {});\n", " }\n", "\n", " this.imageObj.onload = function() {\n", " if (fig.image_mode == 'full') {\n", " // Full images could contain transparency (where diff images\n", " // almost always do), so we need to clear the canvas so that\n", " // there is no ghosting.\n", " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", " }\n", " fig.context.drawImage(fig.imageObj, 0, 0);\n", " };\n", "\n", " this.imageObj.onunload = function() {\n", " fig.ws.close();\n", " }\n", "\n", " this.ws.onmessage = this._make_on_message_function(this);\n", "\n", " this.ondownload = ondownload;\n", "}\n", "\n", "mpl.figure.prototype._init_header = function() {\n", " var titlebar = $(\n", " '
');\n", " var titletext = $(\n", " '
');\n", " titlebar.append(titletext)\n", " this.root.append(titlebar);\n", " this.header = titletext[0];\n", "}\n", "\n", "\n", "\n", "mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n", "\n", "}\n", "\n", "\n", "mpl.figure.prototype._root_extra_style = function(canvas_div) {\n", "\n", "}\n", "\n", "mpl.figure.prototype._init_canvas = function() {\n", " var fig = this;\n", "\n", " var canvas_div = $('
');\n", "\n", " canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n", "\n", " function canvas_keyboard_event(event) {\n", " return fig.key_event(event, event['data']);\n", " }\n", "\n", " canvas_div.keydown('key_press', canvas_keyboard_event);\n", " canvas_div.keyup('key_release', canvas_keyboard_event);\n", " this.canvas_div = canvas_div\n", " this._canvas_extra_style(canvas_div)\n", " this.root.append(canvas_div);\n", "\n", " var canvas = $('');\n", " canvas.addClass('mpl-canvas');\n", " canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n", "\n", " this.canvas = canvas[0];\n", " this.context = canvas[0].getContext(\"2d\");\n", "\n", " var backingStore = this.context.backingStorePixelRatio ||\n", "\tthis.context.webkitBackingStorePixelRatio ||\n", "\tthis.context.mozBackingStorePixelRatio ||\n", "\tthis.context.msBackingStorePixelRatio ||\n", "\tthis.context.oBackingStorePixelRatio ||\n", "\tthis.context.backingStorePixelRatio || 1;\n", "\n", " mpl.ratio = (window.devicePixelRatio || 1) / backingStore;\n", "\n", " var rubberband = $('');\n", " rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n", "\n", " var pass_mouse_events = true;\n", "\n", " canvas_div.resizable({\n", " start: function(event, ui) {\n", " pass_mouse_events = false;\n", " },\n", " resize: function(event, ui) {\n", " fig.request_resize(ui.size.width, ui.size.height);\n", " },\n", " stop: function(event, ui) {\n", " pass_mouse_events = true;\n", " fig.request_resize(ui.size.width, ui.size.height);\n", " },\n", " });\n", "\n", " function mouse_event_fn(event) {\n", " if (pass_mouse_events)\n", " return fig.mouse_event(event, event['data']);\n", " }\n", "\n", " rubberband.mousedown('button_press', mouse_event_fn);\n", " rubberband.mouseup('button_release', mouse_event_fn);\n", " // Throttle sequential mouse events to 1 every 20ms.\n", " rubberband.mousemove('motion_notify', mouse_event_fn);\n", "\n", " rubberband.mouseenter('figure_enter', mouse_event_fn);\n", " rubberband.mouseleave('figure_leave', mouse_event_fn);\n", "\n", " canvas_div.on(\"wheel\", function (event) {\n", " event = event.originalEvent;\n", " event['data'] = 'scroll'\n", " if (event.deltaY < 0) {\n", " event.step = 1;\n", " } else {\n", " event.step = -1;\n", " }\n", " mouse_event_fn(event);\n", " });\n", "\n", " canvas_div.append(canvas);\n", " canvas_div.append(rubberband);\n", "\n", " this.rubberband = rubberband;\n", " this.rubberband_canvas = rubberband[0];\n", " this.rubberband_context = rubberband[0].getContext(\"2d\");\n", " this.rubberband_context.strokeStyle = \"#000000\";\n", "\n", " this._resize_canvas = function(width, height) {\n", " // Keep the size of the canvas, canvas container, and rubber band\n", " // canvas in synch.\n", " canvas_div.css('width', width)\n", " canvas_div.css('height', height)\n", "\n", " canvas.attr('width', width * mpl.ratio);\n", " canvas.attr('height', height * mpl.ratio);\n", " canvas.attr('style', 'width: ' + width + 'px; height: ' + height + 'px;');\n", "\n", " rubberband.attr('width', width);\n", " rubberband.attr('height', height);\n", " }\n", "\n", " // Set the figure to an initial 600x600px, this will subsequently be updated\n", " // upon first draw.\n", " this._resize_canvas(600, 600);\n", "\n", " // Disable right mouse context menu.\n", " $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n", " return false;\n", " });\n", "\n", " function set_focus () {\n", " canvas.focus();\n", " canvas_div.focus();\n", " }\n", "\n", " window.setTimeout(set_focus, 100);\n", "}\n", "\n", "mpl.figure.prototype._init_toolbar = function() {\n", " var fig = this;\n", "\n", " var nav_element = $('
');\n", " nav_element.attr('style', 'width: 100%');\n", " this.root.append(nav_element);\n", "\n", " // Define a callback function for later on.\n", " function toolbar_event(event) {\n", " return fig.toolbar_button_onclick(event['data']);\n", " }\n", " function toolbar_mouse_event(event) {\n", " return fig.toolbar_button_onmouseover(event['data']);\n", " }\n", "\n", " for(var toolbar_ind in mpl.toolbar_items) {\n", " var name = mpl.toolbar_items[toolbar_ind][0];\n", " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", " var image = mpl.toolbar_items[toolbar_ind][2];\n", " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", "\n", " if (!name) {\n", " // put a spacer in here.\n", " continue;\n", " }\n", " var button = $('');\n", " button.click(method_name, toolbar_event);\n", " button.mouseover(tooltip, toolbar_mouse_event);\n", " nav_element.append(button);\n", " }\n", "\n", " // Add the status bar.\n", " var status_bar = $('');\n", " nav_element.append(status_bar);\n", " this.message = status_bar[0];\n", "\n", " // Add the close button to the window.\n", " var buttongrp = $('
');\n", " var button = $('');\n", " button.click(function (evt) { fig.handle_close(fig, {}); } );\n", " button.mouseover('Stop Interaction', toolbar_mouse_event);\n", " buttongrp.append(button);\n", " var titlebar = this.root.find($('.ui-dialog-titlebar'));\n", " titlebar.prepend(buttongrp);\n", "}\n", "\n", "mpl.figure.prototype._root_extra_style = function(el){\n", " var fig = this\n", " el.on(\"remove\", function(){\n", "\tfig.close_ws(fig, {});\n", " });\n", "}\n", "\n", "mpl.figure.prototype._canvas_extra_style = function(el){\n", " // this is important to make the div 'focusable\n", " el.attr('tabindex', 0)\n", " // reach out to IPython and tell the keyboard manager to turn it's self\n", " // off when our div gets focus\n", "\n", " // location in version 3\n", " if (IPython.notebook.keyboard_manager) {\n", " IPython.notebook.keyboard_manager.register_events(el);\n", " }\n", " else {\n", " // location in version 2\n", " IPython.keyboard_manager.register_events(el);\n", " }\n", "\n", "}\n", "\n", "mpl.figure.prototype._key_event_extra = function(event, name) {\n", " var manager = IPython.notebook.keyboard_manager;\n", " if (!manager)\n", " manager = IPython.keyboard_manager;\n", "\n", " // Check for shift+enter\n", " if (event.shiftKey && event.which == 13) {\n", " this.canvas_div.blur();\n", " event.shiftKey = false;\n", " // Send a \"J\" for go to next cell\n", " event.which = 74;\n", " event.keyCode = 74;\n", " manager.command_mode();\n", " manager.handle_keydown(event);\n", " }\n", "}\n", "\n", "mpl.figure.prototype.handle_save = function(fig, msg) {\n", " fig.ondownload(fig, null);\n", "}\n", "\n", "\n", "mpl.find_output_cell = function(html_output) {\n", " // Return the cell and output element which can be found *uniquely* in the notebook.\n", " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", " // IPython event is triggered only after the cells have been serialised, which for\n", " // our purposes (turning an active figure into a static one), is too late.\n", " var cells = IPython.notebook.get_cells();\n", " var ncells = cells.length;\n", " for (var i=0; i= 3 moved mimebundle to data attribute of output\n", " data = data.data;\n", " }\n", " if (data['text/html'] == html_output) {\n", " return [cell, data, j];\n", " }\n", " }\n", " }\n", " }\n", "}\n", "\n", "// Register the function which deals with the matplotlib target/channel.\n", "// The kernel may be null if the page has been refreshed.\n", "if (IPython.notebook.kernel != null) {\n", " IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n", "}\n" ], "text/plain": [ "" ] }, "metadata": { "tags": [] } }, { "output_type": "display_data", "data": { "text/html": [ "" ], "text/plain": [ "" ] }, "metadata": { "tags": [] } }, { "output_type": "execute_result", "data": { "text/plain": [ "Text(0, 0.5, 'Latitude of Earth in radians(-π/2 to +π/2)')" ] }, "metadata": { "tags": [] }, "execution_count": 348 } ] } ] }