diff --git a/frontend/js/phys7_ch4_widgets.js b/frontend/js/phys7_ch4_widgets.js new file mode 100644 index 0000000..0efb454 --- /dev/null +++ b/frontend/js/phys7_ch4_widgets.js @@ -0,0 +1,1300 @@ +// Физика 7 · Глава 4 «Давление» · виджеты §§28–35 + финал. +// Палитра главы — amber (#d97706). + +(function(){ +'use strict'; + +const ACCENT = '#d97706'; +const ACCENT_D = '#92400e'; +const ACCENT_SOFT = '#fef3c7'; + +function renderMath(root){ + if(window.renderMathInElement){ + try{ + window.renderMathInElement(root, { + delimiters: [{left:'$$',right:'$$',display:true},{left:'$',right:'$',display:false}], + throwOnError: false + }); + }catch(e){} + } +} + +function makeCard(kind, title, badge, body){ + const colorByKind = { theory:ACCENT, rule:'#0284c7', example:'#10b981' }; + const labelByKind = { theory:'Теория', rule:'Правило', example:'Пример' }; + const c = colorByKind[kind] || ACCENT; + return '
' + + '
' + + '' + labelByKind[kind] + '' + + '' + (badge||'') + '' + + '' + title + '' + + '
' + + '
' + body + '
' + + '
'; +} + +function wgWrap(id, badge, title, hint, body){ + return '
' + + '
' + + '' + badge + '' + + '' + title + '' + + '
' + + (hint ? '
' + hint + '
' : '') + + body + + '
'; +} + +function readButton(pid){ + return '
'; +} + +function wireReadBtn(pid){ + const btn = document.querySelector('.ph7-read-btn[data-pid="' + pid + '"]'); + if(!btn) return; + const KEY = 'physics7_ch4_read_' + pid; + if(localStorage.getItem(KEY) === '1'){ + btn.innerHTML = ' Прочитано'; + btn.disabled = true; btn.style.background = '#94a3b8'; btn.style.cursor = 'default'; + return; + } + btn.addEventListener('click', function(){ + if(localStorage.getItem(KEY) === '1') return; + localStorage.setItem(KEY, '1'); + if(typeof window.bumpProgress === 'function') window.bumpProgress(pid, 30); + if(typeof window.addXp === 'function') window.addXp(10, 'read-' + pid); + btn.innerHTML = ' Прочитано'; + btn.disabled = true; btn.style.background = '#94a3b8'; btn.style.cursor = 'default'; + }); +} + +function wireDnd(host, items){ + const root = document.getElementById(host); + if(!root) return; + const checkBtn = root.querySelector('.dnd-check'); + const fb = root.querySelector('.dnd-fb'); + let placed = {}, armed = null; + root.querySelectorAll('.dnd-chip').forEach(chip => chip.addEventListener('click', () => { + if(armed === chip){ armed.classList.remove('armed'); armed.style.boxShadow = ''; armed = null; return; } + if(armed){ armed.classList.remove('armed'); armed.style.boxShadow = ''; } + armed = chip; + chip.classList.add('armed'); + chip.style.boxShadow = '0 0 0 3px rgba(217,119,6,.3)'; + })); + root.querySelectorAll('.drop-box').forEach(box => box.addEventListener('click', () => { + if(!armed) return; + const cat = box.dataset.cat; + const id = armed.dataset.id; + placed[id] = cat; + const clone = armed.cloneNode(true); + clone.classList.remove('armed'); clone.classList.add('placed'); + clone.style.background = ACCENT_SOFT; clone.style.borderColor = ACCENT; clone.style.boxShadow = ''; + clone.addEventListener('click', e => { + e.stopPropagation(); + delete placed[id]; + clone.remove(); + armed = null; + const orig = root.querySelector('.dnd-chip[data-id="' + id + '"]:not(.placed)'); + if(orig) orig.style.display = ''; + }); + box.querySelector('.drop-items').appendChild(clone); + armed.style.display = 'none'; + armed.classList.remove('armed'); armed.style.boxShadow = ''; + armed = null; + })); + if(checkBtn) checkBtn.addEventListener('click', () => { + const total = items.length; + let correct = 0; + items.forEach(it => { if(placed[it.id] === it.cat) correct++; }); + fb.style.display = 'block'; + if(correct === total){ + fb.style.background = '#d1fae5'; fb.style.color = '#065f46'; fb.style.borderLeft = '4px solid #10b981'; + fb.innerHTML = '✓ Идеально! ' + total + '/' + total + '.'; + if(typeof window.addXp === 'function') window.addXp(15, 'dnd-' + host); + } else { + fb.style.background = '#fee2e2'; fb.style.color = '#7f1d1d'; fb.style.borderLeft = '4px solid #dc2626'; + fb.innerHTML = '✗ Правильно: ' + correct + '/' + total + '. Попробуй ещё раз.'; + } + }); +} + +function dndPool(host, items, cats){ + const chips = items.map(it => '').join(''); + const boxes = cats.map(c => '
' + c.label + '
').join(''); + return '
' + + '
Кликни по карточке, потом по корзине. Чтобы вернуть — кликни в корзине.
' + + '
' + chips + '
' + + '
' + boxes + '
' + + '
' + + '' + + '
'; +} + +function quizQuestion(host, idx, q, opts, correctIdx, explain){ + const optsHtml = opts.map((o,i) => '').join(''); + return '
' + + '
' + (idx+1) + '. ' + q + '
' + + '
' + optsHtml + '
' + + '' + + '
'; +} + +function wireQuiz(host, onAllCorrect){ + const root = document.getElementById(host); + if(!root) return; + const all = root.querySelectorAll('.qz-q'); + const done = new Set(); + all.forEach(qDiv => { + const opts = qDiv.querySelectorAll('.qz-opt'); + const correct = +qDiv.querySelector('.qz-opts').dataset.correct; + const explain = qDiv.querySelector('.qz-opts').dataset.explain; + const fb = qDiv.querySelector('.qz-fb'); + opts.forEach(o => o.addEventListener('click', () => { + if(done.has(qDiv)) return; + const i = +o.dataset.i; + opts.forEach(x => x.disabled = true); + if(i === correct){ + o.style.background = '#d1fae5'; o.style.borderColor = '#10b981'; o.style.color = '#065f46'; + fb.style.display = 'block'; fb.style.background = '#d1fae5'; fb.style.color = '#065f46'; fb.style.borderLeft = '4px solid #10b981'; + fb.innerHTML = '✓ Верно!' + (explain ? ' ' + explain : ''); + done.add(qDiv); + if(done.size === all.length && typeof onAllCorrect === 'function') onAllCorrect(); + } else { + o.style.background = '#fee2e2'; o.style.borderColor = '#dc2626'; o.style.color = '#7f1d1d'; + opts[correct].style.background = '#d1fae5'; opts[correct].style.borderColor = '#10b981'; opts[correct].style.color = '#065f46'; + fb.style.display = 'block'; fb.style.background = '#fee2e2'; fb.style.color = '#7f1d1d'; fb.style.borderLeft = '4px solid #dc2626'; + fb.innerHTML = '✗ Неверно. Правильно: «' + opts[correct].textContent + '».' + (explain ? ' ' + explain : ''); + done.add(qDiv); + } + })); + }); +} + +/* ========================================================== */ +/* §28 — Давление. Единицы давления */ +/* ========================================================== */ +function add_p28(){ + const body = document.getElementById('p28-body'); + if(!body) return; + let h = ''; + + h += makeCard('theory', 'Что такое давление', '§ 28.1', + 'Давление $p$ — это сила, действующая на единицу площади опоры:
' + + '$$p = \\dfrac{F}{S}$$
' + + 'где $F$ — сила (Н), $S$ — площадь (м²). Единица — паскаль: $1$ Па $= 1$ Н/м².

' + + 'Одно и то же тело может производить очень разное давление — всё зависит от площади опоры.'); + + h += makeCard('rule', 'Производные единицы', '§ 28.2', + ''); + + h += makeCard('example', 'Гвоздь, тапок, трактор', '§ 28.3', + '' + + '' + + [ + ['Гвоздь под молотком',100,'0,1 мм² = 10⁻⁷ м²','10⁹ Па'], + ['Балерина на пуанте',500,'1 см² = 10⁻⁴ м²','5 МПа'], + ['Человек на двух ногах',700,'300 см² = 0,03 м²','23 кПа'], + ['Лыжник',700,'0,25 м²','2,8 кПа'], + ['Трактор (на гусеницах)',50000,'5 м²','10 кПа'] + ].map(r => '').join('') + + '
ОбъектFSp
' + r[0] + '' + r[1] + ' Н' + r[2] + '' + r[3] + '
' + + '

Лыжник давит меньше, чем человек без лыж — поэтому не проваливается в снег.

'); + + /* IV-1 КАЛЬК p = F/S */ + h += wgWrap('p28-iv1', 'КАЛЬК', 'Калькулятор давления', 'Меняй силу и площадь — увидь, как меняется давление.', + '
' + + '' + + '' + + '
' + + '
' + + '$p = F/S = $ 50 000 Па $= $ 50 кПа' + + '
' + + '
'); + + /* IV-2 СИМ: переключатель сценариев */ + h += wgWrap('p28-iv2', 'СИМ', 'Один человек — разные ситуации', 'Один и тот же человек давит на грунт по-разному.', + '
' + + [['boots','В ботинках'],['skis','На лыжах'],['stilet','На каблуке']].map((s, i) => + '').join('') + + '
' + + '' + + '
'); + + /* IV-3 DnD */ + h += wgWrap('p28-iv3', 'DnD', 'Кто давит сильнее (большее p)?', '', + dndPool('p28-dnd', [ + { id:'a1', cat:'low', html:'Танк на гусеницах' }, + { id:'a2', cat:'low', html:'Лыжник на снегу' }, + { id:'a3', cat:'mid', html:'Человек в ботинках' }, + { id:'a4', cat:'mid', html:'Стул на 4 ножках' }, + { id:'a5', cat:'high', html:'Балерина на пуанте' }, + { id:'a6', cat:'high', html:'Гвоздь под молотком' } + ], [ + { cat:'low', label:'Малое (большая S)' }, + { cat:'mid', label:'Среднее' }, + { cat:'high', label:'Огромное (малая S)' } + ])); + + /* IV-4 ТРН */ + h += wgWrap('p28-iv4', 'ТРН', 'Тренажёр §28', '', + '
' + + quizQuestion('p28-tr', 0, '$F = 200$ Н, $S = 0{,}1$ м². Давление $p$?', ['20 Па','200 Па','2000 Па','20 000 Па'], 2, '$p = 200/0{,}1 = 2000$ Па.') + + quizQuestion('p28-tr', 1, 'Кирпич $F = 30$ Н стоит на $S = 100$ см² $= 0{,}01$ м². $p$?', ['300 Па','1500 Па','3000 Па','30 000 Па'], 2, '$p = 30/0{,}01 = 3000$ Па.') + + quizQuestion('p28-tr', 2, 'Какой ответ верный? $1$ кПа $= ?$ Па', ['10','100','1000','10 000'], 2) + + quizQuestion('p28-tr', 3, 'Чтобы уменьшить давление при той же силе, нужно…', ['Увеличить S','Уменьшить S','Уменьшить F','S не влияет'], 0, 'Из $p = F/S$: чем больше $S$, тем меньше $p$.') + + quizQuestion('p28-tr', 4, 'Площадь $S = 5$ см², $p = 200$ кПа. Какова сила $F$?', ['1 Н','10 Н','100 Н','1000 Н'], 2, '$S = 5 \\cdot 10^{-4}$ м², $F = pS = 200\\,000 \\cdot 5 \\cdot 10^{-4} = 100$ Н.') + + '
'); + + h += readButton('p28'); + body.innerHTML = h; + + // §28 IV-1 + const upd28 = () => { + const F = +document.getElementById('p28-F-r').value; + const Scm = +document.getElementById('p28-S-r').value; + const S = Scm * 1e-4; // м² + document.getElementById('p28-F').textContent = F; + document.getElementById('p28-S').textContent = Scm; + const p = F / S; + document.getElementById('p28-p').textContent = p.toLocaleString('ru-RU', { maximumFractionDigits: 0 }); + document.getElementById('p28-pkpa').textContent = (p / 1000).toFixed(2); + let cmp; + if(p < 1000) cmp = 'Очень малое — как давление гирь на резиновый коврик.'; + else if(p < 10000) cmp = 'Похоже на лыжника на снегу.'; + else if(p < 100000) cmp = 'Близко к давлению человека на полу.'; + else if(p < 1e6) cmp = 'Балерина на пуанте, копыто лошади.'; + else cmp = 'Огромное — как у гвоздя под молотком (≈ ГПа).'; + document.getElementById('p28-cmp').textContent = cmp; + }; + ['p28-F-r','p28-S-r'].forEach(id => document.getElementById(id).addEventListener('input', upd28)); + upd28(); + + // §28 IV-2 sims + const scenarios = { + boots: { S: 0.03, nm:'Ботинки на 2 ноги', cmp:'≈ давление человека (700 Н на 300 см²)' }, + skis: { S: 0.25, nm:'Лыжи', cmp:'в ~8 раз меньше — не проваливается в снег' }, + stilet: { S: 0.0001, nm:'Каблук-шпилька', cmp:'~ в 300 раз больше — повреждает паркет' } + }; + function draw28(sc){ + const W = 360, H = 140, baseY = 110; + let s = ''; + s += ''; + for(let i = 0; i < 18; i++) s += ''; + // Человек (упрощённо) + s += ''; // голова + s += ''; + // Опора (разная) + if(sc === 'boots'){ + s += ''; + s += '2 ботинка, S ≈ 300 см²'; + } else if(sc === 'skis'){ + s += ''; + s += '2 лыжи, S ≈ 2500 см²'; + } else { + s += ''; + s += '2 пуанта, S ≈ 1 см²'; + } + // Сила + s += ''; + s += ''; + s += 'F = 700 Н'; + document.getElementById('p28-sc-svg').innerHTML = s; + const d = scenarios[sc]; + const p = 700 / d.S; + document.getElementById('p28-sc-info').innerHTML = '' + d.nm + ': $S = ' + d.S + '$ м², $p = F/S = ' + Math.round(p).toLocaleString('ru-RU') + '$ Па $\\approx ' + (p/1000).toFixed(1) + '$ кПа
' + d.cmp + ''; + renderMath(document.getElementById('p28-sc-info')); + } + body.querySelectorAll('.p28-sc').forEach(btn => btn.addEventListener('click', () => { + body.querySelectorAll('.p28-sc').forEach(b => { b.style.background = '#fff'; b.style.color = ACCENT; }); + btn.style.background = ACCENT; btn.style.color = '#fff'; + draw28(btn.dataset.s); + })); + draw28('boots'); + + wireDnd('p28-dnd', [ + { id:'a1', cat:'low' },{ id:'a2', cat:'low' },{ id:'a3', cat:'mid' }, + { id:'a4', cat:'mid' },{ id:'a5', cat:'high' },{ id:'a6', cat:'high' } + ]); + wireQuiz('p28-tr-host', () => { if(window.addXp) window.addXp(15, 'tr-p28'); }); + wireReadBtn('p28'); + renderMath(body); +} + +/* ========================================================== */ +/* §29 — Давление газа */ +/* ========================================================== */ +function add_p29(){ + const body = document.getElementById('p29-body'); + if(!body) return; + let h = ''; + + h += makeCard('theory', 'Откуда давление у газа', '§ 29.1', + 'Молекулы газа постоянно бьются о стенки сосуда. Каждый удар — крошечная сила. ' + + 'Сумма всех ударов делится на площадь стенки — получается давление газа.

' + + 'У газа нет собственной формы и фиксированного объёма, поэтому давление возникает равномерно во все стороны.'); + + h += makeCard('rule', 'Что увеличивает p газа', '§ 29.2', + 'Давление газа растёт, если:' + + '
    ' + + '
  • Увеличить $T$ — молекулы быстрее, удары сильнее.
  • ' + + '
  • Уменьшить $V$ — то же число молекул на меньшей площади.
  • ' + + '
  • Добавить молекул (накачать) — больше ударов в секунду.
  • ' + + '
'); + + h += makeCard('example', 'Шарик и шина', '§ 29.3', + 'Воздушный шарик: накачиваем (добавляем молекулы) → $p$ растёт → шарик расширяется, ' + + 'пока упругость резины не уравновесит давление.

' + + 'Шина машины: летом нагревается на солнце → $T$ растёт → $p$ растёт. ' + + 'Поэтому летом давление в шинах выше, чем зимой.'); + + /* IV-1 СИМ */ + h += wgWrap('p29-iv1', 'СИМ', 'Молекулы газа в сосуде', 'Меняй число молекул и скорость — увидь, как меняется частота ударов.', + '
' + + '' + + '' + + '
' + + '' + + '
'); + + /* IV-2 КВИЗ */ + h += wgWrap('p29-iv2', 'КВИЗ', 'Давление газа', '', + '
' + + quizQuestion('p29-q', 0, 'Что создаёт давление газа на стенки сосуда?', ['Сила тяжести','Удары молекул о стенки','Поверхностное натяжение','Магнитное поле'], 1) + + quizQuestion('p29-q', 1, 'Если нагреть газ в закрытом сосуде, давление…', ['Не изменится','Уменьшится','Увеличится','Станет нулевым'], 2) + + quizQuestion('p29-q', 2, 'Если сжать газ (уменьшить $V$) при той же температуре, $p$…', ['Уменьшится','Увеличится','Не изменится','Зависит от массы'], 1) + + quizQuestion('p29-q', 3, 'В какую сторону газ давит на стенки сосуда?', ['Только вниз','Только вверх','Равномерно во все стороны','Только в одну сторону'], 2) + + '
'); + + /* IV-3 DnD */ + h += wgWrap('p29-iv3', 'DnD', 'p газа: больше или меньше?', '', + dndPool('p29-dnd', [ + { id:'a1', cat:'up', html:'Накачали колесо насосом' }, + { id:'a2', cat:'up', html:'Шар на солнце летом' }, + { id:'a3', cat:'up', html:'Сжали шприц поршнем' }, + { id:'a4', cat:'down', html:'Газ остыл' }, + { id:'a5', cat:'down', html:'Выпустили часть воздуха' }, + { id:'a6', cat:'down', html:'Расширили сосуд' } + ], [ + { cat:'up', label:'p растёт' }, + { cat:'down', label:'p падает' } + ])); + + /* IV-4 ТРН */ + h += wgWrap('p29-iv4', 'ТРН', 'Тренажёр §29', '', + '
' + + quizQuestion('p29-tr', 0, 'Газ в закрытом цилиндре охладили. С давлением:', ['Растёт','Падает','Не меняется','Становится 0'], 1) + + quizQuestion('p29-tr', 1, 'Где давление газа выше: в надутом мяче или в спущенном?', ['В спущенном','В надутом','Одинаково','Зависит от веса'], 1) + + quizQuestion('p29-tr', 2, 'В баллоне с гелием давление $p$. Если вытащить половину гелия (молекул в 2 раза меньше) при той же $T$ и $V$, $p$ станет…', ['В 2 раза больше','В 2 раза меньше','Тем же','Нулевым'], 1) + + quizQuestion('p29-tr', 3, 'Что произойдёт с шариком в очень холодильнике?', ['Лопнет','Сожмётся (давление упадёт, форма уменьшится)','Не изменится','Улетит'], 1) + + '
'); + + h += readButton('p29'); + body.innerHTML = h; + + // §29 IV-1 sim + const p29 = { parts: [], raf: 0 }; + function init29(){ + const N = +document.getElementById('p29-N-r').value; + const T = +document.getElementById('p29-T-r').value; + p29.parts = []; + for(let i = 0; i < N; i++){ + const ang = Math.random() * Math.PI * 2; + const sp = (0.8 + Math.random() * 0.4) * T; + p29.parts.push({ + x: 20 + Math.random() * 320, + y: 20 + Math.random() * 160, + vx: Math.cos(ang) * sp, + vy: Math.sin(ang) * sp + }); + } + } + function step29(){ + let hits = 0; + p29.parts.forEach(p => { + p.x += p.vx; p.y += p.vy; + if(p.x < 6){ p.x = 6; p.vx = -p.vx; hits++; } + if(p.x > 354){ p.x = 354; p.vx = -p.vx; hits++; } + if(p.y < 6){ p.y = 6; p.vy = -p.vy; hits++; } + if(p.y > 194){ p.y = 194; p.vy = -p.vy; hits++; } + }); + return hits; + } + let frame29 = 0, hitSum = 0; + function render29(){ + const svg = document.getElementById('p29-svg'); + if(!svg){ cancelAnimationFrame(p29.raf); return; } + const hits = step29(); + hitSum += hits; + frame29++; + let s = ''; + s += ''; + p29.parts.forEach(p => { + const sp = Math.hypot(p.vx, p.vy); + const col = sp > 2 ? '#dc2626' : (sp > 1.2 ? '#d97706' : '#0284c7'); + s += ''; + }); + svg.innerHTML = s; + if(frame29 % 30 === 0){ + const avg = (hitSum / 30).toFixed(0); + document.getElementById('p29-info').innerHTML = 'Молекул: ' + p29.parts.length + ' · ударов о стенки за такт: ' + avg + ' · Давление $p$ тем выше, чем больше число молекул × их скорость.'; + renderMath(document.getElementById('p29-info')); + hitSum = 0; + } + p29.raf = requestAnimationFrame(render29); + } + ['p29-N-r','p29-T-r'].forEach(id => document.getElementById(id).addEventListener('input', () => { + document.getElementById('p29-N').textContent = document.getElementById('p29-N-r').value; + document.getElementById('p29-T').textContent = document.getElementById('p29-T-r').value; + init29(); + })); + init29(); + p29.raf = requestAnimationFrame(render29); + + wireDnd('p29-dnd', [ + { id:'a1', cat:'up' },{ id:'a2', cat:'up' },{ id:'a3', cat:'up' }, + { id:'a4', cat:'down' },{ id:'a5', cat:'down' },{ id:'a6', cat:'down' } + ]); + wireQuiz('p29-q-host', () => { if(window.addXp) window.addXp(10, 'q-p29'); }); + wireQuiz('p29-tr-host', () => { if(window.addXp) window.addXp(15, 'tr-p29'); }); + wireReadBtn('p29'); + renderMath(body); +} + +/* ========================================================== */ +/* §30 — Закон Паскаля. Гидравлический пресс */ +/* ========================================================== */ +function add_p30(){ + const body = document.getElementById('p30-body'); + if(!body) return; + let h = ''; + + h += makeCard('theory', 'Закон Паскаля', '§ 30.1', + 'Давление, производимое на жидкость или газ, передаётся без изменения в каждую точку ' + + 'этой жидкости или газа и во все стороны одинаково.

' + + 'Это открыл Блез Паскаль в XVII веке. Поэтому если надуть воздушный шарик и сжать его в одном месте — ' + + 'он раздуется в другом, передавая давление равномерно.'); + + h += makeCard('rule', 'Гидравлический пресс', '§ 30.2', + 'Соединим два цилиндра жидкостью. На малый поршень давит сила $F_1$ — возникает давление $p = F_1/S_1$. ' + + 'Это давление передаётся по жидкости к большому поршню площадью $S_2$:
' + + '$$F_2 = p \\cdot S_2 = F_1 \\cdot \\dfrac{S_2}{S_1}$$
' + + 'Если $S_2 \\gg S_1$, то $F_2 \\gg F_1$ — гидравлика выигрывает в силе. ' + + 'Платой служит то, что большой поршень движется во столько же раз медленнее.'); + + h += makeCard('example', 'Где применяют', '§ 30.3', + '
    ' + + '
  • Гидравлический пресс — гнёт металл, прессует тюки.
  • ' + + '
  • Гидравлический подъёмник в автосервисе.
  • ' + + '
  • Тормоза легкового авто — нажатие на педаль передаётся жидкости.
  • ' + + '
  • Экскаватор, ковш бульдозера — цилиндры с маслом.
  • ' + + '
'); + + /* IV-1 ГЛАВНЫЙ ВИЗУАЛ — гидравлический пресс */ + h += wgWrap('p30-iv1', 'СИМ', 'Гидравлический пресс — главный визуал', 'Меняй площади и силу на малом поршне — увидь силу на большом.', + '
' + + '' + + '' + + '' + + '
' + + '' + + '
'); + + /* IV-2 КАЛЬК */ + h += wgWrap('p30-iv2', 'КАЛЬК', 'F₂ через закон Паскаля', '', + '
' + + '' + + '' + + '' + + '
' + + '
' + + '$p = F_1/S_1 = $ 20 Н/см² · $F_2 = pS_2 = F_1 \\cdot S_2/S_1 = $ 10000 Н' + + '
Выигрыш в силе: в 100 раз
' + + '
'); + + /* IV-3 DnD */ + h += wgWrap('p30-iv3', 'DnD', 'Применения закона Паскаля', '', + dndPool('p30-dnd', [ + { id:'a1', cat:'hyd', html:'Гидравлический пресс' }, + { id:'a2', cat:'hyd', html:'Автомобильный подъёмник' }, + { id:'a3', cat:'hyd', html:'Тормоза машины' }, + { id:'a4', cat:'not', html:'Звонок в дверь' }, + { id:'a5', cat:'not', html:'Лампа накаливания' }, + { id:'a6', cat:'hyd', html:'Ковш бульдозера' } + ], [ + { cat:'hyd', label:'Использует закон Паскаля' }, + { cat:'not', label:'Не относится' } + ])); + + /* IV-4 ТРН */ + h += wgWrap('p30-iv4', 'ТРН', 'Тренажёр §30', '', + '
' + + quizQuestion('p30-tr', 0, '$F_1 = 50$ Н, $S_1 = 5$ см², $S_2 = 50$ см². $F_2$?', ['100 Н','250 Н','500 Н','5000 Н'], 2, '$F_2 = 50 \\cdot 50/5 = 500$ Н.') + + quizQuestion('p30-tr', 1, 'Если $S_2/S_1 = 100$, во сколько раз увеличится сила?', ['В 10','В 100','В 1000','Не изменится'], 1) + + quizQuestion('p30-tr', 2, 'Что является «платой» за выигрыш в силе у гидравлики?', ['Расход воды','Большой поршень движется медленнее','Жидкость греется','Ничего'], 1) + + quizQuestion('p30-tr', 3, 'Жидкости и газы передают давление…', ['Только вниз','Только вверх','Равномерно во все стороны','По-разному в разных точках'], 2) + + '
'); + + h += readButton('p30'); + body.innerHTML = h; + + function draw30(){ + const S1 = +document.getElementById('p30-S1-r').value; + const S2 = +document.getElementById('p30-S2-r').value; + const F1 = +document.getElementById('p30-F1-r').value; + document.getElementById('p30-S1').textContent = S1; + document.getElementById('p30-S2').textContent = S2; + document.getElementById('p30-F1').textContent = F1; + const F2 = F1 * S2 / S1; + // Render via PHYS.hydraulicPress if available + if(window.PHYS && window.PHYS.hydraulicPress){ + const svgInner = window.PHYS.hydraulicPress(40, 30, S1, S2, F1, '#60a5fa'); + document.getElementById('p30-svg').innerHTML = svgInner; + } + document.getElementById('p30-info').innerHTML = '$F_1 = ' + F1 + '$ Н, $S_1 = ' + S1 + '$ см², $S_2 = ' + S2 + '$ см²  →  $F_2 = F_1 \\cdot S_2/S_1 = $ ' + F2.toFixed(0) + ' Н (в ' + (S2/S1).toFixed(1) + ' раз больше)'; + renderMath(document.getElementById('p30-info')); + } + ['p30-S1-r','p30-S2-r','p30-F1-r'].forEach(id => document.getElementById(id).addEventListener('input', draw30)); + draw30(); + + const upd30c = () => { + const F1 = +document.getElementById('p30c-F1-r').value; + const S1 = +document.getElementById('p30c-S1-r').value; + const S2 = +document.getElementById('p30c-S2-r').value; + document.getElementById('p30c-F1').textContent = F1; + document.getElementById('p30c-S1').textContent = S1; + document.getElementById('p30c-S2').textContent = S2; + const p = F1 / S1; + const F2 = p * S2; + document.getElementById('p30c-p').textContent = p.toFixed(1); + document.getElementById('p30c-F2').textContent = F2.toFixed(0); + document.getElementById('p30c-gain').innerHTML = 'Выигрыш в силе: в ' + (S2/S1).toFixed(1) + ' раз'; + }; + ['p30c-F1-r','p30c-S1-r','p30c-S2-r'].forEach(id => document.getElementById(id).addEventListener('input', upd30c)); + upd30c(); + + wireDnd('p30-dnd', [ + { id:'a1', cat:'hyd' },{ id:'a2', cat:'hyd' },{ id:'a3', cat:'hyd' }, + { id:'a4', cat:'not' },{ id:'a5', cat:'not' },{ id:'a6', cat:'hyd' } + ]); + wireQuiz('p30-tr-host', () => { if(window.addXp) window.addXp(15, 'tr-p30'); }); + wireReadBtn('p30'); + renderMath(body); +} + +/* ========================================================== */ +/* §31 — Давление жидкости (гидростатическое) */ +/* ========================================================== */ +function add_p31(){ + const body = document.getElementById('p31-body'); + if(!body) return; + let h = ''; + + h += makeCard('theory', 'Жидкость давит весом', '§ 31.1', + 'Жидкость, имеющая массу, давит на дно сосуда и на боковые стенки. ' + + 'Это давление возникает не от тела, как у твёрдых, а от собственного веса жидкости.

' + + 'Формула гидростатического давления на глубине $h$:
' + + '$$p = \\rho g h$$
' + + 'где $\\rho$ — плотность жидкости (кг/м³), $g \\approx 9{,}8$ Н/кг, $h$ — глубина (м).'); + + h += makeCard('rule', 'Гидростатический парадокс', '§ 31.2', + 'Удивительный факт: давление на дно не зависит от формы сосуда и от количества жидкости. ' + + 'Если налить $h$ воды в узкую трубку или в широкий бассейн — давление на дно одинаково.

' + + 'Зависит только от: плотности жидкости и глубины. Это гидростатический парадокс Паскаля.'); + + h += makeCard('example', 'Давление на глубине', '§ 31.3', + '' + + '' + + [['$1$ м','9,8 кПа'],['$10$ м','98 кПа ≈ 1 атм'],['$100$ м','≈ 10 атм'],['$1000$ м','≈ 100 атм (батискаф)'],['Дно Марианской впадины ($\\approx 11$ км)','≈ 1100 атм']].map(r => + '').join('') + + '
Глубинаp (вода)
' + r[0] + '' + r[1] + '
'); + + /* IV-1 КАЛЬК */ + h += wgWrap('p31-iv1', 'КАЛЬК', 'Калькулятор $p = \\rho g h$', 'Меняй плотность и глубину.', + '
' + + '' + + '' + + '
' + + '
' + + '$p = \\rho g h = $ 29 400 Па $= $ 29.4 кПа $\\approx $ 0.29 атм' + + '
'); + + /* IV-2 СИМ: гидростатический парадокс — 3 сосуда */ + h += wgWrap('p31-iv2', 'СИМ', 'Гидростатический парадокс: 3 сосуда', 'Один уровень воды — одинаковое давление на дно. Форма не важна!', + '' + + '
' + + '
'); + + /* IV-3 DnD */ + h += wgWrap('p31-iv3', 'DnD', 'От чего зависит p жидкости?', '', + dndPool('p31-dnd', [ + { id:'a1', cat:'yes', html:'Глубина $h$' }, + { id:'a2', cat:'yes', html:'Плотность жидкости $\\rho$' }, + { id:'a3', cat:'yes', html:'Ускорение $g$' }, + { id:'a4', cat:'no', html:'Форма сосуда' }, + { id:'a5', cat:'no', html:'Количество жидкости в сосуде' }, + { id:'a6', cat:'no', html:'Площадь дна' } + ], [ + { cat:'yes', label:'p ЗАВИСИТ' }, + { cat:'no', label:'p НЕ зависит' } + ])); + + /* IV-4 ТРН */ + h += wgWrap('p31-iv4', 'ТРН', 'Тренажёр §31', '', + '
' + + quizQuestion('p31-tr', 0, 'Давление воды на дне бассейна глубиной $5$ м ($g = 10$, $\\rho = 1000$)?', ['5 кПа','50 кПа','500 кПа','5000 кПа'], 1, '$p = 1000 \\cdot 10 \\cdot 5 = 50\\,000$ Па $= 50$ кПа.') + + quizQuestion('p31-tr', 1, 'Жидкость глубиной $h = 2$ м, $\\rho = 800$ кг/м³ (бензин). $p$ (g=10)?', ['8 кПа','16 кПа','80 кПа','160 кПа'], 1, '$p = 800 \\cdot 10 \\cdot 2 = 16\\,000$ Па.') + + quizQuestion('p31-tr', 2, 'В двух разных сосудах вода на одной глубине $h = 1$ м. Где $p$ больше?', ['В большом','В малом','Одинаковое','Зависит от формы'], 2) + + quizQuestion('p31-tr', 3, 'В каком случае давление на дно больше: $1$ м воды или $1$ м ртути ($\\rho_{рт} = 13600$)?', ['Воды','Ртути','Одинаково','Воды в 13,6 раз'], 1) + + quizQuestion('p31-tr', 4, 'Дайвер на $h = 30$ м в море ($\\rho = 1030$). Гидростат. давление?', ['3 атм','5 атм','3,1 атм','30 атм'], 2, '$p = 1030 \\cdot 9{,}8 \\cdot 30 \\approx 303\\,000$ Па $\\approx 3$ атм.') + + '
'); + + h += readButton('p31'); + body.innerHTML = h; + + // §31 IV-1 + const upd31 = () => { + const rho = +document.getElementById('p31-rho').value; + const hVal = +document.getElementById('p31-h-r').value; + document.getElementById('p31-h').textContent = hVal; + const p = rho * 9.8 * hVal; + document.getElementById('p31-p').textContent = p.toLocaleString('ru-RU', { maximumFractionDigits: 0 }); + document.getElementById('p31-pkpa').textContent = (p / 1000).toFixed(2); + document.getElementById('p31-patm').textContent = (p / 101325).toFixed(3); + }; + document.getElementById('p31-rho').addEventListener('change', upd31); + document.getElementById('p31-h-r').addEventListener('input', upd31); + upd31(); + + // §31 IV-2 — paradox + function draw31s(){ + const hCm = +document.getElementById('p31s-h-r').value; + document.getElementById('p31s-h').textContent = hCm; + const W = 360, H = 200, baseY = 170, pxPerCm = 9; + const liqColor = '#60a5fa'; + let s = ''; + // Дно + s += ''; + function vessel(x, w, kind){ + const wallH = 130; + const topY = baseY - wallH; + let g = ''; + if(kind === 'cyl'){ + g += ''; + g += ''; + // Жидкость + const fillH = hCm * pxPerCm; + g += ''; + } else if(kind === 'wide'){ + // Конус расширяющийся вверх + g += ''; + g += ''; + const fillH = hCm * pxPerCm; + g += ''; + } else { // narrow — сужающийся + g += ''; + g += ''; + const fillH = hCm * pxPerCm; + g += ''; + } + return g; + } + s += vessel(40, 60, 'cyl'); + s += vessel(150, 60, 'wide'); + s += vessel(260, 60, 'narrow'); + // Линия уровня + const lvlY = baseY - hCm * pxPerCm; + s += ''; + s += 'уровень = ' + hCm + ' см'; + document.getElementById('p31-svg').innerHTML = s; + const p = 1000 * 9.8 * (hCm / 100); + document.getElementById('p31s-info').innerHTML = 'На дне всех трёх сосудов: $p = \\rho g h = ' + Math.round(p).toLocaleString('ru-RU') + '$ Па. Форма не важна!'; + renderMath(document.getElementById('p31s-info')); + } + document.getElementById('p31s-h-r').addEventListener('input', draw31s); + draw31s(); + + wireDnd('p31-dnd', [ + { id:'a1', cat:'yes' },{ id:'a2', cat:'yes' },{ id:'a3', cat:'yes' }, + { id:'a4', cat:'no' },{ id:'a5', cat:'no' },{ id:'a6', cat:'no' } + ]); + wireQuiz('p31-tr-host', () => { if(window.addXp) window.addXp(15, 'tr-p31'); }); + wireReadBtn('p31'); + renderMath(body); +} + +/* ========================================================== */ +/* §32 — Сообщающиеся сосуды */ +/* ========================================================== */ +function add_p32(){ + const body = document.getElementById('p32-body'); + if(!body) return; + let h = ''; + + h += makeCard('theory', 'Что это такое', '§ 32.1', + 'Сообщающиеся сосуды — это два или несколько сосудов, соединённых внизу так, что жидкость может переходить между ними.

' + + 'Главный закон: в сообщающихся сосудах однородная жидкость устанавливается на одном уровне — независимо от формы сосудов.'); + + h += makeCard('rule', 'Почему именно так', '§ 32.2', + 'На одной глубине давление одно и то же ($p = \\rho g h$). Если уровни жидкости разные, то и давления у дна разные, ' + + 'и жидкость будет перетекать в сторону меньшего давления — пока уровни не сравняются.

' + + 'Для разнородных жидкостей: высоты в коленах обратно пропорциональны плотностям: ' + + '$\\rho_1 h_1 = \\rho_2 h_2$.'); + + h += makeCard('example', 'Применения', '§ 32.3', + '
    ' + + '
  • Водопровод в высотных домах — давление от водонапорной башни.
  • ' + + '
  • Шлюзы для пропуска судов.
  • ' + + '
  • Чайник с носиком: чай в чайнике и в носике на одном уровне.
  • ' + + '
  • Кофейник, лейка.
  • ' + + '
  • Артезианские колодцы: вода поднимается естественным образом.
  • ' + + '
'); + + /* IV-1 СИМ: сообщающиеся сосуды */ + h += wgWrap('p32-iv1', 'СИМ', 'Однородная жидкость → один уровень', 'Меняй уровень — оба сосуда уравниваются.', + '
' + + '
' + + '' + + '' + + '' + + '
' + + '' + + '
Уровень одинаков, потому что давления на дне равны.
'); + + /* IV-2 КВИЗ */ + h += wgWrap('p32-iv2', 'КВИЗ', 'Сообщающиеся сосуды', '', + '
' + + quizQuestion('p32-q', 0, 'В двух соединённых сосудах одна и та же вода. Что верно?', ['Уровни могут быть разными','Уровни всегда одинаковы','Зависит от объёмов','Зависит от формы'], 1) + + quizQuestion('p32-q', 1, 'Чайник: уровень чая в носике и корпусе…', ['В носике выше','В корпусе выше','На одном уровне','Зависит от наклона'], 2) + + quizQuestion('p32-q', 2, 'Если жидкости разные (вода и масло), уровни…', ['Одинаковые','Зависят от плотностей (обратно пропорц.)','Зависят от массы','Жидкость смешается'], 1) + + '
'); + + /* IV-3 DnD */ + h += wgWrap('p32-iv3', 'DnD', 'Что использует сообщающиеся сосуды?', '', + dndPool('p32-dnd', [ + { id:'a1', cat:'yes', html:'Шлюз для судов' }, + { id:'a2', cat:'yes', html:'Лейка для воды' }, + { id:'a3', cat:'yes', html:'Водомерное стекло котла' }, + { id:'a4', cat:'no', html:'Микроволновка' }, + { id:'a5', cat:'no', html:'Электронные весы' }, + { id:'a6', cat:'yes', html:'Артезианский колодец' } + ], [ + { cat:'yes', label:'Применение принципа' }, + { cat:'no', label:'Не относится' } + ])); + + /* IV-4 ТРН */ + h += wgWrap('p32-iv4', 'ТРН', 'Тренажёр §32', '', + '
' + + quizQuestion('p32-tr', 0, 'В сообщающиеся сосуды налита однородная вода. Если в одном уровень $h$, то во втором…', ['$h/2$','$h$','$2h$','Любой'], 1) + + quizQuestion('p32-tr', 1, 'Если узкий сосуд тоньше широкого в 5 раз, а вода поднимается в широком на $10$ см, то в узком…', ['10 см','50 см','5 см','100 см'], 0, 'Уровни одной жидкости равны независимо от площади.') + + quizQuestion('p32-tr', 2, 'В U-трубке с двух сторон ртуть. Налили воду — она «выдавила» ртуть. В каком колене ртуть выше?', ['Где налита вода','В противоположном','Одинаково','Ртуть выльется'], 1) + + quizQuestion('p32-tr', 3, 'Принцип сообщающихся сосудов работает потому, что…', ['Жидкость лёгкая','Давление зависит только от $h$ и $\\rho$','Жидкость холодная','Стенки гладкие'], 1) + + '
'); + + h += readButton('p32'); + body.innerHTML = h; + + // §32 IV-1 + let curShape = { a:'cylinder', b:'cylinder' }; + function draw32(){ + const lvlY = 220 - +document.getElementById('p32-l-r').value; // px (220 — низ + base) + // На самом деле проще задать levelY напрямую от верха svg + const Lpx = +document.getElementById('p32-l-r').value; + document.getElementById('p32-l').textContent = Lpx; + if(window.PHYS && window.PHYS.connectedVessels){ + const levelY = 200 - Lpx; // viewBox 200H, уровень от низа + const svgInner = window.PHYS.connectedVessels(50, 30, curShape.a, curShape.b, levelY, '#60a5fa'); + document.getElementById('p32-svg').innerHTML = svgInner; + } + } + body.querySelectorAll('.p32-shape').forEach(btn => btn.addEventListener('click', () => { + body.querySelectorAll('.p32-shape').forEach(b => { b.style.background = '#fff'; b.style.color = ACCENT; b.style.border = '2px solid ' + ACCENT; }); + btn.style.background = ACCENT; btn.style.color = '#fff'; btn.style.border = 'none'; + curShape = { a: btn.dataset.a, b: btn.dataset.b }; + draw32(); + })); + document.getElementById('p32-l-r').addEventListener('input', draw32); + draw32(); + + wireDnd('p32-dnd', [ + { id:'a1', cat:'yes' },{ id:'a2', cat:'yes' },{ id:'a3', cat:'yes' }, + { id:'a4', cat:'no' },{ id:'a5', cat:'no' },{ id:'a6', cat:'yes' } + ]); + wireQuiz('p32-q-host', () => { if(window.addXp) window.addXp(10, 'q-p32'); }); + wireQuiz('p32-tr-host', () => { if(window.addXp) window.addXp(15, 'tr-p32'); }); + wireReadBtn('p32'); + renderMath(body); +} + +/* ========================================================== */ +/* §33 — Газы и их вес */ +/* ========================================================== */ +function add_p33(){ + const body = document.getElementById('p33-body'); + if(!body) return; + let h = ''; + + h += makeCard('theory', 'У воздуха есть вес', '§ 33.1', + 'Любой газ состоит из молекул, у молекул есть масса — значит, и сам газ имеет массу и вес.

' + + 'Плотность воздуха у поверхности Земли: $\\rho_{возд} \\approx 1{,}29$ кг/м³.'); + + h += makeCard('rule', 'Сколько весит воздух', '§ 33.2', + 'Масса газа в сосуде: $m = \\rho V$.
' + + 'Вес: $P = m g$.

' + + 'Воздух в комнате $5 \\times 4 \\times 3$ м$^3 = 60$ м³ имеет массу $m \\approx 1{,}29 \\cdot 60 = 77$ кг — ' + + 'столько весит взрослый человек!'); + + h += makeCard('example', 'Как доказать вес воздуха', '§ 33.3', + 'Опыт: взвесить стеклянный шар на чувствительных весах, затем выкачать из него воздух насосом ' + + 'и взвесить снова. Шар без воздуха окажется легче на массу удалённого воздуха.'); + + /* IV-1 КАЛЬК: масса воздуха в комнате */ + h += wgWrap('p33-iv1', 'КАЛЬК', 'Сколько весит воздух в комнате?', '', + '
' + + '' + + '' + + '' + + '
' + + '
' + + '$V = abc = $ 60 м³ · $m = \\rho V = $ 77 кг · $P = mg = $ 756 Н' + + '
' + + '
'); + + /* IV-2 КВИЗ */ + h += wgWrap('p33-iv2', 'КВИЗ', 'Вес газов', '', + '
' + + quizQuestion('p33-q', 0, 'Воздух имеет массу?', ['Нет, газ невесом','Да, как и любое вещество','Только при низкой T','Только под давлением'], 1) + + quizQuestion('p33-q', 1, 'Плотность воздуха у Земли примерно равна:', ['0,001 кг/м³','1,29 кг/м³','100 кг/м³','1000 кг/м³'], 1) + + quizQuestion('p33-q', 2, 'Воздух в комнате 50 м³ весит примерно:', ['65 г','650 г','65 кг','650 кг'], 2) + + '
'); + + /* IV-3 DnD */ + h += wgWrap('p33-iv3', 'DnD', 'Тяжелее или легче воздуха?', '', + dndPool('p33-dnd', [ + { id:'a1', cat:'lighter', html:'Гелий (He, 0,18 кг/м³)' }, + { id:'a2', cat:'lighter', html:'Водород (H₂, 0,09 кг/м³)' }, + { id:'a3', cat:'lighter', html:'Метан (CH₄, 0,72 кг/м³)' }, + { id:'a4', cat:'heavier', html:'Углекислый газ (CO₂, 1,98)' }, + { id:'a5', cat:'heavier', html:'Хлор (Cl₂, 3,21)' }, + { id:'a6', cat:'heavier', html:'Радон (Rn, 9,73)' } + ], [ + { cat:'lighter', label:'Легче воздуха ($\\rho < 1{,}29$)' }, + { cat:'heavier', label:'Тяжелее воздуха ($\\rho > 1{,}29$)' } + ])); + + /* IV-4 ТРН */ + h += wgWrap('p33-iv4', 'ТРН', 'Тренажёр §33', '', + '
' + + quizQuestion('p33-tr', 0, 'Воздух в комнате $V = 100$ м³ ($\\rho = 1{,}29$). Масса в кг?', ['12,9','129','1290','1,29'], 1, '$m = 1{,}29 \\cdot 100 = 129$ кг.') + + quizQuestion('p33-tr', 1, 'Гелий легче воздуха в ~7 раз. Шарик с гелием…', ['Тяжелее','Не отличается','Легче — может летать','Падает быстрее'], 2) + + quizQuestion('p33-tr', 2, 'Углекислый газ скапливается…', ['У потолка','У пола','Равномерно','Не скапливается'], 1, 'Он тяжелее воздуха — оседает вниз.') + + quizQuestion('p33-tr', 3, '$m$ воздуха в баллоне $0{,}001$ м³ ($\\rho = 1{,}29$)?', ['0,00129 кг','0,0129 кг','1,29 г','Все верны 1 и 3'], 3, '$m = 1{,}29 \\cdot 0{,}001 = 0{,}00129$ кг $= 1{,}29$ г.') + + '
'); + + h += readButton('p33'); + body.innerHTML = h; + + const upd33 = () => { + const a = +document.getElementById('p33-a-r').value; + const b = +document.getElementById('p33-b-r').value; + const c = +document.getElementById('p33-c-r').value; + document.getElementById('p33-a').textContent = a; + document.getElementById('p33-b').textContent = b; + document.getElementById('p33-c').textContent = c; + const V = a * b * c; + const m = V * 1.29; + const P = m * 9.8; + document.getElementById('p33-V').textContent = V.toFixed(1); + document.getElementById('p33-m').textContent = m.toFixed(1); + document.getElementById('p33-P').textContent = P.toFixed(0); + let cmp; + if(m < 30) cmp = 'Меньше школьника.'; + else if(m < 80) cmp = 'Примерно вес взрослого человека.'; + else if(m < 200) cmp = 'Как пара человек.'; + else if(m < 1000) cmp = 'Как пианино или мотоцикл.'; + else cmp = 'Тяжелее тонны — как автомобиль!'; + document.getElementById('p33-cmp').textContent = cmp; + }; + ['p33-a-r','p33-b-r','p33-c-r'].forEach(id => document.getElementById(id).addEventListener('input', upd33)); + upd33(); + + wireDnd('p33-dnd', [ + { id:'a1', cat:'lighter' },{ id:'a2', cat:'lighter' },{ id:'a3', cat:'lighter' }, + { id:'a4', cat:'heavier' },{ id:'a5', cat:'heavier' },{ id:'a6', cat:'heavier' } + ]); + wireQuiz('p33-q-host', () => { if(window.addXp) window.addXp(10, 'q-p33'); }); + wireQuiz('p33-tr-host', () => { if(window.addXp) window.addXp(15, 'tr-p33'); }); + wireReadBtn('p33'); + renderMath(body); +} + +/* ========================================================== */ +/* §34 — Атмосферное давление */ +/* ========================================================== */ +function add_p34(){ + const body = document.getElementById('p34-body'); + if(!body) return; + let h = ''; + + h += makeCard('theory', 'Атмосфера давит на нас', '§ 34.1', + 'Земля окружена слоем воздуха — атмосферой. Этот воздух имеет вес и давит на всё, что находится на поверхности Земли.

' + + 'Нормальное атмосферное давление: $p_0 = 101\\,325$ Па $= 760$ мм рт. ст. $\\approx 1$ атм.'); + + h += makeCard('rule', 'Опыт Торричелли (1643)', '§ 34.2', + 'Эванжелиста Торричелли перевернул трубку, наполненную ртутью, в чашку с ртутью. ' + + 'Ртуть в трубке опустилась до высоты $\\approx 760$ мм над уровнем чашки. ' + + 'Это значит, что атмосфера снаружи давила на чашку с такой же силой, как столб ртути высотой $760$ мм.

' + + 'Так была открыта единица «миллиметр ртутного столба» (мм рт. ст.).'); + + h += makeCard('example', 'С высотой давление падает', '§ 34.3', + 'На каждые $\\approx 12$ м подъёма атмосферное давление уменьшается на $1$ мм рт. ст. (на малых высотах).

' + + 'Поэтому на вершине Эльбруса ($5642$ м) давление $\\approx 400$ мм рт. ст. — почти в 2 раза меньше уровня моря. ' + + 'Космонавтам в открытом космосе нужны скафандры — давление за бортом $\\approx 0$.'); + + /* IV-1 СИМ: ртутный барометр Торричелли */ + h += wgWrap('p34-iv1', 'СИМ', 'Барометр Торричелли', 'Меняй атмосферное давление — увидь высоту столба ртути.', + '
' + + '
' + + '' + + '
' + + '
'); + + /* IV-2 КАЛЬК: высота → давление */ + h += wgWrap('p34-iv2', 'КАЛЬК', 'Давление на высоте', 'На каждые ~12 м давление падает на 1 мм рт. ст.', + '
' + + '
' + + '$\\Delta p = H/12 = $ 0 мм рт. ст. · $p \\approx $ 760 мм рт. ст. $\\approx $ 101.3 кПа' + + '
' + + '
'); + + /* IV-3 DnD */ + h += wgWrap('p34-iv3', 'DnD', 'Где давление какое?', '', + dndPool('p34-dnd', [ + { id:'a1', cat:'norm', html:'Уровень моря (≈760 мм)' }, + { id:'a2', cat:'low', html:'Эверест 8 848 м (≈250 мм)' }, + { id:'a3', cat:'high', html:'Шахта −500 м (≈800 мм)' }, + { id:'a4', cat:'low', html:'Самолёт 10 км (≈190 мм)' }, + { id:'a5', cat:'norm', html:'Город Минск (≈750 мм)' }, + { id:'a6', cat:'high', html:'Мёртвое море −430 м (≈800 мм)' } + ], [ + { cat:'high', label:'Выше нормы (ниже уровня моря)' }, + { cat:'norm', label:'Около нормы (~760)' }, + { cat:'low', label:'Ниже нормы (горы / небо)' } + ])); + + /* IV-4 ТРН */ + h += wgWrap('p34-iv4', 'ТРН', 'Тренажёр §34', '', + '
' + + quizQuestion('p34-tr', 0, 'Нормальное атм. давление в мм рт. ст.?', ['100','500','760','1000'], 2) + + quizQuestion('p34-tr', 1, 'Что произойдёт с давлением, если подняться на 360 м вверх?', ['Не изменится','Упадёт на ~30 мм','Упадёт на ~3 мм','Возрастёт'], 1, '$\\Delta p = 360/12 = 30$ мм рт. ст.') + + quizQuestion('p34-tr', 2, 'Кто открыл атм. давление?', ['Архимед','Торричелли','Галилей','Паскаль'], 1) + + quizQuestion('p34-tr', 3, 'Высота Эвереста ~9 км. Атм. давление там примерно:', ['0 мм','100 мм','250 мм','760 мм'], 2) + + quizQuestion('p34-tr', 4, '$p = 750$ мм рт. ст. в кПа? (1 мм ≈ 133 Па)', ['7,5','75','100','750'], 2, '$750 \\cdot 133 \\approx 100\\,000$ Па $= 100$ кПа.') + + '
'); + + h += readButton('p34'); + body.innerHTML = h; + + // §34 IV-1 — use PHYS.mercuryBarometer + function draw34(){ + const mm = +document.getElementById('p34-mm-r').value; + document.getElementById('p34-mm').textContent = mm; + if(window.PHYS && window.PHYS.mercuryBarometer){ + const inner = window.PHYS.mercuryBarometer(80, 30, mm); + document.getElementById('p34-svg').innerHTML = inner; + } + const pa = mm * 133.322; + let descr; + if(mm > 770) descr = 'Выше нормы — антициклон, ясная погода (или вы в шахте/долине).'; + else if(mm > 745) descr = 'Норма — обычное давление у поверхности Земли.'; + else if(mm > 600) descr = 'Ниже нормы — горы, циклон, плохая погода.'; + else descr = 'Очень низкое — высокогорье или большая высота.'; + document.getElementById('p34-info').innerHTML = '' + mm + ' мм рт. ст. $= $ ' + Math.round(pa).toLocaleString('ru-RU') + ' Па $\\approx $ ' + (pa/1000).toFixed(1) + ' кПа

' + descr; + renderMath(document.getElementById('p34-info')); + } + document.getElementById('p34-mm-r').addEventListener('input', draw34); + draw34(); + + // §34 IV-2 + const upd34c = () => { + const H = +document.getElementById('p34c-H-r').value; + document.getElementById('p34c-H').textContent = H; + const dp = H / 12; + const p = Math.max(0, 760 - dp); + const pa = p * 133.322; + document.getElementById('p34c-dp').textContent = dp.toFixed(1); + document.getElementById('p34c-p').textContent = p.toFixed(0); + document.getElementById('p34c-pkpa').textContent = (pa/1000).toFixed(1); + let place; + if(H < 100) place = 'Уровень моря — норма.'; + else if(H < 500) place = 'Холмистая местность.'; + else if(H < 2000) place = 'Среднегорье (Кавказ, Альпы предгорья).'; + else if(H < 4000) place = 'Высокогорье. Может быть «горная болезнь».'; + else place = 'Очень высоко — Эверест и выше. Нужен кислород.'; + document.getElementById('p34c-place').textContent = place; + }; + document.getElementById('p34c-H-r').addEventListener('input', upd34c); + upd34c(); + + wireDnd('p34-dnd', [ + { id:'a1', cat:'norm' },{ id:'a2', cat:'low' },{ id:'a3', cat:'high' }, + { id:'a4', cat:'low' },{ id:'a5', cat:'norm' },{ id:'a6', cat:'high' } + ]); + wireQuiz('p34-tr-host', () => { if(window.addXp) window.addXp(15, 'tr-p34'); }); + wireReadBtn('p34'); + renderMath(body); +} + +/* ========================================================== */ +/* §35 — Барометры и манометры (ГЛАВНЫЙ ВИЗУАЛ ГЛАВЫ 4) */ +/* ========================================================== */ +function add_p35(){ + const body = document.getElementById('p35-body'); + if(!body) return; + let h = ''; + + h += makeCard('theory', 'Три прибора для давления', '§ 35.1', + '
    ' + + '
  • Ртутный барометр Торричелли — измеряет атм. давление через высоту ртутного столба.
  • ' + + '
  • Анероид (греч. «без жидкости») — пружинный, стрелочный. Не разобьётся, удобен.
  • ' + + '
  • Жидкостный U-манометр — измеряет давление газа относительно атмосферного, через разность уровней.
  • ' + + '
'); + + h += makeCard('rule', 'Где какой прибор', '§ 35.2', + 'Барометры (Торричелли, анероид) — измеряют атмосферное давление воздуха.
' + + 'Манометр — измеряет давление газа в сосуде или жидкости. ' + + 'Например, в шине, в баллоне с пропаном, в трубе с водой.
' + + 'Кардиограф/тонометр — давление в кровеносных сосудах.'); + + h += makeCard('example', 'Манометр на баллоне', '§ 35.3', + 'В баллоне с газом давление много выше атмосферного. Манометр показывает разность: ' + + 'давление в баллоне минус $p_0$. Если шкала показывает $200$ кПа — фактическое давление в баллоне $200 + 100 = 300$ кПа.'); + + /* IV-1 ГЛАВНЫЙ ВИЗУАЛ — все 3 прибора */ + h += wgWrap('p35-iv1', 'СИМ', 'Три прибора рядом — главный визуал', 'Одно и то же давление, три способа показать.', + '
' + + '
' + + '
Торричелли
' + + '
Анероид
' + + '
U-манометр (газ vs $p_0$)
' + + '
' + + '
'); + + /* IV-2 КВИЗ */ + h += wgWrap('p35-iv2', 'КВИЗ', 'Какой прибор для чего', '', + '
' + + quizQuestion('p35-q', 0, 'Чем измеряют атм. давление?', ['Манометр','Барометр','Гигрометр','Термометр'], 1) + + quizQuestion('p35-q', 1, 'Чем измеряют давление газа в шине?', ['Барометр','Манометр','Динамометр','Спидометр'], 1) + + quizQuestion('p35-q', 2, 'Что меряет анероид?', ['Температура','Атм. давление','Скорость','Влажность'], 1) + + quizQuestion('p35-q', 3, 'Что значит «анероид»?', ['Безжидкостный','Сложный','Точный','Электронный'], 0) + + '
'); + + /* IV-3 DnD */ + h += wgWrap('p35-iv3', 'DnD', 'Какой прибор для какой задачи?', '', + dndPool('p35-dnd', [ + { id:'a1', cat:'baro', html:'Атм. давление в школьном кабинете физики' }, + { id:'a2', cat:'baro', html:'Давление перед сменой погоды' }, + { id:'a3', cat:'mano', html:'Давление в шине автомобиля' }, + { id:'a4', cat:'mano', html:'Давление в газовом баллоне' }, + { id:'a5', cat:'mano', html:'Давление в водопроводе' }, + { id:'a6', cat:'baro', html:'Давление на вершине горы' } + ], [ + { cat:'baro', label:'Барометр' }, + { cat:'mano', label:'Манометр' } + ])); + + /* IV-4 ТРН */ + h += wgWrap('p35-iv4', 'ТРН', 'Тренажёр §35', '', + '
' + + quizQuestion('p35-tr', 0, '$1$ мм рт. ст. примерно равен:', ['13,3 Па','133 Па','1330 Па','13 300 Па'], 1) + + quizQuestion('p35-tr', 1, '$200$ мм рт. ст. в Па:', ['2 660','26 600','266 000','2 660 000'], 1, '$200 \\cdot 133 \\approx 26\\,600$ Па.') + + quizQuestion('p35-tr', 2, 'Манометр показал $\\Delta p = 150$ кПа. Полное давление в баллоне (при $p_0 = 100$ кПа):', ['50 кПа','100 кПа','150 кПа','250 кПа'], 3) + + quizQuestion('p35-tr', 3, 'Высота ртутного столба $= 750$ мм. Что измеряем?', ['Атм. давление','Влажность','Температуру','Скорость ветра'], 0) + + '
'); + + h += readButton('p35'); + body.innerHTML = h; + + function draw35(){ + const mm = +document.getElementById('p35-mm-r').value; + document.getElementById('p35-mm').textContent = mm; + const pa = mm * 133.322; + if(window.PHYS){ + if(window.PHYS.mercuryBarometer) document.getElementById('p35-merc').innerHTML = window.PHYS.mercuryBarometer(60, 30, mm); + if(window.PHYS.aneroidBarometer) document.getElementById('p35-aner').innerHTML = window.PHYS.aneroidBarometer(90, 90, 70, pa); + // Для U-манометра показываем разницу давлений (предположим, газ под давлением 800 мм) + if(window.PHYS.uManometer){ + // deltaH в px, положительное — газ давит, правая часть ниже + const gasPMm = mm + 30; // газ всегда выше атмосферного для иллюстрации + const deltaH = (gasPMm - mm) * 1.5; // px + document.getElementById('p35-uman').innerHTML = window.PHYS.uManometer(30, 20, 60, 130, deltaH, '#0891b2'); + } + } + document.getElementById('p35-info').innerHTML = 'Атм. давление: ' + mm + ' мм рт. ст. $= $ ' + Math.round(pa).toLocaleString('ru-RU') + ' Па. Все три прибора показывают одно и то же — по-разному.'; + renderMath(document.getElementById('p35-info')); + } + document.getElementById('p35-mm-r').addEventListener('input', draw35); + draw35(); + + wireDnd('p35-dnd', [ + { id:'a1', cat:'baro' },{ id:'a2', cat:'baro' },{ id:'a3', cat:'mano' }, + { id:'a4', cat:'mano' },{ id:'a5', cat:'mano' },{ id:'a6', cat:'baro' } + ]); + wireQuiz('p35-q-host', () => { if(window.addXp) window.addXp(10, 'q-p35'); }); + wireQuiz('p35-tr-host', () => { if(window.addXp) window.addXp(15, 'tr-p35'); }); + wireReadBtn('p35'); + renderMath(body); +} + +/* ========================================================== */ +/* Финал главы 4 — 7 боссов + ачивка «Властелин давления» */ +/* ========================================================== */ +function add_final4(){ + const body = document.getElementById('final4-body'); + if(!body) return; + let h = ''; + + h += '
' + + '
Финал главы 4: победи 7 боссов
' + + '
Реши все 7 задач — получишь ачивку «Властелин давления» и +50 XP.
' + + '
' + + '
Побеждено: 0 / 7
' + + '
'; + + const bosses = [ + { n:1, tag:'§28', title:'Давление кирпича', + q:'Кирпич весом $F = 30$ Н стоит на грани площадью $S = 60$ см². Найди $p$ в Па.', + hint:'$S = 60 \\cdot 10^{-4} = 0{,}006$ м². $p = F/S = 30/0{,}006 = 5000$ Па.', + ans:5000, tol:50, step:'10' }, + { n:2, tag:'§30', title:'Гидравлический пресс', + q:'Малый поршень $S_1 = 5$ см², большой $S_2 = 500$ см². На малый давит $F_1 = 80$ Н. Найди $F_2$ в Н.', + hint:'$F_2 = F_1 \\cdot S_2/S_1 = 80 \\cdot 500/5 = 8000$ Н.', + ans:8000, tol:50, step:'10' }, + { n:3, tag:'§31', title:'Дайвер на дне моря', + q:'Глубина $h = 20$ м, $\\rho_{море} = 1030$ кг/м³, $g = 10$. Гидростат. давление в кПа?', + hint:'$p = 1030 \\cdot 10 \\cdot 20 = 206\\,000$ Па $= 206$ кПа.', + ans:206, tol:3, step:'1' }, + { n:4, tag:'§32', title:'Сообщающиеся сосуды', + q:'В двух соединённых сосудах одна и та же вода. В одном уровень $h = 18$ см. В другом сосуде, в 3 раза шире, какой уровень будет в см?', + hint:'Уровни однородной жидкости одинаковы независимо от ширины. $h = 18$ см.', + ans:18, tol:0.5, step:'0.1' }, + { n:5, tag:'§34', title:'Давление на горе', + q:'У моря $p_0 = 760$ мм рт. ст. Поднялись на $H = 480$ м. Давление стало:', + hint:'$\\Delta p = H/12 = 40$ мм. $p = 760 - 40 = 720$ мм рт. ст.', + ans:720, tol:3, step:'1' }, + { n:6, tag:'§35', title:'Барометр в Па', + q:'Барометр-анероид показал $p = 740$ мм рт. ст. Сколько это Па? (округли до сотен)', + hint:'$p = 740 \\cdot 133 \\approx 98\\,420$ Па $\\approx 98\\,400$ Па.', + ans:98400, tol:300, step:'100' }, + { n:7, tag:'синтез', title:'Властелин давления', + q:'Дайвер на $h = 30$ м в пресной воде ($\\rho = 1000$). Над водой $p_0 = 100$ кПа. Найди полное давление на дайвера в кПа.', + hint:'$p_{гидр} = 1000 \\cdot 10 \\cdot 30 = 300\\,000$ Па $= 300$ кПа. Полное: $p = p_0 + p_{гидр} = 100 + 300 = 400$ кПа.', + ans:400, tol:5, step:'1' } + ]; + + const STATE_KEY = 'physics7_ch4_final_bosses'; + let solved = {}; + try{ solved = JSON.parse(localStorage.getItem(STATE_KEY) || '{}') || {}; }catch(e){} + + bosses.forEach(b => { + const isSolved = !!solved[b.n]; + h += '
' + + '
' + + '' + b.tag + '' + + 'Босс ' + b.n + '. ' + b.title + '' + + '
' + + '
' + b.q + '
' + + '
' + + '' + + '' + + '' + + '
' + + '' + + '
' + (isSolved ? '✓ Босс повержен! +20 XP.' : '') + '
' + + '
'; + }); + + h += ''; + + body.innerHTML = h; + renderMath(body); + + function updateBar(){ + const cnt = bosses.filter(b => solved[b.n]).length; + document.getElementById('ch4-fin-fill').style.width = (cnt * 100 / bosses.length) + '%'; + document.getElementById('ch4-fin-lab').textContent = 'Побеждено: ' + cnt + ' / ' + bosses.length; + if(cnt === bosses.length){ + document.getElementById('ch4-mastered').style.display = 'flex'; + const ACH_KEY = 'physics7_ch4_master'; + if(localStorage.getItem(ACH_KEY) !== '1'){ + localStorage.setItem(ACH_KEY, '1'); + if(window.addXp) window.addXp(50, 'ach-ch4-master'); + if(window.achievement) window.achievement('ch_done', 'Властелин давления'); + } + } + } + updateBar(); + + body.querySelectorAll('.boss-hint').forEach(btn => btn.addEventListener('click', () => { + const n = btn.dataset.n; + const txt = body.querySelector('.boss-hint-txt[data-n="' + n + '"]'); + if(txt) txt.style.display = txt.style.display === 'none' ? 'block' : 'none'; + })); + body.querySelectorAll('.boss-go').forEach(btn => btn.addEventListener('click', () => { + const n = +btn.dataset.n; + const b = bosses.find(x => x.n === n); + const inp = body.querySelector('.boss-inp[data-n="' + n + '"]'); + const fb = body.querySelector('.boss-fb[data-n="' + n + '"]'); + const card = body.querySelector('[data-boss="' + n + '"]'); + const v = parseFloat((inp.value || '').replace(',', '.')); + if(isNaN(v)){ + fb.style.display = 'block'; + fb.style.background = '#fee2e2'; fb.style.color = '#7f1d1d'; fb.style.borderLeft = '4px solid #dc2626'; + fb.textContent = 'Введи число.'; + return; + } + if(Math.abs(v - b.ans) < b.tol){ + fb.style.display = 'block'; + fb.style.background = '#d1fae5'; fb.style.color = '#065f46'; fb.style.borderLeft = '4px solid #10b981'; + fb.innerHTML = '✓ Босс повержен! +20 XP.'; + card.style.border = '2px solid #10b981'; + card.style.boxShadow = '0 0 0 3px rgba(16,185,129,.16)'; + btn.disabled = true; inp.disabled = true; + if(!solved[n]){ + solved[n] = true; + try{ localStorage.setItem(STATE_KEY, JSON.stringify(solved)); }catch(e){} + if(window.addXp) window.addXp(20, 'boss-ch4-' + n); + updateBar(); + } + } else { + fb.style.display = 'block'; + fb.style.background = '#fee2e2'; fb.style.color = '#7f1d1d'; fb.style.borderLeft = '4px solid #dc2626'; + fb.textContent = 'Не то. Перепроверь решение.'; + } + })); + body.querySelectorAll('.boss-inp').forEach(inp => inp.addEventListener('keydown', e => { + if(e.key === 'Enter'){ e.preventDefault(); body.querySelector('.boss-go[data-n="' + inp.dataset.n + '"]').click(); } + })); +} + +window.PHYS7_CH4_WIDGETS = { + p28: add_p28, + p29: add_p29, + p30: add_p30, + p31: add_p31, + p32: add_p32, + p33: add_p33, + p34: add_p34, + p35: add_p35, + final4: add_final4 +}; + +})();