Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
M
mooc-rr
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
70246f4c8f01100bd046595e4e75f4bf
mooc-rr
Commits
b4674e6d
Commit
b4674e6d
authored
Oct 27, 2023
by
70246f4c8f01100bd046595e4e75f4bf
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
bonsouer
parent
7b9b3022
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
1009 additions
and
0 deletions
+1009
-0
Techniques numériques pour l'optique.ipynb
Techniques numériques pour l'optique.ipynb
+1009
-0
No files found.
Techniques numériques pour l'optique.ipynb
0 → 100644
View file @
b4674e6d
{
"cells": [
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [],
"source": [
"import numpy as np\n",
"import matplotlib.pyplot as plt\n",
"%matplotlib inline"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Fonctions"
]
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {},
"outputs": [],
"source": [
"def translation(coordEntree,n,dist):\n",
" matTranslation=np.array([[1.0, dist/n],[0.0,1.0]])\n",
" coordSortie=np.dot(matTranslation,coordEntree)\n",
" return coordSortie\n",
"\n",
"def ajoutTraj(traj,nouvCoord):\n",
" traj=np.concatenate((traj,nouvCoord),axis=1)\n",
" return traj\n",
"\n",
"\n",
"def dioptre_spherique(coordEntree,n,AS,n_p,SAp,SC):\n",
" matTranslationSAp=np.array([[1.0, SAp/n_p],[0.0,1.0]])\n",
" matTranslationAS=np.array([[1.0, AS/n],[0.0,1.0]])\n",
" coordDioptre=translation(coordEntree,n,AS)\n",
" phi=(n_p-n)/SC\n",
" matDioptreSpherique=np.array([[1.0,0],[-phi,1.0]])\n",
" matTransfer1=np.dot(matTranslationSAp,matDioptreSpherique)\n",
" matTransfer=np.dot(matTransfer1,matTranslationAS)\n",
" coordSortie=np.dot(matTransfer,coordEntree)\n",
" return coordSortie,coordDioptre\n",
"\n",
"def lentille_spherique(coordEntree,n,ASg,n_p,e,SAd,SCg,SCd):\n",
" CoordMilieuLentille,coordDioptreG=dioptre_spherique(coordEntree,n,ASg,n_p,e/2,SCg)\n",
" CoordSortie,coordDioptreD=dioptre_spherique(CoordMilieuLentille,n_p,e/2,n,SAd,SCd)\n",
" return CoordSortie,coordDioptreD,coordDioptreG\n",
"\n",
"def afficher_traj(z,traj):\n",
" plt.plot(z,traj[0,:],color='blue')\n",
" plt.ylim(-2, 2)\n",
" plt.xlim(z[0],z[-1]+10)\n",
" plt.xlabel('z (m)')\n",
" plt.ylabel('x (m)')\n",
" plt.grid(1)\n",
" \n",
"def desssinerAxeOptique(z):\n",
" plt.plot([z[0],z[-1]],[0,0],color='black')\n",
" #plt.axvline(z[0],color='gray')\n",
" #plt.axvline(z[-1],color='gray')\n",
"\n",
"def dessiner_dioptrePlan(position):\n",
" plt.axvline(x=position,color='green')\n",
"\n",
"\n",
"def dessiner_dioptreSpherique(position,SC):\n",
" if SC>0:\n",
" theta = np.linspace(np.pi/2,3/2*np.pi, 100)\n",
" else:\n",
" theta = np.linspace(-np.pi/2,np.pi/2, 100)\n",
" r=np.abs(SC)\n",
" x1 = (position+r)+r*np.cos(theta)\n",
" x2 = r*np.sin(theta)\n",
" plt.plot(x1,x2,color='green')\n",
"\n",
"def dessiner_lentille(positionCentre,SCg,SCd,e):\n",
" if SCg>0:\n",
" thetag = np.linspace(np.pi/2,3/2*np.pi, 100)\n",
" else:\n",
" thetag = np.linspace(-np.pi/2,np.pi/2, 100)\n",
" r=np.abs(SCg)\n",
" x1 = (positionCentre-e/2+SCg)+r*np.cos(thetag)\n",
" x2 = r*np.sin(thetag)\n",
" plt.plot(x1,x2,color='green')\n",
" if SCd>0:\n",
" thetad = np.linspace(np.pi/2,3/2*np.pi, 100)\n",
" else:\n",
" thetad = np.linspace(-np.pi/2,np.pi/2, 100)\n",
" r=np.abs(SCd)\n",
" x1 = (positionCentre+e/2+SCd)+r*np.cos(thetad)\n",
" x2 = r*np.sin(thetag)\n",
" plt.plot(x1,x2,color='green')\n",
" plt.axvline(x=positionCentre,color='green',linestyle='--')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Paramètres"
]
},
{
"cell_type": "code",
"execution_count": 12,
"metadata": {},
"outputs": [],
"source": [
"nMilieu=1.0\n",
"nVerre=1.5\n",
"ABEntree=1\n",
"phiEntree=-0.05\n",
"dist=20.0\n",
"z=[0,dist/2,dist]\n",
"coordEntree=np.array([[ABEntree],[nMilieu*phiEntree]])\n",
"repartitionABPlan =[1 ,0.75, 0.5, 0.25,0 ,-0.25, -0.5 ,-0.75 ,-1]"
]
},
{
"cell_type": "code",
"execution_count": 21,
"metadata": {},
"outputs": [
{
"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 = $('<div/>');\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",
" '<div class=\"ui-dialog-titlebar ui-widget-header ui-corner-all ' +\n",
" 'ui-helper-clearfix\"/>');\n",
" var titletext = $(\n",
" '<div class=\"ui-dialog-title\" style=\"width: 100%; ' +\n",
" 'text-align: center; padding: 3px;\"/>');\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 = $('<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 = $('<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 = $('<canvas/>');\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 = $('<div/>')\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 = $('<button/>');\n",
" button.addClass('ui-button ui-widget ui-state-default ui-corner-all ' +\n",
" 'ui-button-icon-only');\n",
" button.attr('role', 'button');\n",
" button.attr('aria-disabled', 'false');\n",
" button.click(method_name, toolbar_event);\n",
" button.mouseover(tooltip, toolbar_mouse_event);\n",
"\n",
" var icon_img = $('<span/>');\n",
" icon_img.addClass('ui-button-icon-primary ui-icon');\n",
" icon_img.addClass(image);\n",
" icon_img.addClass('ui-corner-all');\n",
"\n",
" var tooltip_span = $('<span/>');\n",
" tooltip_span.addClass('ui-button-text');\n",
" tooltip_span.html(tooltip);\n",
"\n",
" button.append(icon_img);\n",
" button.append(tooltip_span);\n",
"\n",
" nav_element.append(button);\n",
" }\n",
"\n",
" var fmt_picker_span = $('<span/>');\n",
"\n",
" var fmt_picker = $('<select/>');\n",
" fmt_picker.addClass('mpl-toolbar-option ui-widget ui-widget-content');\n",
" fmt_picker_span.append(fmt_picker);\n",
" nav_element.append(fmt_picker_span);\n",
" this.format_dropdown = fmt_picker[0];\n",
"\n",
" for (var ind in mpl.extensions) {\n",
" var fmt = mpl.extensions[ind];\n",
" var option = $(\n",
" '<option/>', {selected: fmt === mpl.default_extension}).html(fmt);\n",
" fmt_picker.append(option)\n",
" }\n",
"\n",
" // Add hover states to the ui-buttons\n",
" $( \".ui-button\" ).hover(\n",
" function() { $(this).addClass(\"ui-state-hover\");},\n",
" function() { $(this).removeClass(\"ui-state-hover\");}\n",
" );\n",
"\n",
" var status_bar = $('<span class=\"mpl-message\"/>');\n",
" nav_element.append(status_bar);\n",
" this.message = status_bar[0];\n",
"}\n",
"\n",
"mpl.figure.prototype.request_resize = function(x_pixels, y_pixels) {\n",
" // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
" // which will in turn request a refresh of the image.\n",
" this.send_message('resize', {'width': x_pixels, 'height': y_pixels});\n",
"}\n",
"\n",
"mpl.figure.prototype.send_message = function(type, properties) {\n",
" properties['type'] = type;\n",
" properties['figure_id'] = this.id;\n",
" this.ws.send(JSON.stringify(properties));\n",
"}\n",
"\n",
"mpl.figure.prototype.send_draw_message = function() {\n",
" if (!this.waiting) {\n",
" this.waiting = true;\n",
" this.ws.send(JSON.stringify({type: \"draw\", figure_id: this.id}));\n",
" }\n",
"}\n",
"\n",
"\n",
"mpl.figure.prototype.handle_save = function(fig, msg) {\n",
" var format_dropdown = fig.format_dropdown;\n",
" var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
" fig.ondownload(fig, format);\n",
"}\n",
"\n",
"\n",
"mpl.figure.prototype.handle_resize = function(fig, msg) {\n",
" var size = msg['size'];\n",
" if (size[0] != fig.canvas.width || size[1] != fig.canvas.height) {\n",
" fig._resize_canvas(size[0], size[1]);\n",
" fig.send_message(\"refresh\", {});\n",
" };\n",
"}\n",
"\n",
"mpl.figure.prototype.handle_rubberband = function(fig, msg) {\n",
" var x0 = msg['x0'] / mpl.ratio;\n",
" var y0 = (fig.canvas.height - msg['y0']) / mpl.ratio;\n",
" var x1 = msg['x1'] / mpl.ratio;\n",
" var y1 = (fig.canvas.height - msg['y1']) / mpl.ratio;\n",
" x0 = Math.floor(x0) + 0.5;\n",
" y0 = Math.floor(y0) + 0.5;\n",
" x1 = Math.floor(x1) + 0.5;\n",
" y1 = Math.floor(y1) + 0.5;\n",
" var min_x = Math.min(x0, x1);\n",
" var min_y = Math.min(y0, y1);\n",
" var width = Math.abs(x1 - x0);\n",
" var height = Math.abs(y1 - y0);\n",
"\n",
" fig.rubberband_context.clearRect(\n",
" 0, 0, fig.canvas.width, fig.canvas.height);\n",
"\n",
" fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
"}\n",
"\n",
"mpl.figure.prototype.handle_figure_label = function(fig, msg) {\n",
" // Updates the figure title.\n",
" fig.header.textContent = msg['label'];\n",
"}\n",
"\n",
"mpl.figure.prototype.handle_cursor = function(fig, msg) {\n",
" var cursor = msg['cursor'];\n",
" switch(cursor)\n",
" {\n",
" case 0:\n",
" cursor = 'pointer';\n",
" break;\n",
" case 1:\n",
" cursor = 'default';\n",
" break;\n",
" case 2:\n",
" cursor = 'crosshair';\n",
" break;\n",
" case 3:\n",
" cursor = 'move';\n",
" break;\n",
" }\n",
" fig.rubberband_canvas.style.cursor = cursor;\n",
"}\n",
"\n",
"mpl.figure.prototype.handle_message = function(fig, msg) {\n",
" fig.message.textContent = msg['message'];\n",
"}\n",
"\n",
"mpl.figure.prototype.handle_draw = function(fig, msg) {\n",
" // Request the server to send over a new figure.\n",
" fig.send_draw_message();\n",
"}\n",
"\n",
"mpl.figure.prototype.handle_image_mode = function(fig, msg) {\n",
" fig.image_mode = msg['mode'];\n",
"}\n",
"\n",
"mpl.figure.prototype.updated_canvas_event = function() {\n",
" // Called whenever the canvas gets updated.\n",
" this.send_message(\"ack\", {});\n",
"}\n",
"\n",
"// A function to construct a web socket function for onmessage handling.\n",
"// Called in the figure constructor.\n",
"mpl.figure.prototype._make_on_message_function = function(fig) {\n",
" return function socket_on_message(evt) {\n",
" if (evt.data instanceof Blob) {\n",
" /* FIXME: We get \"Resource interpreted as Image but\n",
" * transferred with MIME type text/plain:\" errors on\n",
" * Chrome. But how to set the MIME type? It doesn't seem\n",
" * to be part of the websocket stream */\n",
" evt.data.type = \"image/png\";\n",
"\n",
" /* Free the memory for the previous frames */\n",
" if (fig.imageObj.src) {\n",
" (window.URL || window.webkitURL).revokeObjectURL(\n",
" fig.imageObj.src);\n",
" }\n",
"\n",
" fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
" evt.data);\n",
" fig.updated_canvas_event();\n",
" fig.waiting = false;\n",
" return;\n",
" }\n",
" else if (typeof evt.data === 'string' && evt.data.slice(0, 21) == \"data:image/png;base64\") {\n",
" fig.imageObj.src = evt.data;\n",
" fig.updated_canvas_event();\n",
" fig.waiting = false;\n",
" return;\n",
" }\n",
"\n",
" var msg = JSON.parse(evt.data);\n",
" var msg_type = msg['type'];\n",
"\n",
" // Call the \"handle_{type}\" callback, which takes\n",
" // the figure and JSON message as its only arguments.\n",
" try {\n",
" var callback = fig[\"handle_\" + msg_type];\n",
" } catch (e) {\n",
" console.log(\"No handler for the '\" + msg_type + \"' message type: \", msg);\n",
" return;\n",
" }\n",
"\n",
" if (callback) {\n",
" try {\n",
" // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
" callback(fig, msg);\n",
" } catch (e) {\n",
" console.log(\"Exception inside the 'handler_\" + msg_type + \"' callback:\", e, e.stack, msg);\n",
" }\n",
" }\n",
" };\n",
"}\n",
"\n",
"// from http://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
"mpl.findpos = function(e) {\n",
" //this section is from http://www.quirksmode.org/js/events_properties.html\n",
" var targ;\n",
" if (!e)\n",
" e = window.event;\n",
" if (e.target)\n",
" targ = e.target;\n",
" else if (e.srcElement)\n",
" targ = e.srcElement;\n",
" if (targ.nodeType == 3) // defeat Safari bug\n",
" targ = targ.parentNode;\n",
"\n",
" // jQuery normalizes the pageX and pageY\n",
" // pageX,Y are the mouse positions relative to the document\n",
" // offset() returns the position of the element relative to the document\n",
" var x = e.pageX - $(targ).offset().left;\n",
" var y = e.pageY - $(targ).offset().top;\n",
"\n",
" return {\"x\": x, \"y\": y};\n",
"};\n",
"\n",
"/*\n",
" * return a copy of an object with only non-object keys\n",
" * we need this to avoid circular references\n",
" * http://stackoverflow.com/a/24161582/3208463\n",
" */\n",
"function simpleKeys (original) {\n",
" return Object.keys(original).reduce(function (obj, key) {\n",
" if (typeof original[key] !== 'object')\n",
" obj[key] = original[key]\n",
" return obj;\n",
" }, {});\n",
"}\n",
"\n",
"mpl.figure.prototype.mouse_event = function(event, name) {\n",
" var canvas_pos = mpl.findpos(event)\n",
"\n",
" if (name === 'button_press')\n",
" {\n",
" this.canvas.focus();\n",
" this.canvas_div.focus();\n",
" }\n",
"\n",
" var x = canvas_pos.x * mpl.ratio;\n",
" var y = canvas_pos.y * mpl.ratio;\n",
"\n",
" this.send_message(name, {x: x, y: y, button: event.button,\n",
" step: event.step,\n",
" guiEvent: simpleKeys(event)});\n",
"\n",
" /* This prevents the web browser from automatically changing to\n",
" * the text insertion cursor when the button is pressed. We want\n",
" * to control all of the cursor setting manually through the\n",
" * 'cursor' event from matplotlib */\n",
" event.preventDefault();\n",
" return false;\n",
"}\n",
"\n",
"mpl.figure.prototype._key_event_extra = function(event, name) {\n",
" // Handle any extra behaviour associated with a key event\n",
"}\n",
"\n",
"mpl.figure.prototype.key_event = function(event, name) {\n",
"\n",
" // Prevent repeat events\n",
" if (name == 'key_press')\n",
" {\n",
" if (event.which === this._key)\n",
" return;\n",
" else\n",
" this._key = event.which;\n",
" }\n",
" if (name == 'key_release')\n",
" this._key = null;\n",
"\n",
" var value = '';\n",
" if (event.ctrlKey && event.which != 17)\n",
" value += \"ctrl+\";\n",
" if (event.altKey && event.which != 18)\n",
" value += \"alt+\";\n",
" if (event.shiftKey && event.which != 16)\n",
" value += \"shift+\";\n",
"\n",
" value += 'k';\n",
" value += event.which.toString();\n",
"\n",
" this._key_event_extra(event, name);\n",
"\n",
" this.send_message(name, {key: value,\n",
" guiEvent: simpleKeys(event)});\n",
" return false;\n",
"}\n",
"\n",
"mpl.figure.prototype.toolbar_button_onclick = function(name) {\n",
" if (name == 'download') {\n",
" this.handle_save(this, null);\n",
" } else {\n",
" this.send_message(\"toolbar_button\", {name: name});\n",
" }\n",
"};\n",
"\n",
"mpl.figure.prototype.toolbar_button_onmouseover = function(tooltip) {\n",
" this.message.textContent = tooltip;\n",
"};\n",
"mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Pan axes with left mouse, zoom with right\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
"\n",
"mpl.extensions = [\"eps\", \"jpeg\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n",
"\n",
"mpl.default_extension = \"png\";var comm_websocket_adapter = function(comm) {\n",
" // Create a \"websocket\"-like object which calls the given IPython comm\n",
" // object with the appropriate methods. Currently this is a non binary\n",
" // socket, so there is still some room for performance tuning.\n",
" var ws = {};\n",
"\n",
" ws.close = function() {\n",
" comm.close()\n",
" };\n",
" ws.send = function(m) {\n",
" //console.log('sending', m);\n",
" comm.send(m);\n",
" };\n",
" // Register the callback with on_msg.\n",
" comm.on_msg(function(msg) {\n",
" //console.log('receiving', msg['content']['data'], msg);\n",
" // Pass the mpl event to the overridden (by mpl) onmessage function.\n",
" ws.onmessage(msg['content']['data'])\n",
" });\n",
" return ws;\n",
"}\n",
"\n",
"mpl.mpl_figure_comm = function(comm, msg) {\n",
" // This is the function which gets called when the mpl process\n",
" // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
"\n",
" var id = msg.content.data.id;\n",
" // Get hold of the div created by the display call when the Comm\n",
" // socket was opened in Python.\n",
" var element = $(\"#\" + id);\n",
" var ws_proxy = comm_websocket_adapter(comm)\n",
"\n",
" function ondownload(figure, format) {\n",
" window.open(figure.imageObj.src);\n",
" }\n",
"\n",
" var fig = new mpl.figure(id, ws_proxy,\n",
" ondownload,\n",
" element.get(0));\n",
"\n",
" // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
" // web socket which is closed, not our websocket->open comm proxy.\n",
" ws_proxy.onopen();\n",
"\n",
" fig.parent_element = element.get(0);\n",
" fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
" if (!fig.cell_info) {\n",
" console.error(\"Failed to find cell for figure\", id, fig);\n",
" return;\n",
" }\n",
"\n",
" var output_index = fig.cell_info[2]\n",
" var cell = fig.cell_info[0];\n",
"\n",
"};\n",
"\n",
"mpl.figure.prototype.handle_close = function(fig, msg) {\n",
" var width = fig.canvas.width/mpl.ratio\n",
" fig.root.unbind('remove')\n",
"\n",
" // Update the output cell to use the data from the current canvas.\n",
" fig.push_to_output();\n",
" var dataURL = fig.canvas.toDataURL();\n",
" // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
" // the notebook keyboard shortcuts fail.\n",
" IPython.keyboard_manager.enable()\n",
" $(fig.parent_element).html('<img src=\"' + dataURL + '\" width=\"' + width + '\">');\n",
" fig.close_ws(fig, msg);\n",
"}\n",
"\n",
"mpl.figure.prototype.close_ws = function(fig, msg){\n",
" fig.send_message('closing', msg);\n",
" // fig.ws.close()\n",
"}\n",
"\n",
"mpl.figure.prototype.push_to_output = function(remove_interactive) {\n",
" // Turn the data on the canvas into data in the output cell.\n",
" var width = this.canvas.width/mpl.ratio\n",
" var dataURL = this.canvas.toDataURL();\n",
" this.cell_info[1]['text/html'] = '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
"}\n",
"\n",
"mpl.figure.prototype.updated_canvas_event = function() {\n",
" // Tell IPython that the notebook contents must change.\n",
" IPython.notebook.set_dirty(true);\n",
" this.send_message(\"ack\", {});\n",
" var fig = this;\n",
" // Wait a second, then push the new image to the DOM so\n",
" // that it is saved nicely (might be nice to debounce this).\n",
" setTimeout(function () { fig.push_to_output() }, 1000);\n",
"}\n",
"\n",
"mpl.figure.prototype._init_toolbar = function() {\n",
" var fig = this;\n",
"\n",
" var nav_element = $('<div/>')\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) { continue; };\n",
"\n",
" var button = $('<button class=\"btn btn-default\" href=\"#\" title=\"' + name + '\"><i class=\"fa ' + image + ' fa-lg\"></i></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 = $('<span class=\"mpl-message\" style=\"text-align:right; float: right;\"/>');\n",
" nav_element.append(status_bar);\n",
" this.message = status_bar[0];\n",
"\n",
" // Add the close button to the window.\n",
" var buttongrp = $('<div class=\"btn-group inline pull-right\"></div>');\n",
" var button = $('<button class=\"btn btn-mini btn-primary\" href=\"#\" title=\"Stop Interaction\"><i class=\"fa fa-power-off icon-remove icon-large\"></i></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<ncells; i++) {\n",
" var cell = cells[i];\n",
" if (cell.cell_type === 'code'){\n",
" for (var j=0; j<cell.output_area.outputs.length; j++) {\n",
" var data = cell.output_area.outputs[j];\n",
" if (data.data) {\n",
" // IPython >= 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": [
"<IPython.core.display.Javascript object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<img src=\"data:image/png;base64,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\" width=\"432\">"
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"## Boucle pour rayon à travers lentille sphérique infini foyer\n",
"compteur=0;\n",
"SCg=5\n",
"SCd=-5\n",
"e=1\n",
"focale=1.0/((nVerre-nMilieu)*(1/SCg-1/SCd))\n",
"zLentille=[0, dist/2-e/2 ,dist/2+e/2 ,dist/2+focale]\n",
"dist2=3 #Distance entre la focale et la deuxième lentille\n",
"\n",
"%matplotlib notebook\n",
"plt.plot(figsize=(14,16))\n",
"\n",
"for k in repartitionABPlan:\n",
" Traj=0\n",
" ABEntree=k;\n",
" coordEntree=np.array([[ABEntree],[nMilieu*phiEntree]])\n",
" CoordSortie,coordDioptreD,coordDioptreG=lentille_spherique(coordEntree,nMilieu,dist/2-e/2,nVerre,e,focale-e/2,SCg,SCd)\n",
" Traj=ajoutTraj(coordEntree, coordDioptreG)\n",
" Traj=ajoutTraj(Traj, coordDioptreD)\n",
" Traj=ajoutTraj(Traj, CoordSortie)\n",
" Traj=Traj+translation(CoordSortie,nMilieu,dist2)\n",
" \n",
" afficher_traj(zLentille,Traj)\n",
" desssinerAxeOptique(zLentille)\n",
" dessiner_lentille(dist/2,SCg,SCd,e)\n",
" #dessiner_lentille(dist2+14,SCg,SCd,e)\n",
" \n",
" #coordEntree=CoordSortie\n",
" #CoordSortie,coordDioptreD,coordDioptreG=lentille_spherique(coordEntree,nMilieu,dist/2-e/2,nVerre,e,focale-e/2,SCg,SCd)\n",
" #Traj=ajoutTraj(Traj, coordDioptreG)\n",
" #Traj=ajoutTraj(Traj, coordDioptreD)\n",
" #Traj=ajoutTraj(Traj, CoordSortie+1)\n",
" \n",
" #afficher_traj(zLentille, Traj)\n",
" #dessiner_lentille(dist2/2,SCg,SCd,e)"
]
},
{
"cell_type": "code",
"execution_count": 69,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([[-0.33675],\n",
" [ 0.2385 ]])"
]
},
"execution_count": 69,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"CoordSortie"
]
},
{
"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.4"
}
},
"nbformat": 4,
"nbformat_minor": 4
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment