feat(phys10 ch3 wave3): §20 «Линии поля» + §21 «Работа и потенциал»
This commit is contained in:
@@ -2081,34 +2081,717 @@ function build_p19(){
|
||||
function build_p20(){
|
||||
const box = document.getElementById('p20-body');
|
||||
let html = '';
|
||||
|
||||
/* THEORY 1 — Линии напряжённости */
|
||||
html += makeCard('theory', "Линии напряжённости", "§20", `
|
||||
<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 3+:</b> наполнение этого § содержанием по учебнику «Физика 10» (Беларусь, 2019).
|
||||
</p>
|
||||
<p><b>Силовая линия</b> (линия напряжённости) — это линия, касательная к которой в каждой точке совпадает с направлением вектора $\\vec{E}$.</p>
|
||||
<p style="margin-top:10px"><b>Свойства силовых линий:</b></p>
|
||||
<ol style="margin:6px 0 8px 22px;line-height:1.75">
|
||||
<li>Линии <b>начинаются на положительных</b> зарядах (или на бесконечности) и <b>заканчиваются на отрицательных</b> (или уходят на бесконечность).</li>
|
||||
<li>Силовые линии <b>не пересекаются</b> между собой — в каждой точке поле имеет только одно направление.</li>
|
||||
<li><b>Густота линий</b> пропорциональна величине напряжённости $E$: где линии гуще — поле сильнее.</li>
|
||||
<li>Линии <b>перпендикулярны</b> заряженной поверхности проводника.</li>
|
||||
</ol>
|
||||
<p style="margin-top:10px;padding:10px 14px;background:var(--sec-acc-soft);border-radius:9px">Картина силовых линий — это <b>способ визуализации</b> невидимого поля. Чтобы «увидеть» $\\vec{E}$, мы рисуем «карту» из линий.</p>
|
||||
`);
|
||||
|
||||
/* THEORY 2 — Поле точечного заряда и системы зарядов */
|
||||
html += makeCard('rule', "Поле точечного заряда и системы зарядов", "§20", `
|
||||
<p><b>Поле точечного заряда:</b> линии напряжённости — <b>радиальные</b>.</p>
|
||||
<ul style="margin:6px 0 8px 22px;line-height:1.75">
|
||||
<li>От $+q$ — расходятся <b>наружу</b>.</li>
|
||||
<li>К $-q$ — сходятся <b>внутрь</b>.</li>
|
||||
<li>В точке самого заряда линии расходятся бесконечно, плотность бесконечна.</li>
|
||||
</ul>
|
||||
<p style="margin-top:10px"><b>Поле двух одноимённых зарядов $+q$ и $+q$:</b> линии расходятся от обоих зарядов и <b>отталкиваются</b> друг от друга. В середине между зарядами — <b>точка равновесия</b> ($E = 0$, поля компенсируются).</p>
|
||||
<p style="margin-top:10px"><b>Поле двух разноимённых зарядов $+q$ и $-q$ (диполь):</b> линии идут от $+q$ к $-q$, образуя характерную картину (похожую на поле магнита!). В центре между зарядами поле направлено от $+q$ к $-q$.</p>
|
||||
`);
|
||||
|
||||
/* THEORY 3 — Однородное и неоднородное поле */
|
||||
html += makeCard('example', "Однородное и неоднородное поле", "§20", `
|
||||
<p><b>Однородное поле</b> — поле, в котором $\\vec{E}$ одинакова во всех точках:</p>
|
||||
<ul style="margin:6px 0 8px 22px;line-height:1.75">
|
||||
<li>по модулю,</li>
|
||||
<li>по направлению.</li>
|
||||
</ul>
|
||||
<p>Силовые линии однородного поля — <b>параллельные и одинаково расположенные</b>.</p>
|
||||
<p style="margin-top:10px"><b>Где встречается:</b></p>
|
||||
<ul style="margin:6px 0 8px 22px;line-height:1.75">
|
||||
<li>Между пластинами параллельного плоского конденсатора (вдали от краёв).</li>
|
||||
<li>В небольшой области вблизи поверхности большого равномерно заряженного тела.</li>
|
||||
</ul>
|
||||
<p style="margin-top:10px">В однородном поле сила $\\vec{F} = q\\vec{E}$ везде одинакова, а поле описывается одним вектором $\\vec{E}$.</p>
|
||||
<p style="padding:10px 14px;background:var(--warn-bg,#fef3c7);border-left:4px solid var(--warn,#f59e0b);border-radius:9px;margin:10px 0"><b>Неоднородное поле</b> — поле, где $\\vec{E}$ меняется от точки к точке. Примеры: поле точечного заряда, поле системы зарядов, поле заряженной сферы снаружи.</p>
|
||||
`);
|
||||
|
||||
/* INTERACTIVE 1 — Картины полей */
|
||||
html += `<div class="wg" id="p20-iv1">
|
||||
<div class="wg-header"><span class="wg-badge">ИНТЕРАКТИВ 1</span><div class="wg-title">Картины полей — 5 конфигураций</div></div>
|
||||
<div class="wg-help">Переключай тип конфигурации и наблюдай характерную картину силовых линий. Это главный визуализатор электростатики!</div>
|
||||
<div class="sliders">
|
||||
<label>Тип: <b id="p20-iv1-tL">1</b> <input type="range" id="p20-iv1-t" min="1" max="5" value="1" step="1"></label>
|
||||
</div>
|
||||
<div style="background:var(--card);border:1px solid var(--border);border-radius:9px;padding:8px">
|
||||
<svg id="p20-iv1-svg" viewBox="0 0 480 360" width="100%" style="height:auto"></svg>
|
||||
</div>
|
||||
<div id="p20-iv1-out" style="margin-top:10px;padding:10px 14px;background:var(--sec-acc-soft);border-radius:9px;font-size:.94rem;line-height:1.7"></div>
|
||||
</div>`;
|
||||
|
||||
/* INTERACTIVE 2 — Свойства силовых линий (квикфайр) */
|
||||
html += `<div class="wg" id="p20-iv2">
|
||||
<div class="wg-header"><span class="wg-badge">ИНТЕРАКТИВ 2</span><div class="wg-title">Свойства силовых линий</div></div>
|
||||
<div class="wg-help">6 вопросов на понимание свойств линий поля.</div>
|
||||
<div class="score-display"><span>Вопрос <b id="p20-iv2-i">1</b> / 6</span><span>Очки: <b id="p20-iv2-s">0</b> / 6</span></div>
|
||||
<div id="p20-iv2-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="p20-iv2-opts" style="display:grid;grid-template-columns:1fr 1fr;gap:8px"></div>
|
||||
<div class="feedback" id="p20-iv2-fb"></div>
|
||||
<div class="actions"><button class="btn" id="p20-iv2-restart">Начать заново</button></div>
|
||||
</div>`;
|
||||
|
||||
/* INTERACTIVE 3 — Какая картина соответствует конфигурации? */
|
||||
html += `<div class="wg" id="p20-iv3">
|
||||
<div class="wg-header"><span class="wg-badge">ИНТЕРАКТИВ 3</span><div class="wg-title">Какая картина соответствует конфигурации?</div></div>
|
||||
<div class="wg-help">Выбери тип картины силовых линий для каждой конфигурации зарядов.</div>
|
||||
<div class="score-display"><span>Задача <b id="p20-iv3-i">1</b> / 6</span><span>Очки: <b id="p20-iv3-s">0</b> / 6</span></div>
|
||||
<div id="p20-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="p20-iv3-opts" style="display:grid;grid-template-columns:1fr 1fr;gap:8px"></div>
|
||||
<div class="feedback" id="p20-iv3-fb"></div>
|
||||
<div class="actions"><button class="btn" id="p20-iv3-restart">Начать заново</button></div>
|
||||
</div>`;
|
||||
|
||||
/* INTERACTIVE 4 — Тренажёр поля */
|
||||
html += `<div class="wg" id="p20-iv4">
|
||||
<div class="wg-header"><span class="wg-badge">ИНТЕРАКТИВ 4</span><div class="wg-title">Тренажёр поля</div></div>
|
||||
<div class="wg-help">5 задач на свойства поля и силовых линий.</div>
|
||||
<div class="score-display"><span>Задача <b id="p20-iv4-i">1</b> / 5</span><span>Очки: <b id="p20-iv4-s">0</b> / 5</span></div>
|
||||
<div id="p20-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 style="display:flex;gap:10px;align-items:center;flex-wrap:wrap;justify-content:center">
|
||||
<span style="font-family:'JetBrains Mono',monospace">ответ =</span>
|
||||
<input type="number" id="p20-iv4-ans" class="tinp" style="width:140px;text-align:center" step="any">
|
||||
<button class="btn primary" id="p20-iv4-go">Проверить</button>
|
||||
<button class="btn" id="p20-iv4-start">Заново</button>
|
||||
</div>
|
||||
<div class="feedback" id="p20-iv4-fb"></div>
|
||||
</div>`;
|
||||
|
||||
html += secNav('p19', 'p21');
|
||||
html += readButton('p20');
|
||||
|
||||
box.innerHTML = html;
|
||||
renderMath(box);
|
||||
|
||||
/* IV1 — Картины полей (5 конфигураций) */
|
||||
(function(){
|
||||
const svg = document.getElementById('p20-iv1-svg');
|
||||
const tS = document.getElementById('p20-iv1-t');
|
||||
const tL = document.getElementById('p20-iv1-tL');
|
||||
const out = document.getElementById('p20-iv1-out');
|
||||
const seen = new Set();
|
||||
let _done = false;
|
||||
|
||||
const NAMES = {
|
||||
1: 'Точечный заряд $+q$',
|
||||
2: 'Точечный заряд $-q$',
|
||||
3: 'Два одноимённых $+q$, $+q$',
|
||||
4: 'Диполь $+q$, $-q$',
|
||||
5: 'Однородное поле'
|
||||
};
|
||||
const DESC = {
|
||||
1: 'Радиальные линии расходятся <b>от заряда</b> наружу. $E$ максимально у заряда, убывает как $1/r^2$.',
|
||||
2: 'Радиальные линии сходятся <b>к заряду</b>. Картина симметрична относительно центра.',
|
||||
3: 'Линии расходятся от каждого заряда и <b>отталкиваются</b> друг от друга. В середине — <b>точка равновесия</b> $E = 0$.',
|
||||
4: 'Линии идут <b>от $+q$ к $-q$</b>. В центре между зарядами поле максимально и направлено от $+$ к $-$.',
|
||||
5: 'Линии <b>параллельны и одинаково расположены</b>. $\\vec{E}$ одинакова во всех точках. Создаётся между пластинами конденсатора.'
|
||||
};
|
||||
|
||||
function render(){
|
||||
const t = +tS.value;
|
||||
tL.textContent = t;
|
||||
const W = 480, H = 360, cx = W/2, cy = H/2;
|
||||
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">Конфигурация '+t+': '+(t===1?'точечный +q':t===2?'точечный −q':t===3?'два одноимённых ++':t===4?'диполь +−':'однородное поле')+'</text>';
|
||||
|
||||
if(t === 1){
|
||||
// Точечный +q — радиальные линии наружу
|
||||
g += PHYS.fieldLinesPointCharge(cx, cy, +1, 140, 16);
|
||||
g += PHYS.chargeMark(cx, cy, +1, 22, '');
|
||||
} else if(t === 2){
|
||||
// Точечный -q — радиальные линии внутрь
|
||||
g += PHYS.fieldLinesPointCharge(cx, cy, -1, 140, 16);
|
||||
g += PHYS.chargeMark(cx, cy, -1, 22, '');
|
||||
} else if(t === 3){
|
||||
// Два одноимённых +q +q
|
||||
const x1 = cx - 90, x2 = cx + 90;
|
||||
// Радиальные линии от каждого, но с пропуском внутреннего сектора (где линии бы отталкивались)
|
||||
function radial(xC, yC, sign, skipAngleRange){
|
||||
let s = '';
|
||||
const N = 14;
|
||||
const color = sign > 0 ? '#dc2626' : '#2563eb';
|
||||
for(let i=0;i<N;i++){
|
||||
const a = 2*Math.PI*i/N;
|
||||
// пропустить углы, направленные к другому заряду
|
||||
if(skipAngleRange){
|
||||
let aDeg = (a*180/Math.PI + 360) % 360;
|
||||
if(aDeg > skipAngleRange[0] && aDeg < skipAngleRange[1]) continue;
|
||||
}
|
||||
const r1 = 18, r2 = 95;
|
||||
const x1 = xC + r1*Math.cos(a), y1 = yC + r1*Math.sin(a);
|
||||
const x2 = xC + r2*Math.cos(a), y2 = yC + r2*Math.sin(a);
|
||||
if(sign > 0) s += PHYS.drawArrow(x1, y1, x2, y2, color, 1.3, 6);
|
||||
else s += PHYS.drawArrow(x2, y2, x1, y1, color, 1.3, 6);
|
||||
}
|
||||
return s;
|
||||
}
|
||||
// Левый заряд: пропускаем углы вправо (направление к другому заряду)
|
||||
g += radial(x1, cy, +1, [340, 360]);
|
||||
g += radial(x1, cy, +1, [0, 20]);
|
||||
g += radial(x2, cy, +1, [160, 200]);
|
||||
// Точка равновесия
|
||||
g += '<circle cx="'+cx+'" cy="'+cy+'" r="6" fill="none" stroke="#a16207" stroke-width="2" stroke-dasharray="3 2"/>';
|
||||
g += '<text x="'+cx+'" y="'+(cy-12)+'" text-anchor="middle" font-family="JetBrains Mono,monospace" font-size="11" font-weight="700" fill="#a16207">E=0</text>';
|
||||
g += PHYS.chargeMark(x1, cy, +1, 22, '');
|
||||
g += PHYS.chargeMark(x2, cy, +1, 22, '');
|
||||
} else if(t === 4){
|
||||
// Диполь +q, -q
|
||||
const x1 = cx - 90, x2 = cx + 90;
|
||||
// Прямая линия между зарядами
|
||||
g += PHYS.drawArrow(x1+22, cy, x2-22, cy, '#7c3aed', 2.2, 9);
|
||||
// Дуги: от +q к -q сверху и снизу
|
||||
function dipoleArc(yOffset, color){
|
||||
// Кривая Безье из (x1, cy) в (x2, cy) через (cx, cy+yOffset)
|
||||
// Превратим в полилинию из стрелок
|
||||
const N = 8;
|
||||
let prevX = x1+22, prevY = cy;
|
||||
let s = '';
|
||||
for(let i=1;i<=N;i++){
|
||||
const t = i/N;
|
||||
// Quadratic Bezier
|
||||
const bx = (1-t)*(1-t)*(x1+22) + 2*(1-t)*t*cx + t*t*(x2-22);
|
||||
const by = (1-t)*(1-t)*cy + 2*(1-t)*t*(cy+yOffset) + t*t*cy;
|
||||
if(i === N || i % 2 === 0){
|
||||
s += PHYS.drawArrow(prevX, prevY, bx, by, color, 1.4, (i===N?7:0));
|
||||
} else {
|
||||
s += '<line x1="'+prevX.toFixed(1)+'" y1="'+prevY.toFixed(1)+'" x2="'+bx.toFixed(1)+'" y2="'+by.toFixed(1)+'" stroke="'+color+'" stroke-width="1.4" stroke-linecap="round"/>';
|
||||
}
|
||||
prevX = bx; prevY = by;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
g += dipoleArc(-60, '#7c3aed');
|
||||
g += dipoleArc(+60, '#7c3aed');
|
||||
g += dipoleArc(-110, '#7c3aed');
|
||||
g += dipoleArc(+110, '#7c3aed');
|
||||
// Линии, уходящие за пределы (от +q налево, от -q направо — наоборот, к -q справа)
|
||||
// Линия влево от +q
|
||||
g += PHYS.drawArrow(x1-22, cy, x1-90, cy, '#7c3aed', 1.4, 7);
|
||||
// Линия вправо к -q (приходит)
|
||||
g += PHYS.drawArrow(x2+90, cy, x2+22, cy, '#7c3aed', 1.4, 7);
|
||||
g += PHYS.chargeMark(x1, cy, +1, 22, '');
|
||||
g += PHYS.chargeMark(x2, cy, -1, 22, '');
|
||||
} else {
|
||||
// Однородное поле: параллельные стрелки
|
||||
// Условные пластины слева и справа
|
||||
g += '<line x1="40" y1="60" x2="40" y2="300" stroke="#dc2626" stroke-width="4"/>';
|
||||
g += '<line x1="440" y1="60" x2="440" y2="300" stroke="#2563eb" stroke-width="4"/>';
|
||||
g += '<text x="40" y="50" text-anchor="middle" font-family="Inter,sans-serif" font-size="13" font-weight="700" fill="#dc2626">+</text>';
|
||||
g += '<text x="440" y="50" text-anchor="middle" font-family="Inter,sans-serif" font-size="13" font-weight="700" fill="#2563eb">−</text>';
|
||||
// 8 параллельных стрелок
|
||||
const rows = 7;
|
||||
for(let i = 0; i < rows; i++){
|
||||
const y = 90 + i * 32;
|
||||
g += PHYS.drawArrow(70, y, 410, y, '#7c3aed', 2.0, 9);
|
||||
}
|
||||
g += '<text x="240" y="335" text-anchor="middle" font-family="Inter,sans-serif" font-size="12" font-weight="700" fill="#7c3aed">$\\vec{E}$ = const во всех точках</text>';
|
||||
}
|
||||
|
||||
svg.innerHTML = g;
|
||||
out.innerHTML = '<b>'+NAMES[t]+'.</b> '+DESC[t];
|
||||
renderMath(out);
|
||||
|
||||
seen.add(t);
|
||||
if(!_done && seen.size >= 5){ _done = true; addXp(10, 'p20-iv1'); bumpProgress('p20', 15); }
|
||||
}
|
||||
tS.addEventListener('input', render);
|
||||
render();
|
||||
})();
|
||||
|
||||
/* IV2 — Свойства силовых линий (квикфайр да/нет с вариантами) */
|
||||
(function(){
|
||||
const Q = [
|
||||
{ q:'Могут ли две силовые линии пересекаться?', opts:['Да', 'Нет'], ans:1, why:'Нет: в точке пересечения было бы два направления поля одновременно — противоречие.' },
|
||||
{ q:'Где линии плотнее (гуще)?', opts:['Возле заряда', 'Вдали от заряда'], ans:0, why:'Возле заряда: там $E$ больше, плотность линий пропорциональна $E$.' },
|
||||
{ q:'Куда направлены линии от положительного заряда $+q$?', opts:['От заряда (наружу)', 'К заряду (внутрь)'], ans:0, why:'От $+q$ линии расходятся наружу.' },
|
||||
{ q:'Куда направлены линии к отрицательному заряду $-q$?', opts:['От заряда', 'К заряду (внутрь)'], ans:1, why:'К $-q$ линии сходятся внутрь.' },
|
||||
{ q:'Что показывает густота силовых линий?', opts:['Величину $E$', 'Знак заряда'], ans:0, why:'Густота пропорциональна $E$: где гуще — поле сильнее.' },
|
||||
{ q:'Как направлены линии в однородном поле?', opts:['Радиально', 'Параллельно друг другу'], ans:1, why:'Параллельно: $\\vec{E}$ одинакова во всех точках по модулю и направлению.' }
|
||||
];
|
||||
let i = 0, score = 0;
|
||||
const qEl = document.getElementById('p20-iv2-q');
|
||||
const oEl = document.getElementById('p20-iv2-opts');
|
||||
const fb = document.getElementById('p20-iv2-fb');
|
||||
const iEl = document.getElementById('p20-iv2-i');
|
||||
const sEl = document.getElementById('p20-iv2-s');
|
||||
|
||||
function show(){
|
||||
if(i >= Q.length){
|
||||
qEl.innerHTML = '<b>Готово!</b> Результат: ' + score + ' / ' + Q.length;
|
||||
oEl.innerHTML = '';
|
||||
if(score === Q.length){ addXp(15, 'p20-iv2'); bumpProgress('p20', 25); }
|
||||
else if(score >= 4){ addXp(8, 'p20-iv2'); bumpProgress('p20', 15); }
|
||||
return;
|
||||
}
|
||||
iEl.textContent = (i+1);
|
||||
sEl.textContent = score;
|
||||
const item = Q[i];
|
||||
qEl.innerHTML = item.q;
|
||||
oEl.innerHTML = item.opts.map((t, k) => '<button class="btn primary" data-v="' + k + '">' + t + '</button>').join('');
|
||||
fb.style.display = 'none';
|
||||
renderMath(qEl); renderMath(oEl);
|
||||
oEl.querySelectorAll('button').forEach(b => {
|
||||
b.addEventListener('click', () => {
|
||||
const v = +b.dataset.v;
|
||||
if(v === item.ans){ score++; feedback(fb, true, '✓ Верно! ' + item.why + ' Дальше ▶'); }
|
||||
else feedback(fb, false, '✗ Неверно. ' + item.why + ' Дальше ▶');
|
||||
sEl.textContent = score;
|
||||
oEl.querySelectorAll('button').forEach(x => x.disabled = true);
|
||||
i++;
|
||||
setTimeout(show, 1700);
|
||||
});
|
||||
});
|
||||
}
|
||||
document.getElementById('p20-iv2-restart').addEventListener('click', () => { i = 0; score = 0; show(); });
|
||||
show();
|
||||
})();
|
||||
|
||||
/* IV3 — Какая картина соответствует конфигурации? */
|
||||
(function(){
|
||||
const OPTS = ['Радиальные от центра', 'Радиальные к центру', 'Диполь (от + к −)', 'Параллельные'];
|
||||
const Q = [
|
||||
{ q:'Точечный заряд $+q$ в центре.', ans:0, why:'Линии расходятся радиально от $+q$ наружу.' },
|
||||
{ q:'Точечный заряд $-q$ в центре.', ans:1, why:'Линии сходятся радиально к $-q$ внутрь.' },
|
||||
{ q:'Два заряда: $+q$ и $-q$.', ans:2, why:'Это классическая картина диполя: линии идут от $+q$ к $-q$.' },
|
||||
{ q:'Между пластинами заряженного конденсатора.', ans:3, why:'В однородном поле линии параллельны и одинаково расположены.' },
|
||||
{ q:'Заряженная положительно сфера, точка снаружи.', ans:0, why:'Снаружи сфера действует как точечный заряд: линии радиально от центра.' },
|
||||
{ q:'Два одноимённых заряда $+q$ и $+q$.', ans:0, why:'От каждого заряда линии расходятся радиально (ближе всего к этой картине). В центре между ними — точка $E = 0$.' }
|
||||
];
|
||||
let i = 0, score = 0;
|
||||
const qEl = document.getElementById('p20-iv3-q');
|
||||
const oEl = document.getElementById('p20-iv3-opts');
|
||||
const fb = document.getElementById('p20-iv3-fb');
|
||||
const iEl = document.getElementById('p20-iv3-i');
|
||||
const sEl = document.getElementById('p20-iv3-s');
|
||||
|
||||
function show(){
|
||||
if(i >= Q.length){
|
||||
qEl.innerHTML = '<b>Готово!</b> Результат: ' + score + ' / ' + Q.length;
|
||||
oEl.innerHTML = '';
|
||||
if(score === Q.length){ addXp(15, 'p20-iv3'); bumpProgress('p20', 25); }
|
||||
else if(score >= 4){ addXp(8, 'p20-iv3'); bumpProgress('p20', 15); }
|
||||
return;
|
||||
}
|
||||
iEl.textContent = (i+1);
|
||||
sEl.textContent = score;
|
||||
const item = Q[i];
|
||||
qEl.innerHTML = item.q;
|
||||
oEl.innerHTML = OPTS.map((t, k) => '<button class="btn primary" data-v="' + k + '">' + t + '</button>').join('');
|
||||
fb.style.display = 'none';
|
||||
renderMath(qEl); renderMath(oEl);
|
||||
oEl.querySelectorAll('button').forEach(b => {
|
||||
b.addEventListener('click', () => {
|
||||
const v = +b.dataset.v;
|
||||
if(v === item.ans){ score++; feedback(fb, true, '✓ Верно! ' + item.why + ' Дальше ▶'); }
|
||||
else feedback(fb, false, '✗ Неверно. ' + item.why + ' Дальше ▶');
|
||||
sEl.textContent = score;
|
||||
oEl.querySelectorAll('button').forEach(x => x.disabled = true);
|
||||
i++;
|
||||
setTimeout(show, 1700);
|
||||
});
|
||||
});
|
||||
}
|
||||
document.getElementById('p20-iv3-restart').addEventListener('click', () => { i = 0; score = 0; show(); });
|
||||
show();
|
||||
})();
|
||||
|
||||
/* IV4 — Тренажёр поля */
|
||||
(function(){
|
||||
const Q = [
|
||||
{ q:'В однородном поле линии параллельны? Введи $1$ (да) или $2$ (нет).', ans:1, tol:0.1, hint:'Да: однородное поле — параллельные линии.' },
|
||||
{ q:'В точке между двумя одинаковыми $+q$ зарядами $E = ?$ В/м (для симметрии).', ans:0, tol:0.1, hint:'Поля от одинаковых зарядов компенсируются в середине — $E = 0$.' },
|
||||
{ q:'$E \\propto 1/r^2$. На каком $r$ (м) напряжённость уменьшится в $9$ раз по сравнению с $r_0 = 1$ м?', ans:3, tol:0.1, hint:'$E \\propto 1/r^2$: в $9$ раз меньше $\\Rightarrow r^2 = 9 \\Rightarrow r = 3$ м.' },
|
||||
{ q:'Густота линий в точке означает: $1$ = величину $E$, $2$ = направление $E$, $3$ = знак заряда.', ans:1, tol:0.1, hint:'Густота линий пропорциональна модулю $E$.' },
|
||||
{ q:'Силовая линия в точке указывает направление: $1$ = на источник, $2$ = вектора $\\vec{E}$, $3$ = случайно.', ans:2, tol:0.1, hint:'По определению, касательная к силовой линии в каждой точке совпадает с $\\vec{E}$.' }
|
||||
];
|
||||
let i = 0, score = 0;
|
||||
function show(){
|
||||
if(i >= Q.length){
|
||||
document.getElementById('p20-iv4-q').innerHTML = '<b>Готово!</b> Результат: ' + score + ' / ' + Q.length;
|
||||
if(score === Q.length){ addXp(15, 'p20-iv4'); bumpProgress('p20', 25); }
|
||||
else if(score >= 3){ addXp(8, 'p20-iv4'); bumpProgress('p20', 15); }
|
||||
return;
|
||||
}
|
||||
document.getElementById('p20-iv4-i').textContent = (i+1);
|
||||
document.getElementById('p20-iv4-s').textContent = score;
|
||||
document.getElementById('p20-iv4-q').innerHTML = Q[i].q;
|
||||
document.getElementById('p20-iv4-ans').value = '';
|
||||
renderMath(document.getElementById('p20-iv4-q'));
|
||||
document.getElementById('p20-iv4-fb').style.display = 'none';
|
||||
}
|
||||
function go(){
|
||||
if(i >= Q.length) return;
|
||||
const fb = document.getElementById('p20-iv4-fb');
|
||||
const raw = document.getElementById('p20-iv4-ans').value.replace(',', '.');
|
||||
const ans = parseFloat(raw);
|
||||
if(isNaN(ans)){ feedback(fb, false, '✗ Введи число.'); return; }
|
||||
if(Math.abs(ans - Q[i].ans) <= Q[i].tol + 0.001){ score++; feedback(fb, true, '✓ Верно! '+Q[i].hint+' Дальше ▶'); }
|
||||
else feedback(fb, false, '✗ Неверно. Ответ: $'+Q[i].ans+'$. '+Q[i].hint+' Дальше ▶');
|
||||
document.getElementById('p20-iv4-s').textContent = score;
|
||||
i++;
|
||||
setTimeout(show, 1800);
|
||||
}
|
||||
document.getElementById('p20-iv4-go').addEventListener('click', go);
|
||||
document.getElementById('p20-iv4-ans').addEventListener('keydown', e => { if(e.key === 'Enter') go(); });
|
||||
document.getElementById('p20-iv4-start').addEventListener('click', () => { i = 0; score = 0; show(); });
|
||||
show();
|
||||
})();
|
||||
|
||||
wireReadBtn('p20');
|
||||
}
|
||||
|
||||
function build_p21(){
|
||||
const box = document.getElementById('p21-body');
|
||||
let html = '';
|
||||
html += makeCard('theory', "Работа поля. Потенциал", "§21", `
|
||||
<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 3+:</b> наполнение этого § содержанием по учебнику «Физика 10» (Беларусь, 2019).
|
||||
</p>
|
||||
|
||||
/* THEORY 1 — Работа однородного электростатического поля */
|
||||
html += makeCard('theory', "Работа однородного электростатического поля", "§21", `
|
||||
<p>В однородном поле напряжённостью $\\vec{E}$ на заряд $q$ действует сила $\\vec{F} = q\\vec{E}$. При перемещении заряда на расстояние $d$ под углом $\\alpha$ к силе:</p>
|
||||
<p style="text-align:center;margin:10px 0">$$A = Fd\\cos\\alpha = qEd\\cos\\alpha$$</p>
|
||||
<p style="margin-top:10px;padding:10px 14px;background:var(--sec-acc-soft);border-radius:9px"><b>Очень важно:</b> работа электростатического поля <b>не зависит от формы траектории</b> — только от <b>начального</b> и <b>конечного</b> положений заряда.</p>
|
||||
<p style="margin-top:10px">Поле, обладающее этим свойством, называется <b>потенциальным</b> (= консервативным).</p>
|
||||
<p style="margin-top:10px"><b>Следствие:</b> работа по замкнутой траектории равна нулю — $A_{замкн} = 0$.</p>
|
||||
`);
|
||||
|
||||
/* THEORY 2 — Потенциал */
|
||||
html += makeCard('rule', "Потенциал электростатического поля", "§21", `
|
||||
<p><b>Потенциал</b> $\\varphi$ — скалярная энергетическая характеристика электростатического поля в данной точке. Определяется как отношение потенциальной энергии пробного заряда $W_p$ к величине этого заряда:</p>
|
||||
<p style="text-align:center;margin:10px 0">$$\\varphi = \\dfrac{W_p}{q_{пр}}$$</p>
|
||||
<p><b>Единица измерения:</b> <b>Вольт</b> (В) $= 1$ Дж / Кл.</p>
|
||||
<p style="margin-top:10px"><b>Потенциал точечного заряда</b> $q$ на расстоянии $r$:</p>
|
||||
<p style="text-align:center;margin:10px 0">$$\\varphi = k\\,\\dfrac{q}{r}$$</p>
|
||||
<p>Знак потенциала <b>совпадает со знаком заряда</b> (для точечного заряда). На бесконечности $\\varphi = 0$.</p>
|
||||
<p style="margin-top:10px;padding:10px 14px;background:var(--warn-bg,#fef3c7);border-left:4px solid var(--warn,#f59e0b);border-radius:9px"><b>Принцип суперпозиции для потенциала:</b> $\\varphi = \\varphi_1 + \\varphi_2 + \\ldots$ — потенциалы складываются <b>алгебраически</b> (со знаками!), не векторно.</p>
|
||||
`);
|
||||
|
||||
/* THEORY 3 — Работа через потенциал */
|
||||
html += makeCard('example', "Связь работы с потенциалом", "§21", `
|
||||
<p><b>Работа поля</b> при перемещении заряда $q$ из точки 1 в точку 2:</p>
|
||||
<p style="text-align:center;margin:10px 0">$$A_{12} = q(\\varphi_1 - \\varphi_2)$$</p>
|
||||
<p>Это <b>разность потенциалов</b>, умноженная на заряд.</p>
|
||||
<p style="margin-top:10px"><b>В однородном поле</b>:</p>
|
||||
<p style="text-align:center;margin:10px 0">$$E = \\dfrac{\\varphi_1 - \\varphi_2}{d} = \\dfrac{U}{d}$$</p>
|
||||
<p>где $d$ — расстояние между точками вдоль $\\vec{E}$.</p>
|
||||
<p style="padding:10px 14px;background:var(--sec-acc-soft);border-radius:9px;margin:10px 0"><b>Пример.</b> Заряд $q = +2$ нКл перенесли из точки с $\\varphi_1 = 100$ В в точку с $\\varphi_2 = 40$ В. Работа поля?<br>
|
||||
$A = q(\\varphi_1 - \\varphi_2) = 2\\cdot10^{-9} \\cdot 60 = 1{,}2 \\cdot 10^{-7}$ Дж $= 120$ нДж.</p>
|
||||
<p>$A > 0$ — поле совершило положительную работу: заряд перемещался по направлению $\\vec{E}$, от большего $\\varphi$ к меньшему.</p>
|
||||
`);
|
||||
|
||||
/* INTERACTIVE 1 — Однородное поле и работа */
|
||||
html += `<div class="wg" id="p21-iv1">
|
||||
<div class="wg-header"><span class="wg-badge">ИНТЕРАКТИВ 1</span><div class="wg-title">Однородное поле: $A = qEd\\cos\\alpha$</div></div>
|
||||
<div class="wg-help">Меняй $q$, $E$, $d$, угол $\\alpha$ — наблюдай работу поля и направление силы.</div>
|
||||
<div class="sliders">
|
||||
<label>$q$: <b id="p21-iv1-qL">+5</b> нКл <input type="range" id="p21-iv1-q" min="-10" max="10" value="5" step="1"></label>
|
||||
<label>$E$: <b id="p21-iv1-EL">500</b> В/м <input type="range" id="p21-iv1-E" min="100" max="1000" value="500" step="50"></label>
|
||||
<label>$d$: <b id="p21-iv1-dL">0.10</b> м <input type="range" id="p21-iv1-d" min="0.01" max="0.20" value="0.10" step="0.01"></label>
|
||||
<label>$\\alpha$: <b id="p21-iv1-aL">0</b>° <input type="range" id="p21-iv1-a" min="0" max="180" value="0" step="15"></label>
|
||||
</div>
|
||||
<div style="background:var(--card);border:1px solid var(--border);border-radius:9px;padding:8px">
|
||||
<svg id="p21-iv1-svg" viewBox="0 0 480 280" width="100%" style="height:auto"></svg>
|
||||
</div>
|
||||
<div id="p21-iv1-out" style="margin-top:10px;padding:10px 14px;background:var(--sec-acc-soft);border-radius:9px;font-size:.94rem;line-height:1.75;text-align:center"></div>
|
||||
</div>`;
|
||||
|
||||
/* INTERACTIVE 2 — Калькулятор потенциала */
|
||||
html += `<div class="wg" id="p21-iv2">
|
||||
<div class="wg-header"><span class="wg-badge">ИНТЕРАКТИВ 2</span><div class="wg-title">Калькулятор потенциала точечного заряда</div></div>
|
||||
<div class="wg-help">$\\varphi = k\\,q / r$. Для двух зарядов: $\\varphi_{сум} = \\varphi_1 + \\varphi_2$ (алгебраически!).</div>
|
||||
<div style="display:grid;grid-template-columns:1fr 1fr;gap:10px;align-items:end;margin-bottom:10px">
|
||||
<label>$q_1$ (нКл): <input type="number" id="p21-iv2-q1" class="tinp" value="1" step="0.1" style="width:100%"></label>
|
||||
<label>$r_1$ (м): <input type="number" id="p21-iv2-r1" class="tinp" value="0.1" step="0.01" min="0.01" style="width:100%"></label>
|
||||
<label>$q_2$ (нКл, опц.): <input type="number" id="p21-iv2-q2" class="tinp" value="0" step="0.1" style="width:100%"></label>
|
||||
<label>$r_2$ (м): <input type="number" id="p21-iv2-r2" class="tinp" value="0.1" step="0.01" min="0.01" style="width:100%"></label>
|
||||
</div>
|
||||
<div style="display:flex;justify-content:center;margin-bottom:10px">
|
||||
<button class="btn primary" id="p21-iv2-go">Вычислить $\\varphi$</button>
|
||||
</div>
|
||||
<div id="p21-iv2-out" style="padding:12px 14px;background:var(--sec-acc-soft);border-radius:9px;font-size:.95rem;line-height:1.75;text-align:center"></div>
|
||||
</div>`;
|
||||
|
||||
/* INTERACTIVE 3 — Работа поля + или − ? */
|
||||
html += `<div class="wg" id="p21-iv3">
|
||||
<div class="wg-header"><span class="wg-badge">ИНТЕРАКТИВ 3</span><div class="wg-title">Работа поля: $+$, $-$ или $0$?</div></div>
|
||||
<div class="wg-help">Определи знак работы электростатического поля в каждой ситуации.</div>
|
||||
<div class="score-display"><span>Задача <b id="p21-iv3-i">1</b> / 6</span><span>Очки: <b id="p21-iv3-s">0</b> / 6</span></div>
|
||||
<div id="p21-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="p21-iv3-opts" style="display:grid;grid-template-columns:1fr 1fr 1fr;gap:8px"></div>
|
||||
<div class="feedback" id="p21-iv3-fb"></div>
|
||||
<div class="actions"><button class="btn" id="p21-iv3-restart">Начать заново</button></div>
|
||||
</div>`;
|
||||
|
||||
/* INTERACTIVE 4 — Тренажёр работы и потенциала */
|
||||
html += `<div class="wg" id="p21-iv4">
|
||||
<div class="wg-header"><span class="wg-badge">ИНТЕРАКТИВ 4</span><div class="wg-title">Тренажёр работы и потенциала</div></div>
|
||||
<div class="wg-help">5 задач. $k = 9 \\cdot 10^9$. Допуск $\\pm 5\\%$.</div>
|
||||
<div class="score-display"><span>Задача <b id="p21-iv4-i">1</b> / 5</span><span>Очки: <b id="p21-iv4-s">0</b> / 5</span></div>
|
||||
<div id="p21-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 style="display:flex;gap:10px;align-items:center;flex-wrap:wrap;justify-content:center">
|
||||
<span style="font-family:'JetBrains Mono',monospace">ответ =</span>
|
||||
<input type="number" id="p21-iv4-ans" class="tinp" style="width:140px;text-align:center" step="any">
|
||||
<button class="btn primary" id="p21-iv4-go">Проверить</button>
|
||||
<button class="btn" id="p21-iv4-start">Заново</button>
|
||||
</div>
|
||||
<div class="feedback" id="p21-iv4-fb"></div>
|
||||
</div>`;
|
||||
|
||||
html += secNav('p20', 'p22');
|
||||
html += readButton('p21');
|
||||
|
||||
box.innerHTML = html;
|
||||
renderMath(box);
|
||||
|
||||
/* IV1 — Однородное поле: A = qEd cos α */
|
||||
(function(){
|
||||
const svg = document.getElementById('p21-iv1-svg');
|
||||
const qS = document.getElementById('p21-iv1-q');
|
||||
const ES = document.getElementById('p21-iv1-E');
|
||||
const dS = document.getElementById('p21-iv1-d');
|
||||
const aS = document.getElementById('p21-iv1-a');
|
||||
const qL = document.getElementById('p21-iv1-qL');
|
||||
const EL = document.getElementById('p21-iv1-EL');
|
||||
const dL = document.getElementById('p21-iv1-dL');
|
||||
const aL = document.getElementById('p21-iv1-aL');
|
||||
const out = document.getElementById('p21-iv1-out');
|
||||
const seen = new Set();
|
||||
let _done = false;
|
||||
|
||||
function fmtQ(q){ return (q>=0?'+':'') + q; }
|
||||
function render(){
|
||||
const q = +qS.value, E = +ES.value, d = +dS.value, aDeg = +aS.value;
|
||||
qL.textContent = fmtQ(q); EL.textContent = E; dL.textContent = d.toFixed(2); aL.textContent = aDeg;
|
||||
|
||||
const W = 480, H = 280, cy = H/2;
|
||||
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">Однородное поле: $A = qEd\\cos\\alpha$</text>';
|
||||
|
||||
// Поле — 5 параллельных стрелок (горизонтально вправо)
|
||||
const fieldRows = [70, 110, 150, 190, 230];
|
||||
for(let i = 0; i < fieldRows.length; i++){
|
||||
g += PHYS.drawArrow(40, fieldRows[i], 440, fieldRows[i], '#a78bfa', 1.4, 7);
|
||||
}
|
||||
g += '<text x="44" y="60" font-family="Inter,sans-serif" font-size="11" font-weight="700" fill="#7c3aed">$\\vec{E}$</text>';
|
||||
|
||||
// Начальная и конечная точки заряда
|
||||
const x0 = 180, y0 = cy;
|
||||
const Dpx = 130 * (d / 0.2); // длина в px, max 130
|
||||
const aRad = aDeg * Math.PI / 180;
|
||||
const x1 = x0 + Dpx * Math.cos(aRad);
|
||||
const y1 = y0 - Dpx * Math.sin(aRad); // y инвертирована
|
||||
|
||||
// Стрелка перемещения d (зелёная)
|
||||
g += PHYS.drawArrow(x0, y0, x1, y1, '#10b981', 2.6, 10);
|
||||
// Подпись d
|
||||
const midX = (x0+x1)/2, midY = (y0+y1)/2;
|
||||
g += '<text x="'+midX+'" y="'+(midY-10)+'" text-anchor="middle" font-family="JetBrains Mono,monospace" font-size="11" font-weight="700" fill="#10b981">d</text>';
|
||||
|
||||
// Сила F = qE (если q>0 — вправо, если q<0 — влево)
|
||||
const Fdir = q > 0 ? 1 : (q < 0 ? -1 : 0);
|
||||
if(Fdir !== 0){
|
||||
const Flen = 70;
|
||||
const fx0 = x0, fy0 = y0;
|
||||
const fx1 = x0 + Fdir * Flen, fy1 = y0;
|
||||
g += PHYS.drawArrow(fx0, fy0, fx1, fy1, '#dc2626', 2.6, 10);
|
||||
g += '<text x="'+(fx1 + Fdir*8)+'" y="'+(fy1+4)+'" text-anchor="'+(Fdir>0?'start':'end')+'" font-family="Inter,sans-serif" font-size="12" font-weight="700" fill="#dc2626">$\\vec{F}$</text>';
|
||||
}
|
||||
|
||||
// Заряд в начальной точке
|
||||
if(q === 0){
|
||||
g += '<circle cx="'+x0+'" cy="'+y0+'" r="14" fill="#e5e7eb" stroke="#94a3b8" stroke-width="2"/>';
|
||||
g += '<text x="'+x0+'" y="'+(y0+5)+'" text-anchor="middle" font-family="Inter,sans-serif" font-size="13" font-weight="700" fill="#64748b">0</text>';
|
||||
} else {
|
||||
g += PHYS.chargeMark(x0, y0, q > 0 ? 1 : -1, 14, '');
|
||||
}
|
||||
// Подпись заряда
|
||||
g += '<text x="'+x0+'" y="'+(y0+30)+'" text-anchor="middle" font-family="JetBrains Mono,monospace" font-size="11" font-weight="700" fill="#0f172a">q = '+fmtQ(q)+' нКл</text>';
|
||||
|
||||
// Угол α — дуга
|
||||
if(aDeg > 0 && aDeg < 180 && Dpx > 30){
|
||||
const Rarc = 28;
|
||||
const startA = 0, endA = -aRad;
|
||||
const lx1 = x0 + Rarc, ly1 = y0;
|
||||
const lx2 = x0 + Rarc*Math.cos(aRad), ly2 = y0 - Rarc*Math.sin(aRad);
|
||||
g += '<path d="M '+lx1+' '+ly1+' A '+Rarc+' '+Rarc+' 0 0 0 '+lx2+' '+ly2+'" fill="none" stroke="#7c3aed" stroke-width="1.5"/>';
|
||||
const midA = aRad/2;
|
||||
g += '<text x="'+(x0 + (Rarc+8)*Math.cos(midA))+'" y="'+(y0 - (Rarc+8)*Math.sin(midA) + 4)+'" text-anchor="middle" font-family="Inter,sans-serif" font-size="11" font-weight="700" fill="#7c3aed">α</text>';
|
||||
}
|
||||
|
||||
svg.innerHTML = g;
|
||||
|
||||
// Расчёт
|
||||
const qC = q * 1e-9;
|
||||
const F = Math.abs(qC) * E;
|
||||
// A = qEd cos α (сохраняем знак q)
|
||||
const A = qC * E * d * Math.cos(aRad);
|
||||
const Annano = A * 1e9; // нДж
|
||||
|
||||
let sign = '';
|
||||
if(Math.abs(A) < 1e-15){ sign = ' (заряд $0$ или $\\alpha = 90°$)'; }
|
||||
else if(A > 0){ sign = ' <span style="color:#10b981">($A > 0$, поле совершает работу)</span>'; }
|
||||
else { sign = ' <span style="color:#dc2626">($A < 0$, против поля)</span>'; }
|
||||
|
||||
out.innerHTML = '<b>$F = |q|E = '+F.toExponential(2)+'$ Н</b> '
|
||||
+ '<b>$A = qEd\\cos\\alpha = '+Annano.toFixed(1)+'$ нДж</b>' + sign;
|
||||
renderMath(out);
|
||||
|
||||
seen.add(q+':'+E+':'+d.toFixed(2)+':'+aDeg);
|
||||
if(!_done && seen.size >= 4){ _done = true; addXp(10, 'p21-iv1'); bumpProgress('p21', 15); }
|
||||
}
|
||||
qS.addEventListener('input', render);
|
||||
ES.addEventListener('input', render);
|
||||
dS.addEventListener('input', render);
|
||||
aS.addEventListener('input', render);
|
||||
render();
|
||||
})();
|
||||
|
||||
/* IV2 — Калькулятор потенциала */
|
||||
(function(){
|
||||
const k = PHYS.CONST.k;
|
||||
const out = document.getElementById('p21-iv2-out');
|
||||
const seen = new Set();
|
||||
let _done = false;
|
||||
|
||||
function calc(){
|
||||
const q1 = parseFloat(document.getElementById('p21-iv2-q1').value) || 0;
|
||||
const r1 = parseFloat(document.getElementById('p21-iv2-r1').value) || 0.01;
|
||||
const q2 = parseFloat(document.getElementById('p21-iv2-q2').value) || 0;
|
||||
const r2 = parseFloat(document.getElementById('p21-iv2-r2').value) || 0.01;
|
||||
|
||||
const phi1 = k * (q1 * 1e-9) / r1;
|
||||
const phi2 = (q2 !== 0) ? k * (q2 * 1e-9) / r2 : 0;
|
||||
const phiSum = phi1 + phi2;
|
||||
|
||||
let html = '';
|
||||
html += '<div><b>$\\varphi_1 = k\\,q_1/r_1 = 9\\cdot10^9 \\cdot ('+q1+'\\cdot10^{-9})/'+r1+' = '+phi1.toFixed(1)+'$ В</b></div>';
|
||||
if(q2 !== 0){
|
||||
html += '<div style="margin-top:6px"><b>$\\varphi_2 = k\\,q_2/r_2 = '+phi2.toFixed(1)+'$ В</b></div>';
|
||||
html += '<div style="margin-top:8px;font-size:1.05rem;color:#7c3aed"><b>$\\varphi = \\varphi_1 + \\varphi_2 = '+phiSum.toFixed(1)+'$ В</b></div>';
|
||||
} else {
|
||||
html += '<div style="margin-top:6px;font-size:.88rem;color:#64748b">Введи $q_2 \\ne 0$ для суперпозиции потенциалов.</div>';
|
||||
}
|
||||
out.innerHTML = html;
|
||||
renderMath(out);
|
||||
|
||||
seen.add(q1+':'+r1+':'+q2+':'+r2);
|
||||
if(!_done && seen.size >= 3){ _done = true; addXp(10, 'p21-iv2'); bumpProgress('p21', 15); }
|
||||
}
|
||||
document.getElementById('p21-iv2-go').addEventListener('click', calc);
|
||||
['p21-iv2-q1','p21-iv2-r1','p21-iv2-q2','p21-iv2-r2'].forEach(id => {
|
||||
document.getElementById(id).addEventListener('keydown', e => { if(e.key === 'Enter') calc(); });
|
||||
});
|
||||
calc();
|
||||
})();
|
||||
|
||||
/* IV3 — Работа поля + или − ? */
|
||||
(function(){
|
||||
const OPTS = ['$A > 0$', '$A < 0$', '$A = 0$'];
|
||||
const Q = [
|
||||
{ q:'Заряд $+q$ перемещается по направлению $\\vec{E}$.', ans:0, why:'Сила $\\vec{F} = q\\vec{E}$ сонаправлена с перемещением $\\Rightarrow A > 0$.' },
|
||||
{ q:'Заряд $+q$ перемещается против $\\vec{E}$.', ans:1, why:'$\\vec{F}$ противоположна перемещению $\\Rightarrow A < 0$.' },
|
||||
{ q:'Заряд $-q$ перемещается по направлению $\\vec{E}$.', ans:1, why:'У $-q$ сила $\\vec{F} = q\\vec{E}$ направлена против $\\vec{E}$, значит против перемещения $\\Rightarrow A < 0$.' },
|
||||
{ q:'Заряд $-q$ перемещается против $\\vec{E}$.', ans:0, why:'У $-q$ сила направлена против $\\vec{E}$, то есть по направлению перемещения $\\Rightarrow A > 0$.' },
|
||||
{ q:'Заряд перемещается перпендикулярно $\\vec{E}$ ($\\alpha = 90°$).', ans:2, why:'$A = qEd\\cos 90° = 0$.' },
|
||||
{ q:'Заряд вернулся в исходную точку по замкнутой траектории.', ans:2, why:'Поле потенциально: $A_{замкн} = 0$ для любой замкнутой траектории.' }
|
||||
];
|
||||
let i = 0, score = 0;
|
||||
const qEl = document.getElementById('p21-iv3-q');
|
||||
const oEl = document.getElementById('p21-iv3-opts');
|
||||
const fb = document.getElementById('p21-iv3-fb');
|
||||
const iEl = document.getElementById('p21-iv3-i');
|
||||
const sEl = document.getElementById('p21-iv3-s');
|
||||
|
||||
function show(){
|
||||
if(i >= Q.length){
|
||||
qEl.innerHTML = '<b>Готово!</b> Результат: ' + score + ' / ' + Q.length;
|
||||
oEl.innerHTML = '';
|
||||
if(score === Q.length){ addXp(15, 'p21-iv3'); bumpProgress('p21', 25); }
|
||||
else if(score >= 4){ addXp(8, 'p21-iv3'); bumpProgress('p21', 15); }
|
||||
return;
|
||||
}
|
||||
iEl.textContent = (i+1);
|
||||
sEl.textContent = score;
|
||||
const item = Q[i];
|
||||
qEl.innerHTML = item.q;
|
||||
oEl.innerHTML = OPTS.map((t, k) => '<button class="btn primary" data-v="' + k + '">' + t + '</button>').join('');
|
||||
fb.style.display = 'none';
|
||||
renderMath(qEl); renderMath(oEl);
|
||||
oEl.querySelectorAll('button').forEach(b => {
|
||||
b.addEventListener('click', () => {
|
||||
const v = +b.dataset.v;
|
||||
if(v === item.ans){ score++; feedback(fb, true, '✓ Верно! ' + item.why + ' Дальше ▶'); }
|
||||
else feedback(fb, false, '✗ Неверно. ' + item.why + ' Дальше ▶');
|
||||
sEl.textContent = score;
|
||||
oEl.querySelectorAll('button').forEach(x => x.disabled = true);
|
||||
i++;
|
||||
setTimeout(show, 1800);
|
||||
});
|
||||
});
|
||||
}
|
||||
document.getElementById('p21-iv3-restart').addEventListener('click', () => { i = 0; score = 0; show(); });
|
||||
show();
|
||||
})();
|
||||
|
||||
/* IV4 — Тренажёр работы и потенциала */
|
||||
(function(){
|
||||
const Q = [
|
||||
{ q:'Заряд $q = +1$ мкКл перенесли из точки с $\\varphi_1 = 50$ В в точку с $\\varphi_2 = 20$ В. Работа в мкДж?', ans:30, tol:1.5, hint:'$A = q(\\varphi_1 - \\varphi_2) = 10^{-6}\\cdot 30 = 30$ мкДж.' },
|
||||
{ q:'Однородное поле $E = 500$ В/м. Заряд $+2$ нКл перемещают на $10$ см по направлению поля. Работа в нДж?', ans:100, tol:5, hint:'$A = qEd = 2\\cdot10^{-9}\\cdot 500\\cdot 0{,}1 = 10^{-7}$ Дж $= 100$ нДж.' },
|
||||
{ q:'Потенциал поля точечного заряда $+1$ нКл на расстоянии $r = 0{,}1$ м? (В)', ans:90, tol:5, hint:'$\\varphi = kq/r = 9\\cdot10^9\\cdot 10^{-9}/0{,}1 = 90$ В.' },
|
||||
{ q:'Заряд $-2$ нКл. Потенциал на расстоянии $0{,}05$ м? (В)', ans:-360, tol:20, hint:'$\\varphi = kq/r = 9\\cdot10^9\\cdot(-2\\cdot10^{-9})/0{,}05 = -360$ В.' },
|
||||
{ q:'Однородное поле $E = 1000$ В/м между пластинами на расстоянии $d = 0{,}05$ м. Разность потенциалов $U$ в В?', ans:50, tol:3, hint:'$U = Ed = 1000\\cdot 0{,}05 = 50$ В.' }
|
||||
];
|
||||
let i = 0, score = 0;
|
||||
function show(){
|
||||
if(i >= Q.length){
|
||||
document.getElementById('p21-iv4-q').innerHTML = '<b>Готово!</b> Результат: ' + score + ' / ' + Q.length;
|
||||
if(score === Q.length){ addXp(15, 'p21-iv4'); bumpProgress('p21', 25); }
|
||||
else if(score >= 3){ addXp(8, 'p21-iv4'); bumpProgress('p21', 15); }
|
||||
return;
|
||||
}
|
||||
document.getElementById('p21-iv4-i').textContent = (i+1);
|
||||
document.getElementById('p21-iv4-s').textContent = score;
|
||||
document.getElementById('p21-iv4-q').innerHTML = Q[i].q;
|
||||
document.getElementById('p21-iv4-ans').value = '';
|
||||
renderMath(document.getElementById('p21-iv4-q'));
|
||||
document.getElementById('p21-iv4-fb').style.display = 'none';
|
||||
}
|
||||
function go(){
|
||||
if(i >= Q.length) return;
|
||||
const fb = document.getElementById('p21-iv4-fb');
|
||||
const raw = document.getElementById('p21-iv4-ans').value.replace(',', '.');
|
||||
const ans = parseFloat(raw);
|
||||
if(isNaN(ans)){ feedback(fb, false, '✗ Введи число.'); return; }
|
||||
if(Math.abs(ans - Q[i].ans) <= Q[i].tol + 0.001){ score++; feedback(fb, true, '✓ Верно! '+Q[i].hint+' Дальше ▶'); }
|
||||
else feedback(fb, false, '✗ Неверно. Ответ: $'+Q[i].ans+'$. '+Q[i].hint+' Дальше ▶');
|
||||
document.getElementById('p21-iv4-s').textContent = score;
|
||||
i++;
|
||||
setTimeout(show, 1800);
|
||||
}
|
||||
document.getElementById('p21-iv4-go').addEventListener('click', go);
|
||||
document.getElementById('p21-iv4-ans').addEventListener('keydown', e => { if(e.key === 'Enter') go(); });
|
||||
document.getElementById('p21-iv4-start').addEventListener('click', () => { i = 0; score = 0; show(); });
|
||||
show();
|
||||
})();
|
||||
|
||||
wireReadBtn('p21');
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user