feat(phys11 ch3): Wave 6 — §18-§20 + phys-fx SphericalMirror/RefractionLab/PrismSpectrum

- phys-fx.js: PHYS.SphericalMirror (вогнутые/выпуклые с формулой и 3 лучами), PHYS.RefractionLab (закон Снелла + ПВО), PHYS.PrismSpectrum (дисперсия, 7 цветов через модель Коши)
- §18: сферические зеркала, формула 1/d + 1/f = 1/F, увеличение Γ = -f/d, построение
- §19: показатель преломления n=c/v, закон Снелла, полное внутр. отражение
- §20: призма + дисперсия, плоскопараллельная пластинка, оптоволокно
- 6 квизов (I5-I7 CALC/TH) + 3 босса (b5-b7)
- §21-§23 + Final остаются заглушками для W7
This commit is contained in:
Maxim Dolgolyov
2026-05-29 18:41:51 +03:00
parent a5ffc624cf
commit 27a67d0866
2 changed files with 605 additions and 13 deletions
+309 -13
View File
@@ -229,9 +229,9 @@ const PARAS = [
{ id:'p2', num:'§ 15', name:'Интерференция', sub:'$\\Delta = k\\lambda$', built:true },
{ id:'p3', num:'§ 16', name:'Дифракция', sub:'$d\\sin\\varphi = k\\lambda$', built:true },
{ id:'p4', num:'§ 17', name:'Отражение, зеркала', sub:'$\\angle_{пад} = \\angle_{отр}$', built:true },
{ id:'p5', num:'§ 18', name:'Сферические зеркала', sub:'Будет в W6', built:false },
{ id:'p6', num:'§ 19', name:'Преломление', sub:'Будет в W6', built:false },
{ id:'p7', num:'§ 20', name:'Опт. элементы', sub:'Будет в W6', built:false },
{ 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 },
@@ -247,6 +247,9 @@ const ACH_LABELS = {
p2_done:'§15 — интерференция освоена',
p3_done:'§16 — дифракция освоена',
p4_done:'§17 — отражение и зеркала освоены',
p5_done:'§18 — сферические зеркала освоены',
p6_done:'§19 — закон Снелла освоен',
p7_done:'§20 — призма и оптоволокно освоены',
start:'Начало главы 3!',
ch3_done:'Глава 3 пройдена — Оптика!'
};
@@ -329,9 +332,7 @@ function buildParaSelector(){
const BUILT=new Set();
const BUILDERS = {
p1:()=>buildP1(), p2:()=>buildP2(), p3:()=>buildP3(), p4:()=>buildP4(),
p5:()=>buildStubP('p5','§ 18','§18 в разработке (W6) — вогнутые и выпуклые сферические зеркала, фокус $F = R/2$, построение изображений.'),
p6:()=>buildStubP('p6','§ 19','§19 в разработке (W6) — закон Снелла $n_1\\sin\\alpha = n_2\\sin\\beta$, полное внутреннее отражение.'),
p7:()=>buildStubP('p7','§ 20','§20 в разработке (W6) — призмы, плоскопараллельные пластинки, оптоволокно.'),
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) — лупа, микроскоп, телескоп.'),
@@ -355,9 +356,9 @@ const SIDEBARS = {
p2:{title:'Шпаргалка § 15', rows:[['Условие max','$\\Delta = k\\lambda$'],['Условие min','$\\Delta = (2k+1)\\lambda/2$'],['Когерентность','$\\omega$ и $\\Delta\\varphi$ = const'],['Опыт Юнга','2 щели → полосы'],['Кольца Ньютона','тонкие плёнки']]},
p3:{title:'Шпаргалка § 16', rows:[['Гюйгенс','каждая точка фронта — источник'],['Френель','+ интерференция вторичных'],['Решётка','$d\\sin\\varphi = k\\lambda$'],['$k$','порядок'],['$d$','период решётки']]},
p4:{title:'Шпаргалка § 17', rows:[['Прямолинейное','тени'],['Закон отражения','$\\angle_{пад} = \\angle_{отр}$'],['Плоское зеркало','мнимое, прямое, равное'],['Симметрия','$d_{объект} = d_{изобр}$ от зеркала']]},
p5:{title:'§ 18', rows:[['Тема','Сферические зеркала'],['Статус','В разработке (W6)']]},
p6:{title:'§ 19', rows:[['Тема','Преломление'],['Статус','В разработке (W6)']]},
p7:{title:'§ 20', rows:[['Тема','Опт. элементы'],['Статус','В разработке (W6)']]},
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)']]},
@@ -369,9 +370,9 @@ const TIPS=[
{sec:'p2',html:'§ 15 — интерференция = наложение когерентных волн. Условие max: $\\Delta = k\\lambda$. Опыт Юнга с двумя щелями.'},
{sec:'p3',html:'§ 16 — двигай $d$ и $\\lambda$. Чем меньше $d$, тем шире разлёт спектров. Главный max — $k=0$ (прямо).'},
{sec:'p4',html:'§ 17 — закон отражения: угол падения = углу отражения. Изображение в плоском зеркале — мнимое, симметричное.'},
{sec:'p5',html:'§ 18 — в разработке (W6).'},
{sec:'p6',html:'§ 19 — в разработке (W6).'},
{sec:'p7',html:'§ 20 — в разработке (W6).'},
{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).'},
@@ -777,7 +778,233 @@ function buildP4(){
renderMath(box);
}
/* ===== Stubs §18-§23 + Final ===== */
/* ===== §18 Сферические зеркала ===== */
function buildP5(){
const box = document.getElementById('p5-body'); if(!box) return;
let html = '';
html += makeCard('theory', 'Сферические зеркала', '§ 18.1',
'<p><b>Сферическое зеркало</b> — отполированная часть сферической поверхности. Бывают двух типов:</p>'
+ '<ul>'
+ '<li><b>Вогнутое</b> (собирающее) — отражающая поверхность с внутренней стороны сферы.</li>'
+ '<li><b>Выпуклое</b> (рассеивающее) — отражающая поверхность с наружной стороны.</li>'
+ '</ul>'
+ '<p>Основные точки зеркала: <b>оптический центр</b> $O$ (середина зеркала), <b>центр сферы</b> $C$, <b>главный фокус</b> $F$. Прямая, проходящая через $O$ и $C$, — <b>главная оптическая ось</b>.</p>'
+ '<p><b>Главный фокус</b> $F$ — точка, в которой пересекаются (или кажутся пересекающимися) отражённые лучи, параллельные главной оси.</p>'
+ '<p style="text-align:center;margin:8px 0">$$F = \\dfrac{R}{2}$$</p>'
+ '<p>где $R$ — радиус кривизны зеркала. Для выпуклого зеркала $F < 0$ (мнимый фокус).</p>');
html += makeCard('rule', 'Формула зеркала и увеличение', '§ 18.2',
'<p><b>Формула сферического зеркала</b> связывает расстояние до объекта $d$, расстояние до изображения $f$ и фокусное расстояние $F$:</p>'
+ '<p style="text-align:center;margin:8px 0">$$\\dfrac{1}{d} + \\dfrac{1}{f} = \\dfrac{1}{F}$$</p>'
+ '<p><b>Линейное увеличение</b>:</p>'
+ '<p style="text-align:center;margin:8px 0">$$\\Gamma = \\dfrac{h_{изобр}}{h_{объект}} = -\\dfrac{f}{d}$$</p>'
+ '<p><b>Знаки:</b></p>'
+ '<ul>'
+ '<li>$f > 0$ — действительное изображение (перед зеркалом).</li>'
+ '<li>$f < 0$ — мнимое (за зеркалом).</li>'
+ '<li>$\\Gamma < 0$ — перевёрнутое; $\\Gamma > 0$ — прямое.</li>'
+ '</ul>');
html += makeCard('algo', 'Построение изображения — 3 луча', '§ 18.3',
'<p>Чтобы найти изображение объекта в сферическом зеркале, используют <b>три характерных луча</b> от верхней точки объекта:</p>'
+ '<ol>'
+ '<li><b>Параллельный главной оси</b> → отражается через фокус $F$.</li>'
+ '<li><b>Через фокус $F$</b> → отражается параллельно главной оси.</li>'
+ '<li><b>Через центр сферы $C$</b> → отражается обратно по тому же пути (нормаль к поверхности).</li>'
+ '</ol>'
+ '<p>Точка пересечения отражённых лучей — изображение верха объекта. Достаточно <b>двух</b> любых из трёх лучей.</p>');
html += '<div class="wg"><div class="wg-header"><span class="wg-badge">Интерактив 1</span><span class="wg-title">Сферическое зеркало — построение</span></div>'
+ '<div class="wg-help">Двигай ползунки: <b>F</b> — фокусное расстояние, <b>d</b> — расстояние до объекта. Переключай тип зеркала. Зелёный луч — параллельный, синий — через фокус. Тёмно-коричневая стрелка — изображение (пунктир = мнимое).</div>'
+ '<div class="fx-holder" id="fx-mir2"></div>'
+ '<div class="fx-sliders" id="fx-mir2-sl"></div></div>';
html += '<div class="wg"><div class="wg-header"><span class="wg-badge">Инт. 2</span><span class="wg-title">Формула зеркала</span></div>'
+ '<div class="wg-help">$1/d + 1/f = 1/F$. Решено: <b id="i5-calc-score">0</b> / 5.</div>'
+ '<div id="i5-calc-q" style="margin:8px 0"></div><div class="actions"><input class="tinp" id="i5-calc-inp" placeholder="ответ"><button class="btn primary" id="i5-calc-go">Проверить</button></div><div class="feedback" id="i5-calc-fb"></div></div>';
html += '<div class="wg"><div class="wg-header"><span class="wg-badge">Инт. 3</span><span class="wg-title">Теория сферических зеркал</span></div>'
+ '<div class="wg-help">Решено: <b id="i5-th-score">0</b> / 5.</div>'
+ '<div id="i5-th-q" style="margin:8px 0"></div><div class="opts-row" id="i5-th-opts"></div><div class="feedback" id="i5-th-fb"></div></div>';
html += '<div id="boss-5-slot"></div>';
html += readButton('p5');
html += secNavFor('p5');
box.innerHTML = html;
ensureFx(()=>{
const el = document.getElementById('fx-mir2');
const m = new PHYS.SphericalMirror(el, {width:620, height:280, F:80, d:180, objH:50, mode:'concave'});
const slBox = document.getElementById('fx-mir2-sl');
const slMode = '<label style="display:flex;align-items:center;gap:8px;font-size:.82rem;color:#475569;font-weight:600;margin:4px 8px">'
+ '<span style="min-width:90px">Тип зеркала</span>'
+ '<select id="fx-mir2-mode" style="flex:1;padding:4px 8px;border:1px solid #cbd5e1;border-radius:6px;font-family:inherit">'
+ '<option value="concave">Вогнутое</option><option value="convex">Выпуклое</option>'
+ '</select></label>';
const slF = PHYS.util.slider({label:'F (px)', min:30, max:140, step:5, value:80, fmt:v=>v.toFixed(0), onChange:v=>m.setF(v)});
const slD = PHYS.util.slider({label:'d (px)', min:40, max:280, step:10, value:180, fmt:v=>v.toFixed(0), onChange:v=>m.setD(v)});
slBox.innerHTML = slMode + slF.html + slD.html;
document.getElementById('fx-mir2-mode').addEventListener('change', e => m.setMode(e.target.value));
slF.wire(slBox); slD.wire(slBox);
});
runQuizInput('i5-calc', I5_CALC_ITEMS, 16);
runQuizMC('i5-th', I5_TH_ITEMS, 12);
const bs = loadBossState('boss-5') || { stage:0, solved:false };
makeAndBindBoss('boss-5-slot', '5', BOSS_DEFS.b5, bs,
()=>saveBossState('boss-5', bs),
()=>{ bumpProgress('p5', 40); achievement('p5_done'); });
wireReadBtn('p5');
renderMath(box);
}
/* ===== §19 Преломление света ===== */
function buildP6(){
const box = document.getElementById('p6-body'); if(!box) return;
let html = '';
html += makeCard('theory', 'Показатель преломления', '§ 19.1',
'<p>При переходе света из одной прозрачной среды в другую на границе луч <b>преломляется</b> — изменяет направление. Причина — разная скорость света в средах.</p>'
+ '<p><b>Абсолютный показатель преломления</b> среды:</p>'
+ '<p style="text-align:center;margin:8px 0">$$n = \\dfrac{c}{v}$$</p>'
+ '<p>где $c$ — скорость света в вакууме, $v$ — в данной среде. Поскольку $v < c$, всегда $n > 1$.</p>'
+ '<p><b>Типичные значения:</b> воздух $\\approx 1{,}00$ (≈ вакуум), вода 1,33, стекло 1,5, алмаз 2,42.</p>'
+ '<p><b>Относительный показатель</b> для перехода из среды 1 в среду 2:</p>'
+ '<p style="text-align:center;margin:6px 0">$$n_{21} = \\dfrac{n_2}{n_1} = \\dfrac{v_1}{v_2}$$</p>');
html += makeCard('rule', 'Закон преломления (Снелл)', '§ 19.2',
'<p><b>Закон преломления света (Снелла – Декарта):</b></p>'
+ '<ol>'
+ '<li>Луч падающий, преломлённый и нормаль к границе в точке падения лежат в одной плоскости.</li>'
+ '<li>Отношение синуса угла падения к синусу угла преломления равно отношению показателей преломления:</li>'
+ '</ol>'
+ '<p style="text-align:center;margin:8px 0">$$n_1 \\sin\\alpha = n_2 \\sin\\beta$$</p>'
+ '<p>или эквивалентно: $\\dfrac{\\sin\\alpha}{\\sin\\beta} = n_{21} = \\dfrac{n_2}{n_1}$.</p>'
+ '<p><b>Запоминалка:</b> луч «прижимается» к нормали при переходе в более плотную среду ($n_2 > n_1$ ⇒ $\\beta < \\alpha$).</p>');
html += makeCard('example', 'Полное внутреннее отражение', '§ 19.3',
'<p>Если свет идёт из более плотной среды в менее плотную ($n_1 > n_2$), угол преломления $\\beta > \\alpha$. При некотором угле падения $\\beta = 90°$ — луч скользит по границе.</p>'
+ '<p><b>Критический угол</b> $\\alpha_{кр}$ (предельный угол ПВО):</p>'
+ '<p style="text-align:center;margin:8px 0">$$\\sin\\alpha_{кр} = \\dfrac{n_2}{n_1}$$</p>'
+ '<p>При $\\alpha > \\alpha_{кр}$ преломление отсутствует — весь свет отражается обратно. Это <b>полное внутреннее отражение (ПВО)</b>.</p>'
+ '<p><b>Применения:</b> оптоволокно, перископы, бинокли, призмы оборачивающие.</p>'
+ '<p><b>Пример:</b> вода → воздух ($n_1=1{,}33$, $n_2=1$): $\\sin\\alpha_{кр} = 1/1{,}33 \\approx 0{,}75$, $\\alpha_{кр} \\approx 48{,}6°$.</p>');
html += '<div class="wg"><div class="wg-header"><span class="wg-badge">Интерактив 1</span><span class="wg-title">Лаборатория преломления</span></div>'
+ '<div class="wg-help">Меняй угол падения $\\alpha$ и показатели сред. Красный — падающий, зелёный — преломлённый, пунктир — отражённый. При $n_1 > n_2$ можно поймать полное внутреннее отражение.</div>'
+ '<div class="fx-holder" id="fx-ref"></div>'
+ '<div class="fx-sliders" id="fx-ref-sl"></div></div>';
html += '<div class="wg"><div class="wg-header"><span class="wg-badge">Инт. 2</span><span class="wg-title">Закон Снелла — расчёты</span></div>'
+ '<div class="wg-help">$n_1\\sin\\alpha = n_2\\sin\\beta$. Решено: <b id="i6-calc-score">0</b> / 5.</div>'
+ '<div id="i6-calc-q" style="margin:8px 0"></div><div class="actions"><input class="tinp" id="i6-calc-inp" placeholder="ответ"><button class="btn primary" id="i6-calc-go">Проверить</button></div><div class="feedback" id="i6-calc-fb"></div></div>';
html += '<div class="wg"><div class="wg-header"><span class="wg-badge">Инт. 3</span><span class="wg-title">Теория преломления</span></div>'
+ '<div class="wg-help">Решено: <b id="i6-th-score">0</b> / 5.</div>'
+ '<div id="i6-th-q" style="margin:8px 0"></div><div class="opts-row" id="i6-th-opts"></div><div class="feedback" id="i6-th-fb"></div></div>';
html += '<div id="boss-6-slot"></div>';
html += readButton('p6');
html += secNavFor('p6');
box.innerHTML = html;
ensureFx(()=>{
const el = document.getElementById('fx-ref');
const r = new PHYS.RefractionLab(el, {width:540, height:320, n1:1, n2:1.5, alpha:35});
const slBox = document.getElementById('fx-ref-sl');
const slA = PHYS.util.slider({label:'α (град)', min:0, max:89, step:1, value:35, fmt:v=>v.toFixed(0), onChange:v=>r.setAlpha(v)});
const slN2 = PHYS.util.slider({label:'n₂', min:0.5, max:2.5, step:0.05, value:1.5, fmt:v=>v.toFixed(2), onChange:v=>r.setN2(v)});
const slN1 = PHYS.util.slider({label:'n₁', min:1, max:2.5, step:0.05, value:1, fmt:v=>v.toFixed(2), onChange:v=>r.setN1(v)});
slBox.innerHTML = slA.html + slN1.html + slN2.html;
slA.wire(slBox); slN1.wire(slBox); slN2.wire(slBox);
});
runQuizInput('i6-calc', I6_CALC_ITEMS, 16);
runQuizMC('i6-th', I6_TH_ITEMS, 12);
const bs = loadBossState('boss-6') || { stage:0, solved:false };
makeAndBindBoss('boss-6-slot', '6', BOSS_DEFS.b6, bs,
()=>saveBossState('boss-6', bs),
()=>{ bumpProgress('p6', 40); achievement('p6_done'); });
wireReadBtn('p6');
renderMath(box);
}
/* ===== §20 Оптические элементы ===== */
function buildP7(){
const box = document.getElementById('p7-body'); if(!box) return;
let html = '';
html += makeCard('theory', 'Призма и дисперсия', '§ 20.1',
'<p><b>Призма</b> — прозрачное тело с двумя плоскими преломляющими гранями, образующими двугранный угол $A$ (преломляющий угол призмы).</p>'
+ '<p>Луч, проходя через призму, преломляется на обеих гранях и отклоняется от исходного направления на угол отклонения $\\delta$.</p>'
+ '<p><b>Дисперсия света</b> — зависимость показателя преломления от длины волны (частоты): $n = n(\\lambda)$.</p>'
+ '<p>Для большинства прозрачных сред $n$ <b>растёт с уменьшением $\\lambda$</b>: фиолетовый свет ($\\lambda\\approx 400$ нм) преломляется сильнее красного ($\\lambda\\approx 700$ нм).</p>'
+ '<p>Поэтому призма <b>разлагает белый свет в спектр</b> — Ньютон (1666).</p>'
+ '<p><b>Радуга</b> — природный пример дисперсии: капля воды работает как призма + зеркало (внутреннее отражение).</p>');
html += makeCard('rule', 'Плоскопараллельная пластинка', '§ 20.2',
'<p><b>Плоскопараллельная пластинка</b> — стекло с двумя параллельными гранями.</p>'
+ '<p>Луч, проходящий через пластинку, выходит <b>параллельно</b> падающему, но смещённым в сторону. Смещение:</p>'
+ '<p style="text-align:center;margin:8px 0">$$x = h \\cdot \\dfrac{\\sin(\\alpha - \\beta)}{\\cos\\beta}$$</p>'
+ '<p>где $h$ — толщина пластинки, $\\alpha$ — угол падения, $\\beta$ — угол преломления внутри.</p>'
+ '<p>При $\\alpha = 0$ смещения нет — луч идёт перпендикулярно.</p>');
html += makeCard('example', 'Оптоволокно — полное внутреннее отражение', '§ 20.3',
'<p><b>Оптоволокно</b> — тонкая стеклянная или пластиковая нить, передающая свет на большие расстояния благодаря многократному <b>полному внутреннему отражению</b>.</p>'
+ '<p>Строение: <b>сердцевина</b> (core) с показателем $n_1$ и <b>оболочка</b> (cladding) с $n_2 < n_1$. Свет, попавший в сердцевину под углом $\\alpha > \\alpha_{кр}$, отражается от границы без потерь и распространяется вдоль волокна.</p>'
+ '<p><b>Применения:</b></p>'
+ '<ul>'
+ '<li>Интернет и телефонная связь (магистральные сети).</li>'
+ '<li>Эндоскопы в медицине.</li>'
+ '<li>Освещение в зданиях, декоративные подсветки.</li>'
+ '</ul>'
+ '<p>Потери в современных волокнах — менее 0,2 дБ/км, что позволяет передавать сигнал на сотни километров без усиления.</p>');
html += '<div class="wg"><div class="wg-header"><span class="wg-badge">Интерактив 1</span><span class="wg-title">Призма: разложение белого света</span></div>'
+ '<div class="wg-help">Белый луч слева попадает на грань стеклянной призмы. Из-за дисперсии $n(\\lambda)$ цвета преломляются под разными углами. Двигай ползунок угла падения — наблюдай, как меняется спектр.</div>'
+ '<div class="fx-holder" id="fx-pr"></div>'
+ '<div class="fx-sliders" id="fx-pr-sl"></div></div>';
html += '<div class="wg"><div class="wg-header"><span class="wg-badge">Инт. 2</span><span class="wg-title">Расчёты — критический угол</span></div>'
+ '<div class="wg-help">$\\sin\\alpha_{кр} = n_2/n_1$ (если $n_1 > n_2$). Решено: <b id="i7-calc-score">0</b> / 5.</div>'
+ '<div id="i7-calc-q" style="margin:8px 0"></div><div class="actions"><input class="tinp" id="i7-calc-inp" placeholder="ответ"><button class="btn primary" id="i7-calc-go">Проверить</button></div><div class="feedback" id="i7-calc-fb"></div></div>';
html += '<div class="wg"><div class="wg-header"><span class="wg-badge">Инт. 3</span><span class="wg-title">Теория</span></div>'
+ '<div class="wg-help">Решено: <b id="i7-th-score">0</b> / 5.</div>'
+ '<div id="i7-th-q" style="margin:8px 0"></div><div class="opts-row" id="i7-th-opts"></div><div class="feedback" id="i7-th-fb"></div></div>';
html += '<div id="boss-7-slot"></div>';
html += readButton('p7');
html += secNavFor('p7');
box.innerHTML = html;
ensureFx(()=>{
const el = document.getElementById('fx-pr');
const p = new PHYS.PrismSpectrum(el, {width:580, height:260, alpha:50});
const slBox = document.getElementById('fx-pr-sl');
const slA = PHYS.util.slider({label:'α (град)', min:20, max:75, step:1, value:50, fmt:v=>v.toFixed(0), onChange:v=>p.setAlpha(v)});
slBox.innerHTML = slA.html;
slA.wire(slBox);
});
runQuizInput('i7-calc', I7_CALC_ITEMS, 16);
runQuizMC('i7-th', I7_TH_ITEMS, 12);
const bs = loadBossState('boss-7') || { stage:0, solved:false };
makeAndBindBoss('boss-7-slot', '7', BOSS_DEFS.b7, bs,
()=>saveBossState('boss-7', bs),
()=>{ bumpProgress('p7', 40); achievement('p7_done'); });
wireReadBtn('p7');
renderMath(box);
}
/* ===== Stubs §21-§23 + Final ===== */
function buildStubP(id, label, message){
const box = document.getElementById(id + '-body'); if(!box) return;
let html = '<div class="stub-note"><h3>' + label + ' — в разработке</h3><p>' + message + '</p></div>';
@@ -931,6 +1158,54 @@ const I4_IMG_ITEMS = [
{ q:'Угол падения отсчитывается от:', opts:['Поверхности','Нормали','Любого направления','Зеркала'], correct:1, explain:'От перпендикуляра к поверхности.' }
];
const I5_CALC_ITEMS = [
{ q:'$R = 40$ см. Фокус $F$ (см)?', answer:'20', explain:'$F = R/2 = 20$ см.' },
{ q:'$F = 10$ см, $d = 30$ см. $f$ (см)?', answer:'15', explain:'$1/f = 1/10 - 1/30 = 2/30 \\Rightarrow f = 15$ см.' },
{ q:'$F = 20$ см, $d = 60$ см. $\\Gamma$?', answer:['-0.5','-1/2'], explain:'$1/f = 1/20 - 1/60 = 1/30 \\Rightarrow 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 \\Rightarrow f = -30$ (мнимое).' },
{ q:'$d = 2F$. $f$ относительно $F$?', answer:['2f','2','2*f'], explain:'$1/f = 1/F - 1/(2F) = 1/(2F) \\Rightarrow f = 2F$.' }
];
const I5_TH_ITEMS = [
{ q:'Фокусное расстояние сферического зеркала:', opts:['$F = R$','$F = R/2$','$F = 2R$','$F = R^2$'], correct:1, explain:'$F = R/2$.' },
{ q:'Выпуклое зеркало даёт изображение:', opts:['Действительное, перевёрнутое','Мнимое, прямое, уменьшенное','Действительное, увеличенное','Точечное'], correct:1, explain:'Мнимое за зеркалом.' },
{ q:'Луч через центр сферы $C$:', opts:['Отражается обратно','Параллельно оси','Через фокус','Поглощается'], correct:0, explain:'По нормали — обратно.' },
{ q:'Если объект между $F$ и зеркалом (вогнутое), изображение:', opts:['Действительное','Мнимое, увеличенное, прямое','Уменьшенное','Не образуется'], correct:1, explain:'Лупа — мнимое прямое.' },
{ q:'$\\Gamma = -2$ означает:', opts:['Уменьшенное прямое','Увеличенное прямое','Увеличенное перевёрнутое в 2 раза','Без увеличения'], correct:2, explain:'$|\\Gamma|=2$, минус = перевёрнутое.' }
];
const I6_CALC_ITEMS = [
{ q:'$n_1 = 1$, $\\alpha = 30°$, $n_2 = 1{,}5$. $\\sin\\beta$?', answer:['1/3','0.333','0.33'], explain:'$\\sin\\beta = \\sin 30°/1{,}5 = 0{,}5/1{,}5 = 1/3$.' },
{ q:'Вода → воздух ($n_1=1{,}33$). $\\sin\\alpha_{кр}$?', answer:['0.75','3/4'], explain:'$\\sin\\alpha_{кр} = 1/1{,}33 \\approx 0{,}75$.' },
{ q:'Алмаз $n = 2{,}42$, $\\sin\\alpha_{кр}$?', answer:['0.41','0.413'], explain:'$1/2{,}42 \\approx 0{,}413$ ⇒ $\\alpha_{кр} \\approx 24{,}4°$.' },
{ q:'$n_{ст} = 1{,}5$. $v$ в стекле (м/с)?', answer:['2e8','2·10⁸','200000000'], explain:'$v = c/n = 3 \\cdot 10^8/1{,}5 = 2 \\cdot 10^8$.' },
{ q:'$\\alpha = 60°$, $n_2/n_1 = 1{,}5$. $\\sin\\beta$?', answer:['0.577','√3/3','0.58'], explain:'$\\sin\\beta = \\sin 60°/1{,}5 = (\\sqrt 3/2)/1{,}5 \\approx 0{,}577$.' }
];
const I6_TH_ITEMS = [
{ q:'Закон Снелла:', opts:['$n_1 \\sin\\alpha = n_2 \\sin\\beta$','$n_1 \\cos\\alpha = n_2 \\cos\\beta$','$n_1/\\alpha = n_2/\\beta$','$n_1 + n_2 = const$'], correct:0, explain:'Закон Снелла.' },
{ q:'$n = c/v$ означает: в среде свет идёт:', opts:['Быстрее $c$','Медленнее $c$','С такой же скоростью','Не движется'], correct:1, explain:'$v = c/n < c$ при $n>1$.' },
{ q:'ПВО возможно при переходе:', opts:['Воздух → стекло','Стекло → воздух','Вода → стекло','Никогда'], correct:1, explain:'Из более плотной в менее плотную ($n_1 > n_2$).' },
{ q:'Если $n_2 > n_1$, луч:', opts:['Прижимается к нормали','Удаляется от нормали','Идёт по оригинальному пути','Останавливается'], correct:0, explain:'$\\beta < \\alpha$ — прижимается.' },
{ q:'Палка в воде кажется сломанной из-за:', opts:['Отражения','Преломления','Дисперсии','Дифракции'], correct:1, explain:'Преломления на границе вода–воздух.' }
];
const I7_CALC_ITEMS = [
{ q:'Стекло $n = 1{,}5$, воздух $n=1$. $\\sin\\alpha_{кр}$?', answer:['0.667','2/3','0.67'], explain:'$1/1{,}5 = 2/3$.' },
{ q:'$n_{сердцевины} = 1{,}5$, $n_{оболочки} = 1{,}4$. $\\sin\\alpha_{кр}$?', answer:['0.933','14/15','0.93'], explain:'$1{,}4/1{,}5 = 14/15 \\approx 0{,}933$ ⇒ $\\alpha_{кр} \\approx 69°$.' },
{ q:'$\\alpha_{кр} = 30°$. $n_{отношение}$?', answer:'0.5', explain:'$\\sin 30° = 0{,}5 = n_2/n_1$.' },
{ q:'Толщина пластинки 4 см, $\\alpha=30°$, $\\beta = 19°$ (стекло). $x$ ≈ толщина $\\cdot \\sin(\\alpha-\\beta)/\\cos\\beta$ (см)?', answer:['0.8','0.79','0.81'], explain:'$x = 4 \\cdot \\sin 11°/\\cos 19° \\approx 4 \\cdot 0{,}19/0{,}945 \\approx 0{,}8$ см.' },
{ q:'$\\lambda_{красн} = 700$ нм отклоняется призмой <b>слабее</b> или сильнее фиолетового 400 нм?', answer:['слабее','меньше'], explain:'$n(700) < n(400)$ ⇒ красный отклоняется слабее.' }
];
const I7_TH_ITEMS = [
{ q:'Дисперсия — это:', opts:['Отражение','Зависимость $n$ от $\\lambda$','Разложение в спектр интерферометром','Дифракция в кристалле'], correct:1, explain:'$n = n(\\lambda)$.' },
{ q:'Призма разлагает белый свет потому что:', opts:['Разные $\\lambda$ имеют разные $n$','Свет частично отражается','Кристаллы поглощают','Стекло поляризует'], correct:0, explain:'Дисперсия.' },
{ q:'Плоскопараллельная пластинка:', opts:['Меняет направление луча','Смещает луч параллельно','Поглощает свет','Поворачивает поляризацию'], correct:1, explain:'Луч сдвигается, но не меняет угла.' },
{ q:'Оптоволокно работает на:', opts:['Интерференции','Дифракции','Полном внутр. отражении','Поляризации'], correct:2, explain:'ПВО внутри сердцевины.' },
{ q:'В радуге наблюдатель видит красный <b>сверху</b>, фиолетовый снизу потому что:', opts:['Красный преломляется сильнее','Фиолетовый преломляется сильнее','Цвета не отличаются','Капля поглощает синий'], correct:1, explain:'Фиолетовый ($\\lambda<$) преломляется сильнее.' }
];
/* ===== Boss defs ===== */
const BOSS_DEFS = {
b1: { title:'Босс §14 — Скорость света', tag:'§14', xp:65, stages:[
@@ -960,6 +1235,27 @@ const BOSS_DEFS = {
{ q:'Изображение в плоском зеркале:', type:'mc', opts:['Действ., перевёрнутое','Мнимое, прямое, равное','Уменьшенное','Увеличенное'], correct:1, explain:'Мнимое, прямое, равное.' },
{ q:'Объект на 3 м от зеркала. Изображение на сколько метров от объекта?', type:'input', a:'6', explain:'$d + d = 6$ м.' },
{ q:'Если повернуть зеркало на 15°, отражённый луч повернётся на:', type:'input', a:'30', explain:'$2\\alpha = 30°$.' }
]},
b5: { title:'Босс §18 — Сферические зеркала', tag:'§18', xp:75, stages:[
{ q:'$R = 60$ см. $F$ (см)?', type:'input', a:'30', explain:'$F = R/2 = 30$ см.' },
{ q:'$F=10$ см, $d=20$ см. $f$ (см)?', type:'input', a:'20', explain:'$1/f = 1/10 - 1/20 = 1/20 \\Rightarrow f = 20$.' },
{ q:'Изображение в выпуклом зеркале:', type:'mc', opts:['Действительное увеличенное','Мнимое прямое уменьшенное','Перевёрнутое','Равное'], correct:1, explain:'Всегда мнимое, прямое, уменьшенное.' },
{ q:'$\\Gamma = -f/d$. $f = 30$, $d = 15$. $\\Gamma$?', type:'input', a:['-2','-2.0'], explain:'$-30/15 = -2$.' },
{ q:'Луч через фокус $F$ после отражения идёт:', type:'mc', opts:['Через $C$','Параллельно главной оси','Обратно','Через $O$'], correct:1, explain:'Стандартный луч 2.' }
]},
b6: { title:'Босс §19 — Закон Снелла', tag:'§19', xp:75, stages:[
{ q:'$n_1\\sin\\alpha = ?$', type:'mc', opts:['$n_2\\cos\\beta$','$n_2\\sin\\beta$','$n_2/\\sin\\beta$','$\\sin\\beta/n_2$'], correct:1, explain:'Снелл.' },
{ q:'$n = c/v$. Если $n = 2$, то $v = ?$ (м/с)', type:'input', a:['1.5e8','1.5·10⁸','150000000'], explain:'$v = c/n = 1{,}5 \\cdot 10^8$.' },
{ q:'$\\sin\\alpha_{кр} = n_2/n_1$ при условии:', type:'mc', opts:['$n_1 < n_2$','$n_1 > n_2$','$n_1 = n_2$','Любое'], correct:1, explain:'ПВО только из плотной в менее плотную.' },
{ q:'$n_{вода} = 1{,}33$. $\\sin\\alpha_{кр}$ (округлить до 0,01)?', type:'input', a:['0.75','3/4'], explain:'$1/1{,}33 \\approx 0{,}75$.' },
{ q:'Луч из стекла в воздух под $\\alpha = 60°$, $n_{ст}=1{,}5$. Что произойдёт?', type:'mc', opts:['Преломится','Полное внутр. отражение','Поглотится','Удвоится'], correct:1, explain:'$\\sin 60° = 0{,}866 > 0{,}667$ ⇒ ПВО.' }
]},
b7: { title:'Босс §20 — Призма, оптоволокно', tag:'§20', xp:75, stages:[
{ q:'Призма разлагает белый свет в спектр благодаря:', type:'mc', opts:['Дифракции','Интерференции','Дисперсии','Отражению'], correct:2, explain:'Дисперсия $n(\\lambda)$.' },
{ q:'В стекле фиолетовый свет отклоняется ... красного:', type:'mc', opts:['Слабее','Сильнее','Одинаково','Не отклоняется'], correct:1, explain:'$n_{фиол} > n_{кр}$.' },
{ 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:'ПВО в сердцевине.' }
]}
};