feat(phys10 ch5 wave3): §31 «Магнитный поток + ЭМИ» + §32 «Ленц + Фарадей»
This commit is contained in:
@@ -2122,34 +2122,752 @@ function build_p30(){
|
||||
function build_p31(){
|
||||
const box = document.getElementById('p31-body');
|
||||
let html = '';
|
||||
html += makeCard('theory', "Магнитный поток. Электромагнитная индукция", "§31", `
|
||||
<p><b>Магнитный поток. Электромагнитная индукция</b> — этот параграф в разработке (Phase 1+).</p>
|
||||
<p>Здесь появятся: теория, формулы, разобранные примеры и 3–4 интерактива в стиле «алгебры 11» — таблицы, симуляции, ползунки, drag-and-drop и автопроверяемые тренажёры.</p>
|
||||
<p style="margin-top:10px;padding:10px 14px;background:var(--sec-acc-soft);border-radius:9px;font-size:.92rem">
|
||||
<b>Phase 0:</b> создан скелет учебника. <b>Phase 5+:</b> наполнение этого § содержанием по учебнику «Физика 10» (Беларусь, 2019).
|
||||
</p>
|
||||
|
||||
/* THEORY 1 — Магнитный поток */
|
||||
html += makeCard('theory', "Магнитный поток", "§31", `
|
||||
<p><b>Магнитный поток</b> $\\Phi$ через плоскую площадку площадью $S$ в <b>однородном</b> магнитном поле $\\vec{B}$:</p>
|
||||
<p style="text-align:center;margin:8px 0">$$\\Phi = B\\,S\\,\\cos\\alpha$$</p>
|
||||
<p>где $\\alpha$ — угол между $\\vec{B}$ и <b>нормалью</b> $\\vec{n}$ к площадке.</p>
|
||||
<p style="margin-top:10px"><b>Единица</b>: <b>Вебер</b> (Вб) = Тл·м².</p>
|
||||
<p style="margin-top:10px"><b>Особые случаи</b>:</p>
|
||||
<ul style="margin:6px 0 6px 22px">
|
||||
<li>$\\alpha = 0°$ ($\\vec{B} \\parallel \\vec{n}$): $\\Phi_{max} = BS$.</li>
|
||||
<li>$\\alpha = 90°$ ($\\vec{B} \\perp \\vec{n}$, поле параллельно площадке): $\\Phi = 0$.</li>
|
||||
<li>$\\alpha = 180°$: $\\Phi = -BS$ (отрицательный поток).</li>
|
||||
</ul>
|
||||
<p style="margin-top:10px;padding:10px 14px;background:var(--sec-acc-soft);border-radius:9px"><b>Наглядно.</b> Можно представлять $\\Phi$ как «количество силовых линий, пронизывающих площадку».</p>
|
||||
`);
|
||||
|
||||
/* THEORY 2 — Явление электромагнитной индукции */
|
||||
html += makeCard('rule', "Явление электромагнитной индукции", "§31", `
|
||||
<p><b>Электромагнитная индукция</b> — возникновение электрического тока в замкнутом проводящем контуре при <b>изменении</b> магнитного потока через него.</p>
|
||||
<p style="margin-top:8px">Открыта <b>Майклом Фарадеем</b> в 1831 году.</p>
|
||||
<p style="margin-top:10px"><b>Главный принцип</b>: ток в контуре возникает <b>только</b> при изменении $\\Phi$, а не от самого $\\Phi$. Если магнит неподвижен в катушке — тока нет.</p>
|
||||
<p style="margin-top:10px">Возникший ток называется <b>индукционным</b>. ЭДС, которая его вызывает — <b>ЭДС индукции</b> $\\mathcal{E}_i$.</p>
|
||||
<p style="margin-top:10px;padding:10px 14px;background:var(--sec-acc-soft);border-radius:9px"><b>Ключ.</b> Чем <b>быстрее</b> меняется $\\Phi$ — тем <b>больше</b> индукционный ток.</p>
|
||||
`);
|
||||
|
||||
/* THEORY 3 — Опыты Фарадея и способы изменения Ф */
|
||||
html += makeCard('example', "Опыты Фарадея и способы изменения Ф", "§31", `
|
||||
<p><b>Классические опыты Фарадея</b>:</p>
|
||||
<ol style="margin:6px 0 6px 22px">
|
||||
<li><b>Магнит вдвигают в катушку</b> → возникает индукционный ток (одного знака).</li>
|
||||
<li><b>Магнит выдвигают</b> → ток противоположного знака.</li>
|
||||
<li><b>Магнит ближе к катушке = больше скорость изменения $\\Phi$</b> → больше ток.</li>
|
||||
<li><b>Без движения</b> — тока нет.</li>
|
||||
</ol>
|
||||
<p style="margin-top:10px"><b>Способы изменения $\\Phi$</b>:</p>
|
||||
<ul style="margin:6px 0 6px 22px">
|
||||
<li><b>Изменение $B$</b>: движение магнита, изменение тока в соседней катушке.</li>
|
||||
<li><b>Изменение $S$</b>: деформация контура, перемещение проводника-перемычки.</li>
|
||||
<li><b>Изменение $\\alpha$</b>: поворот контура в поле (основа работы генератора).</li>
|
||||
</ul>
|
||||
<p style="margin-top:10px"><b>Применение</b>:</p>
|
||||
<ul style="margin:6px 0 6px 22px">
|
||||
<li><b>Генераторы электрического тока</b> (электростанции).</li>
|
||||
<li><b>Трансформаторы</b>.</li>
|
||||
<li><b>Индукционные плиты</b>.</li>
|
||||
<li><b>Беспроводная зарядка</b> смартфонов.</li>
|
||||
<li><b>Микрофоны</b> и звукосниматели.</li>
|
||||
</ul>
|
||||
`);
|
||||
|
||||
/* INTERACTIVE 1 — Магнитный поток через рамку */
|
||||
html += `<div class="wg" id="p31-iv1">
|
||||
<div class="wg-header"><span class="wg-badge">ИНТЕРАКТИВ 1</span><div class="wg-title">Магнитный поток через рамку</div></div>
|
||||
<div class="wg-help">Меняй $B$, $S$ и угол $\\alpha$ между $\\vec{B}$ и нормалью $\\vec{n}$ к рамке. Смотри, как меняется поток $\\Phi = BS\\cos\\alpha$.</div>
|
||||
<div class="sliders">
|
||||
<label>$B$ (Тл): <b id="p31-iv1-BL">1.0</b> <input type="range" id="p31-iv1-B" min="0" max="2" value="1" step="0.05"></label>
|
||||
<label>$S$ (м²): <b id="p31-iv1-SL">0.20</b> <input type="range" id="p31-iv1-S" min="0.01" max="1" value="0.2" step="0.01"></label>
|
||||
<label>$\\alpha$ (°): <b id="p31-iv1-aL">30</b> <input type="range" id="p31-iv1-a" min="0" max="180" value="30" step="5"></label>
|
||||
</div>
|
||||
<div style="background:var(--card);border:1px solid var(--border);border-radius:9px;padding:8px">
|
||||
<svg id="p31-iv1-svg" viewBox="0 0 480 280" width="100%" style="height:auto"></svg>
|
||||
</div>
|
||||
<div id="p31-iv1-out" style="margin-top:10px;padding:10px 14px;background:var(--sec-acc-soft);border-radius:9px;font-size:.96rem;line-height:1.7;text-align:center"></div>
|
||||
</div>`;
|
||||
|
||||
/* INTERACTIVE 2 — Опыт Фарадея */
|
||||
html += `<div class="wg" id="p31-iv2">
|
||||
<div class="wg-header"><span class="wg-badge">ИНТЕРАКТИВ 2</span><div class="wg-title">Симуляция опыта Фарадея</div></div>
|
||||
<div class="wg-help">Двигай магнит к катушке и от неё. Когда поток меняется — в катушке возникает индукционный ток. Когда магнит неподвижен — тока нет.</div>
|
||||
<div class="sliders">
|
||||
<label>Положение магнита: <b id="p31-iv2-xL">−0.20</b> <input type="range" id="p31-iv2-x" min="-0.50" max="0.30" value="-0.20" step="0.01"></label>
|
||||
</div>
|
||||
<div style="background:var(--card);border:1px solid var(--border);border-radius:9px;padding:8px">
|
||||
<svg id="p31-iv2-svg" viewBox="0 0 480 280" width="100%" style="height:auto"></svg>
|
||||
</div>
|
||||
<div id="p31-iv2-out" style="margin-top:10px;padding:10px 14px;background:var(--sec-acc-soft);border-radius:9px;font-size:.96rem;line-height:1.7;text-align:center"></div>
|
||||
</div>`;
|
||||
|
||||
/* INTERACTIVE 3 — Возникает ли индукционный ток? */
|
||||
html += `<div class="wg" id="p31-iv3">
|
||||
<div class="wg-header"><span class="wg-badge">ИНТЕРАКТИВ 3</span><div class="wg-title">Возникает ли индукционный ток?</div></div>
|
||||
<div class="wg-help">6 ситуаций. Ток возникает только если меняется магнитный поток $\\Phi$ через контур.</div>
|
||||
<div class="score-display"><span>Задача <b id="p31-iv3-i">1</b> / 6</span><span>Очки: <b id="p31-iv3-s">0</b> / 6</span></div>
|
||||
<div id="p31-iv3-q" style="padding:14px;background:var(--sec-acc-soft);border-radius:10px;font-size:1.02rem;margin-bottom:10px;text-align:center;min-height:54px"></div>
|
||||
<div id="p31-iv3-opts" style="display:grid;grid-template-columns:1fr 1fr;gap:8px"></div>
|
||||
<div class="feedback" id="p31-iv3-fb"></div>
|
||||
<div class="actions"><button class="btn" id="p31-iv3-restart">Начать заново</button></div>
|
||||
</div>`;
|
||||
|
||||
/* INTERACTIVE 4 — Тренажёр */
|
||||
html += `<div class="wg" id="p31-iv4">
|
||||
<div class="wg-header"><span class="wg-badge">ИНТЕРАКТИВ 4</span><div class="wg-title">Тренажёр магнитного потока</div></div>
|
||||
<div class="wg-help">5 числовых задач. Допуск ±5%. Используй $\\Phi = BS\\cos\\alpha$.</div>
|
||||
<div class="score-display"><span>Задача <b id="p31-iv4-i">1</b> / 5</span><span>Очки: <b id="p31-iv4-s">0</b> / 5</span></div>
|
||||
<div id="p31-iv4-q" style="padding:14px;background:var(--sec-acc-soft);border-radius:10px;font-size:1.02rem;margin-bottom:10px;text-align:center;min-height:54px"></div>
|
||||
<div id="p31-iv4-form" style="display:flex;gap:8px;justify-content:center;margin-bottom:8px;flex-wrap:wrap">
|
||||
<input type="number" id="p31-iv4-inp" step="any" style="padding:8px 10px;border:1px solid var(--border);border-radius:6px;width:140px;font-size:1rem">
|
||||
<button class="btn primary" id="p31-iv4-go">Проверить</button>
|
||||
</div>
|
||||
<div class="feedback" id="p31-iv4-fb"></div>
|
||||
<div class="actions"><button class="btn" id="p31-iv4-restart">Начать заново</button></div>
|
||||
</div>`;
|
||||
|
||||
html += secNav('p30', 'p32');
|
||||
html += readButton('p31');
|
||||
|
||||
box.innerHTML = html;
|
||||
renderMath(box);
|
||||
|
||||
/* IV1 — Магнитный поток через рамку */
|
||||
(function(){
|
||||
const svg = document.getElementById('p31-iv1-svg');
|
||||
const out = document.getElementById('p31-iv1-out');
|
||||
const bS = document.getElementById('p31-iv1-B');
|
||||
const sS = document.getElementById('p31-iv1-S');
|
||||
const aS = document.getElementById('p31-iv1-a');
|
||||
const bL = document.getElementById('p31-iv1-BL');
|
||||
const sL = document.getElementById('p31-iv1-SL');
|
||||
const aL = document.getElementById('p31-iv1-aL');
|
||||
const seen = new Set();
|
||||
let _done = false;
|
||||
|
||||
function draw(){
|
||||
const W = 480, H = 280;
|
||||
const B = +bS.value, S = +sS.value, aDeg = +aS.value;
|
||||
bL.textContent = B.toFixed(2);
|
||||
sL.textContent = S.toFixed(2);
|
||||
aL.textContent = aDeg.toFixed(0);
|
||||
const alpha = aDeg * Math.PI / 180;
|
||||
const Phi = B * S * Math.cos(alpha);
|
||||
|
||||
let g = '';
|
||||
g += '<rect x="0" y="0" width="'+W+'" height="'+H+'" fill="#fafafa"/>';
|
||||
g += '<text x="240" y="22" text-anchor="middle" font-family="Inter,sans-serif" font-size="13" font-weight="700" fill="#0f172a">B вправо →. Угол между B и нормалью n = '+aDeg+'°</text>';
|
||||
|
||||
// Силовые линии поля B (горизонтальные стрелки слева → направо)
|
||||
for(let i=0;i<5;i++){
|
||||
const yL = 60 + i*40;
|
||||
g += PHYS.drawArrow(40, yL, 440, yL, '#7c3aed', 1.3, 8);
|
||||
}
|
||||
// подпись B
|
||||
g += '<text x="450" y="148" font-family="JetBrains Mono,monospace" font-size="14" font-weight="700" fill="#7c3aed">B</text>';
|
||||
|
||||
// Рамка (вид сверху, поворот вокруг вертикальной оси на угол alpha)
|
||||
// Ширина проекции рамки = w0 * |sin(alpha)| — это «как мы видим её сбоку». Но удобнее
|
||||
// показывать рамку с нормалью под углом alpha к B. Изобразим рамку как ромб (3D-проекция).
|
||||
const cx = 240, cy = 150;
|
||||
const halfW = 60; // полуширина рамки в плоскости поля
|
||||
const halfH = 50; // высота рамки (не меняется)
|
||||
// При alpha=0 рамка видна как горизонтальная линия (поток max); при alpha=90 рамка перпенд. → видна как прямоугольник
|
||||
const projW = Math.max(2, halfW * Math.abs(Math.sin(alpha)));
|
||||
// верхний и нижний край рамки — горизонтальные линии длиной 2*projW
|
||||
// боковые стороны — наклонные (для эффекта 3D)
|
||||
const xL = cx - projW, xR = cx + projW;
|
||||
// Заполнение рамки
|
||||
g += '<polygon points="'+xL.toFixed(1)+','+(cy-halfH).toFixed(1)+' '+xR.toFixed(1)+','+(cy-halfH).toFixed(1)+' '+xR.toFixed(1)+','+(cy+halfH).toFixed(1)+' '+xL.toFixed(1)+','+(cy+halfH).toFixed(1)+'" fill="rgba(8,145,178,0.13)" stroke="#0891b2" stroke-width="2.2"/>';
|
||||
// Нормаль n
|
||||
const nLen = 60;
|
||||
// Направление нормали — повёрнуто на alpha от B (B вдоль +x). Тогда n = (cos(alpha), sin(alpha)).
|
||||
const nx = cx + nLen * Math.cos(alpha);
|
||||
const ny = cy - nLen * Math.sin(alpha);
|
||||
g += PHYS.drawArrow(cx, cy, nx, ny, '#dc2626', 2.4, 11);
|
||||
g += '<text x="'+(nx+8)+'" y="'+(ny-4)+'" font-family="JetBrains Mono,monospace" font-size="13" font-weight="700" fill="#dc2626">n</text>';
|
||||
// Дуга угла между n и B (B = +x)
|
||||
const arcR = 28;
|
||||
const a1 = 0, a2 = -alpha; // угол в SVG-координатах (y вниз)
|
||||
const aStart = Math.min(a1, a2), aEnd = Math.max(a1, a2);
|
||||
g += '<path d="M '+(cx+arcR)+' '+cy+' A '+arcR+' '+arcR+' 0 0 0 '+(cx+arcR*Math.cos(a2)).toFixed(1)+' '+(cy+arcR*Math.sin(a2)).toFixed(1)+'" fill="none" stroke="#0f172a" stroke-width="1.4"/>';
|
||||
g += '<text x="'+(cx+arcR+8)+'" y="'+(cy - 4).toFixed(1)+'" font-family="JetBrains Mono,monospace" font-size="12" fill="#0f172a">α</text>';
|
||||
|
||||
// Подпись параметров рамки
|
||||
g += '<text x="240" y="248" text-anchor="middle" font-family="Inter,sans-serif" font-size="12" fill="#0f172a">B = '+B.toFixed(2)+' Тл, S = '+S.toFixed(2)+' м², α = '+aDeg+'°</text>';
|
||||
g += '<text x="240" y="266" text-anchor="middle" font-family="JetBrains Mono,monospace" font-size="14" font-weight="700" fill="#0891b2">Φ = '+(Phi*1000).toFixed(2)+' мВб</text>';
|
||||
|
||||
svg.innerHTML = g;
|
||||
|
||||
let note = '';
|
||||
if(aDeg === 0) note = '<b>α = 0°:</b> $\\vec{B} \\parallel \\vec{n}$ — поток максимален: $\\Phi_{max} = BS = '+(B*S*1000).toFixed(2)+'$ мВб.';
|
||||
else if(aDeg === 90) note = '<b>α = 90°:</b> $\\vec{B} \\perp \\vec{n}$ — линии поля скользят вдоль рамки. $\\Phi = 0$.';
|
||||
else if(aDeg === 180) note = '<b>α = 180°:</b> $\\vec{B}$ и $\\vec{n}$ направлены противоположно. $\\Phi = -BS = '+(-B*S*1000).toFixed(2)+'$ мВб.';
|
||||
else note = '<b>α = '+aDeg+'°:</b> $\\Phi = BS\\cos\\alpha = '+B.toFixed(2)+'\\cdot '+S.toFixed(2)+'\\cdot \\cos '+aDeg+'° = '+(Phi*1000).toFixed(2)+'$ мВб.';
|
||||
out.innerHTML = note;
|
||||
renderMath(out);
|
||||
|
||||
const key = (B>0.5?'B+':'B-') + ':' + (S>0.3?'S+':'S-') + ':' + Math.round(aDeg/30);
|
||||
seen.add(key);
|
||||
if(!_done && seen.size >= 4){ _done = true; addXp(10, 'p31-iv1'); bumpProgress('p31', 15); }
|
||||
}
|
||||
bS.addEventListener('input', draw);
|
||||
sS.addEventListener('input', draw);
|
||||
aS.addEventListener('input', draw);
|
||||
draw();
|
||||
})();
|
||||
|
||||
/* IV2 — Опыт Фарадея */
|
||||
(function(){
|
||||
const svg = document.getElementById('p31-iv2-svg');
|
||||
const out = document.getElementById('p31-iv2-out');
|
||||
const xS = document.getElementById('p31-iv2-x');
|
||||
const xL = document.getElementById('p31-iv2-xL');
|
||||
let lastX = +xS.value, lastT = performance.now();
|
||||
let movesPos = 0, movesNeg = 0, _done = false;
|
||||
|
||||
function draw(){
|
||||
const W = 480, H = 280;
|
||||
const x = +xS.value;
|
||||
xL.textContent = x.toFixed(2);
|
||||
const now = performance.now();
|
||||
const dt = Math.max(0.01, (now - lastT) / 1000);
|
||||
const dx = x - lastX;
|
||||
const vel = dx / dt; // м/с (условно)
|
||||
lastX = x; lastT = now;
|
||||
|
||||
// Катушка справа: центр около (340, 140), длина 130
|
||||
const coilCx = 340, coilCy = 140, coilL = 130, coilR = 40;
|
||||
// Магнит — прямоугольник; позиция: магнит-середина по x
|
||||
// Сопоставим x ∈ [-0.5 .. 0.3] м со SVG-координатой от 70 (далеко слева) до 320 (входит в катушку)
|
||||
const magW = 90, magH = 40;
|
||||
const magCx = 70 + (x + 0.5) * (320 - 70) / 0.8;
|
||||
const magCy = coilCy;
|
||||
|
||||
let g = '';
|
||||
g += '<rect x="0" y="0" width="'+W+'" height="'+H+'" fill="#fafafa"/>';
|
||||
g += '<text x="240" y="22" text-anchor="middle" font-family="Inter,sans-serif" font-size="13" font-weight="700" fill="#0f172a">Опыт Фарадея: магнит и катушка с амперметром</text>';
|
||||
|
||||
// Катушка — серия дуг (имитация витков)
|
||||
const turns = 10;
|
||||
for(let i=0;i<turns;i++){
|
||||
const cx = coilCx - coilL/2 + i * (coilL / (turns - 1));
|
||||
g += '<ellipse cx="'+cx.toFixed(1)+'" cy="'+coilCy+'" rx="14" ry="'+coilR+'" fill="none" stroke="#0f172a" stroke-width="1.6"/>';
|
||||
}
|
||||
// Боковые «проводки» катушки к амперметру
|
||||
g += PHYS.wire(coilCx - coilL/2 - 4, coilCy + coilR, coilCx - coilL/2 - 4, coilCy + coilR + 30);
|
||||
g += PHYS.wire(coilCx + coilL/2 + 4, coilCy + coilR, coilCx + coilL/2 + 4, coilCy + coilR + 30);
|
||||
g += PHYS.wire(coilCx - coilL/2 - 4, coilCy + coilR + 30, 405, coilCy + coilR + 30);
|
||||
g += PHYS.wire(coilCx + coilL/2 + 4, coilCy + coilR + 30, 435, coilCy + coilR + 30);
|
||||
// Амперметр
|
||||
g += PHYS.ammeterSymbol(420, coilCy + coilR + 30, 14);
|
||||
|
||||
// Магнит: N (красный) | S (синий)
|
||||
g += '<rect x="'+(magCx - magW/2).toFixed(1)+'" y="'+(magCy - magH/2).toFixed(1)+'" width="'+(magW/2).toFixed(1)+'" height="'+magH+'" fill="#fecaca" stroke="#dc2626" stroke-width="1.8"/>';
|
||||
g += '<rect x="'+magCx.toFixed(1)+'" y="'+(magCy - magH/2).toFixed(1)+'" width="'+(magW/2).toFixed(1)+'" height="'+magH+'" fill="#bfdbfe" stroke="#2563eb" stroke-width="1.8"/>';
|
||||
g += '<text x="'+(magCx - magW/4).toFixed(1)+'" y="'+(magCy + 5).toFixed(1)+'" text-anchor="middle" font-family="Inter,sans-serif" font-size="15" font-weight="800" fill="#dc2626">N</text>';
|
||||
g += '<text x="'+(magCx + magW/4).toFixed(1)+'" y="'+(magCy + 5).toFixed(1)+'" text-anchor="middle" font-family="Inter,sans-serif" font-size="15" font-weight="800" fill="#2563eb">S</text>';
|
||||
|
||||
// Поле магнита (стрелка из N) — направление движения магнита
|
||||
if(Math.abs(vel) > 0.02){
|
||||
const dir = vel > 0 ? 1 : -1;
|
||||
const arrFromX = magCx + dir * (magW/2 + 6);
|
||||
const arrToX = arrFromX + dir * 40;
|
||||
g += PHYS.drawArrow(arrFromX, magCy - 30, arrToX, magCy - 30, '#0f172a', 2, 9);
|
||||
g += '<text x="'+((arrFromX+arrToX)/2).toFixed(1)+'" y="'+(magCy - 36)+'" text-anchor="middle" font-family="Inter,sans-serif" font-size="11" fill="#0f172a">движение</text>';
|
||||
}
|
||||
|
||||
// Стрелка амперметра + ток в катушке
|
||||
let curSign = 0; // -1, 0, +1
|
||||
let curMag = 0;
|
||||
if(Math.abs(vel) > 0.02){
|
||||
// приближение N-полюса справа → поток через катушку растёт. Индукционный ток создаёт поле S к магниту,
|
||||
// то есть ток виден против часовой стрелки (со стороны магнита). Возьмём знак произвольно.
|
||||
curSign = vel > 0 ? +1 : -1;
|
||||
curMag = Math.min(1, Math.abs(vel) * 8);
|
||||
}
|
||||
// Стрелка на амперметре
|
||||
const ndlAng = curSign * curMag * 0.7; // рад от вертикали
|
||||
const ax = 420, ay = coilCy + coilR + 30;
|
||||
const ndlEx = ax + 11 * Math.sin(ndlAng);
|
||||
const ndlEy = ay - 11 * Math.cos(ndlAng);
|
||||
g += '<line x1="'+ax+'" y1="'+ay+'" x2="'+ndlEx.toFixed(1)+'" y2="'+ndlEy.toFixed(1)+'" stroke="#0f172a" stroke-width="2"/>';
|
||||
|
||||
// Стрелочки тока в первом витке катушки
|
||||
if(curMag > 0){
|
||||
const dirColor = curSign > 0 ? '#dc2626' : '#0891b2';
|
||||
const ccx = coilCx, ccy = coilCy;
|
||||
const r = coilR + 4;
|
||||
// Верх витка — стрелка вправо/влево
|
||||
const dxArr = curSign > 0 ? +14 : -14;
|
||||
g += PHYS.drawArrow(ccx - dxArr/2, ccy - r, ccx + dxArr/2, ccy - r, dirColor, 2, 8);
|
||||
g += PHYS.drawArrow(ccx + dxArr/2, ccy + r, ccx - dxArr/2, ccy + r, dirColor, 2, 8);
|
||||
g += '<text x="240" y="266" text-anchor="middle" font-family="JetBrains Mono,monospace" font-size="13" font-weight="700" fill="'+dirColor+'">Индукционный ток '+(curSign>0?'→':'←')+'</text>';
|
||||
} else {
|
||||
g += '<text x="240" y="266" text-anchor="middle" font-family="JetBrains Mono,monospace" font-size="13" font-weight="700" fill="#64748b">Тока нет — магнит покоится</text>';
|
||||
}
|
||||
|
||||
svg.innerHTML = g;
|
||||
|
||||
let note = '';
|
||||
if(curMag < 0.05) note = '<b>Магнит покоится.</b> Поток $\\Phi$ через катушку не меняется → индукционного тока <b>нет</b>.';
|
||||
else if(curSign > 0) note = '<b>Магнит приближается</b> к катушке. Поток $\\Phi$ растёт → возникает индукционный ток (одного знака).';
|
||||
else note = '<b>Магнит удаляется</b> от катушки. Поток $\\Phi$ убывает → возникает индукционный ток <b>противоположного</b> знака.';
|
||||
out.innerHTML = note;
|
||||
renderMath(out);
|
||||
|
||||
if(curSign > 0) movesPos = 1;
|
||||
if(curSign < 0) movesNeg = 1;
|
||||
if(!_done && movesPos && movesNeg){ _done = true; addXp(10, 'p31-iv2'); bumpProgress('p31', 15); }
|
||||
}
|
||||
xS.addEventListener('input', draw);
|
||||
// Тикать чаще, чтобы дать стрелке амперметра «остыть»
|
||||
setInterval(draw, 250);
|
||||
draw();
|
||||
})();
|
||||
|
||||
/* IV3 — Возникает ли индукционный ток? */
|
||||
(function(){
|
||||
const OPTS = ['Возникает', 'Не возникает'];
|
||||
const Q = [
|
||||
{ q:'Магнит вдвигают в катушку.', ans:0, why:'$\\Phi$ через катушку меняется → ток есть.' },
|
||||
{ q:'Магнит покоится в катушке.', ans:1, why:'$\\Phi$ не меняется → тока нет.' },
|
||||
{ q:'Катушка вращается в постоянном магнитном поле.', ans:0, why:'Меняется угол $\\alpha$ → меняется $\\Phi$ → ток есть. (Принцип генератора.)' },
|
||||
{ q:'Ток в соседней катушке плавно растёт.', ans:0, why:'$B$ растёт → $\\Phi$ меняется → ток в нашей катушке есть.' },
|
||||
{ q:'В соседней катушке течёт постоянный ток.', ans:1, why:'$B$ постоянно → $\\Phi$ не меняется → тока нет.' },
|
||||
{ q:'Площадь контура в постоянном поле плавно уменьшается.', ans:0, why:'$S$ меняется → $\\Phi = BS\\cos\\alpha$ меняется → ток есть.' }
|
||||
];
|
||||
let i = 0, score = 0;
|
||||
const qEl = document.getElementById('p31-iv3-q');
|
||||
const oEl = document.getElementById('p31-iv3-opts');
|
||||
const fb = document.getElementById('p31-iv3-fb');
|
||||
const iEl = document.getElementById('p31-iv3-i');
|
||||
const sEl = document.getElementById('p31-iv3-s');
|
||||
|
||||
function show(){
|
||||
if(i >= Q.length){
|
||||
qEl.innerHTML = '<b>Готово!</b> Результат: ' + score + ' / ' + Q.length;
|
||||
oEl.innerHTML = '';
|
||||
if(score === Q.length){ addXp(15, 'p31-iv3'); bumpProgress('p31', 25); }
|
||||
else if(score >= 4){ addXp(8, 'p31-iv3'); bumpProgress('p31', 15); }
|
||||
return;
|
||||
}
|
||||
iEl.textContent = (i+1);
|
||||
sEl.textContent = score;
|
||||
qEl.innerHTML = Q[i].q;
|
||||
oEl.innerHTML = OPTS.map((t, k) => '<button class="btn primary" data-v="' + k + '">' + t + '</button>').join('');
|
||||
fb.style.display = 'none';
|
||||
renderMath(qEl);
|
||||
oEl.querySelectorAll('button').forEach(b => {
|
||||
b.addEventListener('click', () => {
|
||||
const v = +b.dataset.v;
|
||||
if(v === Q[i].ans){ score++; feedback(fb, true, '✓ Верно! ' + Q[i].why + ' Дальше ▶'); }
|
||||
else feedback(fb, false, '✗ Верно: ' + OPTS[Q[i].ans] + '. ' + Q[i].why + ' Дальше ▶');
|
||||
sEl.textContent = score;
|
||||
oEl.querySelectorAll('button').forEach(x => x.disabled = true);
|
||||
i++;
|
||||
setTimeout(show, 1800);
|
||||
});
|
||||
});
|
||||
}
|
||||
document.getElementById('p31-iv3-restart').addEventListener('click', () => { i = 0; score = 0; show(); });
|
||||
show();
|
||||
})();
|
||||
|
||||
/* IV4 — Тренажёр */
|
||||
(function(){
|
||||
const Q = [
|
||||
{ q:'$B = 0{,}5$ Тл, $S = 0{,}04$ м², $\\alpha = 0°$. Найди $\\Phi$ (в <b>мВб</b>).', ans:20, tol:1, why:'$\\Phi = BS\\cos 0° = 0{,}5\\cdot 0{,}04 = 0{,}02$ Вб = 20 мВб.' },
|
||||
{ q:'То же поле и площадь, но $\\alpha = 60°$. Найди $\\Phi$ (в <b>мВб</b>).', ans:10, tol:0.6, why:'$\\Phi = 20\\cdot \\cos 60° = 20\\cdot 0{,}5 = 10$ мВб.' },
|
||||
{ q:'$\\alpha = 90°$. Чему равен $\\Phi$ (в мВб)?', ans:0, tol:0.01, why:'$\\cos 90° = 0$ → $\\Phi = 0$. Линии поля скользят вдоль рамки.' },
|
||||
{ q:'При $B = 0$ Тл — каким будет $\\Phi$ (в Вб)?', ans:0, tol:0.01, why:'Нет поля → нет потока. $\\Phi = 0$.' },
|
||||
{ q:'Если площадь $S$ удвоить (при тех же $B$ и $\\alpha$), во сколько раз изменится $\\Phi$?', ans:2, tol:0.1, why:'$\\Phi \\propto S$ → удвоится.' }
|
||||
];
|
||||
let i = 0, score = 0;
|
||||
const qEl = document.getElementById('p31-iv4-q');
|
||||
const fb = document.getElementById('p31-iv4-fb');
|
||||
const iEl = document.getElementById('p31-iv4-i');
|
||||
const sEl = document.getElementById('p31-iv4-s');
|
||||
const inp = document.getElementById('p31-iv4-inp');
|
||||
const bGo = document.getElementById('p31-iv4-go');
|
||||
|
||||
function show(){
|
||||
if(i >= Q.length){
|
||||
qEl.innerHTML = '<b>Готово!</b> Результат: ' + score + ' / ' + Q.length;
|
||||
inp.disabled = true; bGo.disabled = true;
|
||||
if(score === Q.length){ addXp(15, 'p31-iv4'); bumpProgress('p31', 25); }
|
||||
else if(score >= 3){ addXp(8, 'p31-iv4'); bumpProgress('p31', 15); }
|
||||
return;
|
||||
}
|
||||
iEl.textContent = (i+1);
|
||||
sEl.textContent = score;
|
||||
qEl.innerHTML = Q[i].q;
|
||||
fb.style.display = 'none';
|
||||
inp.value = ''; inp.disabled = false; bGo.disabled = false; inp.focus();
|
||||
renderMath(qEl);
|
||||
}
|
||||
function check(){
|
||||
if(inp.disabled) return;
|
||||
const v = parseFloat(inp.value.replace(',','.'));
|
||||
if(!isFinite(v)){ feedback(fb, false, 'Введи число.'); return; }
|
||||
const tol = Math.max(Q[i].tol, Math.abs(Q[i].ans)*0.05);
|
||||
const ok = Math.abs(v - Q[i].ans) <= tol;
|
||||
if(ok){ score++; feedback(fb, true, '✓ Верно! ' + Q[i].why + ' Дальше ▶'); }
|
||||
else feedback(fb, false, '✗ Верно: ' + Q[i].ans + '. ' + Q[i].why + ' Дальше ▶');
|
||||
sEl.textContent = score;
|
||||
inp.disabled = true; bGo.disabled = true;
|
||||
i++;
|
||||
setTimeout(show, 1900);
|
||||
}
|
||||
bGo.addEventListener('click', check);
|
||||
inp.addEventListener('keydown', e => { if(e.key==='Enter') check(); });
|
||||
document.getElementById('p31-iv4-restart').addEventListener('click', () => { i = 0; score = 0; inp.disabled=false; bGo.disabled=false; show(); });
|
||||
show();
|
||||
})();
|
||||
|
||||
wireReadBtn('p31');
|
||||
}
|
||||
|
||||
function build_p32(){
|
||||
const box = document.getElementById('p32-body');
|
||||
let html = '';
|
||||
html += makeCard('theory', "Правило Ленца. Закон Фарадея", "§32", `
|
||||
<p><b>Правило Ленца. Закон Фарадея</b> — этот параграф в разработке (Phase 1+).</p>
|
||||
<p>Здесь появятся: теория, формулы, разобранные примеры и 3–4 интерактива в стиле «алгебры 11» — таблицы, симуляции, ползунки, drag-and-drop и автопроверяемые тренажёры.</p>
|
||||
<p style="margin-top:10px;padding:10px 14px;background:var(--sec-acc-soft);border-radius:9px;font-size:.92rem">
|
||||
<b>Phase 0:</b> создан скелет учебника. <b>Phase 5+:</b> наполнение этого § содержанием по учебнику «Физика 10» (Беларусь, 2019).
|
||||
</p>
|
||||
|
||||
/* THEORY 1 — Правило Ленца */
|
||||
html += makeCard('theory', "Правило Ленца", "§32", `
|
||||
<p><b>Правило Ленца</b> (1834): <b>индукционный ток направлен так, чтобы своим магнитным полем препятствовать изменению магнитного потока, его вызвавшему</b>.</p>
|
||||
<p style="margin-top:10px">Это правило отражает <b>закон сохранения энергии</b>: если бы ток усиливал изменение, можно было бы получать неограниченную энергию из ничего.</p>
|
||||
<p style="margin-top:10px"><b>Пример 1</b>: магнит N-полюсом <b>приближается</b> к катушке.</p>
|
||||
<ul style="margin:6px 0 6px 22px">
|
||||
<li>Поток $\\Phi$ через катушку растёт.</li>
|
||||
<li>Индукционный ток создаёт <b>встречное</b> магнитное поле (его «N-полюс» обращён к магниту).</li>
|
||||
<li>Магнит <b>отталкивается</b> — приходится приложить силу, чтобы продолжать движение.</li>
|
||||
<li>Эта работа преобразуется в энергию индукционного тока.</li>
|
||||
</ul>
|
||||
<p style="margin-top:10px"><b>Пример 2</b>: магнит <b>удаляется</b>. Поток убывает. Индукционный ток создаёт поле, <b>поддерживающее</b> убывающий поток — катушка <b>притягивает</b> магнит.</p>
|
||||
<p style="margin-top:10px;padding:10px 14px;background:var(--sec-acc-soft);border-radius:9px"><b>Короткая мнемоника.</b> «Природа сопротивляется изменению»: ток всегда <b>против</b> того, кто его вызвал.</p>
|
||||
`);
|
||||
|
||||
/* THEORY 2 — Закон Фарадея */
|
||||
html += makeCard('rule', "Закон электромагнитной индукции (Фарадея)", "§32", `
|
||||
<p>Величина <b>ЭДС индукции</b> в контуре равна <b>скорости изменения</b> магнитного потока:</p>
|
||||
<p style="text-align:center;margin:8px 0">$$\\mathcal{E}_i = -\\dfrac{\\Delta\\Phi}{\\Delta t}$$</p>
|
||||
<p>Знак «минус» — математическая запись правила Ленца: ЭДС <b>противодействует</b> изменению потока.</p>
|
||||
<p style="margin-top:10px"><b>Для катушки из $N$ витков</b>:</p>
|
||||
<p style="text-align:center;margin:8px 0">$$\\mathcal{E}_i = -N\\,\\dfrac{\\Delta\\Phi}{\\Delta t}$$</p>
|
||||
<p>Сила индукционного тока: $I_i = \\mathcal{E}_i / R$, где $R$ — сопротивление катушки.</p>
|
||||
<p style="margin-top:10px"><b>Единица</b>: вольт (В).</p>
|
||||
<p style="margin-top:10px"><b>Большая ЭДС</b> возникает при:</p>
|
||||
<ul style="margin:6px 0 6px 22px">
|
||||
<li>быстром изменении $\\Phi$ (резкое движение, быстрое вращение);</li>
|
||||
<li>большом числе витков $N$.</li>
|
||||
</ul>
|
||||
`);
|
||||
|
||||
/* THEORY 3 — Применение и пример */
|
||||
html += makeCard('example', "Применение и пример", "§32", `
|
||||
<p><b>Генератор переменного тока.</b> Рамка вращается в магнитном поле, угол $\\alpha$ непрерывно меняется: $\\Phi = BS\\cos(\\omega t)$. Тогда ЭДС:</p>
|
||||
<p style="text-align:center;margin:8px 0">$$\\mathcal{E}_i = -\\dfrac{d\\Phi}{dt} = BS\\omega\\sin(\\omega t)$$</p>
|
||||
<p>Это <b>переменная синусоидальная</b> ЭДС. Так работают электростанции.</p>
|
||||
<p style="margin-top:10px"><b>Трансформатор.</b> Переменный ток в первичной катушке создаёт переменный $\\Phi$ через сердечник → во вторичной катушке возникает ЭДС. Отношение напряжений равно отношению чисел витков:</p>
|
||||
<p style="text-align:center;margin:8px 0">$$\\dfrac{U_2}{U_1} = \\dfrac{N_2}{N_1}$$</p>
|
||||
<p style="margin-top:10px"><b>Пример расчёта.</b> За $\\Delta t = 0{,}1$ с магнитный поток через катушку из $N = 50$ витков изменился с $0$ до $0{,}4$ Вб. Найди модуль ЭДС индукции.</p>
|
||||
<p style="text-align:center;margin:8px 0">$$|\\mathcal{E}_i| = N\\,\\dfrac{|\\Delta\\Phi|}{\\Delta t} = 50\\cdot \\dfrac{0{,}4}{0{,}1} = 200 \\text{ В}$$</p>
|
||||
<p style="margin-top:10px;padding:10px 14px;background:var(--sec-acc-soft);border-radius:9px"><b>Вывод.</b> Индукция позволяет получать высокие напряжения «из ничего» — но не нарушая закона сохранения энергии: работу совершает тот, кто меняет $\\Phi$.</p>
|
||||
`);
|
||||
|
||||
/* INTERACTIVE 1 — Правило Ленца */
|
||||
html += `<div class="wg" id="p32-iv1">
|
||||
<div class="wg-header"><span class="wg-badge">ИНТЕРАКТИВ 1</span><div class="wg-title">Правило Ленца в действии</div></div>
|
||||
<div class="wg-help">Двигай магнит к катушке и от неё. Индукционный ток создаёт поле, <b>препятствующее</b> изменению потока — магнит чувствует силу отталкивания (приближается) или притяжения (удаляется).</div>
|
||||
<div class="sliders">
|
||||
<label>Положение магнита: <b id="p32-iv1-xL">−0.20</b> <input type="range" id="p32-iv1-x" min="-0.50" max="0.30" value="-0.20" step="0.01"></label>
|
||||
</div>
|
||||
<div style="background:var(--card);border:1px solid var(--border);border-radius:9px;padding:8px">
|
||||
<svg id="p32-iv1-svg" viewBox="0 0 480 280" width="100%" style="height:auto"></svg>
|
||||
</div>
|
||||
<div id="p32-iv1-out" style="margin-top:10px;padding:10px 14px;background:var(--sec-acc-soft);border-radius:9px;font-size:.96rem;line-height:1.7;text-align:center"></div>
|
||||
</div>`;
|
||||
|
||||
/* INTERACTIVE 2 — Калькулятор ЭДС */
|
||||
html += `<div class="wg" id="p32-iv2">
|
||||
<div class="wg-header"><span class="wg-badge">ИНТЕРАКТИВ 2</span><div class="wg-title">Калькулятор ЭДС индукции</div></div>
|
||||
<div class="wg-help">$|\\mathcal{E}_i| = N\\,|\\Delta\\Phi|/\\Delta t$. Введи число витков, изменение потока и время.</div>
|
||||
<div style="display:grid;grid-template-columns:1fr 1fr 1fr;gap:10px;margin-bottom:10px">
|
||||
<label style="display:flex;flex-direction:column;gap:4px;font-size:.92rem">$N$ (витков):<input type="number" id="p32-iv2-N" value="100" step="1" min="1" style="padding:7px;border:1px solid var(--border);border-radius:6px"></label>
|
||||
<label style="display:flex;flex-direction:column;gap:4px;font-size:.92rem">$\\Delta\\Phi$ (Вб):<input type="number" id="p32-iv2-dP" value="0.01" step="any" style="padding:7px;border:1px solid var(--border);border-radius:6px"></label>
|
||||
<label style="display:flex;flex-direction:column;gap:4px;font-size:.92rem">$\\Delta t$ (с):<input type="number" id="p32-iv2-dt" value="0.1" step="any" min="0" style="padding:7px;border:1px solid var(--border);border-radius:6px"></label>
|
||||
</div>
|
||||
<div class="actions"><button class="btn primary" id="p32-iv2-calc">Вычислить $|\\mathcal{E}_i|$</button></div>
|
||||
<div id="p32-iv2-out" style="margin-top:10px;padding:10px 14px;background:var(--sec-acc-soft);border-radius:9px;font-size:.98rem;line-height:1.8;text-align:center;min-height:40px"></div>
|
||||
</div>`;
|
||||
|
||||
/* INTERACTIVE 3 — Куда направлен ток? */
|
||||
html += `<div class="wg" id="p32-iv3">
|
||||
<div class="wg-header"><span class="wg-badge">ИНТЕРАКТИВ 3</span><div class="wg-title">Куда направлен индукционный ток?</div></div>
|
||||
<div class="wg-help">По правилу Ленца ток своим полем <b>противодействует</b> изменению потока (рост → встречное поле; убывание → поддерживающее).</div>
|
||||
<div class="score-display"><span>Задача <b id="p32-iv3-i">1</b> / 6</span><span>Очки: <b id="p32-iv3-s">0</b> / 6</span></div>
|
||||
<div id="p32-iv3-q" style="padding:14px;background:var(--sec-acc-soft);border-radius:10px;font-size:1.02rem;margin-bottom:10px;text-align:center;min-height:54px"></div>
|
||||
<div id="p32-iv3-opts" style="display:grid;grid-template-columns:1fr 1fr;gap:8px"></div>
|
||||
<div class="feedback" id="p32-iv3-fb"></div>
|
||||
<div class="actions"><button class="btn" id="p32-iv3-restart">Начать заново</button></div>
|
||||
</div>`;
|
||||
|
||||
/* INTERACTIVE 4 — Тренажёр */
|
||||
html += `<div class="wg" id="p32-iv4">
|
||||
<div class="wg-header"><span class="wg-badge">ИНТЕРАКТИВ 4</span><div class="wg-title">Тренажёр: закон Фарадея</div></div>
|
||||
<div class="wg-help">5 задач. Допуск ±5%. Используй $|\\mathcal{E}_i| = N\\,|\\Delta\\Phi|/\\Delta t$.</div>
|
||||
<div class="score-display"><span>Задача <b id="p32-iv4-i">1</b> / 5</span><span>Очки: <b id="p32-iv4-s">0</b> / 5</span></div>
|
||||
<div id="p32-iv4-q" style="padding:14px;background:var(--sec-acc-soft);border-radius:10px;font-size:1.02rem;margin-bottom:10px;text-align:center;min-height:54px"></div>
|
||||
<div id="p32-iv4-form" style="display:flex;gap:8px;justify-content:center;margin-bottom:8px;flex-wrap:wrap">
|
||||
<input type="number" id="p32-iv4-inp" step="any" style="padding:8px 10px;border:1px solid var(--border);border-radius:6px;width:140px;font-size:1rem">
|
||||
<button class="btn primary" id="p32-iv4-go">Проверить</button>
|
||||
</div>
|
||||
<div class="feedback" id="p32-iv4-fb"></div>
|
||||
<div class="actions"><button class="btn" id="p32-iv4-restart">Начать заново</button></div>
|
||||
</div>`;
|
||||
|
||||
html += secNav('p31', 'p33');
|
||||
html += readButton('p32');
|
||||
|
||||
box.innerHTML = html;
|
||||
renderMath(box);
|
||||
|
||||
/* IV1 — Правило Ленца */
|
||||
(function(){
|
||||
const svg = document.getElementById('p32-iv1-svg');
|
||||
const out = document.getElementById('p32-iv1-out');
|
||||
const xS = document.getElementById('p32-iv1-x');
|
||||
const xL = document.getElementById('p32-iv1-xL');
|
||||
let lastX = +xS.value, lastT = performance.now();
|
||||
let movesPos = 0, movesNeg = 0, _done = false;
|
||||
|
||||
function draw(){
|
||||
const W = 480, H = 280;
|
||||
const x = +xS.value;
|
||||
xL.textContent = x.toFixed(2);
|
||||
const now = performance.now();
|
||||
const dt = Math.max(0.01, (now - lastT) / 1000);
|
||||
const dx = x - lastX;
|
||||
const vel = dx / dt;
|
||||
lastX = x; lastT = now;
|
||||
|
||||
// Катушка слева, магнит справа подъезжает влево (или удаляется вправо)
|
||||
const coilCx = 160, coilCy = 140, coilL = 120, coilR = 40;
|
||||
const magW = 90, magH = 40;
|
||||
// x: -0.5..0.3, отображаем магнит между 430 (далеко справа) и 240 (внутри катушки правой стороной)
|
||||
const magCx = 430 - (x + 0.5) * (430 - 240) / 0.8;
|
||||
const magCy = coilCy;
|
||||
|
||||
let g = '';
|
||||
g += '<rect x="0" y="0" width="'+W+'" height="'+H+'" fill="#fafafa"/>';
|
||||
g += '<text x="240" y="22" text-anchor="middle" font-family="Inter,sans-serif" font-size="13" font-weight="700" fill="#0f172a">Правило Ленца: индукционный ток противодействует движению магнита</text>';
|
||||
|
||||
// Катушка
|
||||
const turns = 9;
|
||||
for(let i=0;i<turns;i++){
|
||||
const cx = coilCx - coilL/2 + i * (coilL / (turns - 1));
|
||||
g += '<ellipse cx="'+cx.toFixed(1)+'" cy="'+coilCy+'" rx="12" ry="'+coilR+'" fill="none" stroke="#0f172a" stroke-width="1.6"/>';
|
||||
}
|
||||
|
||||
// Магнит: левая сторона = N (красный, обращён к катушке), правая = S (синий)
|
||||
g += '<rect x="'+(magCx - magW/2).toFixed(1)+'" y="'+(magCy - magH/2).toFixed(1)+'" width="'+(magW/2).toFixed(1)+'" height="'+magH+'" fill="#fecaca" stroke="#dc2626" stroke-width="1.8"/>';
|
||||
g += '<rect x="'+magCx.toFixed(1)+'" y="'+(magCy - magH/2).toFixed(1)+'" width="'+(magW/2).toFixed(1)+'" height="'+magH+'" fill="#bfdbfe" stroke="#2563eb" stroke-width="1.8"/>';
|
||||
g += '<text x="'+(magCx - magW/4).toFixed(1)+'" y="'+(magCy + 5).toFixed(1)+'" text-anchor="middle" font-family="Inter,sans-serif" font-size="15" font-weight="800" fill="#dc2626">N</text>';
|
||||
g += '<text x="'+(magCx + magW/4).toFixed(1)+'" y="'+(magCy + 5).toFixed(1)+'" text-anchor="middle" font-family="Inter,sans-serif" font-size="15" font-weight="800" fill="#2563eb">S</text>';
|
||||
|
||||
// Направление движения магнита (стрелка над магнитом)
|
||||
const moving = Math.abs(vel) > 0.02;
|
||||
// приближение: vel > 0 (x растёт) → магнит едет влево к катушке
|
||||
const approaching = vel > 0.02;
|
||||
const receding = vel < -0.02;
|
||||
if(moving){
|
||||
const dir = approaching ? -1 : +1; // экранно: влево или вправо
|
||||
const arrFromX = magCx + dir * (magW/2 + 6);
|
||||
const arrToX = arrFromX + dir * 40;
|
||||
g += PHYS.drawArrow(arrFromX, magCy - 32, arrToX, magCy - 32, '#0f172a', 2, 9);
|
||||
g += '<text x="'+((arrFromX+arrToX)/2).toFixed(1)+'" y="'+(magCy - 38)+'" text-anchor="middle" font-family="Inter,sans-serif" font-size="11" fill="#0f172a">движение</text>';
|
||||
}
|
||||
|
||||
// Сила Ленца на магнит (отталкивание при приближ., притяжение при удалении)
|
||||
// отталкивание: вправо (от катушки); притяжение: влево (к катушке)
|
||||
if(moving){
|
||||
const forceDir = approaching ? +1 : -1;
|
||||
const fLabel = approaching ? 'отталкивание' : 'притяжение';
|
||||
const fColor = approaching ? '#dc2626' : '#0891b2';
|
||||
const fFromX = magCx + (forceDir > 0 ? +magW/2 + 6 : -magW/2 - 6);
|
||||
const fToX = fFromX + forceDir * 36;
|
||||
g += PHYS.drawArrow(fFromX, magCy + 36, fToX, magCy + 36, fColor, 2.4, 10);
|
||||
g += '<text x="'+((fFromX+fToX)/2).toFixed(1)+'" y="'+(magCy + 56)+'" text-anchor="middle" font-family="Inter,sans-serif" font-size="11" font-weight="700" fill="'+fColor+'">F ('+fLabel+')</text>';
|
||||
}
|
||||
|
||||
// Индукционный ток в витках катушки (стрелочки)
|
||||
let curSign = 0;
|
||||
if(approaching) curSign = +1;
|
||||
else if(receding) curSign = -1;
|
||||
if(curSign !== 0){
|
||||
const dirColor = '#0891b2';
|
||||
const ccx = coilCx, ccy = coilCy;
|
||||
const r = coilR + 4;
|
||||
const dxArr = curSign > 0 ? +14 : -14;
|
||||
g += PHYS.drawArrow(ccx - dxArr/2, ccy - r, ccx + dxArr/2, ccy - r, dirColor, 2, 8);
|
||||
g += PHYS.drawArrow(ccx + dxArr/2, ccy + r, ccx - dxArr/2, ccy + r, dirColor, 2, 8);
|
||||
g += '<text x="'+coilCx+'" y="'+(coilCy - r - 8)+'" text-anchor="middle" font-family="Inter,sans-serif" font-size="11" font-weight="700" fill="'+dirColor+'">индукц. ток</text>';
|
||||
}
|
||||
|
||||
// Эквивалентный «магнит-катушка» — какой полюс смотрит на магнит
|
||||
if(curSign !== 0){
|
||||
// приближение: на магнит смотрит N (отталкивает) → правая сторона катушки = N
|
||||
// удаление: на магнит смотрит S (притягивает) → правая сторона катушки = S
|
||||
const eqPole = approaching ? 'N' : 'S';
|
||||
const eqColor = approaching ? '#dc2626' : '#2563eb';
|
||||
g += '<text x="'+(coilCx + coilL/2 + 10)+'" y="'+(coilCy + 28)+'" font-family="Inter,sans-serif" font-size="13" font-weight="800" fill="'+eqColor+'">↔ '+eqPole+'</text>';
|
||||
}
|
||||
|
||||
svg.innerHTML = g;
|
||||
|
||||
let note = '';
|
||||
if(!moving) note = '<b>Магнит покоится.</b> $\\Phi$ не меняется — индукционного тока и силы нет.';
|
||||
else if(approaching) note = '<b>Магнит приближается</b> N-полюсом. $\\Phi$ растёт → индукционный ток создаёт <b>встречное</b> поле (N навстречу N). Катушка <b>отталкивает</b> магнит.';
|
||||
else note = '<b>Магнит удаляется.</b> $\\Phi$ убывает → индукционный ток создаёт <b>поддерживающее</b> поле (S к N). Катушка <b>притягивает</b> магнит.';
|
||||
out.innerHTML = note;
|
||||
renderMath(out);
|
||||
|
||||
if(approaching) movesPos = 1;
|
||||
if(receding) movesNeg = 1;
|
||||
if(!_done && movesPos && movesNeg){ _done = true; addXp(10, 'p32-iv1'); bumpProgress('p32', 15); }
|
||||
}
|
||||
xS.addEventListener('input', draw);
|
||||
setInterval(draw, 250);
|
||||
draw();
|
||||
})();
|
||||
|
||||
/* IV2 — Калькулятор ЭДС индукции */
|
||||
(function(){
|
||||
const out = document.getElementById('p32-iv2-out');
|
||||
const bGo = document.getElementById('p32-iv2-calc');
|
||||
const inN = document.getElementById('p32-iv2-N');
|
||||
const inP = document.getElementById('p32-iv2-dP');
|
||||
const inT = document.getElementById('p32-iv2-dt');
|
||||
let count = 0, _done = false;
|
||||
|
||||
function calc(){
|
||||
const N = +inN.value, dP = +inP.value, dt = +inT.value;
|
||||
if(![N,dP,dt].every(isFinite) || dt <= 0 || N < 1){
|
||||
out.innerHTML = '<b style="color:#dc2626">Проверь ввод: $N \\ge 1$, $\\Delta t > 0$.</b>';
|
||||
renderMath(out);
|
||||
return;
|
||||
}
|
||||
const E = N * Math.abs(dP) / dt;
|
||||
let html = '$|\\mathcal{E}_i| = N\\,\\dfrac{|\\Delta\\Phi|}{\\Delta t} = '+N+'\\cdot \\dfrac{'+Math.abs(dP)+'}{'+dt+'} = $ <b>'+E.toFixed(3)+' В</b>';
|
||||
// Скорость изменения
|
||||
html += '<br><span style="font-size:.9rem;color:#64748b">Скорость изменения потока: $\\Delta\\Phi/\\Delta t = '+(Math.abs(dP)/dt).toFixed(4)+'$ Вб/с.</span>';
|
||||
out.innerHTML = html;
|
||||
renderMath(out);
|
||||
count++;
|
||||
if(!_done && count >= 3){ _done = true; addXp(10, 'p32-iv2'); bumpProgress('p32', 15); }
|
||||
}
|
||||
bGo.addEventListener('click', calc);
|
||||
[inN,inP,inT].forEach(x => x.addEventListener('keydown', e => { if(e.key==='Enter') calc(); }));
|
||||
})();
|
||||
|
||||
/* IV3 — Куда направлен индукционный ток? */
|
||||
(function(){
|
||||
const OPTS = ['Противодействует (встречное поле)', 'Усиливает (поддерживающее поле)'];
|
||||
const Q = [
|
||||
{ q:'Магнит N-полюсом <b>приближается</b> к катушке.', ans:0, why:'$\\Phi$ растёт → ток создаёт встречное поле, навстречу N-полюсу. Магнит отталкивается.' },
|
||||
{ q:'Магнит S-полюсом <b>приближается</b> к катушке.', ans:0, why:'$\\Phi$ растёт (с другим знаком) → ток создаёт встречное поле. Магнит отталкивается.' },
|
||||
{ q:'Магнит N-полюсом <b>удаляется</b> от катушки.', ans:1, why:'$\\Phi$ убывает → ток создаёт поле, поддерживающее убывающий поток. Магнит притягивается.' },
|
||||
{ q:'Магнит S-полюсом <b>удаляется</b> от катушки.', ans:1, why:'$\\Phi$ убывает → ток создаёт поддерживающее поле. Магнит притягивается.' },
|
||||
{ q:'Ток в соседней катушке <b>растёт</b>.', ans:0, why:'$B$ через нашу катушку растёт → $\\Phi$ растёт → ток противодействует.' },
|
||||
{ q:'Ток в соседней катушке <b>убывает</b>.', ans:1, why:'$B$ убывает → $\\Phi$ убывает → ток поддерживает (усиливает) поле.' }
|
||||
];
|
||||
let i = 0, score = 0;
|
||||
const qEl = document.getElementById('p32-iv3-q');
|
||||
const oEl = document.getElementById('p32-iv3-opts');
|
||||
const fb = document.getElementById('p32-iv3-fb');
|
||||
const iEl = document.getElementById('p32-iv3-i');
|
||||
const sEl = document.getElementById('p32-iv3-s');
|
||||
|
||||
function show(){
|
||||
if(i >= Q.length){
|
||||
qEl.innerHTML = '<b>Готово!</b> Результат: ' + score + ' / ' + Q.length;
|
||||
oEl.innerHTML = '';
|
||||
if(score === Q.length){ addXp(15, 'p32-iv3'); bumpProgress('p32', 25); }
|
||||
else if(score >= 4){ addXp(8, 'p32-iv3'); bumpProgress('p32', 15); }
|
||||
return;
|
||||
}
|
||||
iEl.textContent = (i+1);
|
||||
sEl.textContent = score;
|
||||
qEl.innerHTML = Q[i].q;
|
||||
oEl.innerHTML = OPTS.map((t, k) => '<button class="btn primary" data-v="' + k + '">' + t + '</button>').join('');
|
||||
fb.style.display = 'none';
|
||||
renderMath(qEl);
|
||||
oEl.querySelectorAll('button').forEach(b => {
|
||||
b.addEventListener('click', () => {
|
||||
const v = +b.dataset.v;
|
||||
if(v === Q[i].ans){ score++; feedback(fb, true, '✓ Верно! ' + Q[i].why + ' Дальше ▶'); }
|
||||
else feedback(fb, false, '✗ Верно: ' + OPTS[Q[i].ans] + '. ' + Q[i].why + ' Дальше ▶');
|
||||
sEl.textContent = score;
|
||||
oEl.querySelectorAll('button').forEach(x => x.disabled = true);
|
||||
i++;
|
||||
setTimeout(show, 1900);
|
||||
});
|
||||
});
|
||||
}
|
||||
document.getElementById('p32-iv3-restart').addEventListener('click', () => { i = 0; score = 0; show(); });
|
||||
show();
|
||||
})();
|
||||
|
||||
/* IV4 — Тренажёр Фарадея */
|
||||
(function(){
|
||||
const Q = [
|
||||
{ q:'$N = 100$, $\\Delta\\Phi = 0{,}01$ Вб, $\\Delta t = 0{,}1$ с. Найди $|\\mathcal{E}_i|$ (в <b>В</b>).', ans:10, tol:0.6, why:'$|\\mathcal{E}| = 100\\cdot 0{,}01/0{,}1 = 10$ В.' },
|
||||
{ q:'$N = 50$, $\\Delta\\Phi = 0{,}4$ Вб, $\\Delta t = 0{,}1$ с. Найди $|\\mathcal{E}_i|$ (в <b>В</b>).', ans:200, tol:10, why:'$|\\mathcal{E}| = 50\\cdot 0{,}4/0{,}1 = 200$ В.' },
|
||||
{ q:'$N = 200$. За 0,5 с поток изменился от 0,2 Вб до 0,6 Вб. Найди $|\\mathcal{E}_i|$ (в <b>В</b>).', ans:160, tol:8, why:'$|\\Delta\\Phi| = 0{,}4$ Вб → $|\\mathcal{E}| = 200\\cdot 0{,}4/0{,}5 = 160$ В.' },
|
||||
{ q:'Знак «−» в формуле $\\mathcal{E}_i = -\\Delta\\Phi/\\Delta t$ означает: <br>1 = правило Ленца, 2 = отрицательный заряд, 3 = ничего. Введи номер.', ans:1, tol:0.1, why:'Минус — математическая форма правила Ленца: ЭДС противодействует изменению потока.' },
|
||||
{ q:'Если скорость изменения потока удвоить, во сколько раз изменится $|\\mathcal{E}_i|$?', ans:2, tol:0.1, why:'$|\\mathcal{E}| \\propto |\\Delta\\Phi|/\\Delta t$ — удвоится.' }
|
||||
];
|
||||
let i = 0, score = 0;
|
||||
const qEl = document.getElementById('p32-iv4-q');
|
||||
const fb = document.getElementById('p32-iv4-fb');
|
||||
const iEl = document.getElementById('p32-iv4-i');
|
||||
const sEl = document.getElementById('p32-iv4-s');
|
||||
const inp = document.getElementById('p32-iv4-inp');
|
||||
const bGo = document.getElementById('p32-iv4-go');
|
||||
|
||||
function show(){
|
||||
if(i >= Q.length){
|
||||
qEl.innerHTML = '<b>Готово!</b> Результат: ' + score + ' / ' + Q.length;
|
||||
inp.disabled = true; bGo.disabled = true;
|
||||
if(score === Q.length){ addXp(15, 'p32-iv4'); bumpProgress('p32', 25); }
|
||||
else if(score >= 3){ addXp(8, 'p32-iv4'); bumpProgress('p32', 15); }
|
||||
return;
|
||||
}
|
||||
iEl.textContent = (i+1);
|
||||
sEl.textContent = score;
|
||||
qEl.innerHTML = Q[i].q;
|
||||
fb.style.display = 'none';
|
||||
inp.value = ''; inp.disabled = false; bGo.disabled = false; inp.focus();
|
||||
renderMath(qEl);
|
||||
}
|
||||
function check(){
|
||||
if(inp.disabled) return;
|
||||
const v = parseFloat(inp.value.replace(',','.'));
|
||||
if(!isFinite(v)){ feedback(fb, false, 'Введи число.'); return; }
|
||||
const tol = Math.max(Q[i].tol, Math.abs(Q[i].ans)*0.05);
|
||||
const ok = Math.abs(v - Q[i].ans) <= tol;
|
||||
if(ok){ score++; feedback(fb, true, '✓ Верно! ' + Q[i].why + ' Дальше ▶'); }
|
||||
else feedback(fb, false, '✗ Верно: ' + Q[i].ans + '. ' + Q[i].why + ' Дальше ▶');
|
||||
sEl.textContent = score;
|
||||
inp.disabled = true; bGo.disabled = true;
|
||||
i++;
|
||||
setTimeout(show, 1900);
|
||||
}
|
||||
bGo.addEventListener('click', check);
|
||||
inp.addEventListener('keydown', e => { if(e.key==='Enter') check(); });
|
||||
document.getElementById('p32-iv4-restart').addEventListener('click', () => { i = 0; score = 0; inp.disabled=false; bGo.disabled=false; show(); });
|
||||
show();
|
||||
})();
|
||||
|
||||
wireReadBtn('p32');
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user