diff --git a/frontend/js/phys-fx.js b/frontend/js/phys-fx.js index 21f10c2..e5946b1 100644 --- a/frontend/js/phys-fx.js +++ b/frontend/js/phys-fx.js @@ -1329,4 +1329,215 @@ class PrismSpectrum { } P.PrismSpectrum = PrismSpectrum; +/* ============================================================ */ +/* ThinLens — тонкая линза (собирающая / рассеивающая) */ +/* ============================================================ */ + +class ThinLens { + constructor(container, opts){ + opts = opts || {}; + this.el = (typeof container === 'string') ? document.querySelector(container) : container; + this.W = opts.width || 640; + this.H = opts.height || 300; + this.F = opts.F !== undefined ? opts.F : 70; /* фокусное (px) */ + this.d = opts.d !== undefined ? opts.d : 160; /* расст. до объекта (px) */ + this.objH = opts.objH !== undefined ? opts.objH : 50; + this.mode = opts.mode || 'converging'; /* 'converging' | 'diverging' */ + this.color = opts.color || '#d97706'; + this.paused = true; + this.render(); + } + setF(v){ this.F = Math.max(20, v); this.render(); } + setD(v){ this.d = Math.max(20, v); this.render(); } + setMode(m){ this.mode = m; this.render(); } + update(){} + render(){ + if (!this.el) return; + const W = this.W, H = this.H; + const cy = H / 2 + 10; + const lensX = W / 2; + const Fsign = (this.mode === 'converging') ? this.F : -this.F; + const d = this.d; + /* 1/d + 1/f = 1/F → f = 1/(1/F - 1/d) */ + let f; + if (Math.abs(1/Fsign - 1/d) < 1e-6) f = 1e9; + else f = 1 / (1/Fsign - 1/d); + /* По соглашению: f > 0 справа (действительное), f < 0 слева (мнимое) */ + const imgX = lensX + f; + const G = -f / d; + const imgH = this.objH * G; + let svg = util.svgFrame(W, H, {bg:'#f8fafc'}); + /* Главная оптическая ось */ + svg += ''; + /* Линза */ + if (this.mode === 'converging'){ + svg += ''; + svg += ''; + svg += ''; + } else { + svg += ''; + svg += ''; + svg += ''; + } + /* Фокусы F и 2F */ + const Fleft = lensX - this.F, Fright = lensX + this.F; + svg += 'F'; + svg += 'F'; + if (this.mode === 'converging'){ + const F2L = lensX - 2*this.F, F2R = lensX + 2*this.F; + if (F2L > 20) svg += '2F'; + if (F2R < W - 10) svg += '2F'; + } + /* Объект */ + const objX = lensX - d; + const objTopY = cy - this.objH; + svg += ''; + svg += ''; + /* Лучи */ + /* Луч 1: параллельный → через F справа (для собирающей); для рассеивающей — как-будто из F слева */ + svg += ''; + if (this.mode === 'converging'){ + const slope = (cy - objTopY) / (Fright - lensX); + const x2 = Math.min(W - 10, imgX > lensX ? imgX : W - 10); + const y2 = objTopY + slope * (x2 - lensX); + svg += ''; + } else { + /* Рассеивающая: продолжение в сторону F слева */ + const slope = (objTopY - cy) / (lensX - Fleft); + svg += ''; + svg += ''; + } + /* Луч 2: через оптический центр O (без преломления) */ + const slope2 = (cy - objTopY) / (lensX - objX); + const ex = Math.min(W - 10, imgX > lensX ? imgX : W - 10); + const ey = objTopY + slope2 * (ex - objX); + svg += ''; + /* Изображение */ + if (isFinite(imgH) && Math.abs(imgX) < 1e7){ + const imgTopY = cy - imgH; + const isVirtual = (this.mode === 'diverging') || (f < 0); + const sd = isVirtual ? ' stroke-dasharray="4 3"' : ''; + const op = isVirtual ? 0.7 : 1.0; + const fillCol = '#7c2d12'; + if (imgX > 20 && imgX < W - 10){ + svg += ''; + svg += ''; + } + } + /* Подписи */ + const Glabel = isFinite(G) ? G.toFixed(2) : '—'; + const fLabel = (Math.abs(f) < 1e7) ? f.toFixed(0) : '∞'; + svg += '1/d + 1/f = 1/F · Γ = -f/d = ' + Glabel + ' · f = ' + fLabel + 'px'; + svg += '' + (this.mode==='converging'?'собирающая':'рассеивающая') + ' линза · F=' + this.F + 'px · d=' + d + 'px'; + svg += ''; + this.el.innerHTML = svg; + } +} +P.ThinLens = ThinLens; + +/* ============================================================ */ +/* TwoLensSystem — две линзы (микроскоп / телескоп) */ +/* ============================================================ */ + +class TwoLensSystem { + constructor(container, opts){ + opts = opts || {}; + this.el = (typeof container === 'string') ? document.querySelector(container) : container; + this.W = opts.width || 700; + this.H = opts.height || 280; + this.F1 = opts.F1 !== undefined ? opts.F1 : 50; /* объектив */ + this.F2 = opts.F2 !== undefined ? opts.F2 : 90; /* окуляр */ + this.L = opts.L !== undefined ? opts.L : 280; /* расстояние между линзами */ + this.mode = opts.mode || 'telescope'; /* 'telescope' | 'microscope' */ + this.paused = true; + this.render(); + } + setMode(m){ this.mode = m; this.render(); } + setF1(v){ this.F1 = Math.max(20, v); this.render(); } + setF2(v){ this.F2 = Math.max(20, v); this.render(); } + setL(v){ this.L = Math.max(this.F1 + this.F2 + 20, v); this.render(); } + update(){} + drawLens(svg, x, cy, label, F){ + let s = svg; + s += ''; + s += ''; + s += ''; + s += '' + label + ''; + s += ''; + s += ''; + return s; + } + render(){ + if (!this.el) return; + const W = this.W, H = this.H; + const cy = H / 2 + 10; + const x1 = 130; /* объектив */ + const x2 = x1 + this.L; /* окуляр */ + let svg = util.svgFrame(W, H, {bg:'#f8fafc'}); + /* Ось */ + svg += ''; + /* Линзы */ + svg = this.drawLens(svg, x1, cy, 'объектив (F₁=' + this.F1 + ')', this.F1); + svg = this.drawLens(svg, x2, cy, 'окуляр (F₂=' + this.F2 + ')', this.F2); + /* Сценарий */ + if (this.mode === 'telescope'){ + /* Объект «на бесконечности» — пучок параллельных лучей входит слева */ + const angle = -0.06; /* небольшой угол */ + for (let i = -2; i <= 2; i++){ + const yIn = cy + i * 18; + /* Луч входит горизонтально (или под малым углом α₁) */ + const xIn = 25; + svg += ''; + /* После объектива собирается в фокальной плоскости (x1 + F1) */ + const focusX = x1 + this.F1; + const focusY = cy; /* для параллельного пучка вдоль оси — на оси */ + svg += ''; + /* От фокуса (F2 справа от окуляра у телескопа: совмещён с F1 объектива) дальше параллельно */ + /* Лучи проходят через окуляр */ + const yAtEye = focusY + (cy + i * 12 - focusY); /* выходные углы немного шире */ + svg += ''; + /* После окуляра — параллельно (изображение в бесконечности) */ + svg += ''; + } + svg += 'пучок от удалённого объекта'; + svg += 'в глаз наблюдателя'; + svg += 'телескоп Кеплера · Γ = F₁/F₂ = ' + (this.F1/this.F2).toFixed(2) + ''; + } else { + /* Микроскоп: объект чуть дальше F1 от объектива */ + const d1 = this.F1 + 12; + const objX = x1 - d1; + const objH = 40; + /* 1/d + 1/f = 1/F */ + const f1 = 1 / (1/this.F1 - 1/d1); + const G1 = -f1 / d1; + const h1 = objH * G1; + const img1X = x1 + f1; + /* Изображение объектива должно лежать чуть ближе F2 от окуляра, чтобы окуляр работал как лупа */ + /* Объект */ + svg += ''; + svg += ''; + /* Промежуточное изображение */ + if (img1X > x1 && img1X < x2){ + svg += ''; + svg += ''; + svg += 'A₁B₁'; + } + /* Лучи от верха объекта через объектив (2 канонических) */ + svg += ''; + svg += ''; + /* Через оптический центр объектива */ + svg += ''; + /* Окуляр работает как лупа — даёт мнимое увеличенное (за окуляром слева) */ + /* Показ лучей от верха промежуточного изображения через окуляр параллельно (в глаз) */ + svg += ''; + svg += ''; + svg += 'в глаз'; + const Gtotal = G1 * (25 / this.F2); /* приближённо: |Γ_мкс| ≈ |Γ_объ| · 25 см/F_ок */ + svg += 'микроскоп · Γ ≈ Γ_объ · 25 см / F_ок ≈ ' + Gtotal.toFixed(1) + ''; + } + this.el.innerHTML = svg; + } +} +P.TwoLensSystem = TwoLensSystem; + })(); diff --git a/frontend/textbooks/physics_11_ch3.html b/frontend/textbooks/physics_11_ch3.html index 4765e5d..66da196 100644 --- a/frontend/textbooks/physics_11_ch3.html +++ b/frontend/textbooks/physics_11_ch3.html @@ -232,10 +232,10 @@ const PARAS = [ { id:'p5', num:'§ 18', name:'Сферические зеркала', sub:'$1/d + 1/f = 1/F$', built:true }, { id:'p6', num:'§ 19', name:'Преломление', sub:'$n_1\\sin\\alpha = n_2\\sin\\beta$', built:true }, { id:'p7', num:'§ 20', name:'Опт. элементы', sub:'Призма, оптоволокно', built:true }, - { id:'p8', num:'§ 21', name:'Тонкая линза', sub:'Будет в W7', built:false }, - { id:'p9', num:'§ 22', name:'Действ. изображения', sub:'Будет в W7', built:false }, - { id:'p10', num:'§ 23', name:'Угол зрения', sub:'Будет в W7', built:false }, - { id:'final', num:'★', name:'Финал главы', sub:'Будет в W7', final:true, built:false } + { id:'p8', num:'§ 21', name:'Тонкая линза', sub:'$1/d + 1/f = 1/F$', built:true }, + { id:'p9', num:'§ 22', name:'Действ. изображения', sub:'Фотоаппарат, проектор', built:true }, + { id:'p10', num:'§ 23', name:'Угол зрения', sub:'Лупа, микроскоп, телескоп', built:true }, + { id:'final', num:'★', name:'Финал главы 3', sub:'Все 10 параграфов', final:true, built:true } ]; PARAS.forEach(p => { STATE.progress[p.id] = 0; }); @@ -250,6 +250,10 @@ const ACH_LABELS = { p5_done:'§18 — сферические зеркала освоены', p6_done:'§19 — закон Снелла освоен', p7_done:'§20 — призма и оптоволокно освоены', + p8_done:'§21 — тонкая линза освоена', + p9_done:'§22 — фотоаппарат и проектор освоены', + p10_done:'§23 — оптические приборы освоены', + ch3_master:'Магистр оптики — пройден финал главы 3!', start:'Начало главы 3!', ch3_done:'Глава 3 пройдена — Оптика!' }; @@ -333,10 +337,8 @@ const BUILT=new Set(); const BUILDERS = { p1:()=>buildP1(), p2:()=>buildP2(), p3:()=>buildP3(), p4:()=>buildP4(), p5:()=>buildP5(), p6:()=>buildP6(), p7:()=>buildP7(), - p8:()=>buildStubP('p8','§ 21','§21 в разработке (W7) — тонкая линза, формула $1/F = 1/d + 1/f$, оптическая сила $D = 1/F$.'), - p9:()=>buildStubP('p9','§ 22','§22 в разработке (W7) — фотоаппарат, проектор.'), - p10:()=>buildStubP('p10','§ 23','§23 в разработке (W7) — лупа, микроскоп, телескоп.'), - final:()=>buildStubP('final','Финал','Финал главы 3 — в волне W7 (5 интегр. боссов + ачивка ch3_done).') + p8:()=>buildP8(), p9:()=>buildP9(), p10:()=>buildP10(), + final:()=>buildFinal() }; function ensureBuilt(id){ if(BUILT.has(id)) return; const fn=BUILDERS[id]; if(fn){ fn(); BUILT.add(id); } } function goTo(id){ @@ -359,10 +361,10 @@ const SIDEBARS = { p5:{title:'§ 18 — Сферические зеркала', rows:[['Формула','$\\dfrac{1}{d}+\\dfrac{1}{f}=\\dfrac{1}{F}$'],['Фокус','$F = R/2$'],['Увелич.','$\\Gamma = -f/d$']]}, p6:{title:'§ 19 — Преломление', rows:[['Закон','$n_1\\sin\\alpha = n_2\\sin\\beta$'],['Пок. прелом.','$n = c/v$'],['ПВО','$\\sin\\alpha_{кр}=n_2/n_1$ (если $n_1>n_2$)']]}, p7:{title:'§ 20 — Опт. элементы', rows:[['Призма','дисперсия $n(\\lambda)$'],['Пластинка','параллельный сдвиг'],['Оптоволокно','полное внутр. отражение']]}, - p8:{title:'§ 21', rows:[['Тема','Тонкая линза'],['Статус','В разработке (W7)']]}, - p9:{title:'§ 22', rows:[['Тема','Действ. изобр.'],['Статус','В разработке (W7)']]}, - p10:{title:'§ 23', rows:[['Тема','Угол зрения'],['Статус','В разработке (W7)']]}, - final:{title:'Финал главы 3', rows:[['Статус','В разработке (W7)'],['Боссов','5 интегрированных'],['Награда','+150 XP + ачивка']]} + p8:{title:'§ 21 — Тонкая линза', rows:[['Формула','$\\dfrac{1}{d}+\\dfrac{1}{f}=\\dfrac{1}{F}$'],['Опт. сила','$D = 1/F$ (дптр)'],['Увелич.','$\\Gamma = -f/d$']]}, + p9:{title:'§ 22 — Фотоаппарат, проектор', rows:[['Фото','$d > 2F$, изобр. уменьш. перевёрнутое'],['Проектор','$F < d < 2F$, увелич. перевёрнутое']]}, + p10:{title:'§ 23 — Оптические приборы', rows:[['Лупа','$\\Gamma = 25\\text{см}/F$'],['Микроскоп','$\\Gamma \\approx \\Gamma_{об} \\cdot 25\\text{см}/F_{ок}$'],['Телескоп','$\\Gamma = F_{об}/F_{ок}$']]}, + final:{title:'Финал главы 3 — Оптика', rows:[['Боссов','5 интегрированных'],['Покрытие','§14-§23 (10 параграфов)'],['Награда','+200 XP + Магистр оптики']]} }; const TIPS=[ @@ -373,10 +375,10 @@ const TIPS=[ {sec:'p5',html:'§ 18 — фокус сферического зеркала $F = R/2$. Формула $1/d + 1/f = 1/F$ работает для любого зеркала. Если $f<0$ — изображение мнимое (за зеркалом).'}, {sec:'p6',html:'§ 19 — закон Снелла $n_1\\sin\\alpha = n_2\\sin\\beta$. Если идём из плотной среды в менее плотную и $\\alpha > \\alpha_{кр}$ — полное внутреннее отражение.'}, {sec:'p7',html:'§ 20 — призма разлагает белый свет в спектр, потому что $n(\\lambda)$ для разных $\\lambda$ разный. Оптоволокно работает за счёт ПВО.'}, - {sec:'p8',html:'§ 21 — в разработке (W7).'}, - {sec:'p9',html:'§ 22 — в разработке (W7).'}, - {sec:'p10',html:'§ 23 — в разработке (W7).'}, - {sec:'final',html:'Финал главы 3 — в разработке (W7).'} + {sec:'p8',html:'§ 21 — тонкая линза. Если $f>0$ — действительное изображение; если $f<0$ — мнимое. Оптическая сила $D=1/F$ измеряется в дптр (м⁻¹).'}, + {sec:'p9',html:'§ 22 — фотоаппарат: $d > 2F$ ⇒ уменьшенное действительное. Проектор: $F < d < 2F$ ⇒ увеличенное действительное.'}, + {sec:'p10',html:'§ 23 — лупа = одна линза, $\\Gamma = 25/F$ см. Микроскоп = двойная система. Телескоп: чем больше $F_{об}/F_{ок}$, тем больше увеличение.'}, + {sec:'final',html:'Финал главы 3: 5 интегрированных боссов покрывают весь материал §14–§23.'} ]; function buildSidebar(id){ @@ -1004,7 +1006,314 @@ function buildP7(){ renderMath(box); } -/* ===== Stubs §21-§23 + Final ===== */ +/* ===== §21 Тонкая линза ===== */ +function buildP8(){ + const box = document.getElementById('p8-body'); if(!box) return; + let html = ''; + + html += makeCard('theory', 'Тонкая линза — виды и характеристики', '§ 21.1', + '

Линза — прозрачное тело, ограниченное двумя сферическими (или одной сферической и плоской) поверхностями.

' + + '

«Тонкая» — толщина мала по сравнению с радиусами кривизны поверхностей.

' + + '

Различают:

' + + '
    ' + + '
  • Собирающие (выпуклые) — действуют как «солнечные стеклы», $F > 0$.
  • ' + + '
  • Рассеивающие (вогнутые) — расходящие линзы, $F < 0$.
  • ' + + '
' + + '

Основные точки: оптический центр $O$, два фокуса $F_1, F_2$ (симметричны относительно $O$), главная оптическая ось.

' + + '

Оптическая сила:

' + + '

$$D = \\dfrac{1}{F}, \\quad [D] = \\text{дптр} = \\text{м}^{-1}$$

' + + '

Положительная для собирающей, отрицательная для рассеивающей.

'); + + html += makeCard('rule', 'Формула линзы и увеличение', '§ 21.2', + '

Формула тонкой линзы:

' + + '

$$\\dfrac{1}{d} + \\dfrac{1}{f} = \\dfrac{1}{F}$$

' + + '

где $d$ — расстояние до объекта, $f$ — до изображения, $F$ — фокусное.

' + + '

Линейное увеличение:

' + + '

$$\\Gamma = \\dfrac{h_{изобр}}{h_{объект}} = -\\dfrac{f}{d}$$

' + + '

Знаки: $f > 0$ — изображение действительное (за линзой); $f < 0$ — мнимое (с той же стороны, что и объект). $\\Gamma < 0$ — перевёрнутое, $\\Gamma > 0$ — прямое.

'); + + html += makeCard('algo', 'Построение изображения — характерные лучи', '§ 21.3', + '

От верха объекта проводят два из трёх лучей:

' + + '
    ' + + '
  1. Параллельный главной оси — после линзы идёт через дальний фокус $F$.
  2. ' + + '
  3. Через оптический центр $O$ — проходит без преломления (прямо).
  4. ' + + '
  5. Через ближний фокус — после линзы выходит параллельно оси.
  6. ' + + '
' + + '

Пересечение лучей — изображение верха объекта. Достаточно двух любых.

' + + '

Для рассеивающей линзы: лучи расходятся; изображение строится продолжением расходящихся лучей назад (всегда мнимое, прямое, уменьшенное).

'); + + html += '
Интерактив 1Тонкая линза — построение
' + + '
Меняй $F$ и $d$, переключай тип линзы. Зелёный — параллельный луч, синий — через центр $O$. Коричневая стрелка — изображение (пунктир = мнимое).
' + + '
' + + '
'; + + html += '
Инт. 2Формула линзы — расчёты
' + + '
$1/d + 1/f = 1/F$. Решено: 0 / 5.
' + + '
'; + + html += '
Инт. 3Теория линз
' + + '
Решено: 0 / 5.
' + + '
'; + + html += '
'; + html += readButton('p8'); + html += secNavFor('p8'); + box.innerHTML = html; + + ensureFx(()=>{ + const el = document.getElementById('fx-lens'); + const l = new PHYS.ThinLens(el, {width:640, height:300, F:70, d:160, mode:'converging'}); + const slBox = document.getElementById('fx-lens-sl'); + const slMode = ''; + const slF = PHYS.util.slider({label:'F (px)', min:30, max:140, step:5, value:70, fmt:v=>v.toFixed(0), onChange:v=>l.setF(v)}); + const slD = PHYS.util.slider({label:'d (px)', min:30, max:280, step:10, value:160, fmt:v=>v.toFixed(0), onChange:v=>l.setD(v)}); + slBox.innerHTML = slMode + slF.html + slD.html; + document.getElementById('fx-lens-mode').addEventListener('change', e => l.setMode(e.target.value)); + slF.wire(slBox); slD.wire(slBox); + }); + + runQuizInput('i8-calc', I8_CALC_ITEMS, 18); + runQuizMC('i8-th', I8_TH_ITEMS, 14); + + const bs = loadBossState('boss-8') || { stage:0, solved:false }; + makeAndBindBoss('boss-8-slot', '8', BOSS_DEFS.b8, bs, + ()=>saveBossState('boss-8', bs), + ()=>{ bumpProgress('p8', 40); achievement('p8_done'); }); + + wireReadBtn('p8'); + renderMath(box); +} + +/* ===== §22 Фотоаппарат, проектор ===== */ +function buildP9(){ + const box = document.getElementById('p9-body'); if(!box) return; + let html = ''; + + html += makeCard('theory', 'Действительные изображения', '§ 22.1', + '

Если объект находится дальше фокуса ($d > F$), собирающая линза даёт действительное изображение — лучи реально пересекаются и его можно поймать на экран.

' + + '

Возможны три случая:

' + + '
    ' + + '
  • $d > 2F$ — изображение действительное, перевёрнутое, уменьшенное ($|\\Gamma| < 1$), находится между $F$ и $2F$ с другой стороны.
  • ' + + '
  • $d = 2F$ — действительное, перевёрнутое, равное ($|\\Gamma| = 1$), $f = 2F$.
  • ' + + '
  • $F < d < 2F$ — действительное, перевёрнутое, увеличенное ($|\\Gamma| > 1$), $f > 2F$.
  • ' + + '
'); + + html += makeCard('example', 'Фотоаппарат', '§ 22.2', + '

Фотоаппарат создаёт уменьшенное действительное изображение далёких объектов на матрице (или плёнке).

' + + '
    ' + + '
  • Объект находится далеко: $d \\gg F$. По формуле $1/f \\approx 1/F \\Rightarrow f \\approx F$.
  • ' + + '
  • Изображение в фокальной плоскости — на матрице.
  • ' + + '
  • Увеличение $|\\Gamma| = F/d \\ll 1$ — изображение уменьшенное.
  • ' + + '
  • Фокусировка — изменение расстояния между объективом и матрицей.
  • ' + + '
  • Диафрагма регулирует освещённость и глубину резкости.
  • ' + + '
' + + '

Угол поля зрения зависит от $F$: длиннофокусные («теле») — узкое поле; короткофокусные («широкоугольные») — большое.

'); + + html += makeCard('example', 'Проектор', '§ 22.3', + '

Проектор создаёт увеличенное действительное изображение слайда (или экрана LCD) на удалённом экране.

' + + '
    ' + + '
  • Объект (слайд) располагается чуть дальше $F$: $F < d < 2F$.
  • ' + + '
  • Изображение получается перевёрнутым, увеличенным — поэтому слайд вставляют «вверх ногами».
  • ' + + '
  • Увеличение $|\\Gamma| = f/d$, где $f$ — расстояние до экрана.
  • ' + + '
  • Конденсор (короткофокусная собирающая линза) равномерно освещает слайд.
  • ' + + '
' + + '

Принцип проектора используется в кинопроекторах, оверхедах, LCD-проекторах.

'); + + html += '
Интерактив 1Сценарии: фотоаппарат vs проектор
' + + '
Ползунок $d$: при $d > 2F$ — режим «фото» (уменьш.), при $F < d < 2F$ — режим «проектор» (увелич.). Смотри изменения $\\Gamma$ и $f$.
' + + '
' + + '
'; + + html += '
Инт. 2Расчёты
' + + '
Решено: 0 / 5.
' + + '
'; + + html += '
Инт. 3Узнай прибор
' + + '
Решено: 0 / 5.
' + + '
'; + + html += '
'; + html += readButton('p9'); + html += secNavFor('p9'); + box.innerHTML = html; + + ensureFx(()=>{ + const el = document.getElementById('fx-cam'); + const l = new PHYS.ThinLens(el, {width:640, height:300, F:60, d:200, mode:'converging'}); + const slBox = document.getElementById('fx-cam-sl'); + const slD = PHYS.util.slider({label:'d (px)', min:80, max:300, step:10, value:200, fmt:v=>v.toFixed(0), onChange:v=>l.setD(v)}); + const slF = PHYS.util.slider({label:'F (px)', min:30, max:120, step:5, value:60, fmt:v=>v.toFixed(0), onChange:v=>l.setF(v)}); + slBox.innerHTML = slD.html + slF.html; + slD.wire(slBox); slF.wire(slBox); + }); + + runQuizInput('i9-calc', I9_CALC_ITEMS, 18); + runQuizMC('i9-th', I9_TH_ITEMS, 14); + + const bs = loadBossState('boss-9') || { stage:0, solved:false }; + makeAndBindBoss('boss-9-slot', '9', BOSS_DEFS.b9, bs, + ()=>saveBossState('boss-9', bs), + ()=>{ bumpProgress('p9', 40); achievement('p9_done'); }); + + wireReadBtn('p9'); + renderMath(box); +} + +/* ===== §23 Угол зрения. Лупа, микроскоп, телескоп ===== */ +function buildP10(){ + const box = document.getElementById('p10-body'); if(!box) return; + let html = ''; + + html += makeCard('theory', 'Угол зрения и угловое увеличение', '§ 23.1', + '

Глаз — оптическая система с переменной аккомодацией. Видимый размер предмета определяется не его абсолютной высотой, а углом зрения $\\varphi$, под которым предмет виден из точки наблюдения.

' + + '

Минимальный угол, при котором глаз различает две точки как раздельные, $\\varphi_{мин} \\approx 1\'$ (одна угловая минута).

' + + '

Оптические приборы позволяют увеличить угол зрения и рассматривать мелкие или далёкие объекты.

' + + '

Угловое увеличение:

' + + '

$$\\Gamma = \\dfrac{\\varphi}{\\varphi_0}$$

' + + '

где $\\varphi$ — угол зрения через прибор, $\\varphi_0$ — без прибора.

' + + '

Расстояние наилучшего зрения для нормального глаза $L_0 = 25$ см.

'); + + html += makeCard('rule', 'Лупа', '§ 23.2', + '

Лупа — короткофокусная собирающая линза. Объект помещают между линзой и её фокусом: $d < F$. Тогда $f < 0$ — изображение мнимое, прямое, увеличенное (на расстоянии $L_0 = 25$ см от глаза).

' + + '

Угловое увеличение лупы:

' + + '

$$\\Gamma = \\dfrac{25 \\text{ см}}{F}$$

' + + '

Чем меньше $F$, тем больше увеличение, но и меньше поле зрения.

' + + '

Лупа $F = 5$ см даёт $\\Gamma = 5$ крат.

'); + + html += makeCard('rule', 'Микроскоп', '§ 23.3', + '

Микроскоп — двухступенчатая система:

' + + '
    ' + + '
  • Объектив (короткофокусный) даёт действительное увеличенное промежуточное изображение $A_1B_1$ за фокусом окуляра.
  • ' + + '
  • Окуляр работает как лупа, рассматривая это промежуточное изображение.
  • ' + + '
' + + '

Общее увеличение:

' + + '

$$\\Gamma_{мкс} \\approx \\Gamma_{об} \\cdot \\dfrac{25 \\text{ см}}{F_{ок}}$$

' + + '

Современные микроскопы достигают увеличений до 1000–2000 крат. Предел разрешения ограничен дифракцией: $\\sim \\lambda/2 \\approx 0{,}2$ мкм.

'); + + html += makeCard('rule', 'Телескоп (Кеплера)', '§ 23.4', + '

Телескоп Кеплера — двухступенчатая система для рассматривания удалённых объектов.

' + + '
    ' + + '
  • Лучи от далёкого объекта идут параллельно. Объектив даёт изображение $A_1B_1$ в своей фокальной плоскости.
  • ' + + '
  • Окуляр расположен так, что его передняя фокальная плоскость совпадает с задней объектива: $L = F_{об} + F_{ок}$.
  • ' + + '
  • Окуляр превращает изображение в параллельный пучок — глаз воспринимает как «бесконечно далёкое».
  • ' + + '
' + + '

Угловое увеличение:

' + + '

$$\\Gamma = \\dfrac{F_{об}}{F_{ок}}$$

' + + '

Чем больше $F_{об}$, тем больше увеличение. Изображение перевёрнутое — астрономов это не смущает.

' + + '

В зрительной трубе (Галилея) окуляр — рассеивающая линза, изображение прямое.

'); + + html += '
Интерактив 1Двойная оптическая система
' + + '
Переключай режим: микроскоп (короткий объектив + лупа-окуляр) или телескоп (длинный объектив + короткий окуляр). Меняй $F_1, F_2$ — наблюдай ход лучей.
' + + '
' + + '
'; + + html += '
Инт. 2Расчёты увеличений
' + + '
Решено: 0 / 5.
' + + '
'; + + html += '
Инт. 3Узнай прибор
' + + '
Решено: 0 / 5.
' + + '
'; + + html += '
'; + html += readButton('p10'); + html += secNavFor('p10'); + box.innerHTML = html; + + ensureFx(()=>{ + const el = document.getElementById('fx-tel'); + const t = new PHYS.TwoLensSystem(el, {width:700, height:280, F1:120, F2:40, L:200, mode:'telescope'}); + const slBox = document.getElementById('fx-tel-sl'); + const slMode = ''; + const slF1 = PHYS.util.slider({label:'F₁ (объектив)', min:30, max:200, step:5, value:120, fmt:v=>v.toFixed(0), onChange:v=>t.setF1(v)}); + const slF2 = PHYS.util.slider({label:'F₂ (окуляр)', min:20, max:100, step:5, value:40, fmt:v=>v.toFixed(0), onChange:v=>t.setF2(v)}); + slBox.innerHTML = slMode + slF1.html + slF2.html; + document.getElementById('fx-tel-mode').addEventListener('change', e=>{ + t.setMode(e.target.value); + if(e.target.value === 'microscope'){ t.setF1(50); t.setF2(80); t.setL(280); } + else { t.setF1(120); t.setF2(40); t.setL(200); } + }); + slF1.wire(slBox); slF2.wire(slBox); + }); + + runQuizInput('i10-calc', I10_CALC_ITEMS, 18); + runQuizMC('i10-th', I10_TH_ITEMS, 14); + + const bs = loadBossState('boss-10') || { stage:0, solved:false }; + makeAndBindBoss('boss-10-slot', '10', BOSS_DEFS.b10, bs, + ()=>saveBossState('boss-10', bs), + ()=>{ bumpProgress('p10', 40); achievement('p10_done'); }); + + wireReadBtn('p10'); + renderMath(box); +} + +/* ===== Финал главы 3 — 5 интегрированных боссов ===== */ +function buildFinal(){ + const box = document.getElementById('final-body'); if(!box) return; + let html = ''; + + html += '
' + + '
' + + '' + + '
Финал главы 3 — Оптика
' + + '
' + + '

Поздравляем! Ты добрался до финала главы об оптике. Впереди — 5 интегрированных боссов, покрывающих весь материал §14-§23: от природы света и его скорости до сложных оптических приборов.

' + + '

Каждый босс — 5 этапов. Победив всех пятерых, получишь ачивку Магистр оптики и +200 XP бонус.

' + + '

Если что-то забыл — пройди ещё раз нужный параграф через карточки слева.

' + + '
'; + + for (let i = 1; i <= 5; i++){ + html += '
'; + } + + html += ''; + + html += secNavFor('final'); + box.innerHTML = html; + + for (let i = 1; i <= 5; i++){ + const key = 'boss-final-' + i; + const bs = loadBossState(key) || { stage:0, solved:false }; + makeAndBindBoss(key+'-slot', 'final-'+i, FINAL_BOSS_DEFS['fb'+i], bs, + ()=>{ saveBossState(key, bs); checkFinalDone(); }, + ()=>{ checkFinalDone(); }); + } + + renderMath(box); +} + +function checkFinalDone(){ + let all = true; + for (let i = 1; i <= 5; i++){ + const s = loadBossState('boss-final-'+i); + if (!s || !s.solved){ all = false; break; } + } + if (all){ + const v = document.getElementById('final-victory'); if (v) v.style.display = ''; + bumpProgress('final', 100); + if (!STATE.achievements.has('ch3_master')){ + achievement('ch3_master'); + addXp(200, 'ch3-master-bonus'); + } + if (!STATE.achievements.has('ch3_done')) achievement('ch3_done'); + } +} + +/* ===== Stubs (для будущих заглушек, если понадобятся) ===== */ function buildStubP(id, label, message){ const box = document.getElementById(id + '-body'); if(!box) return; let html = '

' + label + ' — в разработке

' + message + '

'; @@ -1206,6 +1515,54 @@ const I7_TH_ITEMS = [ { q:'В радуге наблюдатель видит красный сверху, фиолетовый снизу потому что:', opts:['Красный преломляется сильнее','Фиолетовый преломляется сильнее','Цвета не отличаются','Капля поглощает синий'], correct:1, explain:'Фиолетовый ($\\lambda<$) преломляется сильнее.' } ]; +const I8_CALC_ITEMS = [ + { q:'$F = 0{,}25$ м. $D$ (дптр)?', answer:'4', explain:'$D = 1/F = 1/0{,}25 = 4$ дптр.' }, + { q:'$D = -2$ дптр. $F$ (м)?', answer:['-0.5','-1/2'], explain:'$F = 1/D = -0{,}5$ м (рассеивающая).' }, + { q:'$F = 10$ см, $d = 15$ см. $f$ (см)?', answer:'30', explain:'$1/f = 1/10 - 1/15 = 1/30$.' }, + { q:'$F = 20$ см, $d = 60$ см. $\\Gamma$?', answer:['-0.5','-1/2'], explain:'$f = 30$ см; $\\Gamma = -30/60 = -0{,}5$.' }, + { q:'$F = 15$ см, $d = 10$ см (лупа). $f$ (см)?', answer:['-30','-30см'], explain:'$1/f = 1/15 - 1/10 = -1/30$, мнимое.' } +]; + +const I8_TH_ITEMS = [ + { q:'Собирающая линза имеет $F$:', opts:['$F < 0$','$F > 0$','$F = 0$','$F = \\infty$'], correct:1, explain:'$F > 0$.' }, + { q:'Рассеивающая линза даёт изображение:', opts:['Действ. перевёрнут.','Мнимое прямое уменьшен.','Действ. увеличен.','Равное'], correct:1, explain:'Всегда мнимое, прямое, уменьшенное.' }, + { q:'Луч через оптический центр:', opts:['Преломляется','Идёт без преломления','Поглощается','Удваивается'], correct:1, explain:'Через $O$ — прямо.' }, + { q:'Оптическая сила измеряется в:', opts:['Дж','Н/м','Дптр (м⁻¹)','Гц'], correct:2, explain:'Дптр = м⁻¹.' }, + { q:'$\\Gamma < 0$ означает:', opts:['Прямое','Перевёрнутое','Без увеличения','Мнимое'], correct:1, explain:'Минус = перевёрнутое.' } +]; + +const I9_CALC_ITEMS = [ + { q:'$F = 5$ см, $d = 5$ м. $f$ ≈ (см)?', answer:'5', explain:'При $d \\gg F$: $f \\approx F = 5$ см (фото).' }, + { q:'$F = 10$ см, $d = 15$ см (проектор). $\\Gamma$?', answer:'-2', explain:'$f = 30$ см, $\\Gamma = -30/15 = -2$.' }, + { q:'Слайд 5×5 см на проектор. Экран на 5 м. $F = 10$ см. Изображение (см)?', answer:['250','2.5м','250см'], explain:'$\\Gamma \\approx f/d \\approx 500/10 = 50$; изобр. 5×50 = 250 см.' }, + { q:'$d = 2F = 20$ см. $f$ (см)?', answer:'20', explain:'$f = 2F = 20$.' }, + { q:'Фотокамера $F = 50$ мм, объект на 2 м. $f$ (мм)?', answer:['51','51.3','51мм'], explain:'$1/f = 1/50 - 1/2000 \\approx 1/51{,}3$.' } +]; + +const I9_TH_ITEMS = [ + { q:'В фотоаппарате слайд (объект) находится на расстоянии:', opts:['$d < F$','$F < d < 2F$','$d > 2F$','$d = F$'], correct:2, explain:'$d \\gg F$.' }, + { q:'В проекторе:', opts:['$d > 2F$','$F < d < 2F$','$d < F$','$d = F$'], correct:1, explain:'Чтобы получить увелич. изобр.' }, + { q:'Изображение на матрице фотоаппарата:', opts:['Прямое увелич.','Перевёрнут. уменьш.','Мнимое','Не образуется'], correct:1, explain:'Действ. перевёрн. уменьш.' }, + { q:'Слайды в проекторе вставляют:', opts:['Прямо','Вверх ногами','Боком','Любо'], correct:1, explain:'Изобр. перевёрнутое.' }, + { q:'Чем короче $F$ объектива, тем поле зрения:', opts:['Уже','Шире','Не меняется','Исчезает'], correct:1, explain:'Широкоугольный объектив.' } +]; + +const I10_CALC_ITEMS = [ + { q:'Лупа $F = 5$ см. $\\Gamma$?', answer:'5', explain:'$\\Gamma = 25/5 = 5$.' }, + { q:'Лупа $\\Gamma = 10$. $F$ (см)?', answer:'2.5', explain:'$F = 25/10 = 2{,}5$ см.' }, + { q:'Микроскоп: $\\Gamma_{об} = 40$, $F_{ок} = 2{,}5$ см. $\\Gamma_{мкс}$?', answer:'400', explain:'$40 \\cdot 25/2{,}5 = 400$.' }, + { q:'Телескоп $F_{об} = 1$ м, $F_{ок} = 2$ см. $\\Gamma$?', answer:'50', explain:'$\\Gamma = 100/2 = 50$.' }, + { q:'Расстояние между линзами телескопа: $F_{об}=80$, $F_{ок}=20$ (мм). $L$ (мм)?', answer:'100', explain:'$L = F_{об} + F_{ок} = 100$ мм.' } +]; + +const I10_TH_ITEMS = [ + { q:'Угол зрения — это:', opts:['Размер объекта','Угол под которым виден объект','Угол падения','Угол отражения'], correct:1, explain:'Углов. размер.' }, + { q:'Расстояние наилучшего зрения:', opts:['10 см','25 см','50 см','1 м'], correct:1, explain:'$L_0 = 25$ см.' }, + { q:'Лупа использует:', opts:['Рассеивающую линзу','Короткофокусную собирающую','Зеркало','Призму'], correct:1, explain:'Собирающая, $d < F$.' }, + { q:'В телескопе Кеплера окуляр:', opts:['Собирающая','Рассеивающая','Зеркало','Без линзы'], correct:0, explain:'Собирающая.' }, + { q:'Изображение в астрономич. телескопе:', opts:['Прямое','Перевёрнутое','Боком'], correct:1, explain:'Перевёрнутое.' } +]; + /* ===== Boss defs ===== */ const BOSS_DEFS = { b1: { title:'Босс §14 — Скорость света', tag:'§14', xp:65, stages:[ @@ -1256,6 +1613,65 @@ const BOSS_DEFS = { { q:'$n_{серд}=1{,}5$, $n_{обол}=1{,}4$. $\\sin\\alpha_{кр}$?', type:'input', a:['0.933','14/15','0.93'], explain:'$1{,}4/1{,}5 \\approx 0{,}933$.' }, { q:'Плоскопараллельная пластинка ... луч:', type:'mc', opts:['Поворачивает на 90°','Смещает параллельно','Поглощает','Разлагает в спектр'], correct:1, explain:'Параллельное смещение.' }, { q:'Оптоволокно использует:', type:'mc', opts:['Поляризацию','Полное внутр. отражение','Дифракцию','Радугу'], correct:1, explain:'ПВО в сердцевине.' } + ]}, + b8: { title:'Босс §21 — Тонкая линза', tag:'§21', xp:80, stages:[ + { q:'Формула тонкой линзы:', type:'mc', opts:['$1/d + 1/f = 1/F$','$d + f = F$','$d \\cdot f = F$','$d - f = F$'], correct:0, explain:'Формула линзы.' }, + { q:'$F = 0{,}5$ м. $D$ (дптр)?', type:'input', a:'2', explain:'$1/0{,}5 = 2$.' }, + { q:'$D = -4$ дптр — линза:', type:'mc', opts:['Собирающая','Рассеивающая','Плоская','Не существует'], correct:1, explain:'$D < 0$ — рассеивающая.' }, + { q:'$F=20$ см, $d=30$ см. $f$ (см)?', type:'input', a:'60', explain:'$1/f = 1/20 - 1/30 = 1/60$.' }, + { q:'Луч через оптический центр $O$:', type:'mc', opts:['Преломляется','Идёт без преломления','Отражается','Поглощается'], correct:1, explain:'Через $O$ прямо.' } + ]}, + b9: { title:'Босс §22 — Фотоаппарат, проектор', tag:'§22', xp:80, stages:[ + { q:'В фотокамере объект на расстоянии:', type:'mc', opts:['$d < F$','$F < d < 2F$','$d > 2F$','$d = F$'], correct:2, explain:'Далеко.' }, + { q:'$F = 50$ мм, $d = \\infty$. $f \\approx$ (мм)?', type:'input', a:'50', explain:'$f \\approx F$.' }, + { q:'В проекторе слайд вставляют:', type:'mc', opts:['Прямо','Вверх ногами','Боком'], correct:1, explain:'Изобр. перевёрнутое.' }, + { q:'$d = 2F$ — изображение:', type:'mc', opts:['Уменьшенное','Равное','Увеличенное','Мнимое'], correct:1, explain:'$f = 2F$, $|\\Gamma| = 1$.' }, + { q:'$F=10$ см, $d=12$ см. $|\\Gamma|$?', type:'input', a:['5','5.0'], explain:'$f = 60$, $\\Gamma = -5$.' } + ]}, + b10: { title:'Босс §23 — Оптические приборы', tag:'§23', xp:80, stages:[ + { q:'Лупа $F = 5$ см. $\\Gamma$?', type:'input', a:'5', explain:'$25/5 = 5$.' }, + { q:'Телескоп: $\\Gamma = ?$', type:'mc', opts:['$F_{ок}/F_{об}$','$F_{об}/F_{ок}$','$F_{об} \\cdot F_{ок}$','$F_{об}+F_{ок}$'], correct:1, explain:'$\\Gamma = F_{об}/F_{ок}$.' }, + { q:'Микроскоп: $\\Gamma_{об} = 20$, $F_{ок} = 5$ см. $\\Gamma_{мкс}$?', type:'input', a:'100', explain:'$20 \\cdot 25/5 = 100$.' }, + { q:'Расстояние наилучшего зрения (см)?', type:'input', a:'25', explain:'$L_0 = 25$ см.' }, + { q:'В телескопе Кеплера расстояние между линзами:', type:'mc', opts:['$F_{об} - F_{ок}$','$F_{об} + F_{ок}$','$F_{об} \\cdot F_{ок}$','любое'], correct:1, explain:'Фокусы совпадают.' } + ]} +}; + +const FINAL_BOSS_DEFS = { + fb1: { title:'Финал §14–§16 — Свет и его свойства', tag:'Финал I', xp:50, stages:[ + { q:'$c$ в вакууме (м/с)?', type:'input', a:['3e8','3·10⁸','300000000','3*10^8'], explain:'$3 \\cdot 10^8$.' }, + { q:'Условие max интерференции:', type:'mc', opts:['$\\Delta = k\\lambda$','$\\Delta = (2k+1)\\lambda/2$','$\\Delta = 0$ всегда','$\\Delta = \\lambda^2$'], correct:0, explain:'$\\Delta = k\\lambda$.' }, + { q:'$d = 2$ мкм, $\\lambda = 500$ нм, $k = 1$. $\\sin\\varphi$?', type:'input', a:'0.25', explain:'$500/2000 = 0{,}25$.' }, + { q:'Дифракция — это:', type:'mc', opts:['Отражение','Огибание препятствий','Преломление','Поглощение'], correct:1, explain:'Огибание препятствий.' }, + { q:'Свет в стекле $n = 1{,}5$. $v$ (м/с)?', type:'input', a:['2e8','2·10⁸','200000000'], explain:'$v = c/n = 2 \\cdot 10^8$.' } + ]}, + fb2: { title:'Финал §17–§19 — Зеркала и преломление', tag:'Финал II', xp:50, stages:[ + { q:'Закон отражения:', type:'mc', opts:['$\\angle_п=\\angle_о$','$\\angle_п>\\angle_о$','$\\angle_п<\\angle_о$','Не связаны'], correct:0, explain:'Равны.' }, + { q:'Сферич. зеркало: $R = 40$ см. $F$ (см)?', type:'input', a:'20', explain:'$R/2 = 20$.' }, + { q:'$n_1\\sin\\alpha = ?$', type:'mc', opts:['$n_2\\sin\\beta$','$n_2\\cos\\beta$','$n_2$','$\\sin\\beta$'], correct:0, explain:'Снелл.' }, + { q:'Вода $n=1{,}33$. $\\sin\\alpha_{кр}$?', type:'input', a:['0.75','3/4'], explain:'$1/1{,}33 \\approx 0{,}75$.' }, + { q:'Изображение в плоском зеркале:', type:'mc', opts:['Действ. перевёрнутое','Мнимое прямое равное','Уменьшенное','Увеличенное'], correct:1, explain:'Мнимое прямое равное.' } + ]}, + fb3: { title:'Финал §20–§21 — Призма, линза', tag:'Финал III', xp:50, stages:[ + { q:'Дисперсия — это:', type:'mc', opts:['Отражение','$n = n(\\lambda)$','Дифракция','Поляризация'], correct:1, explain:'Зависимость $n$ от $\\lambda$.' }, + { q:'Оптоволокно работает на:', type:'mc', opts:['Дисперсии','Интерференции','ПВО','Поляризации'], correct:2, explain:'Полное внутреннее отражение.' }, + { q:'$F = 0{,}25$ м. $D$ (дптр)?', type:'input', a:'4', explain:'$1/F = 4$.' }, + { q:'Рассеивающая линза имеет:', type:'mc', opts:['$F > 0$','$F < 0$','$F = 0$','$F = \\infty$'], correct:1, explain:'Отрицательное $F$.' }, + { q:'$F = 10$ см, $d = 30$ см. $\\Gamma$?', type:'input', a:['-0.5','-1/2'], explain:'$f = 15$, $-15/30$.' } + ]}, + fb4: { title:'Финал §22 — Фотоаппарат, проектор', tag:'Финал IV', xp:50, stages:[ + { q:'В фотокамере $d$:', type:'mc', opts:['$< F$','$F < d < 2F$','$> 2F$'], correct:2, explain:'Далеко.' }, + { q:'В проекторе $d$:', type:'mc', opts:['$< F$','$F < d < 2F$','$> 2F$'], correct:1, explain:'Между $F$ и $2F$.' }, + { q:'$F = 50$ мм, объект на 1 м. $f$ ≈ (мм)?', type:'input', a:['52.6','53','52'], explain:'$1/f = 1/50 - 1/1000 = 19/1000 \\Rightarrow f \\approx 52{,}6$.' }, + { q:'Изображение в проекторе:', type:'mc', opts:['Прямое','Перевёрнутое','Мнимое','Уменьшенное'], correct:1, explain:'Действ. перевёрн. увеличенное.' }, + { q:'$d = 15$ см, $F = 10$ см. $|\\Gamma|$?', type:'input', a:'2', explain:'$f = 30$, $|\\Gamma| = 2$.' } + ]}, + fb5: { title:'Финал §23 — Лупа, микроскоп, телескоп', tag:'Финал V', xp:50, stages:[ + { q:'$L_0$ — расстояние наилучшего зрения (см)?', type:'input', a:'25', explain:'25 см.' }, + { q:'Лупа $\\Gamma = 25/F$. $F = 2{,}5$ см. $\\Gamma$?', type:'input', a:'10', explain:'$25/2{,}5 = 10$.' }, + { q:'Телескоп: $\\Gamma = ?$', type:'mc', opts:['$F_{об}/F_{ок}$','$F_{ок}/F_{об}$','$F_{об}+F_{ок}$','$F_{об}\\cdot F_{ок}$'], correct:0, explain:'$\\Gamma = F_{об}/F_{ок}$.' }, + { q:'$F_{об} = 1{,}5$ м, $F_{ок} = 3$ см. $\\Gamma$?', type:'input', a:'50', explain:'$150/3 = 50$.' }, + { q:'Микроскоп: $\\Gamma_{об}=25$, $F_{ок}=5$ см. $\\Gamma$ всего?', type:'input', a:'125', explain:'$25 \\cdot 25/5 = 125$.' } ]} };