From 4154e0b79116e6088c0d10247eda4f2eb8645cde Mon Sep 17 00:00:00 2001 From: Maxim Dolgolyov Date: Fri, 29 May 2026 16:42:20 +0300 Subject: [PATCH] =?UTF-8?q?feat(phys10=20ch1=20wave4):=20=C2=A77=20=C2=AB?= =?UTF-8?q?=D0=A2=D0=B2=D1=91=D1=80=D0=B4=D1=8B=D0=B5=20=D1=82=D0=B5=D0=BB?= =?UTF-8?q?=D0=B0=C2=BB=20+=20=C2=A78=20=C2=AB=D0=96=D0=B8=D0=B4=D0=BA?= =?UTF-8?q?=D0=BE=D1=81=D1=82=D0=B8=C2=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/textbooks/physics_10_ch1.html | 774 ++++++++++++++++++++++++- 1 file changed, 762 insertions(+), 12 deletions(-) diff --git a/frontend/textbooks/physics_10_ch1.html b/frontend/textbooks/physics_10_ch1.html index 7e71d55..cb01da6 100644 --- a/frontend/textbooks/physics_10_ch1.html +++ b/frontend/textbooks/physics_10_ch1.html @@ -2803,34 +2803,784 @@ function build_p6(){ function build_p7(){ const box = document.getElementById('p7-body'); let html = ''; - html += makeCard('theory', "Строение и свойства твёрдых тел", "§7", ` -

Строение и свойства твёрдых тел — этот параграф в разработке (Phase 1+).

-

Здесь появятся: теория, формулы, разобранные примеры и 3–4 интерактива в стиле «алгебры 11» — таблицы, симуляции, ползунки, drag-and-drop и автопроверяемые тренажёры.

-

- Phase 0: создан скелет учебника. Phase 1+: наполнение этого § содержанием по учебнику «Физика 10» (Беларусь, 2019). -

+ + /* THEORY 1 — Кристаллические и аморфные тела */ + html += makeCard('theory', "Кристаллические и аморфные тела", "§7", ` +

Кристаллические тела имеют упорядоченное расположение частиц — кристаллическую решётку.

+

Виды кристаллических тел:

+ +

У кристаллических тел есть точная температура плавления: при $t_{\\text{пл}}$ решётка разрушается, и тело переходит в жидкое состояние.

+

Аморфные тела (стекло, смола, пластмассы, янтарь, воск) не имеют упорядоченной решётки. Их называют «переохлаждёнными жидкостями». При нагревании они размягчаются плавно, без чёткой температуры плавления.

`); + + /* THEORY 2 — Анизотропия и изотропия */ + html += makeCard('rule', "Анизотропия и изотропия", "§7", ` +

Анизотропия — зависимость физических свойств от направления (твёрдость, теплопроводность, скорость распространения света). Характерна для монокристаллов.

+

Примеры:

+ +

Изотропия — свойства одинаковы во всех направлениях. Характерна для поликристаллов и аморфных тел.

+

Поликристаллы состоят из множества мелких разно ориентированных кристалликов, поэтому в среднем свойства одинаковы по всем направлениям.

+ `); + + /* THEORY 3 — Типы кристаллических решёток */ + html += makeCard('example', "Типы кристаллических решёток", "§7", ` +

По типу связи частиц различают четыре основных типа решёток:

+ +

Один и тот же элемент может образовывать разные решётки: алмаз (атомная решётка, очень твёрдый) и графит (слоистая, мягкий) — оба состоят из углерода.

+ `); + + /* INTERACTIVE 1 — Визуализатор кристаллической решётки */ + html += `
+
ИНТЕРАКТИВ 1
Визуализатор кристаллической решётки
+
Переключай тип решётки и наблюдай расположение частиц. Просмотри все 4 типа.
+
+ + + + +
+
+ +
+
+
`; + + /* INTERACTIVE 2 — Кристалл или аморфное (DnD) */ + html += `
+
ИНТЕРАКТИВ 2
Кристалл или аморфное?
+
Перетащи 8 веществ в нужный ящик.
+
8 веществ — 2 группы
+
+
+
Кристаллическое
+
Аморфное
+
+
+ +
`; + + /* INTERACTIVE 3 — квикфайр: свойство → тип решётки */ + html += `
+
ИНТЕРАКТИВ 3
Какой тип решётки?
+
6 веществ. Жми кнопку с типом решётки.
+
Задача 1 / 6Очки: 0 / 6
+
+
+ +
+
`; + + /* INTERACTIVE 4 — тренажёр свойств твёрдых тел */ + html += `
+
ИНТЕРАКТИВ 4
Тренажёр свойств твёрдых тел
+
5 задач. Допуск для чисел $\\pm 5\\%$.
+
Задача 1 / 5Очки: 0 / 5
+
+
+ ответ = + + + +
+ +
`; + html += secNav('p6', 'p8'); html += readButton('p7'); + box.innerHTML = html; renderMath(box); + + /* IV1 — Визуализатор решётки */ + (function(){ + const tabs = document.getElementById('p7-iv1-tabs'); + const svg = document.getElementById('p7-iv1-svg'); + const info = document.getElementById('p7-iv1-info'); + const seen = new Set(); + let _done = false; + let mode = 'ion'; + + function drawIon(){ + // 5×5 сетка чередующихся Na+/Cl− + let g = ''; + const cols = 6, rows = 5, sx = 50, sy = 30, dx = 56, dy = 48; + for(let j = 0; j < rows; j++){ + for(let i = 0; i < cols; i++){ + const cx = sx + i * dx, cy = sy + j * dy; + const isPlus = ((i + j) % 2 === 0); + // соединительные линии (соседи справа/снизу) + if(i < cols-1) g += ''; + if(j < rows-1) g += ''; + } + } + for(let j = 0; j < rows; j++){ + for(let i = 0; i < cols; i++){ + const cx = sx + i * dx, cy = sy + j * dy; + const isPlus = ((i + j) % 2 === 0); + const col = isPlus ? '#e11d48' : '#2563eb'; + const r = isPlus ? 13 : 17; + g += ''; + g += ''+(isPlus?'Na⁺':'Cl⁻')+''; + } + } + svg.innerHTML = g; + } + + function drawAtom(){ + // Тетраэдрическая сетка алмаза — упрощённая 2D-проекция + let g = ''; + const sx = 50, sy = 40, dx = 70, dy = 60; + const nodes = []; + for(let j = 0; j < 4; j++){ + for(let i = 0; i < 5; i++){ + const off = (j % 2) * dx / 2; + nodes.push({x: sx + i*dx + off, y: sy + j*dy, i, j}); + } + } + // соединения — ковалентные связи (жирные линии к ближайшим) + for(const a of nodes){ + for(const b of nodes){ + if(a === b) continue; + const d = Math.hypot(a.x - b.x, a.y - b.y); + if(d < dx * 1.05 && d > 0.1){ + g += ''; + } + } + } + for(const n of nodes){ + g += ''; + g += 'C'; + } + svg.innerHTML = g; + } + + function drawMol(){ + // Молекулы H₂O в упорядоченной сетке + водородные связи (пунктир) + let g = ''; + const cols = 4, rows = 3, sx = 60, sy = 50, dx = 90, dy = 80; + const centers = []; + for(let j = 0; j < rows; j++){ + for(let i = 0; i < cols; i++){ + centers.push({x: sx + i*dx, y: sy + j*dy}); + } + } + // водородные связи (пунктир) между соседями + for(let i = 0; i < centers.length; i++){ + for(let k = i+1; k < centers.length; k++){ + const d = Math.hypot(centers[i].x - centers[k].x, centers[i].y - centers[k].y); + if(d < dx * 1.05){ + g += ''; + } + } + } + // молекулы H₂O: 1 кислород (синий) + 2 водорода (белые) + for(const c of centers){ + const ox = c.x, oy = c.y; + const ang1 = -Math.PI/2 - 0.5, ang2 = -Math.PI/2 + 0.5; + const hr = 18; + const h1x = ox + hr*Math.cos(ang1), h1y = oy + hr*Math.sin(ang1); + const h2x = ox + hr*Math.cos(ang2), h2y = oy + hr*Math.sin(ang2); + g += ''; + g += ''; + g += ''; + g += 'O'; + g += ''; + g += 'H'; + g += ''; + g += 'H'; + } + svg.innerHTML = g; + } + + function drawMet(){ + // Положительные ионы (большие синие круги) + свободные электроны (точки) + let g = ''; + const cols = 5, rows = 4, sx = 50, sy = 40, dx = 70, dy = 60; + // электронное «море» — фоновая дымка + g += ''; + // свободные электроны (50 хаотичных точек) + for(let k = 0; k < 70; k++){ + const ex = 30 + Math.random() * 320; + const ey = 30 + Math.random() * 220; + g += ''; + g += ''; + } + // положительные ионы + for(let j = 0; j < rows; j++){ + for(let i = 0; i < cols; i++){ + const cx = sx + i*dx, cy = sy + j*dy; + g += ''; + g += '+'; + } + } + svg.innerHTML = g; + } + + const INFO = { + ion: 'Ионная решётка (пример: NaCl, поваренная соль). Связь: электростатическая между «+» и «−» ионами. Свойства: твёрдые, $t_{\\text{пл}}$ высокая (≈ 800°C), хрупкие, в расплаве проводят ток.', + atom: 'Атомная решётка (пример: алмаз, кремний). Связь: ковалентная между атомами. Свойства: очень твёрдые, тугоплавкие ($t_{\\text{пл}}$ > 1000°C), плохо проводят ток.', + mol: 'Молекулярная решётка (пример: лёд H$_2$O, нафталин, йод). Связь: слабая (Ван-дер-Ваальса, водородные связи). Свойства: мягкие, легкоплавкие, не проводят ток.', + met: 'Металлическая решётка (пример: Cu, Fe, Al). «+» ионы в «море» свободных электронов. Свойства: пластичные, отлично проводят ток и тепло, имеют металлический блеск.' + }; + + function render(){ + if(mode === 'ion') drawIon(); + else if(mode === 'atom') drawAtom(); + else if(mode === 'mol') drawMol(); + else drawMet(); + info.innerHTML = INFO[mode]; + renderMath(info); + seen.add(mode); + if(!_done && seen.size >= 4){ _done = true; addXp(10, 'p7-iv1'); bumpProgress('p7', 15); } + } + tabs.querySelectorAll('button').forEach(b => { + b.addEventListener('click', () => { + mode = b.dataset.mode; + const colMap = { ion:'#e11d48', atom:'#475569', mol:'#0ea5e9', met:'#f59e0b' }; + tabs.querySelectorAll('button').forEach(x => { x.className = 'btn'; x.style.background=''; x.style.borderColor=''; }); + b.className = 'btn primary'; + b.style.background = colMap[mode]; b.style.borderColor = colMap[mode]; + render(); + }); + }); + render(); + })(); + + /* IV2 — DnD: кристалл/аморф */ + (function(){ + const items = [ + { id:'s1', cat:'cryst', html:'Поваренная соль (NaCl)' }, + { id:'s2', cat:'amorph', html:'Стекло' }, + { id:'s3', cat:'cryst', html:'Алмаз' }, + { id:'s4', cat:'amorph', html:'Янтарь' }, + { id:'s5', cat:'cryst', html:'Лёд' }, + { id:'s6', cat:'amorph', html:'Парафин' }, + { id:'s7', cat:'cryst', html:'Железо' }, + { id:'s8', cat:'amorph', html:'Резина' }, + ]; + const sorter = setupSorter({ + poolId:'p7-iv2-pool', + scopeSelector:'#p7-iv2', + items: items, + cats:['cryst','amorph'], + columnLayout:false, + }); + document.getElementById('p7-iv2-check').addEventListener('click', () => { + const fb = document.getElementById('p7-iv2-fb'); + const placedCount = items.filter(it => sorter.placed[it.id]).length; + const correct = items.filter(it => sorter.placed[it.id] === it.cat).length; + if(placedCount < items.length){ feedback(fb, false, '✗ Размести все 8 веществ.'); return; } + if(correct === items.length){ feedback(fb, true, '✓ Все 8 верно! +10 XP'); addXp(10,'p7-iv2'); bumpProgress('p7', 15); } + else feedback(fb, false, '✗ Правильно ' + correct + ' из 8. Попробуй ещё.'); + }); + document.getElementById('p7-iv2-reset').addEventListener('click', () => { sorter.reset(); document.getElementById('p7-iv2-fb').style.display = 'none'; }); + })(); + + /* IV3 — квикфайр: тип решётки */ + (function(){ + // ans: 0=ион, 1=атом, 2=мол, 3=метал + const Q = [ + { q:'NaCl — поваренная соль', ans:0, why:'Чередование Na⁺ и Cl⁻ — ионная решётка.' }, + { q:'Алмаз', ans:1, why:'Атомы углерода связаны ковалентными связями — атомная решётка.' }, + { q:'Лёд (H$_2$O в твёрдом состоянии)', ans:2, why:'Между молекулами H$_2$O слабые водородные связи — молекулярная решётка.' }, + { q:'Медь, железо, алюминий', ans:3, why:'Положительные ионы в «море» свободных электронов — металлическая.' }, + { q:'Кремний (полупроводник)', ans:1, why:'Атомная решётка (как у алмаза), ковалентные связи.' }, + { q:'Йод (I$_2$)', ans:2, why:'Молекулы I$_2$ связаны слабыми силами — молекулярная.' }, + ]; + const LABELS = ['Ионная','Атомная','Молекулярная','Металлическая']; + const COLS = ['#e11d48','#475569','#0ea5e9','#f59e0b']; + let i = 0, score = 0; + const qEl = document.getElementById('p7-iv3-q'); + const oEl = document.getElementById('p7-iv3-opts'); + const fb = document.getElementById('p7-iv3-fb'); + const iEl = document.getElementById('p7-iv3-i'); + const sEl = document.getElementById('p7-iv3-s'); + function show(){ + if(i >= Q.length){ + qEl.innerHTML = 'Готово! Результат: ' + score + ' / ' + Q.length; + oEl.innerHTML = ''; + if(score === Q.length){ addXp(15, 'p7-iv3'); bumpProgress('p7', 25); } + else if(score >= 4){ addXp(8, 'p7-iv3'); bumpProgress('p7', 15); } + return; + } + iEl.textContent = (i+1); sEl.textContent = score; + qEl.innerHTML = Q[i].q; + let opts = ''; + for(let k = 0; k < 4; k++){ + opts += ''; + } + oEl.innerHTML = opts; + fb.style.display = 'none'; + renderMath(qEl); + oEl.querySelectorAll('button').forEach(b => { + b.addEventListener('click', () => { + const v = +b.dataset.v; + if(v === Q[i].ans){ score++; feedback(fb, true, '✓ Верно! ' + Q[i].why + ' Дальше ▶'); } + else feedback(fb, false, '✗ Неверно. Правильно: '+LABELS[Q[i].ans]+'. '+Q[i].why+' Дальше ▶'); + sEl.textContent = score; + oEl.querySelectorAll('button').forEach(x => x.disabled = true); + i++; + setTimeout(show, 1700); + }); + }); + } + document.getElementById('p7-iv3-restart').addEventListener('click', () => { i = 0; score = 0; show(); }); + show(); + })(); + + /* IV4 — Тренажёр свойств твёрдых тел */ + (function(){ + const Q = [ + { q:'В монокристалле скорость звука вдоль оси $X$ равна $5000$ м/с, вдоль $Y$ — $3000$ м/с. Найди разность в м/с (это пример анизотропии).', ans:2000, hint:'$5000 - 3000 = 2000$ м/с — разные направления, разные скорости.' }, + { q:'Стекло — это кристаллическое (1) или аморфное (2) тело?', ans:2, hint:'Стекло не имеет упорядоченной решётки — это «переохлаждённая жидкость».' }, + { q:'Алмаз и графит — оба состоят из углерода. У какого больше твёрдость? Введи: алмаз = 1, графит = 2.', ans:1, hint:'У алмаза 3D-решётка ковалентных связей — он твёрже. Графит — слоистый.' }, + { q:'Сколько типов кристаллических решёток рассматривается в §7?', ans:4, hint:'Ионная, атомная, молекулярная, металлическая.' }, + { q:'Какой тип решётки у меди? Введи цифру: 1 = ионная, 2 = атомная, 3 = молекулярная, 4 = металлическая.', ans:4, hint:'Cu — металл, значит решётка металлическая («+» ионы в «море» электронов).' }, + ]; + let i = 0, score = 0; + function show(){ + if(i >= Q.length){ + document.getElementById('p7-iv4-q').innerHTML = 'Готово! Результат: ' + score + ' / ' + Q.length; + if(score === Q.length){ addXp(15, 'p7-iv4'); bumpProgress('p7', 25); } + else if(score >= 3){ addXp(8, 'p7-iv4'); bumpProgress('p7', 15); } + return; + } + document.getElementById('p7-iv4-i').textContent = (i+1); + document.getElementById('p7-iv4-s').textContent = score; + document.getElementById('p7-iv4-q').innerHTML = Q[i].q; + document.getElementById('p7-iv4-ans').value = ''; + renderMath(document.getElementById('p7-iv4-q')); + document.getElementById('p7-iv4-fb').style.display = 'none'; + } + function go(){ + if(i >= Q.length) return; + const fb = document.getElementById('p7-iv4-fb'); + const raw = document.getElementById('p7-iv4-ans').value.replace(',', '.'); + const ans = parseFloat(raw); + if(isNaN(ans)){ feedback(fb, false, '✗ Введи число.'); return; } + const tol = Math.max(0.05 * Math.abs(Q[i].ans), 0.5); + if(Math.abs(ans - Q[i].ans) < tol + 0.001){ score++; feedback(fb, true, '✓ Верно! '+Q[i].hint+' Дальше ▶'); } + else feedback(fb, false, '✗ Неверно. Ответ: $'+Q[i].ans+'$. '+Q[i].hint+' Дальше ▶'); + document.getElementById('p7-iv4-s').textContent = score; + i++; + setTimeout(show, 1800); + } + document.getElementById('p7-iv4-go').addEventListener('click', go); + document.getElementById('p7-iv4-ans').addEventListener('keydown', e => { if(e.key === 'Enter') go(); }); + document.getElementById('p7-iv4-start').addEventListener('click', () => { i = 0; score = 0; show(); }); + show(); + })(); + wireReadBtn('p7'); } function build_p8(){ const box = document.getElementById('p8-body'); let html = ''; - html += makeCard('theory', "Строение и свойства жидкостей", "§8", ` -

Строение и свойства жидкостей — этот параграф в разработке (Phase 1+).

-

Здесь появятся: теория, формулы, разобранные примеры и 3–4 интерактива в стиле «алгебры 11» — таблицы, симуляции, ползунки, drag-and-drop и автопроверяемые тренажёры.

-

- Phase 0: создан скелет учебника. Phase 1+: наполнение этого § содержанием по учебнику «Физика 10» (Беларусь, 2019). -

+ + /* THEORY 1 — Свойства и строение жидкостей */ + html += makeCard('theory', "Свойства и строение жидкостей", "§8", ` +

Жидкости занимают промежуточное положение между газами и твёрдыми телами:

+
    +
  • От твёрдых тел жидкость унаследовала: сохранение объёма (несжимаемость).
  • +
  • От газов: отсутствие собственной формы — жидкость принимает форму сосуда.
  • +
+

Молекулы жидкости расположены тесно (как в твёрдом теле), но могут перемещаться (как в газе).

+

Ближний порядок — упорядоченность молекул в области порядка нескольких диаметров молекулы. На больших расстояниях упорядоченности нет (в отличие от кристалла).

+

При охлаждении жидкость может кристаллизоваться (вода → лёд) или, при особых условиях, остаться аморфной (стекло — переохлаждённая жидкость).

`); + + /* THEORY 2 — Поверхностное натяжение */ + html += makeCard('rule', "Поверхностное натяжение", "§8", ` +

На поверхности жидкости молекулы испытывают силу, направленную внутрь жидкости. Это объясняется тем, что молекула в объёме окружена молекулами со всех сторон, а молекула на поверхности — только снизу и с боков.

+

В результате жидкость стремится минимизировать площадь поверхности. Поэтому маленькая капля принимает почти сферическую форму.

+

Сила поверхностного натяжения на границе пленки длиной $L$:

+

$$F = \\sigma L$$

+

где $\\sigma$ — коэффициент поверхностного натяжения (Н/м).

+

Значения $\\sigma$ при $20°$C:

+
    +
  • вода: $\\sigma_{\\text{в}} \\approx 0{,}073$ Н/м;
  • +
  • спирт: $\\sigma_{\\text{сп}} \\approx 0{,}022$ Н/м;
  • +
  • ртуть: $\\sigma_{\\text{Hg}} \\approx 0{,}465$ Н/м.
  • +
+ `); + + /* THEORY 3 — Смачивание и капиллярность */ + html += makeCard('example', "Смачивание и капиллярность", "§8", ` +

Когда жидкость соприкасается с твёрдой поверхностью, поверхность жидкости образует краевой угол $\\theta$ с твёрдым телом:

+
    +
  • $\\theta < 90°$ — смачивание (вода на чистом стекле: $\\theta \\approx 0°$).
  • +
  • $\\theta > 90°$ — несмачивание (ртуть на стекле: $\\theta \\approx 140°$).
  • +
+

Капиллярные явления: в тонкой трубке (капилляре) смачивающая жидкость поднимается, несмачивающая — опускается ниже общего уровня.

+

Высота поднятия в капилляре радиуса $r$:

+

$$h = \\dfrac{2 \\sigma \\cos\\theta}{\\rho g r}$$

+

где $\\rho$ — плотность жидкости, $g$ — ускорение свободного падения.

+

Пример. Вода в капилляре $r = 1$ мм: $h = \\dfrac{2 \\cdot 0{,}073}{1000 \\cdot 10 \\cdot 10^{-3}} \\approx 0{,}015$ м $= 15$ мм.

+

Капиллярность важна в природе: вода поднимается по корням растений, по тонким сосудам в почве, по фитилю свечи.

+ `); + + /* INTERACTIVE 1 — Симуляция жидкости */ + html += `
+
ИНТЕРАКТИВ 1
Симуляция жидкости: молекулы плотно упакованы
+
Молекулы расположены тесно и колеблются. Меняй $t$: при росте температуры амплитуда колебаний растёт, при $t \\to 100°$C — молекулы начинают «вырываться» (испарение → §9).
+
+ +
+
+ +
+
+ + +
+
+
`; + + /* INTERACTIVE 2 — Калькулятор поверхностного натяжения */ + html += `
+
ИНТЕРАКТИВ 2
Калькулятор поверхностного натяжения
+
Выбери жидкость, введи длину $L$ — получишь силу $F = \\sigma L$. Дополнительно — высота поднятия в капилляре $r = 1$ мм.
+
+ + + +
+
+ +
+
+ +
`; + + /* INTERACTIVE 3 — квикфайр: смачивает или нет */ + html += `
+
ИНТЕРАКТИВ 3
Смачивает или нет?
+
6 ситуаций. Жми соответствующую кнопку.
+
Задача 1 / 6Очки: 0 / 6
+
+
+ +
+
`; + + /* INTERACTIVE 4 — Тренажёр жидкости */ + html += `
+
ИНТЕРАКТИВ 4
Тренажёр жидкости
+
5 задач. Допуск ±5%.
+
Задача 1 / 5Очки: 0 / 5
+
+
+ ответ = + + + +
+ +
`; + html += secNav('p7', 'p9'); html += readButton('p8'); + box.innerHTML = html; renderMath(box); + + /* IV1 — Симуляция жидкости */ + (function(){ + const svg = document.getElementById('p8-iv1-svg'); + const tInp = document.getElementById('p8-iv1-t'); + const tLab = document.getElementById('p8-iv1-tL'); + const btnPause = document.getElementById('p8-iv1-pause'); + const btnReset = document.getElementById('p8-iv1-reset'); + const info = document.getElementById('p8-iv1-info'); + const W = 360, H = 240; + const N = 60; // число молекул + let raf = null, lastT = 0, paused = false; + let parts = []; + const tempChanges = new Set(); + let _xpDone = false; + + function makeParts(){ + parts = []; + const cols = 10, rows = 6, sx = 30, sy = 80, dx = 30, dy = 24; + for(let j = 0; j < rows; j++){ + for(let i = 0; i < cols; i++){ + parts.push({ + x0: sx + i*dx + (j%2)*dx/2, + y0: sy + j*dy, + x: sx + i*dx + (j%2)*dx/2, + y: sy + j*dy, + vx: 0, vy: 0, + escaped: false + }); + } + } + } + + function frame(t){ + raf = requestAnimationFrame(frame); + if(!lastT){ lastT = t; return; } + let dt = (t - lastT) / 1000; + lastT = t; + if(paused){ render(); return; } + if(dt > 0.06) dt = 0.06; + + const T = +tInp.value; + // амплитуда колебаний ~ T (px) + const amp = 1 + T * 0.12; + // вероятность испарения ~ при T → 100 + const escapeProb = Math.max(0, (T - 75)) / 25 * 0.0005; + + for(const p of parts){ + if(p.escaped){ + // улетает вверх + p.x += p.vx * dt; + p.y += p.vy * dt; + p.vy -= 30 * dt; // тянет вверх (отрицательное y) + if(p.y < -10){ + // респаун обратно в массу + p.escaped = false; + p.vx = 0; p.vy = 0; + p.x = p.x0; p.y = p.y0; + } + } else { + // случайные толчки + возврат к равновесному положению + p.vx += (Math.random() - 0.5) * amp * 20 * dt; + p.vy += (Math.random() - 0.5) * amp * 20 * dt; + // пружина к (x0, y0) + p.vx += (p.x0 - p.x) * 8 * dt; + p.vy += (p.y0 - p.y) * 8 * dt; + // демпфирование + p.vx *= 0.92; + p.vy *= 0.92; + p.x += p.vx * dt; + p.y += p.vy * dt; + // шанс испариться (для верхнего ряда) + if(p.y0 < 100 && Math.random() < escapeProb){ + p.escaped = true; + p.vx = (Math.random() - 0.5) * 40; + p.vy = -60 - Math.random() * 40; + } + } + } + render(); + } + + function render(){ + let g = ''; + g += ''; + // «поверхность» воды + g += ''; + g += 'поверхность'; + // дно + g += ''; + for(const p of parts){ + const col = p.escaped ? '#fbbf24' : '#60a5fa'; + g += ''; + } + svg.innerHTML = g; + } + + function updateInfo(T){ + let txt; + if(T < 30){ + txt = 'Низкая $t$. Молекулы колеблются слабо, плотно упакованы. Ближний порядок чётко виден.'; + } else if(T < 70){ + txt = 'Комнатная $t$. Амплитуда колебаний растёт, отдельные молекулы могут менять соседей.'; + } else if(T < 95){ + txt = 'Высокая $t$. Колебания сильные, ближний порядок размывается. Возможно появление пузырьков пара.'; + } else { + txt = '$t \\to 100°$C. Молекулы у поверхности «вырываются» наружу — испарение (см. §9).'; + } + info.innerHTML = txt; + renderMath(info); + } + + makeParts(); + raf = requestAnimationFrame(frame); + updateInfo(+tInp.value); + + tInp.addEventListener('input', () => { + const T = +tInp.value; + tLab.textContent = T; + updateInfo(T); + tempChanges.add(Math.round(T/20)); + if(!_xpDone && tempChanges.size >= 3){ + _xpDone = true; + addXp(10, 'p8-iv1'); + bumpProgress('p8', 15); + } + }); + btnPause.addEventListener('click', () => { + paused = !paused; + btnPause.textContent = paused ? 'Продолжить' : 'Пауза'; + }); + btnReset.addEventListener('click', () => { makeParts(); }); + document.addEventListener('visibilitychange', () => { + if(document.hidden && raf){ cancelAnimationFrame(raf); raf = null; lastT = 0; } + else if(!document.hidden && !raf){ raf = requestAnimationFrame(frame); } + }); + })(); + + /* IV2 — Калькулятор поверхностного натяжения */ + (function(){ + const liqSel = document.getElementById('p8-iv2-liq'); + const lInp = document.getElementById('p8-iv2-L'); + const rInp = document.getElementById('p8-iv2-r'); + const out = document.getElementById('p8-iv2-out'); + const fb = document.getElementById('p8-iv2-fb'); + const go = document.getElementById('p8-iv2-go'); + const DATA = { + water: { sigma: 0.073, rho: 1000, name: 'Вода' }, + alc: { sigma: 0.022, rho: 790, name: 'Спирт' }, + hg: { sigma: 0.465, rho: 13600, name: 'Ртуть' }, + }; + const used = new Set(); + let _done = false; + function calc(){ + const liq = liqSel.value; + const d = DATA[liq]; + const L = parseFloat((lInp.value||'').replace(',','.')); + const r_mm = parseFloat((rInp.value||'').replace(',','.')); + if(!isFinite(L) || L <= 0 || !isFinite(r_mm) || r_mm <= 0){ + feedback(fb, false, '✗ $L$ и $r$ должны быть положительными.'); + return; + } + const F = d.sigma * L; + const r = r_mm / 1000; + const g = 9.8; + // для смачивающей (вода/спирт) θ ≈ 0, cosθ = 1; для ртути — несмачивает, θ > 90 → h отрицательное + let h_m, hLabel; + if(liq === 'hg'){ + // ртуть на стекле: θ ≈ 140°, cos ≈ −0.766 + h_m = 2 * d.sigma * Math.cos(140 * Math.PI / 180) / (d.rho * g * r); + hLabel = 'опускается на $|h| \\approx '+(Math.abs(h_m)*1000).toFixed(2)+'$ мм (несмачивание)'; + } else { + h_m = 2 * d.sigma / (d.rho * g * r); + hLabel = 'поднимается на $h \\approx '+(h_m*1000).toFixed(2)+'$ мм'; + } + out.innerHTML = + '
'+d.name+': $\\sigma = '+d.sigma+'$ Н/м, $\\rho = '+d.rho+'$ кг/м³
' + + '
Сила натяжения: $F = \\sigma L = '+d.sigma+' \\cdot '+L+' \\approx '+(+F.toFixed(5))+'$ Н
' + + '
В капилляре $r = '+r_mm+'$ мм: жидкость '+hLabel+'
'; + renderMath(out); + feedback(fb, true, '✓ Вычислено.'); + used.add(liq); + if(!_done && used.size >= 2){ _done = true; addXp(10, 'p8-iv2'); bumpProgress('p8', 15); } + } + go.addEventListener('click', calc); + })(); + + /* IV3 — квикфайр: смачивает или нет */ + (function(){ + const Q = [ + { q:'Вода на чистом стекле', ans:1, why:'Стекло хорошо смачивается водой ($\\theta \\approx 0°$).' }, + { q:'Ртуть на стекле', ans:0, why:'Ртуть не смачивает стекло, $\\theta \\approx 140°$, образует выпуклый мениск.' }, + { q:'Вода на парафине (свечном воске)', ans:0, why:'Парафин гидрофобен — вода не смачивает, скатывается каплями.' }, + { q:'Спирт на стекле', ans:1, why:'Спирт смачивает стекло ещё лучше воды.' }, + { q:'Жидкое мыло на тарелке', ans:1, why:'Мыло — поверхностно-активное вещество, отлично смачивает.' }, + { q:'Капля воды на листе лотоса', ans:0, why:'Лист лотоса имеет микрорельеф и воск — вода скатывается шариками.' }, + ]; + let i = 0, score = 0; + const qEl = document.getElementById('p8-iv3-q'); + const oEl = document.getElementById('p8-iv3-opts'); + const fb = document.getElementById('p8-iv3-fb'); + const iEl = document.getElementById('p8-iv3-i'); + const sEl = document.getElementById('p8-iv3-s'); + function show(){ + if(i >= Q.length){ + qEl.innerHTML = 'Готово! Результат: ' + score + ' / ' + Q.length; + oEl.innerHTML = ''; + if(score === Q.length){ addXp(15, 'p8-iv3'); bumpProgress('p8', 25); } + else if(score >= 4){ addXp(8, 'p8-iv3'); bumpProgress('p8', 15); } + return; + } + iEl.textContent = (i+1); sEl.textContent = score; + qEl.innerHTML = Q[i].q; + oEl.innerHTML = ''; + fb.style.display = 'none'; + renderMath(qEl); + oEl.querySelectorAll('button').forEach(b => { + b.addEventListener('click', () => { + const v = +b.dataset.v; + if(v === Q[i].ans){ score++; feedback(fb, true, '✓ Верно! '+Q[i].why+' Дальше ▶'); } + else feedback(fb, false, '✗ Неверно. '+Q[i].why+' Дальше ▶'); + sEl.textContent = score; + oEl.querySelectorAll('button').forEach(x => x.disabled = true); + i++; + setTimeout(show, 1700); + }); + }); + } + document.getElementById('p8-iv3-restart').addEventListener('click', () => { i = 0; score = 0; show(); }); + show(); + })(); + + /* IV4 — Тренажёр жидкости */ + (function(){ + const Q = [ + { q:'$\\sigma = 0{,}073$ Н/м, $L = 0{,}2$ м. Найди силу $F$ в Н (с точностью до 3 знаков).', ans:0.0146, hint:'$F = \\sigma L = 0{,}073 \\cdot 0{,}2 = 0{,}0146$ Н.', tol:0.002 }, + { q:'При одинаковой длине $L = 1$ м что больше: $F$ для воды или для ртути? Введи 1 = вода, 2 = ртуть.', ans:2, hint:'$\\sigma_{\\text{Hg}} = 0{,}465 > \\sigma_{\\text{в}} = 0{,}073$ — больше у ртути.', tol:0.1 }, + { q:'Высота поднятия воды в капилляре $r = 0{,}5$ мм. Введи в мм (целое). $\\sigma = 0{,}073$, $\\rho = 1000$, $g = 10$, $\\cos\\theta = 1$.', ans:29, hint:'$h = \\dfrac{2\\sigma}{\\rho g r} = \\dfrac{2 \\cdot 0{,}073}{1000 \\cdot 10 \\cdot 0{,}0005} \\approx 0{,}029$ м $\\approx 29$ мм.', tol:3 }, + { q:'Жидкость, у которой $\\theta < 90°$ на твёрдой поверхности — смачивает (1) или нет (2)?', ans:1, hint:'По определению, $\\theta < 90°$ — это смачивание.', tol:0.1 }, + { q:'В капилляре жидкость поднимается выше при меньшем (1) или большем (2) радиусе?', ans:1, hint:'$h \\sim 1/r$ — чем тоньше капилляр, тем выше поднятие.', tol:0.1 }, + ]; + let i = 0, score = 0; + function show(){ + if(i >= Q.length){ + document.getElementById('p8-iv4-q').innerHTML = 'Готово! Результат: ' + score + ' / ' + Q.length; + if(score === Q.length){ addXp(15, 'p8-iv4'); bumpProgress('p8', 25); } + else if(score >= 3){ addXp(8, 'p8-iv4'); bumpProgress('p8', 15); } + return; + } + document.getElementById('p8-iv4-i').textContent = (i+1); + document.getElementById('p8-iv4-s').textContent = score; + document.getElementById('p8-iv4-q').innerHTML = Q[i].q; + document.getElementById('p8-iv4-ans').value = ''; + renderMath(document.getElementById('p8-iv4-q')); + document.getElementById('p8-iv4-fb').style.display = 'none'; + } + function go(){ + if(i >= Q.length) return; + const fb = document.getElementById('p8-iv4-fb'); + const raw = document.getElementById('p8-iv4-ans').value.replace(',', '.'); + const ans = parseFloat(raw); + if(isNaN(ans)){ feedback(fb, false, '✗ Введи число.'); return; } + const tol = Q[i].tol || Math.max(0.05 * Math.abs(Q[i].ans), 0.05); + if(Math.abs(ans - Q[i].ans) < tol + 0.001){ score++; feedback(fb, true, '✓ Верно! '+Q[i].hint+' Дальше ▶'); } + else feedback(fb, false, '✗ Неверно. Ответ: $'+Q[i].ans+'$. '+Q[i].hint+' Дальше ▶'); + document.getElementById('p8-iv4-s').textContent = score; + i++; + setTimeout(show, 1900); + } + document.getElementById('p8-iv4-go').addEventListener('click', go); + document.getElementById('p8-iv4-ans').addEventListener('keydown', e => { if(e.key === 'Enter') go(); }); + document.getElementById('p8-iv4-start').addEventListener('click', () => { i = 0; score = 0; show(); }); + show(); + })(); + wireReadBtn('p8'); }