Created
October 24, 2019 14:30
-
-
Save hannorein/4cac4297c485b281076cf7d756f3d3f9 to your computer and use it in GitHub Desktop.
Starlink in REBOUND
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"cells": [ | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"# Starlink in REBOUND\n", | |
"Use [Cees Bassa](https://twitter.com/cgbassa)'s [notebook](https://nbviewer.jupyter.org/github/cbassa/satellite_analysis/blob/master/starlink_sunlit_satellites.ipynb) to generate the `tles.txt` file with the orbital parameters of the starlink constellation. " | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 1, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"import rebound\n", | |
"import numpy as np" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 2, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"sim = rebound.Simulation()\n", | |
"sim.G = 6.67408e-20 # m^3 / kg s^2\n", | |
"sim.add(m = 5.972e24) # earth mass in kg\n", | |
"sim.N_active = 1\n", | |
"with open(\"tles.txt\", \"r\") as fp:\n", | |
" lines = fp.readlines()\n", | |
" for i in range(len(lines)//3):\n", | |
" fields = lines[i*3+2].split()\n", | |
" n = float(fields[7])/24/60/60*np.pi*2.\n", | |
" a = np.power(sim.G*sim.particles[0].m/(n*n),1./3.)\n", | |
" sim.add(a=a,\n", | |
" inc=float(fields[2])/180.*np.pi,\n", | |
" Omega=float(fields[3])/180.*np.pi,\n", | |
" e=float(\"0.\"+fields[4]),\n", | |
" omega=float(fields[5])/180.*np.pi,\n", | |
" M=float(fields[6])/180.*np.pi)" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 3, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/html": [ | |
"\n", | |
"<script id=\"orbit_shader-vs\" type=\"x-shader/x-vertex\">\n", | |
" uniform vec3 focus;\n", | |
" uniform vec3 aef;\n", | |
" uniform vec3 omegaOmegainc;\n", | |
" attribute float lintwopi;\n", | |
" varying float lin;\n", | |
" uniform mat4 mvp;\n", | |
" const float M_PI = 3.14159265359;\n", | |
" void main() {\n", | |
" float a = aef.x;\n", | |
" float e = aef.y;\n", | |
" float f = aef.z+lintwopi;\n", | |
" lin = lintwopi/(M_PI*2.);\n", | |
" if (e>1.){\n", | |
" float theta_max = acos(-1./e);\n", | |
" f = 0.0001-theta_max+1.9998*lin*theta_max;\n", | |
" lin = sqrt(min(0.5,lin));\n", | |
" }\n", | |
" float omega = omegaOmegainc.x;\n", | |
" float Omega = omegaOmegainc.y;\n", | |
" float inc = omegaOmegainc.z;\n", | |
" float r = a*(1.-e*e)/(1. + e*cos(f));\n", | |
" float cO = cos(Omega);\n", | |
" float sO = sin(Omega);\n", | |
" float co = cos(omega);\n", | |
" float so = sin(omega);\n", | |
" float cf = cos(f);\n", | |
" float sf = sin(f);\n", | |
" float ci = cos(inc);\n", | |
" float si = sin(inc);\n", | |
" vec3 pos = vec3(r*(cO*(co*cf-so*sf) - sO*(so*cf+co*sf)*ci),r*(sO*(co*cf-so*sf) + cO*(so*cf+co*sf)*ci),+ r*(so*cf+co*sf)*si);\n", | |
" gl_Position = mvp*(vec4(focus+pos, 1.0));\n", | |
" }\n", | |
"</script>\n", | |
"<script id=\"orbit_shader-fs\" type=\"x-shader/x-fragment\">\n", | |
" precision mediump float;\n", | |
" varying float lin;\n", | |
" void main() {\n", | |
" float fog = max(max(0.,-1.+2.*gl_FragCoord.z),max(0.,1.-2.*gl_FragCoord.z));\n", | |
" gl_FragColor = vec4(1.,1.,1.,sqrt(lin)*(1.-fog));\n", | |
" }\n", | |
"</script>\n", | |
"<script id=\"point_shader-vs\" type=\"x-shader/x-vertex\">\n", | |
" attribute vec3 vp;\n", | |
" uniform mat4 mvp;\n", | |
" //uniform vec4 vc;\n", | |
" //varying vec4 color;\n", | |
" void main() {\n", | |
" gl_PointSize = 15.0;\n", | |
" gl_Position = mvp*vec4(vp, 1.0);\n", | |
" //color = vc;\n", | |
" }\n", | |
"</script>\n", | |
"<script id=\"point_shader-fs\" type=\"x-shader/x-fragment\">\n", | |
" precision mediump float;\n", | |
" //varying vec4 color;\n", | |
" void main() {\n", | |
" vec2 rel = gl_PointCoord.st;\n", | |
" rel.s -=0.5;\n", | |
" rel.t -=0.5;\n", | |
" if (length(rel)>0.25){\n", | |
" gl_FragColor = vec4(0.,0.,0.,0.); \n", | |
" }else{\n", | |
" vec4 cmod = vec4(1.,1.,1.,1.);\n", | |
" float fog = max(max(0.,-1.+2.*gl_FragCoord.z),max(0.,1.-2.*gl_FragCoord.z));\n", | |
" cmod.a*= (1.-fog)*min(1.,1.-4.*(length(rel)/0.25-0.75));\n", | |
" gl_FragColor = cmod;\n", | |
" }\n", | |
" }\n", | |
"</script>\n", | |
"\n", | |
"<script>\n", | |
"function compileShader(glr, shaderSource, shaderType) {\n", | |
" // Create the shader object\n", | |
" var shader = glr.createShader(shaderType);\n", | |
" \n", | |
" // Set the shader source code.\n", | |
" glr.shaderSource(shader, shaderSource);\n", | |
" \n", | |
" // Compile the shader\n", | |
" glr.compileShader(shader);\n", | |
" \n", | |
" // Check if it compiled\n", | |
" var success = glr.getShaderParameter(shader, glr.COMPILE_STATUS);\n", | |
" if (!success) {\n", | |
" // Something went wrong during compilation; get the error\n", | |
" throw \"could not compile shader:\" + glr.getShaderInfoLog(shader);\n", | |
" }\n", | |
" \n", | |
" return shader;\n", | |
"}\n", | |
"function createShaderFromScript(glr, scriptId, opt_shaderType) {\n", | |
" // look up the script tag by id.\n", | |
" var shaderScript = document.getElementById(scriptId);\n", | |
" if (!shaderScript) {\n", | |
" throw(\"*** Error: unknown script element\" + scriptId);\n", | |
" }\n", | |
" \n", | |
" // extract the contents of the script tag.\n", | |
" var shaderSource = shaderScript.text;\n", | |
" \n", | |
" // If we didn't pass in a type, use the 'type' from\n", | |
" // the script tag.\n", | |
" if (!opt_shaderType) {\n", | |
" if (shaderScript.type == \"x-shader/x-vertex\") {\n", | |
" opt_shaderType = glr.VERTEX_SHADER;\n", | |
" } else if (shaderScript.type == \"x-shader/x-fragment\") {\n", | |
" opt_shaderType = glr.FRAGMENT_SHADER;\n", | |
" } else if (!opt_shaderType) {\n", | |
" throw(\"*** Error: shader type not set\");\n", | |
" }\n", | |
" }\n", | |
" \n", | |
" return compileShader(glr, shaderSource, opt_shaderType);\n", | |
"};\n", | |
"function createProgramFromScripts( glr, vertexShaderId, fragmentShaderId) {\n", | |
" var vertexShader = createShaderFromScript(glr, vertexShaderId, glr.VERTEX_SHADER);\n", | |
" var fragmentShader = createShaderFromScript(glr, fragmentShaderId, glr.FRAGMENT_SHADER);\n", | |
" var program = glr.createProgram();\n", | |
" \n", | |
" // attach the shaders.\n", | |
" glr.attachShader(program, vertexShader);\n", | |
" glr.attachShader(program, fragmentShader);\n", | |
" \n", | |
" // link the program.\n", | |
" glr.linkProgram(program);\n", | |
" \n", | |
" // Check if it linked.\n", | |
" var success = glr.getProgramParameter(program, glr.LINK_STATUS);\n", | |
" if (!success) {\n", | |
" // something went wrong with the link\n", | |
" throw (\"program filed to link:\" + glr.getProgramInfoLog (program));\n", | |
" }\n", | |
" \n", | |
" return program;\n", | |
"}\n", | |
"function quat2mat(A,mat){\n", | |
" var xx = A.x*A.x; var xy = A.x*A.y; var xz = A.x*A.z;\n", | |
" var xw = A.x*A.w; var yy = A.y*A.y; var yz = A.y*A.z;\n", | |
" var yw = A.y*A.w; var zz = A.z*A.z; var zw = A.z*A.w;\n", | |
" mat[0] = 1.-2.*(yy+zz);\n", | |
" mat[1] = 2.*(xy-zw);\n", | |
" mat[2] = 2.*(xz+yw);\n", | |
" mat[4] = 2.*(xy+zw);\n", | |
" mat[5] = 1.-2.*(xx+zz);\n", | |
" mat[6] = 2.*(yz-xw);\n", | |
" mat[8] = 2.*(xz-yw);\n", | |
" mat[9] = 2.*(yz+xw);\n", | |
" mat[10]= 1.-2.*(xx+yy);\n", | |
" mat[3] = mat[7] = mat[11] = mat[12] = mat[13] = mat[14] = 0.; mat[15]= 1.;\n", | |
"}\n", | |
"function multvec(A, B, vecr){\n", | |
" var mat = [0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.];\n", | |
" quat2mat(A,mat);\n", | |
" vecr[0] = mat[0]*B[0] + mat[1]*B[1] + mat[2]*B[2];\n", | |
" vecr[1] = mat[4]*B[0] + mat[5]*B[1] + mat[6]*B[2];\n", | |
" vecr[2] = mat[8]*B[0] + mat[9]*B[1] + mat[10]*B[2];\n", | |
"}\n", | |
"function mattransp(mat){\n", | |
" var matt = [\n", | |
" mat[0], mat[4], mat[8], mat[12],\n", | |
" mat[1], mat[5], mat[9], mat[13],\n", | |
" mat[2], mat[6], mat[10], mat[14],\n", | |
" mat[3], mat[7], mat[11], mat[15]];\n", | |
" return matt;\n", | |
"}\n", | |
"function conjugate(quat){\n", | |
" var cquat = {x:-quat.x, y:-quat.y, z:-quat.z, w:quat.w};\n", | |
" return cquat;\n", | |
"}\n", | |
"function mult(A, B){\n", | |
" var mquat = { x: A.w*B.x + A.x*B.w + A.y*B.z - A.z*B.y,\n", | |
" y: A.w*B.y - A.x*B.z + A.y*B.w + A.z*B.x,\n", | |
" z: A.w*B.z + A.x*B.y - A.y*B.x + A.z*B.w,\n", | |
" w: A.w*B.w - A.x*B.x - A.y*B.y - A.z*B.z};\n", | |
" return mquat;\n", | |
"}\n", | |
"\n", | |
"function normalize(quat){\n", | |
" var L = Math.sqrt(quat.x*quat.x + quat.y*quat.y + quat.z*quat.z + quat.w*quat.w);\n", | |
" var nquat = {x:quat.x/L, y:quat.y/L, z:quat.z/L, w:quat.w/L};\n", | |
" return nquat;\n", | |
"}\n", | |
"function matortho(mat, l, r, b, t, n, f){\n", | |
" mat[0] = 2./(r-l); mat[1] = 0.; mat[2] = 0.; mat[3] = -(r+l)/(r-l);\n", | |
" mat[4] = 0.; mat[5] = 2./(t-b); mat[6] = 0.; mat[7] = -(t+b)/(t-b);\n", | |
" mat[8] = 0.; mat[9] = 0.; mat[10] = -2./(f-n); mat[11] = -(f+n)/(f-n);\n", | |
" mat[12] = 0.; mat[13] = 0.; mat[14] = 0.; mat[15] = 1.;\n", | |
"}\n", | |
"function matmult(A,B,C){\n", | |
" for(i=0;i<4;i++){\n", | |
" for(j=0;j<4;j++){\n", | |
" C[i+4*j] = 0.;\n", | |
" for(k=0;k<4;k++){\n", | |
" C[i+4*j] += A[k+4*j]*B[i+4*k];\n", | |
" }}}\n", | |
"}\n", | |
"function startGL(reboundView) {\n", | |
" var canvas = document.getElementById(\"reboundcanvas-\"+reboundView.cid);\n", | |
" if (!canvas){\n", | |
" reboundView.startCount = reboundView.startCount+1;\n", | |
" if (reboundView.startCount>1000){\n", | |
" console.log(\"Cannot find element.\");\n", | |
" }else{\n", | |
" setTimeout(function(){ startGL(reboundView); }, 10);\n", | |
" }\n", | |
" return;\n", | |
" }\n", | |
" var rect = canvas.getBoundingClientRect()\n", | |
" reboundView.ratio = rect.width/rect.height;\n", | |
" reboundView.view = normalize({x:reboundView.orientation[0], y:reboundView.orientation[1], z:reboundView.orientation[2], w:reboundView.orientation[3]});\n", | |
"\n", | |
" canvas.addEventListener('mousedown', function() {\n", | |
" reboundView.mouseDown=1;\n", | |
" }, false);\n", | |
" canvas.addEventListener('mouseup', function() {\n", | |
" reboundView.mouseDown=0;\n", | |
" }, false);\n", | |
" canvas.addEventListener('mouseleave', function() {\n", | |
" reboundView.mouseDown=0;\n", | |
" }, false);\n", | |
"\n", | |
" canvas.addEventListener('mousemove', function(evt) {\n", | |
" var rect = canvas.getBoundingClientRect()\n", | |
" if (reboundView.mouseDown==1){\n", | |
" reboundView.mouseDown = 2;\n", | |
" reboundView.mouse_x = evt.clientX-rect.left;\n", | |
" reboundView.mouse_y = evt.clientY-rect.top;\n", | |
" return;\n", | |
" }else if (reboundView.mouseDown==2){\n", | |
" var width = rect.width;\n", | |
" var height = rect.height;\n", | |
" var dx = 3.*(evt.clientX-rect.left-reboundView.mouse_x)/width;\n", | |
" var dy = 3.*(evt.clientY-rect.top-reboundView.mouse_y)/height;\n", | |
" reboundView.mouse_x = evt.clientX-rect.left;\n", | |
" reboundView.mouse_y = evt.clientY-rect.top;\n", | |
" if (evt.shiftKey){\n", | |
" reboundView.scale *= (1.+dx+dy);\n", | |
" }else{\n", | |
" var inv = conjugate(reboundView.view);\n", | |
" var up = [0.,1.,0.];\n", | |
" var right = [1.,0.,0.];\n", | |
" var inv_up = [0.,0.,0.];\n", | |
" var inv_right = [0.,0.,0.];\n", | |
" multvec(inv, right, inv_right);\n", | |
" multvec(inv, up, inv_up);\n", | |
" \n", | |
" var sin_dy = Math.sin(dy);\n", | |
" var rot_dy = {x:inv_right[0]*sin_dy, y:inv_right[1]*sin_dy, z:inv_right[2]*sin_dy, w:Math.cos(dy)};\n", | |
" reboundView.view = mult(reboundView.view, normalize(rot_dy));\n", | |
" \n", | |
" var sin_dx = Math.sin(dx);\n", | |
" var rot_dx = {x:inv_up[0]*sin_dx, y:inv_up[1]*sin_dx, z:inv_up[2]*sin_dx, w:Math.cos(dx)};\n", | |
" reboundView.view = normalize(mult(reboundView.view, normalize(rot_dx)));\n", | |
" }\n", | |
"\n", | |
" drawGL(reboundView);\n", | |
" }\n", | |
"\n", | |
"\n", | |
" }, false);\n", | |
"\n", | |
" reboundView.gl = canvas.getContext(\"webgl\")||canvas.getContext(\"experimental-webgl\");\n", | |
" if (!reboundView.gl) {\n", | |
" alert(\"Unable to initialize WebGL. Your browser may not support it.\");\n", | |
" return;\n", | |
" }\n", | |
" var gl = reboundView.gl\n", | |
" gl.enable(gl.BLEND);\n", | |
" gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);\n", | |
" \n", | |
" reboundView.orbit_shader_program = createProgramFromScripts(gl,\"orbit_shader-vs\",\"orbit_shader-fs\");\n", | |
" reboundView.point_shader_program = createProgramFromScripts(gl,\"point_shader-vs\",\"point_shader-fs\");\n", | |
" \n", | |
" var lintwopi = new Float32Array(500);\n", | |
" for(i=0;i<500;i++){\n", | |
" lintwopi[i] = 2.*Math.PI/500.*i;\n", | |
" }\n", | |
" reboundView.orbit_lintwopi_buffer = gl.createBuffer();\n", | |
" gl.bindBuffer(gl.ARRAY_BUFFER, reboundView.orbit_lintwopi_buffer);\n", | |
" gl.bufferData(gl.ARRAY_BUFFER, 4*500, gl.STATIC_DRAW);\n", | |
" gl.bufferSubData(gl.ARRAY_BUFFER, 0, lintwopi)\n", | |
" reboundView.orbit_shader_mvp_location = gl.getUniformLocation(reboundView.orbit_shader_program,\"mvp\");\n", | |
" reboundView.orbit_shader_focus_location = gl.getUniformLocation(reboundView.orbit_shader_program,\"focus\");\n", | |
" reboundView.orbit_shader_aef_location = gl.getUniformLocation(reboundView.orbit_shader_program,\"aef\");\n", | |
" reboundView.orbit_shader_omegaOmegainc_location = gl.getUniformLocation(reboundView.orbit_shader_program,\"omegaOmegainc\");\n", | |
" \n", | |
" reboundView.particle_data_buffer = gl.createBuffer();\n", | |
" gl.useProgram(reboundView.point_shader_program);\n", | |
" reboundView.point_shader_mvp_location = gl.getUniformLocation(reboundView.point_shader_program,\"mvp\");\n", | |
" \n", | |
" updateRenderData(reboundView);\n", | |
" gl.clearColor(0.0, 0.0, 0.0, 1.0);\n", | |
" gl.clear(gl.COLOR_BUFFER_BIT);\n", | |
" drawGL(reboundView);\n", | |
"}\n", | |
"function updateRenderData(reboundView){\n", | |
" var overlay = document.getElementById(\"reboundoverlay-\"+reboundView.cid);\n", | |
" overlay.innerHTML = reboundView.model.get(\"overlay\");\n", | |
" var previousN = reboundView.N;\n", | |
" reboundView.N = reboundView.model.get(\"N\");\n", | |
" reboundView.t = reboundView.model.get(\"t\");\n", | |
" reboundView.particle_data = reboundView.model.get('particle_data');\n", | |
" if (reboundView.orbits){\n", | |
" reboundView.orbit_data = reboundView.model.get('orbit_data');\n", | |
" }\n", | |
" var gl = reboundView.gl\n", | |
" if (reboundView.N>0){\n", | |
" gl.bindBuffer(gl.ARRAY_BUFFER, reboundView.particle_data_buffer);\n", | |
" gl.bufferData(gl.ARRAY_BUFFER, reboundView.N*7*4, gl.DYNAMIC_DRAW);\n", | |
" gl.bufferSubData(gl.ARRAY_BUFFER, 0, reboundView.particle_data)\n", | |
" }\n", | |
"}\n", | |
"function drawGL(reboundView) {\n", | |
" if (!reboundView.gl){\n", | |
" return;\n", | |
" }\n", | |
" // Cleanup\n", | |
" var gl = reboundView.gl\n", | |
" gl.clearColor(0.0, 0.0, 0.0, 1.0);\n", | |
" gl.clear(gl.COLOR_BUFFER_BIT);\n", | |
" \n", | |
" // Draw\n", | |
" gl.useProgram(reboundView.point_shader_program);\n", | |
" gl.bindBuffer(gl.ARRAY_BUFFER, reboundView.particle_data_buffer);\n", | |
" var pvp = gl.getAttribLocation(reboundView.point_shader_program,\"vp\");\n", | |
" gl.enableVertexAttribArray(pvp);\n", | |
" gl.vertexAttribPointer(pvp, 3, gl.FLOAT, 0, 4*7,0); // 4 = size of float\n", | |
" var projection = [0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.];\n", | |
" if (reboundView.ratio>=1.){\n", | |
" matortho(projection, \n", | |
" -1.6*reboundView.scale, 1.6*reboundView.scale,\n", | |
" -1.6/reboundView.ratio*reboundView.scale, 1.6/reboundView.ratio*reboundView.scale,\n", | |
" -2.5*reboundView.scale, 2.5*reboundView.scale);\n", | |
" }else{\n", | |
" matortho(projection, \n", | |
" -1.6*reboundView.ratio*reboundView.scale, 1.6*reboundView.ratio*reboundView.scale,\n", | |
" -1.6*reboundView.scale, 1.6*reboundView.scale,\n", | |
" -2.5*reboundView.scale, 2.5*reboundView.scale);\n", | |
" }\n", | |
" var view = [0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.];\n", | |
" quat2mat(reboundView.view,view);\n", | |
" var mvp = [0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.];\n", | |
" matmult(projection,view,mvp);\n", | |
" gl.uniformMatrix4fv(reboundView.point_shader_mvp_location,false,mattransp(mvp));\n", | |
" gl.drawArrays(gl.POINTS,0,reboundView.N);\n", | |
" \n", | |
" if (reboundView.orbits){\n", | |
" gl.useProgram(reboundView.orbit_shader_program);\n", | |
" gl.bindBuffer(gl.ARRAY_BUFFER, reboundView.orbit_lintwopi_buffer);\n", | |
" var ltp = gl.getAttribLocation(reboundView.orbit_shader_program,\"lintwopi\");\n", | |
" gl.enableVertexAttribArray(ltp);\n", | |
" gl.vertexAttribPointer(ltp, 1, gl.FLOAT, 0, 0,0); // 4 = size of float\n", | |
" gl.uniformMatrix4fv(reboundView.orbit_shader_mvp_location,false,mattransp(mvp));\n", | |
"\n", | |
" // Need to do this one by one\n", | |
" // because WebGL is not supporting\n", | |
" // instancing:\n", | |
" for(i=0;i<reboundView.N-1;i++){\n", | |
" var focus = new Float32Array(reboundView.orbit_data.buffer,4*9*i,3);\n", | |
" gl.uniform3fv(reboundView.orbit_shader_focus_location,focus);\n", | |
" var aef = new Float32Array(reboundView.orbit_data.buffer,4*(9*i+3),3);\n", | |
" gl.uniform3fv(reboundView.orbit_shader_aef_location,aef);\n", | |
" var omegaOmegainc = new Float32Array(reboundView.orbit_data.buffer,4*(9*i+6),3);\n", | |
" gl.uniform3fv(reboundView.orbit_shader_omegaOmegainc_location,omegaOmegainc);\n", | |
"\n", | |
" gl.drawArrays(gl.LINE_STRIP,0,500);\n", | |
" }\n", | |
" }\n", | |
"}\n", | |
"require.undef('rebound');\n", | |
" define('rebound', [\"@jupyter-widgets/base\"], function(widgets) {\n", | |
" var ReboundView = widgets.DOMWidgetView.extend({\n", | |
" render: function() {\n", | |
" this.el.innerHTML = '<span style=\"display: inline-block; position: relative;\" width=\"'+this.model.get(\"width\")+'\" height=\"'+this.model.get(\"height\")+'\"><canvas style=\"border: none;\" id=\"reboundcanvas-'+this.cid+'\" width=\"'+this.model.get(\"width\")+'\" height=\"'+this.model.get(\"height\")+'\"></canvas><span style=\"position: absolute; color: #FFF; pointer-events:none; bottom:5px; right:0px; padding-right:5px; font-family: monospace;\" id=\"reboundoverlay-'+this.cid+'\">REBOUND</span></span>';\n", | |
" this.model.on('change:t', this.trigger_refresh, this);\n", | |
" this.model.on('change:count', this.trigger_refresh, this);\n", | |
" this.model.on('change:screenshotcount', this.take_screenshot, this);\n", | |
" this.startCount = 0;\n", | |
" this.gl = null;\n", | |
" // Only copy those once\n", | |
" this.scale = this.model.get(\"scale\");\n", | |
" this.width = this.model.get(\"width\");\n", | |
" this.height = this.model.get(\"height\");\n", | |
" this.orbits = this.model.get(\"orbits\");\n", | |
" this.orientation = this.model.get(\"orientation\");\n", | |
" startGL(this);\n", | |
" },\n", | |
" take_screenshot: function() {\n", | |
" drawGL(this);\n", | |
" var canvas = document.getElementById(\"reboundcanvas-\"+this.cid);\n", | |
" var img = canvas.toDataURL(\"image/png\");\n", | |
" this.model.set(\"screenshot\",img, {updated_view: this});\n", | |
" this.touch();\n", | |
" },\n", | |
" trigger_refresh: function() {\n", | |
" updateRenderData(this);\n", | |
" drawGL(this);\n", | |
" },\n", | |
" });\n", | |
" return {\n", | |
" ReboundView: ReboundView\n", | |
" };\n", | |
"});\n", | |
" \n", | |
"</script>\n" | |
], | |
"text/plain": [ | |
"<IPython.core.display.HTML object>" | |
] | |
}, | |
"metadata": {}, | |
"output_type": "display_data" | |
}, | |
{ | |
"data": { | |
"application/vnd.jupyter.widget-view+json": { | |
"model_id": "003b484463df41e9abe570791c5c7e7b", | |
"version_major": 2, | |
"version_minor": 0 | |
}, | |
"text/plain": [ | |
"Widget(N=11928, count=2, height=500.0, orientation=(0.0, 0.0, 0.0, 1.0), overlay='REBOUND (ias15), N=11928, t=…" | |
] | |
}, | |
"metadata": {}, | |
"output_type": "display_data" | |
} | |
], | |
"source": [ | |
"sim.getWidget(size=(500,500),orbits=False)" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 4, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"sim.integrator = \"leapfrog\"\n", | |
"sim.dt = 0.1\n", | |
"sim.integrate(sim.t+1000)" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"## Using the Moon the clear up the mess\n", | |
"Same as before, but not the simulation includes the Moon at a distance 50 times closer than in reality." | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 5, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"sim = rebound.Simulation()\n", | |
"sim.G = 6.67408e-20 # m^3 / kg s^2\n", | |
"sim.add(m=5.972e24) # earth mass in kg\n", | |
"sim.add(m=7.348e22, a=384400/50, inc=0.0898, e=0.0549) # moon in kg, km\n", | |
"sim.N_active = 2\n", | |
"with open(\"tles.txt\", \"r\") as fp:\n", | |
" lines = fp.readlines()\n", | |
" for i in range(len(lines)//3):\n", | |
" fields = lines[i*3+2].split()\n", | |
" n = float(fields[7])/24/60/60*np.pi*2.\n", | |
" a = np.power(sim.G*sim.particles[0].m/(n*n),1./3.)\n", | |
" sim.add(a=a,\n", | |
" inc=float(fields[2])/180.*np.pi,\n", | |
" Omega=float(fields[3])/180.*np.pi,\n", | |
" e=float(\"0.\"+fields[4]),\n", | |
" omega=float(fields[5])/180.*np.pi,\n", | |
" M=float(fields[6])/180.*np.pi)" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 6, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/html": [ | |
"\n", | |
"<script id=\"orbit_shader-vs\" type=\"x-shader/x-vertex\">\n", | |
" uniform vec3 focus;\n", | |
" uniform vec3 aef;\n", | |
" uniform vec3 omegaOmegainc;\n", | |
" attribute float lintwopi;\n", | |
" varying float lin;\n", | |
" uniform mat4 mvp;\n", | |
" const float M_PI = 3.14159265359;\n", | |
" void main() {\n", | |
" float a = aef.x;\n", | |
" float e = aef.y;\n", | |
" float f = aef.z+lintwopi;\n", | |
" lin = lintwopi/(M_PI*2.);\n", | |
" if (e>1.){\n", | |
" float theta_max = acos(-1./e);\n", | |
" f = 0.0001-theta_max+1.9998*lin*theta_max;\n", | |
" lin = sqrt(min(0.5,lin));\n", | |
" }\n", | |
" float omega = omegaOmegainc.x;\n", | |
" float Omega = omegaOmegainc.y;\n", | |
" float inc = omegaOmegainc.z;\n", | |
" float r = a*(1.-e*e)/(1. + e*cos(f));\n", | |
" float cO = cos(Omega);\n", | |
" float sO = sin(Omega);\n", | |
" float co = cos(omega);\n", | |
" float so = sin(omega);\n", | |
" float cf = cos(f);\n", | |
" float sf = sin(f);\n", | |
" float ci = cos(inc);\n", | |
" float si = sin(inc);\n", | |
" vec3 pos = vec3(r*(cO*(co*cf-so*sf) - sO*(so*cf+co*sf)*ci),r*(sO*(co*cf-so*sf) + cO*(so*cf+co*sf)*ci),+ r*(so*cf+co*sf)*si);\n", | |
" gl_Position = mvp*(vec4(focus+pos, 1.0));\n", | |
" }\n", | |
"</script>\n", | |
"<script id=\"orbit_shader-fs\" type=\"x-shader/x-fragment\">\n", | |
" precision mediump float;\n", | |
" varying float lin;\n", | |
" void main() {\n", | |
" float fog = max(max(0.,-1.+2.*gl_FragCoord.z),max(0.,1.-2.*gl_FragCoord.z));\n", | |
" gl_FragColor = vec4(1.,1.,1.,sqrt(lin)*(1.-fog));\n", | |
" }\n", | |
"</script>\n", | |
"<script id=\"point_shader-vs\" type=\"x-shader/x-vertex\">\n", | |
" attribute vec3 vp;\n", | |
" uniform mat4 mvp;\n", | |
" //uniform vec4 vc;\n", | |
" //varying vec4 color;\n", | |
" void main() {\n", | |
" gl_PointSize = 15.0;\n", | |
" gl_Position = mvp*vec4(vp, 1.0);\n", | |
" //color = vc;\n", | |
" }\n", | |
"</script>\n", | |
"<script id=\"point_shader-fs\" type=\"x-shader/x-fragment\">\n", | |
" precision mediump float;\n", | |
" //varying vec4 color;\n", | |
" void main() {\n", | |
" vec2 rel = gl_PointCoord.st;\n", | |
" rel.s -=0.5;\n", | |
" rel.t -=0.5;\n", | |
" if (length(rel)>0.25){\n", | |
" gl_FragColor = vec4(0.,0.,0.,0.); \n", | |
" }else{\n", | |
" vec4 cmod = vec4(1.,1.,1.,1.);\n", | |
" float fog = max(max(0.,-1.+2.*gl_FragCoord.z),max(0.,1.-2.*gl_FragCoord.z));\n", | |
" cmod.a*= (1.-fog)*min(1.,1.-4.*(length(rel)/0.25-0.75));\n", | |
" gl_FragColor = cmod;\n", | |
" }\n", | |
" }\n", | |
"</script>\n", | |
"\n", | |
"<script>\n", | |
"function compileShader(glr, shaderSource, shaderType) {\n", | |
" // Create the shader object\n", | |
" var shader = glr.createShader(shaderType);\n", | |
" \n", | |
" // Set the shader source code.\n", | |
" glr.shaderSource(shader, shaderSource);\n", | |
" \n", | |
" // Compile the shader\n", | |
" glr.compileShader(shader);\n", | |
" \n", | |
" // Check if it compiled\n", | |
" var success = glr.getShaderParameter(shader, glr.COMPILE_STATUS);\n", | |
" if (!success) {\n", | |
" // Something went wrong during compilation; get the error\n", | |
" throw \"could not compile shader:\" + glr.getShaderInfoLog(shader);\n", | |
" }\n", | |
" \n", | |
" return shader;\n", | |
"}\n", | |
"function createShaderFromScript(glr, scriptId, opt_shaderType) {\n", | |
" // look up the script tag by id.\n", | |
" var shaderScript = document.getElementById(scriptId);\n", | |
" if (!shaderScript) {\n", | |
" throw(\"*** Error: unknown script element\" + scriptId);\n", | |
" }\n", | |
" \n", | |
" // extract the contents of the script tag.\n", | |
" var shaderSource = shaderScript.text;\n", | |
" \n", | |
" // If we didn't pass in a type, use the 'type' from\n", | |
" // the script tag.\n", | |
" if (!opt_shaderType) {\n", | |
" if (shaderScript.type == \"x-shader/x-vertex\") {\n", | |
" opt_shaderType = glr.VERTEX_SHADER;\n", | |
" } else if (shaderScript.type == \"x-shader/x-fragment\") {\n", | |
" opt_shaderType = glr.FRAGMENT_SHADER;\n", | |
" } else if (!opt_shaderType) {\n", | |
" throw(\"*** Error: shader type not set\");\n", | |
" }\n", | |
" }\n", | |
" \n", | |
" return compileShader(glr, shaderSource, opt_shaderType);\n", | |
"};\n", | |
"function createProgramFromScripts( glr, vertexShaderId, fragmentShaderId) {\n", | |
" var vertexShader = createShaderFromScript(glr, vertexShaderId, glr.VERTEX_SHADER);\n", | |
" var fragmentShader = createShaderFromScript(glr, fragmentShaderId, glr.FRAGMENT_SHADER);\n", | |
" var program = glr.createProgram();\n", | |
" \n", | |
" // attach the shaders.\n", | |
" glr.attachShader(program, vertexShader);\n", | |
" glr.attachShader(program, fragmentShader);\n", | |
" \n", | |
" // link the program.\n", | |
" glr.linkProgram(program);\n", | |
" \n", | |
" // Check if it linked.\n", | |
" var success = glr.getProgramParameter(program, glr.LINK_STATUS);\n", | |
" if (!success) {\n", | |
" // something went wrong with the link\n", | |
" throw (\"program filed to link:\" + glr.getProgramInfoLog (program));\n", | |
" }\n", | |
" \n", | |
" return program;\n", | |
"}\n", | |
"function quat2mat(A,mat){\n", | |
" var xx = A.x*A.x; var xy = A.x*A.y; var xz = A.x*A.z;\n", | |
" var xw = A.x*A.w; var yy = A.y*A.y; var yz = A.y*A.z;\n", | |
" var yw = A.y*A.w; var zz = A.z*A.z; var zw = A.z*A.w;\n", | |
" mat[0] = 1.-2.*(yy+zz);\n", | |
" mat[1] = 2.*(xy-zw);\n", | |
" mat[2] = 2.*(xz+yw);\n", | |
" mat[4] = 2.*(xy+zw);\n", | |
" mat[5] = 1.-2.*(xx+zz);\n", | |
" mat[6] = 2.*(yz-xw);\n", | |
" mat[8] = 2.*(xz-yw);\n", | |
" mat[9] = 2.*(yz+xw);\n", | |
" mat[10]= 1.-2.*(xx+yy);\n", | |
" mat[3] = mat[7] = mat[11] = mat[12] = mat[13] = mat[14] = 0.; mat[15]= 1.;\n", | |
"}\n", | |
"function multvec(A, B, vecr){\n", | |
" var mat = [0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.];\n", | |
" quat2mat(A,mat);\n", | |
" vecr[0] = mat[0]*B[0] + mat[1]*B[1] + mat[2]*B[2];\n", | |
" vecr[1] = mat[4]*B[0] + mat[5]*B[1] + mat[6]*B[2];\n", | |
" vecr[2] = mat[8]*B[0] + mat[9]*B[1] + mat[10]*B[2];\n", | |
"}\n", | |
"function mattransp(mat){\n", | |
" var matt = [\n", | |
" mat[0], mat[4], mat[8], mat[12],\n", | |
" mat[1], mat[5], mat[9], mat[13],\n", | |
" mat[2], mat[6], mat[10], mat[14],\n", | |
" mat[3], mat[7], mat[11], mat[15]];\n", | |
" return matt;\n", | |
"}\n", | |
"function conjugate(quat){\n", | |
" var cquat = {x:-quat.x, y:-quat.y, z:-quat.z, w:quat.w};\n", | |
" return cquat;\n", | |
"}\n", | |
"function mult(A, B){\n", | |
" var mquat = { x: A.w*B.x + A.x*B.w + A.y*B.z - A.z*B.y,\n", | |
" y: A.w*B.y - A.x*B.z + A.y*B.w + A.z*B.x,\n", | |
" z: A.w*B.z + A.x*B.y - A.y*B.x + A.z*B.w,\n", | |
" w: A.w*B.w - A.x*B.x - A.y*B.y - A.z*B.z};\n", | |
" return mquat;\n", | |
"}\n", | |
"\n", | |
"function normalize(quat){\n", | |
" var L = Math.sqrt(quat.x*quat.x + quat.y*quat.y + quat.z*quat.z + quat.w*quat.w);\n", | |
" var nquat = {x:quat.x/L, y:quat.y/L, z:quat.z/L, w:quat.w/L};\n", | |
" return nquat;\n", | |
"}\n", | |
"function matortho(mat, l, r, b, t, n, f){\n", | |
" mat[0] = 2./(r-l); mat[1] = 0.; mat[2] = 0.; mat[3] = -(r+l)/(r-l);\n", | |
" mat[4] = 0.; mat[5] = 2./(t-b); mat[6] = 0.; mat[7] = -(t+b)/(t-b);\n", | |
" mat[8] = 0.; mat[9] = 0.; mat[10] = -2./(f-n); mat[11] = -(f+n)/(f-n);\n", | |
" mat[12] = 0.; mat[13] = 0.; mat[14] = 0.; mat[15] = 1.;\n", | |
"}\n", | |
"function matmult(A,B,C){\n", | |
" for(i=0;i<4;i++){\n", | |
" for(j=0;j<4;j++){\n", | |
" C[i+4*j] = 0.;\n", | |
" for(k=0;k<4;k++){\n", | |
" C[i+4*j] += A[k+4*j]*B[i+4*k];\n", | |
" }}}\n", | |
"}\n", | |
"function startGL(reboundView) {\n", | |
" var canvas = document.getElementById(\"reboundcanvas-\"+reboundView.cid);\n", | |
" if (!canvas){\n", | |
" reboundView.startCount = reboundView.startCount+1;\n", | |
" if (reboundView.startCount>1000){\n", | |
" console.log(\"Cannot find element.\");\n", | |
" }else{\n", | |
" setTimeout(function(){ startGL(reboundView); }, 10);\n", | |
" }\n", | |
" return;\n", | |
" }\n", | |
" var rect = canvas.getBoundingClientRect()\n", | |
" reboundView.ratio = rect.width/rect.height;\n", | |
" reboundView.view = normalize({x:reboundView.orientation[0], y:reboundView.orientation[1], z:reboundView.orientation[2], w:reboundView.orientation[3]});\n", | |
"\n", | |
" canvas.addEventListener('mousedown', function() {\n", | |
" reboundView.mouseDown=1;\n", | |
" }, false);\n", | |
" canvas.addEventListener('mouseup', function() {\n", | |
" reboundView.mouseDown=0;\n", | |
" }, false);\n", | |
" canvas.addEventListener('mouseleave', function() {\n", | |
" reboundView.mouseDown=0;\n", | |
" }, false);\n", | |
"\n", | |
" canvas.addEventListener('mousemove', function(evt) {\n", | |
" var rect = canvas.getBoundingClientRect()\n", | |
" if (reboundView.mouseDown==1){\n", | |
" reboundView.mouseDown = 2;\n", | |
" reboundView.mouse_x = evt.clientX-rect.left;\n", | |
" reboundView.mouse_y = evt.clientY-rect.top;\n", | |
" return;\n", | |
" }else if (reboundView.mouseDown==2){\n", | |
" var width = rect.width;\n", | |
" var height = rect.height;\n", | |
" var dx = 3.*(evt.clientX-rect.left-reboundView.mouse_x)/width;\n", | |
" var dy = 3.*(evt.clientY-rect.top-reboundView.mouse_y)/height;\n", | |
" reboundView.mouse_x = evt.clientX-rect.left;\n", | |
" reboundView.mouse_y = evt.clientY-rect.top;\n", | |
" if (evt.shiftKey){\n", | |
" reboundView.scale *= (1.+dx+dy);\n", | |
" }else{\n", | |
" var inv = conjugate(reboundView.view);\n", | |
" var up = [0.,1.,0.];\n", | |
" var right = [1.,0.,0.];\n", | |
" var inv_up = [0.,0.,0.];\n", | |
" var inv_right = [0.,0.,0.];\n", | |
" multvec(inv, right, inv_right);\n", | |
" multvec(inv, up, inv_up);\n", | |
" \n", | |
" var sin_dy = Math.sin(dy);\n", | |
" var rot_dy = {x:inv_right[0]*sin_dy, y:inv_right[1]*sin_dy, z:inv_right[2]*sin_dy, w:Math.cos(dy)};\n", | |
" reboundView.view = mult(reboundView.view, normalize(rot_dy));\n", | |
" \n", | |
" var sin_dx = Math.sin(dx);\n", | |
" var rot_dx = {x:inv_up[0]*sin_dx, y:inv_up[1]*sin_dx, z:inv_up[2]*sin_dx, w:Math.cos(dx)};\n", | |
" reboundView.view = normalize(mult(reboundView.view, normalize(rot_dx)));\n", | |
" }\n", | |
"\n", | |
" drawGL(reboundView);\n", | |
" }\n", | |
"\n", | |
"\n", | |
" }, false);\n", | |
"\n", | |
" reboundView.gl = canvas.getContext(\"webgl\")||canvas.getContext(\"experimental-webgl\");\n", | |
" if (!reboundView.gl) {\n", | |
" alert(\"Unable to initialize WebGL. Your browser may not support it.\");\n", | |
" return;\n", | |
" }\n", | |
" var gl = reboundView.gl\n", | |
" gl.enable(gl.BLEND);\n", | |
" gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);\n", | |
" \n", | |
" reboundView.orbit_shader_program = createProgramFromScripts(gl,\"orbit_shader-vs\",\"orbit_shader-fs\");\n", | |
" reboundView.point_shader_program = createProgramFromScripts(gl,\"point_shader-vs\",\"point_shader-fs\");\n", | |
" \n", | |
" var lintwopi = new Float32Array(500);\n", | |
" for(i=0;i<500;i++){\n", | |
" lintwopi[i] = 2.*Math.PI/500.*i;\n", | |
" }\n", | |
" reboundView.orbit_lintwopi_buffer = gl.createBuffer();\n", | |
" gl.bindBuffer(gl.ARRAY_BUFFER, reboundView.orbit_lintwopi_buffer);\n", | |
" gl.bufferData(gl.ARRAY_BUFFER, 4*500, gl.STATIC_DRAW);\n", | |
" gl.bufferSubData(gl.ARRAY_BUFFER, 0, lintwopi)\n", | |
" reboundView.orbit_shader_mvp_location = gl.getUniformLocation(reboundView.orbit_shader_program,\"mvp\");\n", | |
" reboundView.orbit_shader_focus_location = gl.getUniformLocation(reboundView.orbit_shader_program,\"focus\");\n", | |
" reboundView.orbit_shader_aef_location = gl.getUniformLocation(reboundView.orbit_shader_program,\"aef\");\n", | |
" reboundView.orbit_shader_omegaOmegainc_location = gl.getUniformLocation(reboundView.orbit_shader_program,\"omegaOmegainc\");\n", | |
" \n", | |
" reboundView.particle_data_buffer = gl.createBuffer();\n", | |
" gl.useProgram(reboundView.point_shader_program);\n", | |
" reboundView.point_shader_mvp_location = gl.getUniformLocation(reboundView.point_shader_program,\"mvp\");\n", | |
" \n", | |
" updateRenderData(reboundView);\n", | |
" gl.clearColor(0.0, 0.0, 0.0, 1.0);\n", | |
" gl.clear(gl.COLOR_BUFFER_BIT);\n", | |
" drawGL(reboundView);\n", | |
"}\n", | |
"function updateRenderData(reboundView){\n", | |
" var overlay = document.getElementById(\"reboundoverlay-\"+reboundView.cid);\n", | |
" overlay.innerHTML = reboundView.model.get(\"overlay\");\n", | |
" var previousN = reboundView.N;\n", | |
" reboundView.N = reboundView.model.get(\"N\");\n", | |
" reboundView.t = reboundView.model.get(\"t\");\n", | |
" reboundView.particle_data = reboundView.model.get('particle_data');\n", | |
" if (reboundView.orbits){\n", | |
" reboundView.orbit_data = reboundView.model.get('orbit_data');\n", | |
" }\n", | |
" var gl = reboundView.gl\n", | |
" if (reboundView.N>0){\n", | |
" gl.bindBuffer(gl.ARRAY_BUFFER, reboundView.particle_data_buffer);\n", | |
" gl.bufferData(gl.ARRAY_BUFFER, reboundView.N*7*4, gl.DYNAMIC_DRAW);\n", | |
" gl.bufferSubData(gl.ARRAY_BUFFER, 0, reboundView.particle_data)\n", | |
" }\n", | |
"}\n", | |
"function drawGL(reboundView) {\n", | |
" if (!reboundView.gl){\n", | |
" return;\n", | |
" }\n", | |
" // Cleanup\n", | |
" var gl = reboundView.gl\n", | |
" gl.clearColor(0.0, 0.0, 0.0, 1.0);\n", | |
" gl.clear(gl.COLOR_BUFFER_BIT);\n", | |
" \n", | |
" // Draw\n", | |
" gl.useProgram(reboundView.point_shader_program);\n", | |
" gl.bindBuffer(gl.ARRAY_BUFFER, reboundView.particle_data_buffer);\n", | |
" var pvp = gl.getAttribLocation(reboundView.point_shader_program,\"vp\");\n", | |
" gl.enableVertexAttribArray(pvp);\n", | |
" gl.vertexAttribPointer(pvp, 3, gl.FLOAT, 0, 4*7,0); // 4 = size of float\n", | |
" var projection = [0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.];\n", | |
" if (reboundView.ratio>=1.){\n", | |
" matortho(projection, \n", | |
" -1.6*reboundView.scale, 1.6*reboundView.scale,\n", | |
" -1.6/reboundView.ratio*reboundView.scale, 1.6/reboundView.ratio*reboundView.scale,\n", | |
" -2.5*reboundView.scale, 2.5*reboundView.scale);\n", | |
" }else{\n", | |
" matortho(projection, \n", | |
" -1.6*reboundView.ratio*reboundView.scale, 1.6*reboundView.ratio*reboundView.scale,\n", | |
" -1.6*reboundView.scale, 1.6*reboundView.scale,\n", | |
" -2.5*reboundView.scale, 2.5*reboundView.scale);\n", | |
" }\n", | |
" var view = [0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.];\n", | |
" quat2mat(reboundView.view,view);\n", | |
" var mvp = [0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.];\n", | |
" matmult(projection,view,mvp);\n", | |
" gl.uniformMatrix4fv(reboundView.point_shader_mvp_location,false,mattransp(mvp));\n", | |
" gl.drawArrays(gl.POINTS,0,reboundView.N);\n", | |
" \n", | |
" if (reboundView.orbits){\n", | |
" gl.useProgram(reboundView.orbit_shader_program);\n", | |
" gl.bindBuffer(gl.ARRAY_BUFFER, reboundView.orbit_lintwopi_buffer);\n", | |
" var ltp = gl.getAttribLocation(reboundView.orbit_shader_program,\"lintwopi\");\n", | |
" gl.enableVertexAttribArray(ltp);\n", | |
" gl.vertexAttribPointer(ltp, 1, gl.FLOAT, 0, 0,0); // 4 = size of float\n", | |
" gl.uniformMatrix4fv(reboundView.orbit_shader_mvp_location,false,mattransp(mvp));\n", | |
"\n", | |
" // Need to do this one by one\n", | |
" // because WebGL is not supporting\n", | |
" // instancing:\n", | |
" for(i=0;i<reboundView.N-1;i++){\n", | |
" var focus = new Float32Array(reboundView.orbit_data.buffer,4*9*i,3);\n", | |
" gl.uniform3fv(reboundView.orbit_shader_focus_location,focus);\n", | |
" var aef = new Float32Array(reboundView.orbit_data.buffer,4*(9*i+3),3);\n", | |
" gl.uniform3fv(reboundView.orbit_shader_aef_location,aef);\n", | |
" var omegaOmegainc = new Float32Array(reboundView.orbit_data.buffer,4*(9*i+6),3);\n", | |
" gl.uniform3fv(reboundView.orbit_shader_omegaOmegainc_location,omegaOmegainc);\n", | |
"\n", | |
" gl.drawArrays(gl.LINE_STRIP,0,500);\n", | |
" }\n", | |
" }\n", | |
"}\n", | |
"require.undef('rebound');\n", | |
" define('rebound', [\"@jupyter-widgets/base\"], function(widgets) {\n", | |
" var ReboundView = widgets.DOMWidgetView.extend({\n", | |
" render: function() {\n", | |
" this.el.innerHTML = '<span style=\"display: inline-block; position: relative;\" width=\"'+this.model.get(\"width\")+'\" height=\"'+this.model.get(\"height\")+'\"><canvas style=\"border: none;\" id=\"reboundcanvas-'+this.cid+'\" width=\"'+this.model.get(\"width\")+'\" height=\"'+this.model.get(\"height\")+'\"></canvas><span style=\"position: absolute; color: #FFF; pointer-events:none; bottom:5px; right:0px; padding-right:5px; font-family: monospace;\" id=\"reboundoverlay-'+this.cid+'\">REBOUND</span></span>';\n", | |
" this.model.on('change:t', this.trigger_refresh, this);\n", | |
" this.model.on('change:count', this.trigger_refresh, this);\n", | |
" this.model.on('change:screenshotcount', this.take_screenshot, this);\n", | |
" this.startCount = 0;\n", | |
" this.gl = null;\n", | |
" // Only copy those once\n", | |
" this.scale = this.model.get(\"scale\");\n", | |
" this.width = this.model.get(\"width\");\n", | |
" this.height = this.model.get(\"height\");\n", | |
" this.orbits = this.model.get(\"orbits\");\n", | |
" this.orientation = this.model.get(\"orientation\");\n", | |
" startGL(this);\n", | |
" },\n", | |
" take_screenshot: function() {\n", | |
" drawGL(this);\n", | |
" var canvas = document.getElementById(\"reboundcanvas-\"+this.cid);\n", | |
" var img = canvas.toDataURL(\"image/png\");\n", | |
" this.model.set(\"screenshot\",img, {updated_view: this});\n", | |
" this.touch();\n", | |
" },\n", | |
" trigger_refresh: function() {\n", | |
" updateRenderData(this);\n", | |
" drawGL(this);\n", | |
" },\n", | |
" });\n", | |
" return {\n", | |
" ReboundView: ReboundView\n", | |
" };\n", | |
"});\n", | |
" \n", | |
"</script>\n" | |
], | |
"text/plain": [ | |
"<IPython.core.display.HTML object>" | |
] | |
}, | |
"metadata": {}, | |
"output_type": "display_data" | |
}, | |
{ | |
"data": { | |
"application/vnd.jupyter.widget-view+json": { | |
"model_id": "593a859f949347dea1e208652dbb534a", | |
"version_major": 2, | |
"version_minor": 0 | |
}, | |
"text/plain": [ | |
"Widget(N=11929, count=2, height=500.0, orientation=(0.0, 0.0, 0.0, 1.0), overlay='REBOUND (ias15), N=11929, t=…" | |
] | |
}, | |
"metadata": {}, | |
"output_type": "display_data" | |
} | |
], | |
"source": [ | |
"sim.getWidget(size=(500,500),orbits=False)" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 7, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"sim.integrator = \"leapfrog\"\n", | |
"sim.dt = 0.5\n", | |
"sim.integrate(sim.t+10000)" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"metadata": {}, | |
"outputs": [], | |
"source": [] | |
} | |
], | |
"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.6.5" | |
} | |
}, | |
"nbformat": 4, | |
"nbformat_minor": 2 | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment