c7345a71cf
Глава 4 «Давление» закрыта целиком. Файл phys7_ch4_widgets.js (1300 строк, 9 экспортов: p28..p35 + final4). Палитра amber. §28 Давление и единицы: - 3 карточки + таблица сравнения 5 объектов (гвоздь / балерина / человек / лыжник / трактор) - IV-1 КАЛЬК p=F/S с автосравнением (лыжник на снегу / каблук на паркете / ГПа гвоздь) - IV-2 СИМ: 3 сценария «один человек — разные опоры» (ботинки / лыжи / каблук) - DnD 6→3 / тренажёр 5 §29 Давление газа: - 3 карточки (удары молекул / что увеличивает p / шар и шина) - IV-1 СИМ: анимация молекул в сосуде, slider N и T, подсчёт ударов о стенки в реальном времени - DnD 6→2 (растёт/падает) / квиз 4 / тренажёр 4 §30 Закон Паскаля + гидравлический пресс: - 3 карточки (закон / формула F2/F1=S2/S1 / применения) - IV-1 СИМ: использует PHYS.hydraulicPress, 3 slider'а S1/S2/F1, вывод F2 + выигрыш - IV-2 КАЛЬК с формулой - DnD 6→2 / тренажёр 4 §31 Гидростатика: - 3 карточки + таблица «глубина / давление» - IV-1 КАЛЬК ρgh с выбором жидкости (вода/бензин/морская/ртуть/спирт) - IV-2 СИМ: гидростатический парадокс — 3 сосуда разной формы (цилиндр/широкий/узкий), один уровень → одинаковое p на дне - DnD 6→2 / тренажёр 5 §32 Сообщающиеся сосуды: - 3 карточки + IV-1 СИМ: использует PHYS.connectedVessels, 3 варианта форм (2 цилиндра / цилиндр+широкий / узкий+широкий), slider уровня - DnD 6→2 / квиз 3 / тренажёр 4 §33 Газы и их вес: - 3 карточки (m=ρV / опыт со взвешиванием шара) - IV-1 КАЛЬК: 3 slider'а a/b/c комнаты → V, m, P воздуха с автосравнением (школьник / человек / пианино / автомобиль) - DnD 6→2 (легче/тяжелее воздуха): He/H2/CH4 vs CO2/Cl2/Rn - квиз 3 / тренажёр 4 §34 Атмосферное давление: - 3 карточки (опыт Торричелли / падение с высотой 1мм/12м) - IV-1 СИМ: PHYS.mercuryBarometer, slider 400..800 мм рт.ст. с описанием погоды - IV-2 КАЛЬК: slider высоты 0..5000 м → давление с автоописанием места - DnD 6→3 (норма/выше/ниже) / тренажёр 5 §35 БАРОМЕТРЫ И МАНОМЕТРЫ — ГЛАВНЫЙ ВИЗУАЛ ГЛАВЫ 4: - 3 карточки (3 прибора / где какой / манометр на баллоне) - IV-1 СИМ: три прибора рядом — Торричелли + Анероид + U-манометр (все 3 PHYS-хелпера). Один slider давления → видишь одно давление в трёх формах. - DnD 6→2 (баро/мано) / квиз 4 / тренажёр 4 ФИНАЛ ГЛАВЫ 4 (7 боссов + ачивка «Властелин давления» +50 XP): 1. p кирпича (5000 Па) 2. Гидравлический пресс (8000 Н) 3. Дайвер 20 м в море (206 кПа) 4. Сообщ. сосуды (одинаковый уровень 18 см) 5. Давление на высоте 480 м (720 мм) 6. Барометр → Па (98 400 Па) 7. Властелин: полное давление дайвера = атмосферное + гидростатич. (400 кПа) Parse OK, smoke (9 экспортов) OK.
1301 lines
97 KiB
JavaScript
1301 lines
97 KiB
JavaScript
// Физика 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 '<div style="background:#fff;border:1.5px solid ' + ACCENT_SOFT + ';border-left:5px solid ' + c + ';border-radius:11px;padding:14px 16px;margin-bottom:14px;box-shadow:0 2px 8px rgba(0,0,0,.05)">'
|
||
+ '<div style="display:flex;align-items:center;gap:10px;margin-bottom:8px;flex-wrap:wrap">'
|
||
+ '<span style="background:' + c + ';color:#fff;padding:3px 10px;border-radius:99px;font-size:.7rem;font-weight:800;text-transform:uppercase;letter-spacing:.05em">' + labelByKind[kind] + '</span>'
|
||
+ '<span style="font-size:.72rem;font-weight:700;color:#64748b;letter-spacing:.04em">' + (badge||'') + '</span>'
|
||
+ '<span style="font-family:Unbounded,sans-serif;font-weight:800;font-size:.96rem;color:#0f172a;flex:1;min-width:0">' + title + '</span>'
|
||
+ '</div>'
|
||
+ '<div style="font-size:.94rem;line-height:1.6;color:#0f172a">' + body + '</div>'
|
||
+ '</div>';
|
||
}
|
||
|
||
function wgWrap(id, badge, title, hint, body){
|
||
return '<div id="' + id + '" style="background:#fff;border:1.5px solid ' + ACCENT_SOFT + ';border-radius:12px;padding:14px 16px;margin-bottom:14px;box-shadow:0 2px 8px rgba(0,0,0,.05)">'
|
||
+ '<div style="display:flex;align-items:center;gap:10px;margin-bottom:8px;flex-wrap:wrap">'
|
||
+ '<span style="background:' + ACCENT + ';color:#fff;padding:3px 10px;border-radius:99px;font-size:.7rem;font-weight:800;letter-spacing:.05em">' + badge + '</span>'
|
||
+ '<span style="font-family:Unbounded,sans-serif;font-weight:800;font-size:.92rem;color:#0f172a">' + title + '</span>'
|
||
+ '</div>'
|
||
+ (hint ? '<div style="font-size:.84rem;color:#64748b;background:' + ACCENT_SOFT + ';border-left:3px solid ' + ACCENT + ';border-radius:6px;padding:8px 12px;margin-bottom:10px;line-height:1.5">' + hint + '</div>' : '')
|
||
+ body
|
||
+ '</div>';
|
||
}
|
||
|
||
function readButton(pid){
|
||
return '<div style="text-align:center;margin-top:18px"><button class="ph7-read-btn" data-pid="' + pid + '" '
|
||
+ 'style="background:linear-gradient(135deg,#10b981,#047857);color:#fff;border:none;padding:11px 22px;border-radius:11px;font-weight:700;font-size:.92rem;cursor:pointer;font-family:inherit;display:inline-flex;align-items:center;gap:8px;box-shadow:0 4px 14px rgba(16,185,129,.32)">'
|
||
+ '<svg viewBox="0 0 24 24" style="width:16px;height:16px;stroke:currentColor;fill:none;stroke-width:2.5;stroke-linecap:round;stroke-linejoin:round"><polyline points="20 6 9 17 4 12"/></svg>'
|
||
+ 'Я прочитал § <span style="opacity:.85;font-size:.86rem">+10 XP</span>'
|
||
+ '</button></div>';
|
||
}
|
||
|
||
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 = '<svg viewBox="0 0 24 24" style="width:16px;height:16px;stroke:currentColor;fill:none;stroke-width:2.5;stroke-linecap:round;stroke-linejoin:round"><polyline points="20 6 9 17 4 12"/></svg> Прочитано';
|
||
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 = '<svg viewBox="0 0 24 24" style="width:16px;height:16px;stroke:currentColor;fill:none;stroke-width:2.5;stroke-linecap:round;stroke-linejoin:round"><polyline points="20 6 9 17 4 12"/></svg> Прочитано';
|
||
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 => '<button class="dnd-chip" data-id="' + it.id + '" type="button" style="background:#fff;border:1.5px solid ' + ACCENT_SOFT + ';border-radius:10px;padding:7px 13px;cursor:pointer;font-size:.9rem;font-family:inherit;transition:all .15s">' + it.html + '</button>').join('');
|
||
const boxes = cats.map(c => '<div class="drop-box" data-cat="' + c.cat + '" style="background:#fff;border:1.5px dashed ' + ACCENT_SOFT + ';border-radius:10px;padding:10px;min-height:80px"><h5 style="font-family:Unbounded,sans-serif;font-size:.76rem;color:' + ACCENT_D + ';margin-bottom:8px;text-transform:uppercase;letter-spacing:.04em">' + c.label + '</h5><div class="drop-items" style="display:flex;flex-wrap:wrap;gap:6px;min-height:32px"></div></div>').join('');
|
||
return '<div id="' + host + '" class="dnd-host">'
|
||
+ '<div style="font-size:.86rem;color:#475569;margin-bottom:10px">Кликни по карточке, потом по корзине. Чтобы вернуть — кликни в корзине.</div>'
|
||
+ '<div style="display:flex;flex-wrap:wrap;gap:8px;margin-bottom:14px;padding:10px;border:1.5px dashed ' + ACCENT_SOFT + ';border-radius:10px;background:#fffbeb">' + chips + '</div>'
|
||
+ '<div style="display:grid;grid-template-columns:repeat(auto-fit,minmax(170px,1fr));gap:10px;margin-bottom:12px">' + boxes + '</div>'
|
||
+ '<div style="display:flex;gap:8px"><button class="dnd-check" type="button" style="background:linear-gradient(135deg,' + ACCENT + ',' + ACCENT_D + ');color:#fff;border:none;padding:9px 18px;border-radius:9px;font-weight:700;font-size:.86rem;cursor:pointer;font-family:inherit">Проверить</button></div>'
|
||
+ '<div class="dnd-fb" style="padding:10px 14px;border-radius:9px;font-weight:600;font-size:.88rem;margin-top:8px;display:none;line-height:1.45"></div>'
|
||
+ '</div>';
|
||
}
|
||
|
||
function quizQuestion(host, idx, q, opts, correctIdx, explain){
|
||
const optsHtml = opts.map((o,i) => '<button class="qz-opt" data-i="' + i + '" type="button" style="background:#fff;border:1.5px solid ' + ACCENT_SOFT + ';border-radius:9px;padding:9px 14px;cursor:pointer;font-size:.92rem;font-family:inherit;text-align:left;width:100%;margin-bottom:6px">' + o + '</button>').join('');
|
||
return '<div class="qz-q" data-idx="' + idx + '" style="background:' + ACCENT_SOFT + ';border:1.5px solid ' + ACCENT_SOFT + ';border-radius:10px;padding:12px 14px;margin-bottom:10px">'
|
||
+ '<div style="font-weight:700;margin-bottom:8px;font-size:.94rem">' + (idx+1) + '. ' + q + '</div>'
|
||
+ '<div class="qz-opts" data-correct="' + correctIdx + '" data-explain="' + (explain||'').replace(/"/g,'"') + '">' + optsHtml + '</div>'
|
||
+ '<div class="qz-fb" style="padding:9px 12px;border-radius:8px;font-size:.86rem;margin-top:6px;display:none;line-height:1.45"></div>'
|
||
+ '</div>';
|
||
}
|
||
|
||
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',
|
||
'<b>Давление</b> $p$ — это сила, действующая на единицу площади опоры:<br>'
|
||
+ '$$p = \\dfrac{F}{S}$$<br>'
|
||
+ 'где $F$ — сила (Н), $S$ — площадь (м²). Единица — <b>паскаль</b>: $1$ Па $= 1$ Н/м².<br><br>'
|
||
+ 'Одно и то же тело может производить очень разное давление — всё зависит от <b>площади</b> опоры.');
|
||
|
||
h += makeCard('rule', 'Производные единицы', '§ 28.2',
|
||
'<ul style="padding-left:20px;margin:6px 0">'
|
||
+ '<li>$1$ кПа $= 1000$ Па</li>'
|
||
+ '<li>$1$ МПа $= 10^6$ Па</li>'
|
||
+ '<li>$1$ ГПа $= 10^9$ Па</li>'
|
||
+ '<li>$1$ Н/см² $= 10\\,000$ Па $= 10$ кПа</li>'
|
||
+ '</ul>');
|
||
|
||
h += makeCard('example', 'Гвоздь, тапок, трактор', '§ 28.3',
|
||
'<table style="width:100%;border-collapse:collapse;font-size:.92rem">'
|
||
+ '<tr style="background:' + ACCENT_SOFT + '"><th style="padding:6px 10px;text-align:left;border-bottom:2px solid ' + ACCENT + '">Объект</th><th style="padding:6px 10px;text-align:right;border-bottom:2px solid ' + ACCENT + '">F</th><th style="padding:6px 10px;text-align:right;border-bottom:2px solid ' + ACCENT + '">S</th><th style="padding:6px 10px;text-align:right;border-bottom:2px solid ' + ACCENT + '">p</th></tr>'
|
||
+ [
|
||
['Гвоздь под молотком',100,'0,1 мм² = 10⁻⁷ м²','10⁹ Па'],
|
||
['Балерина на пуанте',500,'1 см² = 10⁻⁴ м²','5 МПа'],
|
||
['Человек на двух ногах',700,'300 см² = 0,03 м²','23 кПа'],
|
||
['Лыжник',700,'0,25 м²','2,8 кПа'],
|
||
['Трактор (на гусеницах)',50000,'5 м²','10 кПа']
|
||
].map(r => '<tr><td style="padding:5px 10px;border-bottom:1px solid ' + ACCENT_SOFT + '">' + r[0] + '</td><td style="padding:5px 10px;text-align:right;border-bottom:1px solid ' + ACCENT_SOFT + ';font-family:JetBrains Mono,monospace">' + r[1] + ' Н</td><td style="padding:5px 10px;text-align:right;border-bottom:1px solid ' + ACCENT_SOFT + ';font-family:JetBrains Mono,monospace;font-size:.82rem">' + r[2] + '</td><td style="padding:5px 10px;text-align:right;border-bottom:1px solid ' + ACCENT_SOFT + ';font-family:JetBrains Mono,monospace;font-weight:700">' + r[3] + '</td></tr>').join('')
|
||
+ '</table>'
|
||
+ '<p style="margin-top:8px;font-size:.86rem;color:#475569">Лыжник давит меньше, чем человек без лыж — поэтому не проваливается в снег.</p>');
|
||
|
||
/* IV-1 КАЛЬК p = F/S */
|
||
h += wgWrap('p28-iv1', 'КАЛЬК', 'Калькулятор давления', 'Меняй силу и площадь — увидь, как меняется давление.',
|
||
'<div style="display:grid;grid-template-columns:1fr 1fr;gap:8px;margin-bottom:10px">'
|
||
+ '<label style="display:block;font-size:.86rem;color:#475569;background:#fff;padding:8px 12px;border-radius:8px;border:1px solid ' + ACCENT_SOFT + '">Сила $F$, Н: <b id="p28-F" style="color:' + ACCENT_D + ';font-family:JetBrains Mono,monospace">500</b><input type="range" id="p28-F-r" min="1" max="10000" step="1" value="500" style="display:block;width:100%;margin-top:6px;accent-color:' + ACCENT + '"></label>'
|
||
+ '<label style="display:block;font-size:.86rem;color:#475569;background:#fff;padding:8px 12px;border-radius:8px;border:1px solid ' + ACCENT_SOFT + '">Площадь $S$, см²: <b id="p28-S" style="color:' + ACCENT_D + ';font-family:JetBrains Mono,monospace">100</b><input type="range" id="p28-S-r" min="0.01" max="10000" step="0.01" value="100" style="display:block;width:100%;margin-top:6px;accent-color:' + ACCENT + '"></label>'
|
||
+ '</div>'
|
||
+ '<div style="background:' + ACCENT_SOFT + ';border-radius:9px;padding:12px 14px;font-size:.94rem;line-height:1.7">'
|
||
+ '$p = F/S = $ <b id="p28-p" style="color:' + ACCENT_D + ';font-family:JetBrains Mono,monospace">50 000</b> Па $= $ <b id="p28-pkpa" style="color:' + ACCENT_D + ';font-family:JetBrains Mono,monospace">50</b> кПа'
|
||
+ '<div id="p28-cmp" style="font-size:.84rem;color:#475569;margin-top:4px"></div>'
|
||
+ '</div>');
|
||
|
||
/* IV-2 СИМ: переключатель сценариев */
|
||
h += wgWrap('p28-iv2', 'СИМ', 'Один человек — разные ситуации', 'Один и тот же человек давит на грунт по-разному.',
|
||
'<div style="display:flex;gap:6px;margin-bottom:10px;flex-wrap:wrap">'
|
||
+ [['boots','В ботинках'],['skis','На лыжах'],['stilet','На каблуке']].map((s, i) =>
|
||
'<button class="p28-sc" data-s="' + s[0] + '" type="button" style="background:' + (i===0 ? ACCENT : '#fff') + ';color:' + (i===0 ? '#fff' : ACCENT) + ';border:2px solid ' + ACCENT + ';padding:7px 14px;border-radius:9px;cursor:pointer;font-weight:700;font-family:inherit;font-size:.86rem">' + s[1] + '</button>').join('')
|
||
+ '</div>'
|
||
+ '<svg id="p28-sc-svg" viewBox="0 0 360 140" width="100%" style="max-width:500px;display:block;margin:0 auto;background:#fffbeb;border-radius:9px;border:1px solid ' + ACCENT_SOFT + '"></svg>'
|
||
+ '<div id="p28-sc-info" style="background:' + ACCENT_SOFT + ';border-radius:9px;padding:10px 14px;margin-top:8px;font-size:.92rem;line-height:1.6"></div>');
|
||
|
||
/* 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', '',
|
||
'<div id="p28-tr-host">'
|
||
+ 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$ Н.')
|
||
+ '</div>');
|
||
|
||
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 += '<rect x="0" y="' + baseY + '" width="' + W + '" height="30" fill="#94a3b8"/>';
|
||
for(let i = 0; i < 18; i++) s += '<line x1="' + (i*22+5) + '" y1="' + baseY + '" x2="' + (i*22+15) + '" y2="' + (baseY+8) + '" stroke="#374151" stroke-width="0.8"/>';
|
||
// Человек (упрощённо)
|
||
s += '<circle cx="180" cy="40" r="14" fill="#fbbf24" stroke="#0f172a" stroke-width="1.5"/>'; // голова
|
||
s += '<rect x="170" y="55" width="20" height="35" fill="#dc2626"/>';
|
||
// Опора (разная)
|
||
if(sc === 'boots'){
|
||
s += '<rect x="165" y="100" width="30" height="10" fill="#374151"/>';
|
||
s += '<text x="180" y="135" text-anchor="middle" font-size="10" fill="#0f172a" font-family="Inter,sans-serif">2 ботинка, S ≈ 300 см²</text>';
|
||
} else if(sc === 'skis'){
|
||
s += '<rect x="100" y="100" width="160" height="10" fill="#92400e" stroke="#0f172a" stroke-width="1"/>';
|
||
s += '<text x="180" y="135" text-anchor="middle" font-size="10" fill="#0f172a" font-family="Inter,sans-serif">2 лыжи, S ≈ 2500 см²</text>';
|
||
} else {
|
||
s += '<polygon points="178,100 182,100 180,108" fill="#374151"/>';
|
||
s += '<text x="180" y="135" text-anchor="middle" font-size="10" fill="#0f172a" font-family="Inter,sans-serif">2 пуанта, S ≈ 1 см²</text>';
|
||
}
|
||
// Сила
|
||
s += '<line x1="220" y1="50" x2="220" y2="98" stroke="#dc2626" stroke-width="2.5"/>';
|
||
s += '<polygon points="215,90 225,90 220,100" fill="#dc2626"/>';
|
||
s += '<text x="228" y="78" font-family="Inter,sans-serif" font-size="11" font-weight="700" fill="#dc2626">F = 700 Н</text>';
|
||
document.getElementById('p28-sc-svg').innerHTML = s;
|
||
const d = scenarios[sc];
|
||
const p = 700 / d.S;
|
||
document.getElementById('p28-sc-info').innerHTML = '<b>' + d.nm + '</b>: $S = ' + d.S + '$ м², $p = F/S = ' + Math.round(p).toLocaleString('ru-RU') + '$ Па $\\approx ' + (p/1000).toFixed(1) + '$ кПа<br><span style="font-size:.84rem;color:#64748b">' + d.cmp + '</span>';
|
||
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',
|
||
'Молекулы газа постоянно <b>бьются о стенки</b> сосуда. Каждый удар — крошечная сила. '
|
||
+ 'Сумма всех ударов делится на площадь стенки — получается <b>давление газа</b>.<br><br>'
|
||
+ 'У газа нет собственной формы и фиксированного объёма, поэтому давление возникает <b>равномерно во все стороны</b>.');
|
||
|
||
h += makeCard('rule', 'Что увеличивает p газа', '§ 29.2',
|
||
'Давление газа растёт, если:'
|
||
+ '<ul style="padding-left:20px;margin:5px 0">'
|
||
+ '<li><b>Увеличить $T$</b> — молекулы быстрее, удары сильнее.</li>'
|
||
+ '<li><b>Уменьшить $V$</b> — то же число молекул на меньшей площади.</li>'
|
||
+ '<li><b>Добавить молекул</b> (накачать) — больше ударов в секунду.</li>'
|
||
+ '</ul>');
|
||
|
||
h += makeCard('example', 'Шарик и шина', '§ 29.3',
|
||
'<b>Воздушный шарик</b>: накачиваем (добавляем молекулы) → $p$ растёт → шарик расширяется, '
|
||
+ 'пока упругость резины не уравновесит давление.<br><br>'
|
||
+ '<b>Шина машины</b>: летом нагревается на солнце → $T$ растёт → $p$ растёт. '
|
||
+ 'Поэтому летом давление в шинах выше, чем зимой.');
|
||
|
||
/* IV-1 СИМ */
|
||
h += wgWrap('p29-iv1', 'СИМ', 'Молекулы газа в сосуде', 'Меняй число молекул и скорость — увидь, как меняется частота ударов.',
|
||
'<div style="display:grid;grid-template-columns:1fr 1fr;gap:8px;margin-bottom:10px">'
|
||
+ '<label style="display:block;font-size:.86rem;color:#475569;background:#fff;padding:8px 12px;border-radius:8px;border:1px solid ' + ACCENT_SOFT + '">Число молекул: <b id="p29-N" style="color:' + ACCENT_D + ';font-family:JetBrains Mono,monospace">30</b><input type="range" id="p29-N-r" min="5" max="80" step="1" value="30" style="display:block;width:100%;margin-top:6px;accent-color:' + ACCENT + '"></label>'
|
||
+ '<label style="display:block;font-size:.86rem;color:#475569;background:#fff;padding:8px 12px;border-radius:8px;border:1px solid ' + ACCENT_SOFT + '">Температура $T$, отн. ед.: <b id="p29-T" style="color:' + ACCENT_D + ';font-family:JetBrains Mono,monospace">2</b><input type="range" id="p29-T-r" min="1" max="5" step="0.5" value="2" style="display:block;width:100%;margin-top:6px;accent-color:' + ACCENT + '"></label>'
|
||
+ '</div>'
|
||
+ '<svg id="p29-svg" viewBox="0 0 360 200" width="100%" style="max-width:500px;display:block;margin:0 auto;background:#fffbeb;border-radius:9px;border:1px solid ' + ACCENT_SOFT + '"></svg>'
|
||
+ '<div id="p29-info" style="background:' + ACCENT_SOFT + ';border-radius:9px;padding:10px 14px;margin-top:8px;font-size:.92rem;text-align:center"></div>');
|
||
|
||
/* IV-2 КВИЗ */
|
||
h += wgWrap('p29-iv2', 'КВИЗ', 'Давление газа', '',
|
||
'<div id="p29-q-host">'
|
||
+ quizQuestion('p29-q', 0, 'Что создаёт давление газа на стенки сосуда?', ['Сила тяжести','Удары молекул о стенки','Поверхностное натяжение','Магнитное поле'], 1)
|
||
+ quizQuestion('p29-q', 1, 'Если нагреть газ в закрытом сосуде, давление…', ['Не изменится','Уменьшится','Увеличится','Станет нулевым'], 2)
|
||
+ quizQuestion('p29-q', 2, 'Если сжать газ (уменьшить $V$) при той же температуре, $p$…', ['Уменьшится','Увеличится','Не изменится','Зависит от массы'], 1)
|
||
+ quizQuestion('p29-q', 3, 'В какую сторону газ давит на стенки сосуда?', ['Только вниз','Только вверх','Равномерно во все стороны','Только в одну сторону'], 2)
|
||
+ '</div>');
|
||
|
||
/* 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', '',
|
||
'<div id="p29-tr-host">'
|
||
+ 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)
|
||
+ '</div>');
|
||
|
||
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 += '<rect x="3" y="3" width="354" height="194" fill="none" stroke="' + ACCENT_D + '" stroke-width="2"/>';
|
||
p29.parts.forEach(p => {
|
||
const sp = Math.hypot(p.vx, p.vy);
|
||
const col = sp > 2 ? '#dc2626' : (sp > 1.2 ? '#d97706' : '#0284c7');
|
||
s += '<circle cx="' + p.x.toFixed(1) + '" cy="' + p.y.toFixed(1) + '" r="3.5" fill="' + col + '"/>';
|
||
});
|
||
svg.innerHTML = s;
|
||
if(frame29 % 30 === 0){
|
||
const avg = (hitSum / 30).toFixed(0);
|
||
document.getElementById('p29-info').innerHTML = 'Молекул: <b>' + p29.parts.length + '</b> · ударов о стенки за такт: <b>' + avg + '</b> · Давление $p$ <b>тем выше</b>, чем больше число молекул × их скорость.';
|
||
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',
|
||
'Давление, производимое на жидкость или газ, передаётся <b>без изменения</b> в каждую точку '
|
||
+ 'этой жидкости или газа и <b>во все стороны одинаково</b>.<br><br>'
|
||
+ 'Это открыл Блез Паскаль в XVII веке. Поэтому если надуть воздушный шарик и сжать его в одном месте — '
|
||
+ 'он раздуется в другом, передавая давление равномерно.');
|
||
|
||
h += makeCard('rule', 'Гидравлический пресс', '§ 30.2',
|
||
'Соединим два цилиндра жидкостью. На малый поршень давит сила $F_1$ — возникает давление $p = F_1/S_1$. '
|
||
+ 'Это давление передаётся по жидкости к большому поршню площадью $S_2$:<br>'
|
||
+ '$$F_2 = p \\cdot S_2 = F_1 \\cdot \\dfrac{S_2}{S_1}$$<br>'
|
||
+ '<b>Если $S_2 \\gg S_1$</b>, то $F_2 \\gg F_1$ — гидравлика <b>выигрывает в силе</b>. '
|
||
+ 'Платой служит то, что большой поршень движется во столько же раз медленнее.');
|
||
|
||
h += makeCard('example', 'Где применяют', '§ 30.3',
|
||
'<ul style="padding-left:20px;margin:5px 0">'
|
||
+ '<li><b>Гидравлический пресс</b> — гнёт металл, прессует тюки.</li>'
|
||
+ '<li><b>Гидравлический подъёмник</b> в автосервисе.</li>'
|
||
+ '<li><b>Тормоза</b> легкового авто — нажатие на педаль передаётся жидкости.</li>'
|
||
+ '<li><b>Экскаватор, ковш бульдозера</b> — цилиндры с маслом.</li>'
|
||
+ '</ul>');
|
||
|
||
/* IV-1 ГЛАВНЫЙ ВИЗУАЛ — гидравлический пресс */
|
||
h += wgWrap('p30-iv1', 'СИМ', 'Гидравлический пресс — главный визуал', 'Меняй площади и силу на малом поршне — увидь силу на большом.',
|
||
'<div style="display:grid;grid-template-columns:repeat(auto-fit,minmax(140px,1fr));gap:8px;margin-bottom:10px">'
|
||
+ '<label style="display:block;font-size:.86rem;color:#475569;background:#fff;padding:7px 11px;border-radius:8px;border:1px solid ' + ACCENT_SOFT + '">$S_1$, см²: <b id="p30-S1" style="color:' + ACCENT_D + ';font-family:JetBrains Mono,monospace">2</b><input type="range" id="p30-S1-r" min="1" max="50" step="1" value="2" style="display:block;width:100%;margin-top:6px;accent-color:' + ACCENT + '"></label>'
|
||
+ '<label style="display:block;font-size:.86rem;color:#475569;background:#fff;padding:7px 11px;border-radius:8px;border:1px solid ' + ACCENT_SOFT + '">$S_2$, см²: <b id="p30-S2" style="color:' + ACCENT_D + ';font-family:JetBrains Mono,monospace">200</b><input type="range" id="p30-S2-r" min="10" max="500" step="5" value="200" style="display:block;width:100%;margin-top:6px;accent-color:' + ACCENT + '"></label>'
|
||
+ '<label style="display:block;font-size:.86rem;color:#475569;background:#fff;padding:7px 11px;border-radius:8px;border:1px solid ' + ACCENT_SOFT + '">$F_1$, Н: <b id="p30-F1" style="color:' + ACCENT_D + ';font-family:JetBrains Mono,monospace">50</b><input type="range" id="p30-F1-r" min="1" max="500" step="1" value="50" style="display:block;width:100%;margin-top:6px;accent-color:' + ACCENT + '"></label>'
|
||
+ '</div>'
|
||
+ '<svg id="p30-svg" viewBox="0 0 320 200" width="100%" style="max-width:500px;display:block;margin:0 auto;background:#fffbeb;border-radius:9px;border:1px solid ' + ACCENT_SOFT + '"></svg>'
|
||
+ '<div id="p30-info" style="background:' + ACCENT_SOFT + ';border-radius:9px;padding:10px 14px;margin-top:8px;font-size:.94rem;line-height:1.65"></div>');
|
||
|
||
/* IV-2 КАЛЬК */
|
||
h += wgWrap('p30-iv2', 'КАЛЬК', 'F₂ через закон Паскаля', '',
|
||
'<div style="display:grid;grid-template-columns:repeat(auto-fit,minmax(120px,1fr));gap:8px;margin-bottom:10px">'
|
||
+ '<label style="display:block;font-size:.86rem;color:#475569;background:#fff;padding:8px 12px;border-radius:8px;border:1px solid ' + ACCENT_SOFT + '">$F_1$, Н: <b id="p30c-F1" style="color:' + ACCENT_D + ';font-family:JetBrains Mono,monospace">100</b><input type="range" id="p30c-F1-r" min="1" max="1000" step="1" value="100" style="display:block;width:100%;margin-top:6px;accent-color:' + ACCENT + '"></label>'
|
||
+ '<label style="display:block;font-size:.86rem;color:#475569;background:#fff;padding:8px 12px;border-radius:8px;border:1px solid ' + ACCENT_SOFT + '">$S_1$: <b id="p30c-S1" style="color:' + ACCENT_D + ';font-family:JetBrains Mono,monospace">5</b><input type="range" id="p30c-S1-r" min="1" max="100" step="1" value="5" style="display:block;width:100%;margin-top:6px;accent-color:' + ACCENT + '"></label>'
|
||
+ '<label style="display:block;font-size:.86rem;color:#475569;background:#fff;padding:8px 12px;border-radius:8px;border:1px solid ' + ACCENT_SOFT + '">$S_2$: <b id="p30c-S2" style="color:' + ACCENT_D + ';font-family:JetBrains Mono,monospace">500</b><input type="range" id="p30c-S2-r" min="10" max="2000" step="10" value="500" style="display:block;width:100%;margin-top:6px;accent-color:' + ACCENT + '"></label>'
|
||
+ '</div>'
|
||
+ '<div style="background:' + ACCENT_SOFT + ';border-radius:9px;padding:12px 14px;font-size:.94rem;line-height:1.7">'
|
||
+ '$p = F_1/S_1 = $ <b id="p30c-p" style="color:' + ACCENT_D + ';font-family:JetBrains Mono,monospace">20</b> Н/см² · $F_2 = pS_2 = F_1 \\cdot S_2/S_1 = $ <b id="p30c-F2" style="color:' + ACCENT_D + ';font-family:JetBrains Mono,monospace">10000</b> Н'
|
||
+ '<div id="p30c-gain" style="font-size:.84rem;color:#475569;margin-top:5px">Выигрыш в силе: <b style="color:#10b981">в 100 раз</b></div>'
|
||
+ '</div>');
|
||
|
||
/* 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', '',
|
||
'<div id="p30-tr-host">'
|
||
+ 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)
|
||
+ '</div>');
|
||
|
||
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 = $ <b>' + F2.toFixed(0) + '</b> Н <span style="color:#10b981;font-weight:700">(в ' + (S2/S1).toFixed(1) + ' раз больше)</span>';
|
||
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 = 'Выигрыш в силе: <b style="color:#10b981">в ' + (S2/S1).toFixed(1) + ' раз</b>';
|
||
};
|
||
['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',
|
||
'Жидкость, имеющая массу, давит на дно сосуда и на боковые стенки. '
|
||
+ 'Это давление возникает <b>не от тела</b>, как у твёрдых, а от <b>собственного веса жидкости</b>.<br><br>'
|
||
+ 'Формула гидростатического давления на глубине $h$:<br>'
|
||
+ '$$p = \\rho g h$$<br>'
|
||
+ 'где $\\rho$ — плотность жидкости (кг/м³), $g \\approx 9{,}8$ Н/кг, $h$ — глубина (м).');
|
||
|
||
h += makeCard('rule', 'Гидростатический парадокс', '§ 31.2',
|
||
'<b>Удивительный факт:</b> давление на дно <b>не зависит</b> от формы сосуда и от количества жидкости. '
|
||
+ 'Если налить $h$ воды в узкую трубку или в широкий бассейн — давление на дно <b>одинаково</b>.<br><br>'
|
||
+ 'Зависит только от: плотности жидкости и глубины. Это <b>гидростатический парадокс</b> Паскаля.');
|
||
|
||
h += makeCard('example', 'Давление на глубине', '§ 31.3',
|
||
'<table style="width:100%;border-collapse:collapse;font-size:.92rem">'
|
||
+ '<tr style="background:' + ACCENT_SOFT + '"><th style="padding:6px 10px;text-align:left;border-bottom:2px solid ' + ACCENT + '">Глубина</th><th style="padding:6px 10px;text-align:right;border-bottom:2px solid ' + ACCENT + '">p (вода)</th></tr>'
|
||
+ [['$1$ м','9,8 кПа'],['$10$ м','98 кПа ≈ 1 атм'],['$100$ м','≈ 10 атм'],['$1000$ м','≈ 100 атм (батискаф)'],['Дно Марианской впадины ($\\approx 11$ км)','≈ 1100 атм']].map(r =>
|
||
'<tr><td style="padding:5px 10px;border-bottom:1px solid ' + ACCENT_SOFT + '">' + r[0] + '</td><td style="padding:5px 10px;text-align:right;border-bottom:1px solid ' + ACCENT_SOFT + ';font-family:JetBrains Mono,monospace;font-weight:700">' + r[1] + '</td></tr>').join('')
|
||
+ '</table>');
|
||
|
||
/* IV-1 КАЛЬК */
|
||
h += wgWrap('p31-iv1', 'КАЛЬК', 'Калькулятор $p = \\rho g h$', 'Меняй плотность и глубину.',
|
||
'<div style="display:grid;grid-template-columns:1fr 1fr;gap:8px;margin-bottom:10px">'
|
||
+ '<label style="display:block;font-size:.86rem;color:#475569;background:#fff;padding:8px 12px;border-radius:8px;border:1px solid ' + ACCENT_SOFT + '">Жидкость:<select id="p31-rho" style="width:100%;margin-top:6px;padding:6px;border-radius:6px;border:1px solid ' + ACCENT_SOFT + ';font-family:inherit"><option value="1000" selected>Вода (1000 кг/м³)</option><option value="800">Бензин (800)</option><option value="1030">Морская вода (1030)</option><option value="13600">Ртуть (13600)</option><option value="900">Спирт (900)</option></select></label>'
|
||
+ '<label style="display:block;font-size:.86rem;color:#475569;background:#fff;padding:8px 12px;border-radius:8px;border:1px solid ' + ACCENT_SOFT + '">Глубина $h$, м: <b id="p31-h" style="color:' + ACCENT_D + ';font-family:JetBrains Mono,monospace">3</b><input type="range" id="p31-h-r" min="0.1" max="100" step="0.1" value="3" style="display:block;width:100%;margin-top:6px;accent-color:' + ACCENT + '"></label>'
|
||
+ '</div>'
|
||
+ '<div style="background:' + ACCENT_SOFT + ';border-radius:9px;padding:12px 14px;font-size:.94rem;line-height:1.65">'
|
||
+ '$p = \\rho g h = $ <b id="p31-p" style="color:' + ACCENT_D + ';font-family:JetBrains Mono,monospace">29 400</b> Па $= $ <b id="p31-pkpa" style="color:' + ACCENT_D + ';font-family:JetBrains Mono,monospace">29.4</b> кПа $\\approx $ <b id="p31-patm" style="color:' + ACCENT_D + ';font-family:JetBrains Mono,monospace">0.29</b> атм'
|
||
+ '</div>');
|
||
|
||
/* IV-2 СИМ: гидростатический парадокс — 3 сосуда */
|
||
h += wgWrap('p31-iv2', 'СИМ', 'Гидростатический парадокс: 3 сосуда', 'Один уровень воды — одинаковое давление на дно. Форма не важна!',
|
||
'<svg id="p31-svg" viewBox="0 0 360 200" width="100%" style="max-width:500px;display:block;margin:0 auto;background:#fffbeb;border-radius:9px;border:1px solid ' + ACCENT_SOFT + '"></svg>'
|
||
+ '<div style="margin-top:10px"><label style="display:block;font-size:.86rem;color:#475569;background:#fff;padding:8px 12px;border-radius:8px;border:1px solid ' + ACCENT_SOFT + '">Уровень воды, см: <b id="p31s-h" style="color:' + ACCENT_D + ';font-family:JetBrains Mono,monospace">10</b><input type="range" id="p31s-h-r" min="2" max="15" step="1" value="10" style="display:block;width:100%;margin-top:6px;accent-color:' + ACCENT + '"></label></div>'
|
||
+ '<div id="p31s-info" style="background:' + ACCENT_SOFT + ';border-radius:9px;padding:10px 14px;margin-top:8px;font-size:.92rem;text-align:center"></div>');
|
||
|
||
/* 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', '',
|
||
'<div id="p31-tr-host">'
|
||
+ 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$ атм.')
|
||
+ '</div>');
|
||
|
||
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 += '<rect x="20" y="' + baseY + '" width="320" height="10" fill="#475569"/>';
|
||
function vessel(x, w, kind){
|
||
const wallH = 130;
|
||
const topY = baseY - wallH;
|
||
let g = '';
|
||
if(kind === 'cyl'){
|
||
g += '<line x1="' + x + '" y1="' + topY + '" x2="' + x + '" y2="' + baseY + '" stroke="#0f172a" stroke-width="2"/>';
|
||
g += '<line x1="' + (x+w) + '" y1="' + topY + '" x2="' + (x+w) + '" y2="' + baseY + '" stroke="#0f172a" stroke-width="2"/>';
|
||
// Жидкость
|
||
const fillH = hCm * pxPerCm;
|
||
g += '<rect x="' + (x+1) + '" y="' + (baseY - fillH) + '" width="' + (w-2) + '" height="' + fillH + '" fill="' + liqColor + '" opacity="0.7"/>';
|
||
} else if(kind === 'wide'){
|
||
// Конус расширяющийся вверх
|
||
g += '<line x1="' + (x+5) + '" y1="' + topY + '" x2="' + x + '" y2="' + baseY + '" stroke="#0f172a" stroke-width="2"/>';
|
||
g += '<line x1="' + (x+w-5) + '" y1="' + topY + '" x2="' + (x+w) + '" y2="' + baseY + '" stroke="#0f172a" stroke-width="2"/>';
|
||
const fillH = hCm * pxPerCm;
|
||
g += '<polygon points="' + (x+1) + ',' + baseY + ' ' + (x+w-1) + ',' + baseY + ' ' + (x+w-1-fillH*0.05) + ',' + (baseY-fillH) + ' ' + (x+1+fillH*0.05) + ',' + (baseY-fillH) + '" fill="' + liqColor + '" opacity="0.7"/>';
|
||
} else { // narrow — сужающийся
|
||
g += '<line x1="' + x + '" y1="' + topY + '" x2="' + (x+10) + '" y2="' + baseY + '" stroke="#0f172a" stroke-width="2"/>';
|
||
g += '<line x1="' + (x+w) + '" y1="' + topY + '" x2="' + (x+w-10) + '" y2="' + baseY + '" stroke="#0f172a" stroke-width="2"/>';
|
||
const fillH = hCm * pxPerCm;
|
||
g += '<polygon points="' + (x+10) + ',' + baseY + ' ' + (x+w-10) + ',' + baseY + ' ' + (x+w-10-fillH*0.05) + ',' + (baseY-fillH) + ' ' + (x+10+fillH*0.05) + ',' + (baseY-fillH) + '" fill="' + liqColor + '" opacity="0.7"/>';
|
||
}
|
||
return g;
|
||
}
|
||
s += vessel(40, 60, 'cyl');
|
||
s += vessel(150, 60, 'wide');
|
||
s += vessel(260, 60, 'narrow');
|
||
// Линия уровня
|
||
const lvlY = baseY - hCm * pxPerCm;
|
||
s += '<line x1="20" y1="' + lvlY + '" x2="340" y2="' + lvlY + '" stroke="#dc2626" stroke-width="1.5" stroke-dasharray="4 3"/>';
|
||
s += '<text x="20" y="' + (lvlY-3) + '" font-family="Inter,sans-serif" font-size="10" font-weight="700" fill="#dc2626">уровень = ' + hCm + ' см</text>';
|
||
document.getElementById('p31-svg').innerHTML = s;
|
||
const p = 1000 * 9.8 * (hCm / 100);
|
||
document.getElementById('p31s-info').innerHTML = 'На дне всех трёх сосудов: <b>$p = \\rho g h = ' + Math.round(p).toLocaleString('ru-RU') + '$ Па</b>. Форма не важна!';
|
||
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',
|
||
'<b>Сообщающиеся сосуды</b> — это два или несколько сосудов, соединённых внизу так, что жидкость может переходить между ними.<br><br>'
|
||
+ '<b>Главный закон:</b> в сообщающихся сосудах <b>однородная</b> жидкость устанавливается на <b>одном уровне</b> — независимо от формы сосудов.');
|
||
|
||
h += makeCard('rule', 'Почему именно так', '§ 32.2',
|
||
'На одной глубине давление одно и то же ($p = \\rho g h$). Если уровни жидкости разные, то и давления у дна разные, '
|
||
+ 'и жидкость будет перетекать в сторону <b>меньшего</b> давления — пока уровни не сравняются.<br><br>'
|
||
+ 'Для <b>разнородных</b> жидкостей: высоты в коленах <b>обратно пропорциональны плотностям</b>: '
|
||
+ '$\\rho_1 h_1 = \\rho_2 h_2$.');
|
||
|
||
h += makeCard('example', 'Применения', '§ 32.3',
|
||
'<ul style="padding-left:20px;margin:5px 0">'
|
||
+ '<li><b>Водопровод</b> в высотных домах — давление от водонапорной башни.</li>'
|
||
+ '<li><b>Шлюзы</b> для пропуска судов.</li>'
|
||
+ '<li><b>Чайник с носиком</b>: чай в чайнике и в носике на одном уровне.</li>'
|
||
+ '<li><b>Кофейник, лейка</b>.</li>'
|
||
+ '<li><b>Артезианские колодцы</b>: вода поднимается естественным образом.</li>'
|
||
+ '</ul>');
|
||
|
||
/* IV-1 СИМ: сообщающиеся сосуды */
|
||
h += wgWrap('p32-iv1', 'СИМ', 'Однородная жидкость → один уровень', 'Меняй уровень — оба сосуда уравниваются.',
|
||
'<div style="margin-bottom:10px"><label style="display:block;font-size:.86rem;color:#475569;background:#fff;padding:8px 12px;border-radius:8px;border:1px solid ' + ACCENT_SOFT + '">Уровень воды, px: <b id="p32-l" style="color:' + ACCENT_D + ';font-family:JetBrains Mono,monospace">100</b><input type="range" id="p32-l-r" min="40" max="160" step="2" value="100" style="display:block;width:100%;margin-top:6px;accent-color:' + ACCENT + '"></label></div>'
|
||
+ '<div style="display:flex;gap:6px;margin-bottom:10px;flex-wrap:wrap">'
|
||
+ '<button class="p32-shape" data-a="cylinder" data-b="cylinder" type="button" style="background:' + ACCENT + ';color:#fff;border:none;padding:7px 14px;border-radius:9px;cursor:pointer;font-weight:700;font-family:inherit;font-size:.84rem">Два цилиндра</button>'
|
||
+ '<button class="p32-shape" data-a="cylinder" data-b="wide" type="button" style="background:#fff;color:' + ACCENT + ';border:2px solid ' + ACCENT + ';padding:7px 14px;border-radius:9px;cursor:pointer;font-weight:700;font-family:inherit;font-size:.84rem">Цилиндр + широкий</button>'
|
||
+ '<button class="p32-shape" data-a="narrow" data-b="wide" type="button" style="background:#fff;color:' + ACCENT + ';border:2px solid ' + ACCENT + ';padding:7px 14px;border-radius:9px;cursor:pointer;font-weight:700;font-family:inherit;font-size:.84rem">Узкий + широкий</button>'
|
||
+ '</div>'
|
||
+ '<svg id="p32-svg" viewBox="0 0 320 200" width="100%" style="max-width:500px;display:block;margin:0 auto;background:#fffbeb;border-radius:9px;border:1px solid ' + ACCENT_SOFT + '"></svg>'
|
||
+ '<div id="p32-info" style="background:' + ACCENT_SOFT + ';border-radius:9px;padding:10px 14px;margin-top:8px;font-size:.92rem;text-align:center">Уровень одинаков, потому что давления на дне равны.</div>');
|
||
|
||
/* IV-2 КВИЗ */
|
||
h += wgWrap('p32-iv2', 'КВИЗ', 'Сообщающиеся сосуды', '',
|
||
'<div id="p32-q-host">'
|
||
+ quizQuestion('p32-q', 0, 'В двух соединённых сосудах одна и та же вода. Что верно?', ['Уровни могут быть разными','Уровни всегда одинаковы','Зависит от объёмов','Зависит от формы'], 1)
|
||
+ quizQuestion('p32-q', 1, 'Чайник: уровень чая в носике и корпусе…', ['В носике выше','В корпусе выше','На одном уровне','Зависит от наклона'], 2)
|
||
+ quizQuestion('p32-q', 2, 'Если жидкости разные (вода и масло), уровни…', ['Одинаковые','Зависят от плотностей (обратно пропорц.)','Зависят от массы','Жидкость смешается'], 1)
|
||
+ '</div>');
|
||
|
||
/* 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', '',
|
||
'<div id="p32-tr-host">'
|
||
+ 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)
|
||
+ '</div>');
|
||
|
||
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',
|
||
'Любой газ состоит из молекул, у молекул есть масса — значит, и сам газ имеет <b>массу</b> и <b>вес</b>.<br><br>'
|
||
+ 'Плотность воздуха у поверхности Земли: $\\rho_{возд} \\approx 1{,}29$ кг/м³.');
|
||
|
||
h += makeCard('rule', 'Сколько весит воздух', '§ 33.2',
|
||
'Масса газа в сосуде: $m = \\rho V$.<br>'
|
||
+ 'Вес: $P = m g$.<br><br>'
|
||
+ 'Воздух в комнате $5 \\times 4 \\times 3$ м$^3 = 60$ м³ имеет массу $m \\approx 1{,}29 \\cdot 60 = 77$ кг — '
|
||
+ 'столько весит взрослый человек!');
|
||
|
||
h += makeCard('example', 'Как доказать вес воздуха', '§ 33.3',
|
||
'<b>Опыт:</b> взвесить стеклянный шар на чувствительных весах, затем выкачать из него воздух насосом '
|
||
+ 'и взвесить снова. Шар без воздуха окажется <b>легче</b> на массу удалённого воздуха.');
|
||
|
||
/* IV-1 КАЛЬК: масса воздуха в комнате */
|
||
h += wgWrap('p33-iv1', 'КАЛЬК', 'Сколько весит воздух в комнате?', '',
|
||
'<div style="display:grid;grid-template-columns:repeat(auto-fit,minmax(140px,1fr));gap:8px;margin-bottom:10px">'
|
||
+ '<label style="display:block;font-size:.86rem;color:#475569;background:#fff;padding:8px 12px;border-radius:8px;border:1px solid ' + ACCENT_SOFT + '">Длина $a$, м: <b id="p33-a" style="color:' + ACCENT_D + ';font-family:JetBrains Mono,monospace">5</b><input type="range" id="p33-a-r" min="2" max="20" step="0.5" value="5" style="display:block;width:100%;margin-top:6px;accent-color:' + ACCENT + '"></label>'
|
||
+ '<label style="display:block;font-size:.86rem;color:#475569;background:#fff;padding:8px 12px;border-radius:8px;border:1px solid ' + ACCENT_SOFT + '">Ширина $b$, м: <b id="p33-b" style="color:' + ACCENT_D + ';font-family:JetBrains Mono,monospace">4</b><input type="range" id="p33-b-r" min="2" max="20" step="0.5" value="4" style="display:block;width:100%;margin-top:6px;accent-color:' + ACCENT + '"></label>'
|
||
+ '<label style="display:block;font-size:.86rem;color:#475569;background:#fff;padding:8px 12px;border-radius:8px;border:1px solid ' + ACCENT_SOFT + '">Высота $c$, м: <b id="p33-c" style="color:' + ACCENT_D + ';font-family:JetBrains Mono,monospace">3</b><input type="range" id="p33-c-r" min="2" max="10" step="0.5" value="3" style="display:block;width:100%;margin-top:6px;accent-color:' + ACCENT + '"></label>'
|
||
+ '</div>'
|
||
+ '<div style="background:' + ACCENT_SOFT + ';border-radius:9px;padding:12px 14px;font-size:.94rem;line-height:1.7">'
|
||
+ '$V = abc = $ <b id="p33-V" style="color:' + ACCENT_D + ';font-family:JetBrains Mono,monospace">60</b> м³ · $m = \\rho V = $ <b id="p33-m" style="color:' + ACCENT_D + ';font-family:JetBrains Mono,monospace">77</b> кг · $P = mg = $ <b id="p33-P" style="color:' + ACCENT_D + ';font-family:JetBrains Mono,monospace">756</b> Н'
|
||
+ '<div id="p33-cmp" style="font-size:.84rem;color:#475569;margin-top:4px"></div>'
|
||
+ '</div>');
|
||
|
||
/* IV-2 КВИЗ */
|
||
h += wgWrap('p33-iv2', 'КВИЗ', 'Вес газов', '',
|
||
'<div id="p33-q-host">'
|
||
+ 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)
|
||
+ '</div>');
|
||
|
||
/* 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', '',
|
||
'<div id="p33-tr-host">'
|
||
+ 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$ г.')
|
||
+ '</div>');
|
||
|
||
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',
|
||
'Земля окружена слоем воздуха — <b>атмосферой</b>. Этот воздух имеет вес и давит на всё, что находится на поверхности Земли.<br><br>'
|
||
+ '<b>Нормальное атмосферное давление</b>: $p_0 = 101\\,325$ Па $= 760$ мм рт. ст. $\\approx 1$ атм.');
|
||
|
||
h += makeCard('rule', 'Опыт Торричелли (1643)', '§ 34.2',
|
||
'Эванжелиста Торричелли перевернул трубку, наполненную ртутью, в чашку с ртутью. '
|
||
+ 'Ртуть в трубке опустилась до высоты $\\approx 760$ мм над уровнем чашки. '
|
||
+ 'Это значит, что атмосфера снаружи давила на чашку с такой же силой, как столб ртути высотой $760$ мм.<br><br>'
|
||
+ 'Так была открыта единица «миллиметр ртутного столба» (мм рт. ст.).');
|
||
|
||
h += makeCard('example', 'С высотой давление падает', '§ 34.3',
|
||
'На каждые $\\approx 12$ м подъёма атмосферное давление уменьшается на $1$ мм рт. ст. (на малых высотах).<br><br>'
|
||
+ 'Поэтому на вершине Эльбруса ($5642$ м) давление $\\approx 400$ мм рт. ст. — почти в 2 раза меньше уровня моря. '
|
||
+ 'Космонавтам в открытом космосе нужны скафандры — давление за бортом $\\approx 0$.');
|
||
|
||
/* IV-1 СИМ: ртутный барометр Торричелли */
|
||
h += wgWrap('p34-iv1', 'СИМ', 'Барометр Торричелли', 'Меняй атмосферное давление — увидь высоту столба ртути.',
|
||
'<div style="margin-bottom:10px"><label style="display:block;font-size:.86rem;color:#475569;background:#fff;padding:8px 12px;border-radius:8px;border:1px solid ' + ACCENT_SOFT + '">Давление, мм рт. ст.: <b id="p34-mm" style="color:' + ACCENT_D + ';font-family:JetBrains Mono,monospace">760</b><input type="range" id="p34-mm-r" min="400" max="800" step="5" value="760" style="display:block;width:100%;margin-top:6px;accent-color:' + ACCENT + '"></label></div>'
|
||
+ '<div style="display:grid;grid-template-columns:160px 1fr;gap:14px;align-items:center">'
|
||
+ '<svg id="p34-svg" viewBox="0 0 160 380" width="100%" style="max-width:180px;display:block"></svg>'
|
||
+ '<div id="p34-info" style="background:' + ACCENT_SOFT + ';border-radius:9px;padding:12px 14px;font-size:.94rem;line-height:1.7"></div>'
|
||
+ '</div>');
|
||
|
||
/* IV-2 КАЛЬК: высота → давление */
|
||
h += wgWrap('p34-iv2', 'КАЛЬК', 'Давление на высоте', 'На каждые ~12 м давление падает на 1 мм рт. ст.',
|
||
'<div style="margin-bottom:10px"><label style="display:block;font-size:.86rem;color:#475569;background:#fff;padding:8px 12px;border-radius:8px;border:1px solid ' + ACCENT_SOFT + '">Высота над уровнем моря, м: <b id="p34c-H" style="color:' + ACCENT_D + ';font-family:JetBrains Mono,monospace">0</b><input type="range" id="p34c-H-r" min="0" max="5000" step="50" value="0" style="display:block;width:100%;margin-top:6px;accent-color:' + ACCENT + '"></label></div>'
|
||
+ '<div style="background:' + ACCENT_SOFT + ';border-radius:9px;padding:12px 14px;font-size:.94rem;line-height:1.65">'
|
||
+ '$\\Delta p = H/12 = $ <b id="p34c-dp" style="color:' + ACCENT_D + ';font-family:JetBrains Mono,monospace">0</b> мм рт. ст. · $p \\approx $ <b id="p34c-p" style="color:' + ACCENT_D + ';font-family:JetBrains Mono,monospace">760</b> мм рт. ст. $\\approx $ <b id="p34c-pkpa" style="color:' + ACCENT_D + ';font-family:JetBrains Mono,monospace">101.3</b> кПа'
|
||
+ '<div id="p34c-place" style="font-size:.84rem;color:#475569;margin-top:5px"></div>'
|
||
+ '</div>');
|
||
|
||
/* 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', '',
|
||
'<div id="p34-tr-host">'
|
||
+ 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$ кПа.')
|
||
+ '</div>');
|
||
|
||
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 = '<b>Выше нормы</b> — антициклон, ясная погода (или вы в шахте/долине).';
|
||
else if(mm > 745) descr = '<b>Норма</b> — обычное давление у поверхности Земли.';
|
||
else if(mm > 600) descr = '<b>Ниже нормы</b> — горы, циклон, плохая погода.';
|
||
else descr = '<b>Очень низкое</b> — высокогорье или большая высота.';
|
||
document.getElementById('p34-info').innerHTML = '<b>' + mm + '</b> мм рт. ст. $= $ <b>' + Math.round(pa).toLocaleString('ru-RU') + '</b> Па $\\approx $ <b>' + (pa/1000).toFixed(1) + '</b> кПа<br><br>' + 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',
|
||
'<ul style="padding-left:20px;margin:6px 0">'
|
||
+ '<li><b>Ртутный барометр Торричелли</b> — измеряет атм. давление через высоту ртутного столба.</li>'
|
||
+ '<li><b>Анероид</b> (греч. «без жидкости») — пружинный, стрелочный. Не разобьётся, удобен.</li>'
|
||
+ '<li><b>Жидкостный U-манометр</b> — измеряет давление газа относительно атмосферного, через разность уровней.</li>'
|
||
+ '</ul>');
|
||
|
||
h += makeCard('rule', 'Где какой прибор', '§ 35.2',
|
||
'<b>Барометры</b> (Торричелли, анероид) — измеряют <b>атмосферное</b> давление воздуха.<br>'
|
||
+ '<b>Манометр</b> — измеряет давление <b>газа в сосуде</b> или жидкости. '
|
||
+ 'Например, в шине, в баллоне с пропаном, в трубе с водой.<br>'
|
||
+ '<b>Кардиограф/тонометр</b> — давление в кровеносных сосудах.');
|
||
|
||
h += makeCard('example', 'Манометр на баллоне', '§ 35.3',
|
||
'В баллоне с газом давление много выше атмосферного. Манометр показывает <b>разность</b>: '
|
||
+ 'давление в баллоне минус $p_0$. Если шкала показывает $200$ кПа — фактическое давление в баллоне $200 + 100 = 300$ кПа.');
|
||
|
||
/* IV-1 ГЛАВНЫЙ ВИЗУАЛ — все 3 прибора */
|
||
h += wgWrap('p35-iv1', 'СИМ', 'Три прибора рядом — главный визуал', 'Одно и то же давление, три способа показать.',
|
||
'<div style="margin-bottom:10px"><label style="display:block;font-size:.86rem;color:#475569;background:#fff;padding:8px 12px;border-radius:8px;border:1px solid ' + ACCENT_SOFT + '">Атм. давление, мм рт. ст.: <b id="p35-mm" style="color:' + ACCENT_D + ';font-family:JetBrains Mono,monospace">760</b><input type="range" id="p35-mm-r" min="720" max="800" step="2" value="760" style="display:block;width:100%;margin-top:6px;accent-color:' + ACCENT + '"></label></div>'
|
||
+ '<div style="display:grid;grid-template-columns:repeat(auto-fit,minmax(160px,1fr));gap:12px">'
|
||
+ '<div style="text-align:center"><div style="font-weight:700;font-size:.84rem;color:' + ACCENT_D + ';margin-bottom:6px">Торричелли</div><svg id="p35-merc" viewBox="0 0 140 340" width="100%" style="max-width:140px"></svg></div>'
|
||
+ '<div style="text-align:center"><div style="font-weight:700;font-size:.84rem;color:' + ACCENT_D + ';margin-bottom:6px">Анероид</div><svg id="p35-aner" viewBox="0 0 180 200" width="100%" style="max-width:180px"></svg></div>'
|
||
+ '<div style="text-align:center"><div style="font-weight:700;font-size:.84rem;color:' + ACCENT_D + ';margin-bottom:6px">U-манометр (газ vs $p_0$)</div><svg id="p35-uman" viewBox="0 0 120 160" width="100%" style="max-width:120px"></svg></div>'
|
||
+ '</div>'
|
||
+ '<div id="p35-info" style="background:' + ACCENT_SOFT + ';border-radius:9px;padding:10px 14px;margin-top:10px;font-size:.92rem;text-align:center"></div>');
|
||
|
||
/* IV-2 КВИЗ */
|
||
h += wgWrap('p35-iv2', 'КВИЗ', 'Какой прибор для чего', '',
|
||
'<div id="p35-q-host">'
|
||
+ quizQuestion('p35-q', 0, 'Чем измеряют атм. давление?', ['Манометр','Барометр','Гигрометр','Термометр'], 1)
|
||
+ quizQuestion('p35-q', 1, 'Чем измеряют давление газа в шине?', ['Барометр','Манометр','Динамометр','Спидометр'], 1)
|
||
+ quizQuestion('p35-q', 2, 'Что меряет анероид?', ['Температура','Атм. давление','Скорость','Влажность'], 1)
|
||
+ quizQuestion('p35-q', 3, 'Что значит «анероид»?', ['Безжидкостный','Сложный','Точный','Электронный'], 0)
|
||
+ '</div>');
|
||
|
||
/* 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', '',
|
||
'<div id="p35-tr-host">'
|
||
+ 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)
|
||
+ '</div>');
|
||
|
||
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 = 'Атм. давление: <b>' + mm + '</b> мм рт. ст. $= $ <b>' + Math.round(pa).toLocaleString('ru-RU') + '</b> Па. Все три прибора показывают одно и то же — по-разному.';
|
||
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 += '<div style="background:linear-gradient(135deg,' + ACCENT_SOFT + ',#fff7ed);border:1.5px solid ' + ACCENT + ';border-radius:14px;padding:16px;margin-bottom:14px;text-align:center">'
|
||
+ '<div style="font-family:Unbounded,sans-serif;font-weight:800;font-size:1.12rem;color:' + ACCENT_D + '">Финал главы 4: победи 7 боссов</div>'
|
||
+ '<div style="font-size:.88rem;color:#475569;margin-top:5px">Реши все 7 задач — получишь ачивку «Властелин давления» и +50 XP.</div>'
|
||
+ '<div style="height:10px;background:#fff;border-radius:6px;overflow:hidden;margin-top:12px;border:1px solid ' + ACCENT_SOFT + '"><div id="ch4-fin-fill" style="height:100%;background:linear-gradient(90deg,' + ACCENT + ',' + ACCENT_D + ');width:0%;transition:width .4s"></div></div>'
|
||
+ '<div id="ch4-fin-lab" style="font-size:.84rem;color:#475569;margin-top:6px">Побеждено: 0 / 7</div>'
|
||
+ '</div>';
|
||
|
||
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 += '<div data-boss="' + b.n + '" style="background:#fff;border:2px solid ' + (isSolved ? '#10b981' : ACCENT_SOFT) + ';border-radius:12px;padding:14px 16px;margin-bottom:12px;box-shadow:' + (isSolved ? '0 0 0 3px rgba(16,185,129,.16)' : '0 2px 8px rgba(0,0,0,.05)') + '">'
|
||
+ '<div style="display:flex;align-items:center;gap:10px;margin-bottom:8px;flex-wrap:wrap">'
|
||
+ '<span style="background:' + ACCENT + ';color:#fff;padding:3px 10px;border-radius:99px;font-size:.7rem;font-weight:800;letter-spacing:.04em">' + b.tag + '</span>'
|
||
+ '<span style="font-family:Unbounded,sans-serif;font-weight:800;font-size:.96rem;color:#0f172a">Босс ' + b.n + '. ' + b.title + '</span>'
|
||
+ '</div>'
|
||
+ '<div style="padding:10px 12px;background:' + ACCENT_SOFT + ';border-radius:8px;margin-bottom:10px;font-size:.94rem;line-height:1.55">' + b.q + '</div>'
|
||
+ '<div style="display:flex;gap:8px;flex-wrap:wrap;align-items:center">'
|
||
+ '<input type="number" step="' + b.step + '" class="boss-inp" data-n="' + b.n + '" placeholder="число" style="padding:8px 12px;border:1.5px solid ' + ACCENT_SOFT + ';border-radius:8px;width:140px;text-align:center;font-family:JetBrains Mono,monospace;font-size:.95rem"' + (isSolved ? ' value="' + b.ans + '" disabled' : '') + '>'
|
||
+ '<button class="boss-go" data-n="' + b.n + '" type="button" style="background:linear-gradient(135deg,' + ACCENT + ',' + ACCENT_D + ');color:#fff;border:none;padding:8px 16px;border-radius:9px;font-weight:700;font-size:.88rem;cursor:pointer;font-family:inherit"' + (isSolved ? ' disabled' : '') + '>Атаковать</button>'
|
||
+ '<button class="boss-hint" data-n="' + b.n + '" type="button" style="background:#fff;color:#475569;border:1.5px solid ' + ACCENT_SOFT + ';padding:8px 14px;border-radius:9px;font-weight:600;font-size:.86rem;cursor:pointer;font-family:inherit">Подсказка</button>'
|
||
+ '</div>'
|
||
+ '<div class="boss-hint-txt" data-n="' + b.n + '" style="margin-top:8px;padding:9px 13px;background:#fef3c7;border-left:3px solid #f59e0b;border-radius:6px;font-size:.86rem;line-height:1.5;display:none">' + b.hint + '</div>'
|
||
+ '<div class="boss-fb" data-n="' + b.n + '" style="margin-top:8px;padding:9px 13px;border-radius:8px;font-weight:600;font-size:.88rem;line-height:1.45;' + (isSolved ? 'background:#d1fae5;color:#065f46;border-left:4px solid #10b981' : 'display:none') + '">' + (isSolved ? '✓ Босс повержен! +20 XP.' : '') + '</div>'
|
||
+ '</div>';
|
||
});
|
||
|
||
h += '<div id="ch4-mastered" style="margin-top:14px;padding:14px 18px;border-radius:12px;background:linear-gradient(135deg,#fef3c7,#fde68a);border:1.5px solid #f59e0b;display:none;align-items:center;gap:12px"><svg style="width:32px;height:32px;stroke:#92400e;fill:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round" viewBox="0 0 24 24"><polygon points="12,2 15,9 22,9.3 17,14 18.5,21 12,17 5.5,21 7,14 2,9.3 9,9"/></svg><div style="flex:1"><div style="font-weight:800;color:#92400e;font-family:Unbounded,sans-serif">Ачивка «Властелин давления» получена!</div><div style="font-size:.86rem;color:#78350f;margin-top:2px">+50 XP · Глава 4 полностью пройдена.</div></div></div>';
|
||
|
||
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
|
||
};
|
||
|
||
})();
|