{"id":276,"date":"2026-09-14T20:17:54","date_gmt":"2026-09-14T18:17:54","guid":{"rendered":"https:\/\/benlhajlahsen.fr\/?page_id=276"},"modified":"2026-09-14T20:17:54","modified_gmt":"2026-09-14T18:17:54","slug":"fibre-optique","status":"publish","type":"page","link":"https:\/\/benlhajlahsen.fr\/index.php\/fibre-optique\/","title":{"rendered":"Fibre optique"},"content":{"rendered":"\n<!DOCTYPE html>\n<html lang=\"fr\">\n<head>\n<meta charset=\"UTF-8\">\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n<title>Guidage de la lumi\u00e8re dans une fibre optique<\/title>\n<style>\n  :root{\n    --bg:#ffffff; --panel:#f7f8fa; --border:#e0e3e8;\n    --text:#1c1f26; --muted:#6b7280; --accent:#c0392b;\n    --core:#eaf4ff; --clad:#fff3e6; --air:#ffffff;\n    --guided:#1f9d55; --lost:#c0392b;\n  }\n  @media (prefers-color-scheme: dark){\n    :root{\n      --bg:#14161a; --panel:#1c1f26; --border:#2c313a;\n      --text:#e7e9ee; --muted:#9aa2b1; --accent:#ff6b5e;\n      --core:#16324a; --clad:#3a2a17; --air:#14161a;\n    }\n  }\n  *{box-sizing:border-box;}\n  body{\n    margin:0; padding:20px; background:var(--bg); color:var(--text);\n    font-family: system-ui, -apple-system, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif;\n  }\n  .wrap{max-width:900px; margin:0 auto;}\n  h1{font-size:1.25rem; font-weight:600; margin:0 0 4px;}\n  p.sub{color:var(--muted); font-size:0.92rem; margin:0 0 18px;}\n  .panel{\n    background:var(--panel); border:1px solid var(--border); border-radius:12px;\n    padding:16px; margin-bottom:16px;\n  }\n  svg{width:100%; height:auto; display:block; background:var(--air); border-radius:8px;}\n  .controls{display:grid; grid-template-columns:1fr; gap:14px;}\n  .ctrl-row{display:flex; align-items:center; gap:12px;}\n  .ctrl-row label{flex:0 0 220px; font-size:0.92rem;}\n  .ctrl-row input[type=range]{flex:1;}\n  .ctrl-row .val{flex:0 0 70px; text-align:right; font-variant-numeric:tabular-nums; font-weight:600;}\n  .status{\n    display:flex; flex-wrap:wrap; gap:8px 22px; margin-top:14px; font-size:0.92rem;\n  }\n  .status div{display:flex; gap:6px;}\n  .status span.k{color:var(--muted);}\n  .status span.v{font-weight:600; font-variant-numeric:tabular-nums;}\n  .badge{\n    display:inline-block; padding:2px 10px; border-radius:999px; font-size:0.82rem; font-weight:600;\n  }\n  .badge.ok{background:rgba(31,157,85,0.15); color:var(--guided);}\n  .badge.no{background:rgba(192,57,43,0.15); color:var(--lost);}\n  footer{color:var(--muted); font-size:0.8rem; text-align:center; margin-top:10px;}\n<\/style>\n<\/head>\n<body>\n<div class=\"wrap\">\n  <h1>Guidage de la lumi\u00e8re dans une fibre optique \u00e0 saut d&rsquo;indice<\/h1>\n  <p class=\"sub\">Faites varier l&rsquo;angle d&rsquo;incidence et les indices pour observer le guidage par r\u00e9flexion totale \u2014 et sa disparition au-del\u00e0 de l&rsquo;angle d&rsquo;acceptance.<\/p>\n\n  <div class=\"panel\">\n    <svg id=\"scene\" viewBox=\"0 0 900 320\" preserveAspectRatio=\"xMidYMid meet\"><\/svg>\n    <div class=\"status\" id=\"status\"><\/div>\n  <\/div>\n\n  <div class=\"panel controls\">\n    <div class=\"ctrl-row\">\n      <label for=\"i\">Angle d&rsquo;incidence <i>i<\/i> (air \u2192 c\u0153ur)<\/label>\n      <input type=\"range\" id=\"i\" min=\"0\" max=\"89\" step=\"0.5\" value=\"20\">\n      <span class=\"val\" id=\"iVal\">20\u00b0<\/span>\n    <\/div>\n    <div class=\"ctrl-row\">\n      <label for=\"n1\">Indice du c\u0153ur n\u2081<\/label>\n      <input type=\"range\" id=\"n1\" min=\"1.30\" max=\"1.75\" step=\"0.005\" value=\"1.456\">\n      <span class=\"val\" id=\"n1Val\">1.456<\/span>\n    <\/div>\n    <div class=\"ctrl-row\">\n      <label for=\"n2\">Indice de la gaine n\u2082<\/label>\n      <input type=\"range\" id=\"n2\" min=\"1.20\" max=\"1.70\" step=\"0.005\" value=\"1.410\">\n      <span class=\"val\" id=\"n2Val\">1.410<\/span>\n    <\/div>\n  <\/div>\n\n  <footer>S. Benlhajlahsen \u2014 PCSI \u00b7 Guidage par r\u00e9flexion totale dans une fibre \u00e0 saut d&rsquo;indice<\/footer>\n<\/div>\n\n<script>\nconst svg = document.getElementById('scene');\nconst NS = 'http:\/\/www.w3.org\/2000\/svg';\n\n\/\/ --- geometry constants (svg units) ---\nconst X0 = 130;           \/\/ entrance face x\nconst XMAX = 880;         \/\/ right edge\nconst AXIS_Y = 160;       \/\/ fiber axis height\nconst HALF_CORE = 45;     \/\/ core half-thickness\nconst CLAD_T = 45;        \/\/ cladding thickness (each side)\n\nfunction el(tag, attrs){\n  const e = document.createElementNS(NS, tag);\n  for(const k in attrs) e.setAttribute(k, attrs[k]);\n  return e;\n}\n\nfunction build(){\n  svg.innerHTML = '';\n\n  \/\/ cladding bands\n  svg.appendChild(el('rect',{x:X0,y:AXIS_Y-HALF_CORE-CLAD_T,width:XMAX-X0,height:CLAD_T,fill:'var(--clad)'}));\n  svg.appendChild(el('rect',{x:X0,y:AXIS_Y+HALF_CORE,width:XMAX-X0,height:CLAD_T,fill:'var(--clad)'}));\n  \/\/ core band\n  svg.appendChild(el('rect',{x:X0,y:AXIS_Y-HALF_CORE,width:XMAX-X0,height:2*HALF_CORE,fill:'var(--core)'}));\n\n  \/\/ interfaces\n  svg.appendChild(el('line',{x1:X0,y1:AXIS_Y-HALF_CORE,x2:XMAX,y2:AXIS_Y-HALF_CORE,stroke:'var(--border)','stroke-width':1.5}));\n  svg.appendChild(el('line',{x1:X0,y1:AXIS_Y+HALF_CORE,x2:XMAX,y2:AXIS_Y+HALF_CORE,stroke:'var(--border)','stroke-width':1.5}));\n  svg.appendChild(el('line',{x1:X0,y1:AXIS_Y-HALF_CORE-CLAD_T,x2:XMAX,y2:AXIS_Y-HALF_CORE-CLAD_T,stroke:'var(--border)','stroke-width':1,'stroke-dasharray':'2,4'}));\n  svg.appendChild(el('line',{x1:X0,y1:AXIS_Y+HALF_CORE+CLAD_T,x2:XMAX,y2:AXIS_Y+HALF_CORE+CLAD_T,stroke:'var(--border)','stroke-width':1,'stroke-dasharray':'2,4'}));\n  \/\/ entrance face\n  svg.appendChild(el('line',{x1:X0,y1:AXIS_Y-HALF_CORE-CLAD_T,x2:X0,y2:AXIS_Y+HALF_CORE+CLAD_T,stroke:'var(--text)','stroke-width':1.5}));\n  \/\/ axis (dashed)\n  svg.appendChild(el('line',{x1:X0,y1:AXIS_Y,x2:XMAX,y2:AXIS_Y,stroke:'var(--muted)','stroke-width':1,'stroke-dasharray':'4,4'}));\n\n  \/\/ labels\n  const t1 = el('text',{x:XMAX-6,y:AXIS_Y-HALF_CORE-14,'text-anchor':'end','font-size':'13',fill:'var(--muted)'});\n  t1.textContent = 'gaine (n\u2082)'; svg.appendChild(t1);\n  const t2 = el('text',{x:XMAX-6,y:AXIS_Y+4,'text-anchor':'end','font-size':'13',fill:'var(--muted)'});\n  t2.textContent = 'c\u0153ur (n\u2081)'; svg.appendChild(t2);\n  const t3 = el('text',{x:XMAX-6,y:AXIS_Y+HALF_CORE+28,'text-anchor':'end','font-size':'13',fill:'var(--muted)'});\n  t3.textContent = 'gaine (n\u2082)'; svg.appendChild(t3);\n  const t4 = el('text',{x:X0-6,y:AXIS_Y-HALF_CORE-CLAD_T-10,'text-anchor':'start','font-size':'13',fill:'var(--muted)'});\n  t4.textContent = 'air (n\u2080=1,00)'; svg.appendChild(t4);\n}\n\nfunction rayPath(points, color, width, dashed){\n  const d = points.map((p,idx)=> (idx===0?'M':'L') + p[0].toFixed(2) + ',' + p[1].toFixed(2)).join(' ');\n  const attrs = {d, fill:'none', stroke:color, 'stroke-width':width};\n  if(dashed) attrs['stroke-dasharray'] = '5,4';\n  svg.appendChild(el('path', attrs));\n}\n\nfunction arrowHead(p1, p2, color){\n  const ang = Math.atan2(p2[1]-p1[1], p2[0]-p1[0]);\n  const len = 10, spread = 0.45;\n  const x = p2[0], y = p2[1];\n  const p3 = [x - len*Math.cos(ang-spread), y - len*Math.sin(ang-spread)];\n  const p4 = [x - len*Math.cos(ang+spread), y - len*Math.sin(ang+spread)];\n  svg.appendChild(el('polygon',{points:`${x},${y} ${p3[0]},${p3[1]} ${p4[0]},${p4[1]}`, fill:color}));\n}\n\nfunction update(){\n  const iDeg = parseFloat(document.getElementById('i').value);\n  const n1 = parseFloat(document.getElementById('n1').value);\n  let n2 = parseFloat(document.getElementById('n2').value);\n  if(n2 >= n1) n2 = n1 - 0.01; \/\/ garde-fou : la gaine doit rester moins refringente\n\n  document.getElementById('iVal').textContent = iDeg.toFixed(1) + '\u00b0';\n  document.getElementById('n1Val').textContent = n1.toFixed(3);\n  document.getElementById('n2Val').textContent = n2.toFixed(3);\n\n  const n0 = 1.0;\n  const iRad = iDeg * Math.PI\/180;\n\n  build();\n\n  \/\/ acceptance cone (visual wedge at entrance)\n  const ia = Math.asin(Math.min(1, Math.sqrt(Math.max(0,n1*n1-n2*n2))\/n0));\n  const coneLen = 90;\n  const topY = AXIS_Y - coneLen*Math.sin(ia);\n  const botY = AXIS_Y + coneLen*Math.sin(ia);\n  svg.appendChild(el('polygon',{\n    points:`${X0},${AXIS_Y} ${X0-coneLen*Math.cos(ia)},${topY} ${X0-coneLen*Math.cos(ia)},${botY}`,\n    fill:'rgba(31,157,85,0.12)'\n  }));\n\n  \/\/ theta = angle from axis inside the core\n  const sinTheta = n0*Math.sin(iRad)\/n1;\n  const theta = Math.asin(Math.min(1,sinTheta));\n  const thetaDeg = theta*180\/Math.PI;\n\n  \/\/ guiding condition: cos(theta) >= n2\/n1\n  const guided = Math.cos(theta) >= n2\/n1;\n\n  \/\/ incident ray in air, arriving at entry point (axis center), angle i above axis\n  const entry = [X0, AXIS_Y];\n  const Lin = 110;\n  const start = [X0 - Lin*Math.cos(iRad), AXIS_Y - Lin*Math.sin(iRad)];\n  rayPath([start, entry], 'var(--accent)', 2.4, false);\n  arrowHead(start, entry, 'var(--accent)');\n\n  \/\/ build zigzag inside core\n  let pts = [entry];\n  let x = X0, y = AXIS_Y;\n  let goingDown = true; \/\/ first bounce toward bottom interface (matches incoming angle > 0)\n  let guidedColor = guided ? 'var(--guided)' : 'var(--accent)';\n\n  if(guided){\n    \/\/ distance to first boundary from axis\n    let dyFirst = HALF_CORE;\n    let dx = dyFirst\/Math.tan(theta);\n    x += dx; y = AXIS_Y + HALF_CORE;\n    pts.push([x,y]);\n    let dir = 1; \/\/ 1 = going down last, next goes up\n    while(x < XMAX - 5){\n      const dy = 2*HALF_CORE;\n      const dx2 = dy\/Math.tan(theta);\n      x += dx2;\n      y = dir>0 ? AXIS_Y - HALF_CORE : AXIS_Y + HALF_CORE;\n      if(x > XMAX){\n        \/\/ clip last segment\n        const prev = pts[pts.length-1];\n        const frac = (XMAX - prev[0])\/(x - prev[0]);\n        x = XMAX; y = prev[1] + frac*(y-prev[1]);\n        pts.push([x,y]);\n        break;\n      }\n      pts.push([x,y]);\n      dir *= -1;\n    }\n    rayPath(pts, guidedColor, 2.6, false);\n    for(let k=1;k<pts.length;k++) arrowHead(pts[k-1], pts[k], guidedColor);\n  } else {\n    \/\/ hits first interface then escapes into the cladding (refraction)\n    let dx = HALF_CORE\/Math.tan(theta);\n    x += dx; y = AXIS_Y + HALF_CORE;\n    pts.push([x,y]);\n    rayPath(pts, 'var(--core)'.startsWith('#')?'#3b6ea5':'#3b6ea5', 2.6, false);\n    \/\/ redraw properly (core segment) in blue-ish guided-like color before leak\n    svg.lastChild.remove();\n    rayPath(pts, '#2f7dd1', 2.6, false);\n    arrowHead(entry, [x,y], '#2f7dd1');\n\n    \/\/ angle from the interface normal (vertical) = 90-theta ; refract into cladding\n    const angFromNormal = Math.PI\/2 - theta;\n    const sinOut = (n1\/n2)*Math.sin(angFromNormal);\n    if(sinOut <= 1){\n      const angOut = Math.asin(sinOut); \/\/ from normal, in cladding\n      const thetaClad = Math.PI\/2 - angOut; \/\/ from horizontal\n      const Lout = 140;\n      const end = [x + Lout*Math.cos(thetaClad), y + Lout*Math.sin(thetaClad)];\n      const clippedEnd = [Math.min(end[0], XMAX), end[1] + (Math.min(end[0],XMAX)-x)\/(end[0]-x)*0 ];\n      \/\/ simple straight clip to XMAX\n      let ex = end[0], ey = end[1];\n      if(ex > XMAX){\n        const frac = (XMAX - x)\/(ex-x);\n        ex = XMAX; ey = y + frac*(end[1]-y);\n      }\n      rayPath([[x,y],[ex,ey]], 'var(--accent)', 2.6, true);\n      arrowHead([x,y],[ex,ey],'var(--accent)');\n    }\n  }\n\n  \/\/ status readouts\n  const st = document.getElementById('status');\n  const betaDeg = 90 - thetaDeg;\n  const NA = Math.sqrt(Math.max(0,n1*n1-n2*n2));\n  st.innerHTML = `\n    <div><span class=\"k\">\u03b8 (depuis l'axe) :<\/span><span class=\"v\">${thetaDeg.toFixed(1)}\u00b0<\/span><\/div>\n    <div><span class=\"k\">angle sur l'interface c\u0153ur\/gaine :<\/span><span class=\"v\">${betaDeg.toFixed(1)}\u00b0<\/span><\/div>\n    <div><span class=\"k\">angle d'acceptance i_a :<\/span><span class=\"v\">${(ia*180\/Math.PI).toFixed(1)}\u00b0<\/span><\/div>\n    <div><span class=\"k\">ouverture num\u00e9rique ON :<\/span><span class=\"v\">${NA.toFixed(3)}<\/span><\/div>\n    <div><span class=\"badge ${guided?'ok':'no'}\">${guided ? 'Guid\u00e9 (r\u00e9flexion totale)' : 'Non guid\u00e9 (fuite dans la gaine)'}<\/span><\/div>\n  `;\n}\n\n['i','n1','n2'].forEach(id=>{\n  document.getElementById(id).addEventListener('input', update);\n});\nupdate();\n<\/script>\n<\/body>\n<\/html>\n","protected":false},"excerpt":{"rendered":"<p>Guidage de la lumi\u00e8re dans une fibre optique Guidage de la lumi\u00e8re dans une fibre optique \u00e0 saut d&rsquo;indice Faites varier l&rsquo;angle d&rsquo;incidence et les indices pour observer le guidage par r\u00e9flexion totale \u2014 et sa disparition au-del\u00e0 de l&rsquo;angle d&rsquo;acceptance. Angle d&rsquo;incidence i (air \u2192 c\u0153ur) 20\u00b0 Indice du c\u0153ur n\u2081 1.456 Indice de &hellip; <a href=\"https:\/\/benlhajlahsen.fr\/index.php\/fibre-optique\/\" class=\"more-link\">Continuer la lecture<span class=\"screen-reader-text\"> de &laquo;&nbsp;Fibre optique&nbsp;&raquo;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"class_list":["post-276","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/benlhajlahsen.fr\/index.php\/wp-json\/wp\/v2\/pages\/276","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/benlhajlahsen.fr\/index.php\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/benlhajlahsen.fr\/index.php\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/benlhajlahsen.fr\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/benlhajlahsen.fr\/index.php\/wp-json\/wp\/v2\/comments?post=276"}],"version-history":[{"count":1,"href":"https:\/\/benlhajlahsen.fr\/index.php\/wp-json\/wp\/v2\/pages\/276\/revisions"}],"predecessor-version":[{"id":278,"href":"https:\/\/benlhajlahsen.fr\/index.php\/wp-json\/wp\/v2\/pages\/276\/revisions\/278"}],"wp:attachment":[{"href":"https:\/\/benlhajlahsen.fr\/index.php\/wp-json\/wp\/v2\/media?parent=276"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}