diff --git a/frontend/js/phys-fx.js b/frontend/js/phys-fx.js index 5a53f6e..43953d0 100644 --- a/frontend/js/phys-fx.js +++ b/frontend/js/phys-fx.js @@ -389,4 +389,210 @@ class EnergyView { } P.EnergyView = EnergyView; +/* ============================================================ */ +/* ResonanceCurve — резонансная кривая A(ω) при разных γ */ +/* ============================================================ */ + +class ResonanceCurve { + constructor(container, opts){ + opts = opts || {}; + this.el = (typeof container === 'string') ? document.querySelector(container) : container; + this.W = opts.width || 540; + this.H = opts.height || 240; + this.pad = opts.pad || 40; + this.omega0 = opts.omega0 || 1.0; /* собственная частота (норм.) */ + this.gamma = opts.gamma !== undefined ? opts.gamma : 0.15; + this.omegaCur = opts.omegaCur !== undefined ? opts.omegaCur : 0.6; + this.color = opts.color || '#7c3aed'; + this.paused = false; + this.render(); + } + setGamma(g){ this.gamma = Math.max(0.02, g); this.render(); } + setOmegaCur(w){ this.omegaCur = Math.max(0.02, w); this.render(); } + /* update не нужен — статический график, обновляется по setter */ + update(){} + render(){ + if (!this.el) return; + const W = this.W, H = this.H, pad = this.pad; + const wMin = 0, wMax = 2 * this.omega0; + /* Подсчитаем все амплитуды чтобы знать max */ + function amp(w, g, w0){ + const dw2 = (w0 * w0 - w * w); + const denom = Math.sqrt(dw2 * dw2 + (2 * g * w) * (2 * g * w)); + return 1 / Math.max(denom, 1e-6); + } + const gMin = 0.05; + const ampMax = amp(this.omega0, gMin, this.omega0) * 1.1; + /* Сетка */ + const left = pad, right = W - pad, top = pad, bot = H - pad; + const ux = (right - left) / (wMax - wMin); + const uy = (bot - top) / ampMax; + function toX(w){ return left + (w - wMin) * ux; } + function toY(a){ return bot - a * uy; } + let svg = util.svgFrame(W, H); + /* Линии сетки */ + svg += ''; + for (let i = 0; i <= 4; i++){ + const w = wMin + (wMax - wMin) * i / 4; + svg += ''; + } + for (let i = 0; i <= 4; i++){ + svg += ''; + } + svg += ''; + /* Оси */ + svg += ''; + svg += ''; + /* Подписи осей */ + svg += 'ω'; + svg += 'A'; + /* Линия ω₀ — собственная частота */ + svg += ''; + svg += 'ω₀'; + /* Кривая A(ω) */ + let path = 'M '; + const N = 200; + for (let i = 0; i <= N; i++){ + const w = wMin + (wMax - wMin) * i / N; + const a = amp(w, this.gamma, this.omega0); + path += toX(w).toFixed(1) + ',' + toY(Math.min(a, ampMax)).toFixed(1); + if (i < N) path += ' L '; + } + svg += ''; + /* Точка-маркер на текущей ω */ + const aCur = Math.min(amp(this.omegaCur, this.gamma, this.omega0), ampMax); + svg += ''; + svg += ''; + /* Подпись γ */ + svg += 'γ = ' + this.gamma.toFixed(2) + ''; + svg += 'ω = ' + this.omegaCur.toFixed(2) + ' · A = ' + aCur.toFixed(2) + ''; + svg += ''; + this.el.innerHTML = svg; + } +} +P.ResonanceCurve = ResonanceCurve; + +/* ============================================================ */ +/* TransverseWave — поперечная волна на струне */ +/* y(x, t) = A sin(kx - ωt + φ) */ +/* ============================================================ */ + +class TransverseWave { + constructor(container, opts){ + opts = opts || {}; + this.el = (typeof container === 'string') ? document.querySelector(container) : container; + this.W = opts.width || 560; + this.H = opts.height || 180; + this.A = opts.A !== undefined ? opts.A : 0.4; /* отн. амплитуда (0..1) */ + this.lambda = opts.lambda !== undefined ? opts.lambda : 1.0; /* отн. длина волны */ + this.v = opts.v !== undefined ? opts.v : 0.8; /* скорость распространения (отн./с) */ + this.color = opts.color || '#0891b2'; + this.markerX = opts.markerX !== undefined ? opts.markerX : 0.4; /* пол. красной точки (0..1 от ширины) */ + this.paused = false; + this.t = 0; + util.subscribe(this); + util.observe(this); + this.render(); + } + setA(v){ this.A = v; } + setLambda(v){ this.lambda = Math.max(0.1, v); } + setV(v){ this.v = v; } + update(dt){ this.t += dt; } + render(){ + if (!this.el) return; + const W = this.W, H = this.H; + const yCenter = H / 2; + const amp = this.A * (H / 2 - 18); + const k = 2 * Math.PI / this.lambda; + const omega = k * this.v; + /* SVG: горизонтальная ось + волна как polyline */ + let svg = util.svgFrame(W, H, {bg:'#f8fafc'}); + /* Ось */ + svg += ''; + /* Кривая */ + const N = 180; + let path = 'M '; + for (let i = 0; i <= N; i++){ + const px = (W * i / N); + /* Реальное x в относительных единицах (1 длина волны на ~120px) */ + const x = px / 120; + const y = yCenter - amp * Math.sin(k * x - omega * this.t); + path += px.toFixed(1) + ',' + y.toFixed(1); + if (i < N) path += ' L '; + } + svg += ''; + /* Красный маркер — колеблющаяся точка */ + const mPx = this.markerX * W; + const mX = mPx / 120; + const mY = yCenter - amp * Math.sin(k * mX - omega * this.t); + svg += ''; + svg += ''; + /* Метка λ — горизонтальная скобка над волной */ + const lambdaPx = 120 * this.lambda; + if (lambdaPx < W - 60){ + const lxStart = 20, lxEnd = lxStart + lambdaPx; + svg += ''; + svg += ''; + svg += ''; + svg += 'λ'; + } + svg += ''; + this.el.innerHTML = svg; + } +} +P.TransverseWave = TransverseWave; + +/* ============================================================ */ +/* LongitudinalWave — продольная волна (сжатия/разрежения) */ +/* ============================================================ */ + +class LongitudinalWave { + constructor(container, opts){ + opts = opts || {}; + this.el = (typeof container === 'string') ? document.querySelector(container) : container; + this.W = opts.width || 560; + this.H = opts.height || 130; + this.A = opts.A !== undefined ? opts.A : 0.5; /* амплитуда (0..1) */ + this.lambda = opts.lambda !== undefined ? opts.lambda : 1.0; + this.v = opts.v !== undefined ? opts.v : 0.8; + this.color = opts.color || '#0891b2'; + this.nDots = opts.nDots || 60; + this.paused = false; + this.t = 0; + util.subscribe(this); + util.observe(this); + this.render(); + } + setA(v){ this.A = v; } + setLambda(v){ this.lambda = Math.max(0.1, v); } + setV(v){ this.v = v; } + update(dt){ this.t += dt; } + render(){ + if (!this.el) return; + const W = this.W, H = this.H; + const yC = H / 2; + const k = 2 * Math.PI / this.lambda; + const omega = k * this.v; + const xScale = 120; /* px на 1 ед. */ + const amp = this.A * 10; /* px смещения */ + const margin = 20; + let svg = util.svgFrame(W, H, {bg:'#f8fafc'}); + /* Точки-молекулы */ + let dots = ''; + for (let i = 0; i < this.nDots; i++){ + const x0 = margin + (W - 2 * margin) * i / (this.nDots - 1); + const xRel = x0 / xScale; + const disp = amp * Math.sin(k * xRel - omega * this.t); + const x = x0 + disp; + dots += ''; + } + svg += dots; + /* Подписи зон сжатия / разрежения */ + svg += 'сжатие ↔ разрежение'; + svg += ''; + this.el.innerHTML = svg; + } +} +P.LongitudinalWave = LongitudinalWave; + })(); diff --git a/frontend/textbooks/physics_11_ch1.html b/frontend/textbooks/physics_11_ch1.html index ed7f588..e403e07 100644 --- a/frontend/textbooks/physics_11_ch1.html +++ b/frontend/textbooks/physics_11_ch1.html @@ -229,10 +229,10 @@ const PARAS = [ { id:'p1', num:'§ 1', name:'Гармонические колебания', sub:'$T, \\nu, \\omega$', built:true }, { id:'p2', num:'§ 2', name:'Маятники', sub:'$T = 2\\pi\\sqrt{m/k}$', built:true }, { id:'p3', num:'§ 3', name:'Превращения энергии', sub:'$W_{мех} = \\text{const}$', built:true }, - { id:'p4', num:'§ 4', name:'Резонанс', sub:'Будет в W2', built:false }, - { id:'p5', num:'§ 5', name:'Волны', sub:'Будет в W2', built:false }, - { id:'p6', num:'§ 6', name:'Звук', sub:'Будет в W2', built:false }, - { id:'final', num:'★', name:'Финал главы', sub:'4 босса · W2', final:true, built:false } + { id:'p4', num:'§ 4', name:'Резонанс', sub:'$\\omega_{рез} \\approx \\omega_0$', built:true }, + { id:'p5', num:'§ 5', name:'Волны', sub:'$\\lambda = vT$', built:true }, + { id:'p6', num:'§ 6', name:'Звук', sub:'16 Гц – 20 кГц', built:true }, + { id:'final', num:'★', name:'Финал главы', sub:'4 интегр. босса', final:true, built:true } ]; PARAS.forEach(p => { STATE.progress[p.id] = 0; }); @@ -243,7 +243,11 @@ const ACH_LABELS = { p1_done:'§1 — гармонические колебания освоены', p2_done:'§2 — маятники освоены', p3_done:'§3 — превращения энергии освоены', - start:'Начало главы 1!' + p4_done:'§4 — резонанс освоен', + p5_done:'§5 — волны освоены', + p6_done:'§6 — звук освоен', + start:'Начало главы 1!', + ch1_done:'Глава 1 пройдена — колебания и волны!' }; function loadProgress(){ @@ -322,7 +326,7 @@ function buildParaSelector(){ } const BUILT=new Set(); -const BUILDERS = { p1:()=>buildP1(), p2:()=>buildP2(), p3:()=>buildP3(), p4:()=>buildStubP('p4','§ 4','§4 в разработке (W2)'), p5:()=>buildStubP('p5','§ 5','§5 в разработке (W2)'), p6:()=>buildStubP('p6','§ 6','§6 в разработке (W2)'), final:()=>buildStubP('final','Финал','Финал главы 1 — в волне W2') }; +const BUILDERS = { p1:()=>buildP1(), p2:()=>buildP2(), p3:()=>buildP3(), p4:()=>buildP4(), p5:()=>buildP5(), p6:()=>buildP6(), final:()=>buildFinal() }; function ensureBuilt(id){ if(BUILT.has(id)) return; const fn=BUILDERS[id]; if(fn){ fn(); BUILT.add(id); } } function goTo(id){ STATE.current=id; ensureBuilt(id); @@ -340,20 +344,20 @@ const SIDEBARS = { p1:{title:'Шпаргалка § 1', rows:[['Период','$T = \\Delta t / N$'],['Частота','$\\nu = 1/T$'],['Цикл. частота','$\\omega = 2\\pi\\nu = 2\\pi/T$'],['Уравнение','$x = A\\cos(\\omega t + \\varphi_0)$'],['Размерности','$[T]=$ с, $[\\nu]=$ Гц, $[\\omega]=$ рад/с']]}, p2:{title:'Шпаргалка § 2', rows:[['Пружинный','$T = 2\\pi\\sqrt{m/k}$'],['Математ.','$T = 2\\pi\\sqrt{l/g}$'],['Условие','малые амплитуды'],['Не зависит от','амплитуды (для гарм.)']]}, p3:{title:'Шпаргалка § 3', rows:[['$W_{кинет}$','$\\dfrac{mv^2}{2}$'],['$W_{потенц}$','$\\dfrac{kx^2}{2}$'],['$W_{мех}$','$\\dfrac{kA^2}{2} = $ const'],['Связь','$k = m\\omega^2$']]}, - p4:{title:'§ 4', rows:[['Тема','Резонанс'],['Статус','В разработке (W2)']]}, - p5:{title:'§ 5', rows:[['Тема','Волны'],['Статус','В разработке (W2)']]}, - p6:{title:'§ 6', rows:[['Тема','Звук'],['Статус','В разработке (W2)']]}, - final:{title:'Финал главы 1', rows:[['Статус','В разработке (W2)'],['Боссов','4 интегрированных'],['Награда','+100 XP + ачивка']]} + p4:{title:'Шпаргалка § 4', rows:[['Свободные','без внеш. силы, затухают'],['Вынужденные','$F_{вынужд} = F_0\\cos(\\omega t)$'],['Резонанс','$\\omega \\to \\omega_0$, $A \\to $ max'],['Декремент','$\\gamma$ — затухание']]}, + p5:{title:'Шпаргалка § 5', rows:[['Длина волны','$\\lambda = vT = v/\\nu$'],['Скорость','$v = \\lambda\\nu$'],['Поперечная','колебание $\\perp$ распр.'],['Продольная','колебание $\\parallel$ распр.'],['Примеры','струна (попереч.), звук (продол.)']]}, + p6:{title:'Шпаргалка § 6', rows:[['Слышимый','16 Гц – 20 кГц'],['Инфразвук','$\\nu < 16$ Гц'],['Ультразвук','$\\nu > 20$ кГц'],['$v$ в возд.','$\\approx 340$ м/с'],['$v$ в воде','$\\approx 1500$ м/с'],['Природа','продольная упругая волна']]}, + final:{title:'Финал главы 1', rows:[['§ 1 – § 6','Все темы главы'],['Боссов','4 интегрированных'],['Награда','+100 XP + ачивка ch1_done']]} }; const TIPS=[ {sec:'p1',html:'§ 1 — крути ползунки осциллограммы. Главное: $\\omega = 2\\pi/T$ связывает все 3 величины.'}, {sec:'p2',html:'§ 2 — для пружины период зависит от $m, k$, для матем. от $l, g$. Амплитуда не входит!'}, {sec:'p3',html:'§ 3 — пока $W_к$ растёт, $W_п$ убывает. Сумма постоянна: $W_{мех} = kA^2/2$.'}, - {sec:'p4',html:'§ 4 — в разработке (W2).'}, - {sec:'p5',html:'§ 5 — в разработке (W2).'}, - {sec:'p6',html:'§ 6 — в разработке (W2).'}, - {sec:'final',html:'Финал главы 1 — в разработке (W2).'} + {sec:'p4',html:'§ 4 — двигай ползунок $\\gamma$ (затухание). При $\\gamma \\to 0$ резонансный пик становится бесконечно острым.'}, + {sec:'p5',html:'§ 5 — $\\lambda = vT$ — главная формула. Поперечные: волна на струне. Продольные: звук.'}, + {sec:'p6',html:'§ 6 — звук = продольная упругая волна. В вакууме не распространяется! $v_{зв}^{возд} \\approx 340$ м/с.'}, + {sec:'final',html:'Финал главы 1 — 4 интегральных босса на все темы главы. Победа = ачивка ch1_done + 100 XP.'} ]; function buildSidebar(id){ @@ -718,12 +722,252 @@ function buildP3(){ renderMath(box); } -/* ===== Stubs §4-§6, Final ===== */ -function buildStubP(id, label, message){ - const box = document.getElementById(id + '-body'); if(!box) return; - let html = '

' + label + ' — в разработке

' + message + '

'; - html += secNavFor(id); +/* ===== §4 Резонанс ===== */ +function buildP4(){ + const box = document.getElementById('p4-body'); if(!box) return; + let html = ''; + + html += makeCard('theory', 'Свободные и вынужденные колебания', '§ 4.1', + '

Свободные колебания — колебания, происходящие после однократного выведения системы из равновесия. В реальности всегда затухают из-за диссипации энергии (трение, сопротивление воздуха).

' + + '

Вынужденные колебания — колебания под действием периодической внешней силы $F = F_0\\cos(\\omega t)$.

' + + '

В установившемся режиме система колеблется с частотой вынуждающей силы $\\omega$, не со своей собственной $\\omega_0$.

' + + '

Амплитуда установившихся колебаний:

' + + '

$$A(\\omega) = \\dfrac{F_0/m}{\\sqrt{(\\omega_0^2 - \\omega^2)^2 + (2\\gamma\\omega)^2}}$$

' + + '

где $\\gamma$ — коэффициент затухания.

'); + + html += makeCard('rule', 'Резонанс', '§ 4.2', + '

Резонанс — явление резкого возрастания амплитуды вынужденных колебаний при приближении частоты вынуждающей силы к собственной частоте системы.

' + + '

При малом затухании резонансная частота близка к $\\omega_0$:

' + + '

$$\\omega_{рез} \\approx \\omega_0 = \\sqrt{k/m}$$

' + + '

Чем меньше затухание $\\gamma$, тем выше и уже резонансный пик.

' + + '

Примеры: качели (раскачивать в такт), Тихоокеанский мост (Tacoma Narrows, 1940), солдатский шаг по мосту (запрещён).

'); + + html += '
Интерактив 1Резонансная кривая $A(\\omega)$
' + + '
Двигай ползунок $\\gamma$ — затухание. Видно, что при $\\gamma \\to 0$ резонансный пик растёт. Двигай $\\omega$ — красная точка показывает $A$ на текущей частоте.
' + + '
' + + '
'; + + html += '
Инт. 2Резонанс: верно или нет?
' + + '
Решено: 0 / 5.
' + + '
'; + + html += '
Инт. 3Что произойдёт?
' + + '
Решено: 0 / 5.
' + + '
'; + + html += '
'; + html += readButton('p4'); + html += secNavFor('p4'); box.innerHTML = html; + + ensureFx(()=>{ + const rcEl = document.getElementById('fx-resonance'); + const rc = new PHYS.ResonanceCurve(rcEl, {width:560, height:240, omega0:1.0, gamma:0.15, omegaCur:0.6}); + const slBox = document.getElementById('fx-resonance-sl'); + const slG = PHYS.util.slider({label:'γ (затухание)', min:0.03, max:0.6, step:0.01, value:0.15, fmt:v=>v.toFixed(2), onChange:v=>rc.setGamma(v)}); + const slW = PHYS.util.slider({label:'ω (рад/с)', min:0.05, max:2.0, step:0.02, value:0.6, fmt:v=>v.toFixed(2), onChange:v=>rc.setOmegaCur(v)}); + slBox.innerHTML = slG.html + slW.html; + slG.wire(slBox); slW.wire(slBox); + }); + + runQuizMC('i4-tf', I4_TF_ITEMS, 10); + runQuizMC('i4-what', I4_WHAT_ITEMS, 12); + + const bs = loadBossState('boss-4') || { stage:0, solved:false }; + makeAndBindBoss('boss-4-slot', '4', BOSS_DEFS.b4, bs, + ()=>saveBossState('boss-4', bs), + ()=>{ bumpProgress('p4', 40); achievement('p4_done'); }); + + wireReadBtn('p4'); + renderMath(box); +} + +/* ===== §5 Волны ===== */ +function buildP5(){ + const box = document.getElementById('p5-body'); if(!box) return; + let html = ''; + + html += makeCard('theory', 'Распространение колебаний', '§ 5.1', + '

Волна — процесс распространения колебаний в пространстве. При этом переносится энергия, но не вещество: частицы среды лишь колеблются около положений равновесия.

' + + '

Волны бывают двух типов:

' + + '
    ' + + '
  • Поперечные — частицы колеблются перпендикулярно направлению распространения (волна на струне, ЭМ-волны).
  • ' + + '
  • Продольные — частицы колеблются вдоль направления распространения (звук в воздухе, пружина).
  • ' + + '
'); + + html += makeCard('rule', 'Длина волны, скорость, частота', '§ 5.2', + '

Длина волны $\\lambda$ — расстояние между двумя ближайшими точками, колеблющимися в одной фазе.

' + + '

За один период $T$ волна проходит расстояние, равное длине волны:

' + + '

$$\\lambda = vT = \\dfrac{v}{\\nu}$$

' + + '

где $v$ — скорость распространения волны в среде. Эта скорость определяется свойствами среды, а не источника.

' + + '

Связь циклической частоты, волнового числа и скорости: $\\omega = vk$, где $k = 2\\pi/\\lambda$.

'); + + html += '
Интерактив 1Поперечная волна (струна)
' + + '
Бегущая волна вправо. Красная точка показывает: частица среды колеблется на месте — она не движется по направлению распространения.
' + + '
' + + '
'; + + html += '
Интерактив 2Продольная волна (зоны сжатия и разрежения)
' + + '
Молекулы колеблются вдоль направления распространения. Видны области сжатия (плотности) и разрежения. Так распространяется звук.
' + + '
' + + '
'; + + html += '
Инт. 3Расчёт $\\lambda, v, T$
' + + '
Используй $\\lambda = vT = v/\\nu$. Решено: 0 / 5.
' + + '
'; + + html += '
Инт. 4Тип волны и свойства
' + + '
Решено: 0 / 5.
' + + '
'; + + html += '
'; + html += readButton('p5'); + html += secNavFor('p5'); + box.innerHTML = html; + + ensureFx(()=>{ + const twEl = document.getElementById('fx-transv'); + const tw = new PHYS.TransverseWave(twEl, {width:560, height:180, A:0.5, lambda:1.5, v:1.0, markerX:0.35}); + const slBox = document.getElementById('fx-transv-sl'); + const slA = PHYS.util.slider({label:'A (отн.)', min:0.1, max:0.9, step:0.05, value:0.5, fmt:v=>v.toFixed(2), onChange:v=>tw.setA(v)}); + const slL = PHYS.util.slider({label:'λ (отн.)', min:0.5, max:3.0, step:0.1, value:1.5, fmt:v=>v.toFixed(1), onChange:v=>tw.setLambda(v)}); + const slV = PHYS.util.slider({label:'v (отн./с)', min:0.2, max:2.5, step:0.1, value:1.0, fmt:v=>v.toFixed(1), onChange:v=>tw.setV(v)}); + slBox.innerHTML = slA.html + slL.html + slV.html; + slA.wire(slBox); slL.wire(slBox); slV.wire(slBox); + + const lwEl = document.getElementById('fx-longi'); + const lw = new PHYS.LongitudinalWave(lwEl, {width:560, height:130, A:0.6, lambda:1.5, v:1.0}); + const lwSl = document.getElementById('fx-longi-sl'); + const slA2 = PHYS.util.slider({label:'A (отн.)', min:0.1, max:1.0, step:0.05, value:0.6, fmt:v=>v.toFixed(2), onChange:v=>lw.setA(v)}); + const slL2 = PHYS.util.slider({label:'λ (отн.)', min:0.5, max:3.0, step:0.1, value:1.5, fmt:v=>v.toFixed(1), onChange:v=>lw.setLambda(v)}); + lwSl.innerHTML = slA2.html + slL2.html; + slA2.wire(lwSl); slL2.wire(lwSl); + }); + + runQuizInput('i5-calc', I5_CALC_ITEMS, 14); + runQuizMC('i5-type', I5_TYPE_ITEMS, 12); + + const bs = loadBossState('boss-5') || { stage:0, solved:false }; + makeAndBindBoss('boss-5-slot', '5', BOSS_DEFS.b5, bs, + ()=>saveBossState('boss-5', bs), + ()=>{ bumpProgress('p5', 40); achievement('p5_done'); }); + + wireReadBtn('p5'); + renderMath(box); +} + +/* ===== §6 Звук ===== */ +function buildP6(){ + const box = document.getElementById('p6-body'); if(!box) return; + let html = ''; + + html += makeCard('theory', 'Звуковые волны', '§ 6.1', + '

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

' + + '

В вакууме звук не распространяется — нет среды для передачи колебаний.

' + + '

Звуковая волна — это последовательное чередование зон сжатия и разрежения в среде.

' + + '

Скорость звука зависит от среды:

' + + '
    ' + + '
  • В воздухе ($t = 20°$C): $v \\approx 340$ м/с
  • ' + + '
  • В воде: $v \\approx 1500$ м/с
  • ' + + '
  • В стали: $v \\approx 5000$ м/с
  • ' + + '
'); + + html += makeCard('rule', 'Диапазоны частот', '§ 6.2', + '

По частоте звуковые волны делятся на три диапазона:

' + + '
    ' + + '
  • Инфразвук: $\\nu < 16$ Гц — не слышим, но ощущаем (землетрясения, штормы).
  • ' + + '
  • Слышимый звук: $16 \\text{ Гц} \\le \\nu \\le 20 \\text{ кГц}$ — воспринимается ухом человека.
  • ' + + '
  • Ультразвук: $\\nu > 20$ кГц — медицина (УЗИ), эхолокация, обработка материалов.
  • ' + + '
' + + '

Характеристики звука:

' + + '
    ' + + '
  • Громкость — связана с амплитудой звуковой волны, измеряется в децибелах (дБ).
  • ' + + '
  • Высота тона — определяется частотой $\\nu$: чем выше $\\nu$, тем выше тон.
  • ' + + '
  • Тембр — определяется набором обертонов, отличает голоса и инструменты.
  • ' + + '
'); + + html += '
Интерактив 1Звук как продольная волна
' + + '
Зелёные точки — молекулы воздуха. Изменяй частоту $\\nu$ — мысленно представляй, как звук разной высоты выглядит «изнутри» воздуха. (Звук не воспроизводится.)
' + + '
' + + '
'; + + html += '
Инт. 2Расчёт длины звуковой волны
' + + '
$\\lambda = v/\\nu$. Скорость звука в воздухе $v = 340$ м/с (если не указано иное). Решено: 0 / 5.
' + + '
'; + + html += '
Инт. 3Свойства и характеристики звука
' + + '
Решено: 0 / 5.
' + + '
'; + + html += '
'; + html += readButton('p6'); + html += secNavFor('p6'); + box.innerHTML = html; + + ensureFx(()=>{ + const lwEl = document.getElementById('fx-sound'); + const lw = new PHYS.LongitudinalWave(lwEl, {width:560, height:130, A:0.7, lambda:1.0, v:1.0, color:'#16a34a', nDots:70}); + const slBox = document.getElementById('fx-sound-sl'); + const slA = PHYS.util.slider({label:'A (громкость)', min:0.1, max:1.0, step:0.05, value:0.7, fmt:v=>v.toFixed(2), onChange:v=>lw.setA(v)}); + const slL = PHYS.util.slider({label:'λ (длина волны)', min:0.3, max:3.0, step:0.1, value:1.0, fmt:v=>v.toFixed(1), onChange:v=>lw.setLambda(v)}); + slBox.innerHTML = slA.html + slL.html; + slA.wire(slBox); slL.wire(slBox); + }); + + runQuizInput('i6-calc', I6_CALC_ITEMS, 14); + runQuizMC('i6-prop', I6_PROP_ITEMS, 12); + + const bs = loadBossState('boss-6') || { stage:0, solved:false }; + makeAndBindBoss('boss-6-slot', '6', BOSS_DEFS.b6, bs, + ()=>saveBossState('boss-6', bs), + ()=>{ bumpProgress('p6', 40); achievement('p6_done'); }); + + wireReadBtn('p6'); + renderMath(box); +} + +/* ===== Финал главы 1 ===== */ +function buildFinal(){ + const box = document.getElementById('final-body'); if(!box) return; + let html = ''; + html += '

Финальное испытание · 4 интегрированных босса

Победи 4 финальных боссов (колебания, маятники, энергия+резонанс, волны+звук). После — ачивка phys11_ch1_master + 100 XP бонус.

'; + html += '
'; + html += '
'; + html += '
'; + html += '
'; + html += ''; + html += secNavFor('final'); + box.innerHTML = html; + + ['f1','f2','f3','f4'].forEach(id=>{ + const def = FINAL_BOSS_DEFS[id]; + const st = loadBossState('boss-'+id) || { stage:0, solved:false }; + makeAndBindBoss('boss-'+id+'-slot', id, def, st, + ()=>saveBossState('boss-'+id, st), + ()=>{ checkFinalComplete(); }); + }); + checkFinalComplete(); + renderMath(box); +} + +function checkFinalComplete(){ + const allBeat = ['f1','f2','f3','f4'].every(k=>{ + const st = loadBossState('boss-'+k); return st && st.solved; + }); + if(!allBeat) return; + const cel = document.getElementById('celebration'); + if(!cel || cel.dataset.shown === '1') return; + cel.dataset.shown = '1'; cel.style.display = 'block'; + cel.innerHTML = '
★ Глава 1 пройдена! ★
Все 4 финальных босса побеждены. Колебания и волны — освоены.
+ 100 XP бонус + ачивка phys11_ch1_master
'; + + const ach = JSON.parse(localStorage.getItem('physics11_achievements')||'[]'); + if(ach.indexOf('phys11_ch1_master') < 0){ + ach.push('phys11_ch1_master'); + localStorage.setItem('physics11_achievements', JSON.stringify(ach)); + addXp(100, 'ch1-master'); + achievement('ch1_done'); + } + bumpProgress('final', 100); } /* ===== Boss state ===== */ @@ -857,6 +1101,54 @@ const I3_TRANS_ITEMS = [ { q:'$W_к$ и $W_п$:', opts:['В фазе','В противофазе','Не связаны','Растут вместе'], correct:1, explain:'Когда $W_к$ max, $W_п$ = 0 (и наоборот). Сумма = const.' } ]; +const I4_TF_ITEMS = [ + { q:'Свободные колебания в реальной среде всегда затухают.', opts:['Верно','Неверно'], correct:0, explain:'Из-за диссипации (трение, сопротивление).' }, + { q:'Вынужденные колебания происходят с частотой собственной $\\omega_0$.', opts:['Верно','Неверно'], correct:1, explain:'В установив. режиме — с частотой вынуждающей силы.' }, + { q:'При резонансе амплитуда максимальна.', opts:['Верно','Неверно'], correct:0, explain:'Это и есть определение резонанса.' }, + { q:'При $\\gamma \\to 0$ резонансный пик стремится к бесконечности.', opts:['Верно','Неверно'], correct:0, explain:'Без затухания амплитуда не ограничена.' }, + { q:'Резонансная частота равна точно $\\omega_0$ при любом затухании.', opts:['Верно','Неверно'], correct:1, explain:'При большом $\\gamma$ резонанс смещается влево от $\\omega_0$.' } +]; + +const I4_WHAT_ITEMS = [ + { q:'Что произойдёт с амплитудой, если частота вынуждающей силы будет приближаться к $\\omega_0$?', opts:['Уменьшится','Возрастёт','Не изменится','Станет нулевой'], correct:1, explain:'Резонанс.' }, + { q:'Раскачивание качелей — пример:', opts:['Свободных колеб.','Вынужденных колеб.','Затухающих','Резонанса'], correct:3, explain:'Подталкивая в такт собственной частоте — резонанс.' }, + { q:'Чтобы избежать резонанса моста под марширующим строем, солдатам приказывают:', opts:['Маршировать в такт','Сбить шаг','Бежать','Тише'], correct:1, explain:'Сбить шаг = не дать частоте совпасть с собственной.' }, + { q:'При большом затухании пик резонансной кривой:', opts:['Острый и высокий','Низкий и широкий','Не существует','Идеально симметричный'], correct:1, explain:'Затухание сглаживает пик.' }, + { q:'Свободные колебания идеализированного маятника без трения:', opts:['Затухают','Не затухают','Усиливаются','Случайны'], correct:1, explain:'Без диссипации энергии — не затухают (идеализация).' } +]; + +const I5_CALC_ITEMS = [ + { q:'$v = 340$ м/с, $\\nu = 170$ Гц. $\\lambda$ (м)?', answer:'2', explain:'$\\lambda = v/\\nu = 340/170 = 2$ м.' }, + { q:'$\\lambda = 0{,}5$ м, $T = 0{,}01$ с. $v$ (м/с)?', answer:'50', explain:'$v = \\lambda/T = 0{,}5/0{,}01 = 50$ м/с.' }, + { q:'$v = 1500$ м/с (вода), $\\nu = 300$ Гц. $\\lambda$ (м)?', answer:'5', explain:'$\\lambda = 1500/300 = 5$ м.' }, + { q:'$\\lambda = 2$ м, $v = 8$ м/с. $\\nu$ (Гц)?', answer:'4', explain:'$\\nu = v/\\lambda = 8/2 = 4$ Гц.' }, + { q:'$T = 0{,}5$ с, $v = 4$ м/с. $\\lambda$ (м)?', answer:'2', explain:'$\\lambda = vT = 2$ м.' } +]; + +const I5_TYPE_ITEMS = [ + { q:'Волна, в которой частицы колеблются $\\perp$ направлению распространения, — это:', opts:['Продольная','Поперечная','Стоячая','Бегущая'], correct:1, explain:'Поперечная.' }, + { q:'Звук в воздухе — это волна:', opts:['Поперечная','Продольная','Стоячая','Сферическая'], correct:1, explain:'Молекулы воздуха колеблются вдоль распространения.' }, + { q:'Свет — это:', opts:['Продольная упругая','Поперечная ЭМ-волна','Продольная ЭМ','Стоячая'], correct:1, explain:'ЭМ-волны — поперечные.' }, + { q:'Волна переносит:', opts:['Вещество','Энергию','Массу','Скорость'], correct:1, explain:'Энергию, но не вещество.' }, + { q:'Скорость волны определяется:', opts:['Источником','Свойствами среды','Амплитудой','Длиной волны'], correct:1, explain:'$v$ зависит от среды, $\\lambda = vT$.' } +]; + +const I6_CALC_ITEMS = [ + { q:'$\\nu = 340$ Гц, воздух. $\\lambda$ (м)?', answer:'1', explain:'$\\lambda = 340/340 = 1$ м.' }, + { q:'$\\nu = 1000$ Гц, воздух. $\\lambda$ (м)?', answer:'0.34', explain:'$\\lambda = 340/1000 = 0{,}34$ м.' }, + { q:'Молния увидена за 3 с до грома. Расстояние до неё (м)?', answer:['1020','1000'], explain:'$L = v \\cdot t = 340 \\cdot 3 \\approx 1020$ м.' }, + { q:'$\\nu = 100$ Гц в воде ($v=1500$ м/с). $\\lambda$ (м)?', answer:'15', explain:'$\\lambda = 1500/100 = 15$ м.' }, + { q:'Слышимая частота $\\nu = 20$ Гц — это верхняя граница диапазона:', answer:['16','17','15'], explain:'Слышимый: 16-20000 Гц; нижняя граница ~16 Гц.' } +]; + +const I6_PROP_ITEMS = [ + { q:'Звук — это волна:', opts:['Поперечная ЭМ','Продольная упругая','Стоячая','Поверхностная'], correct:1, explain:'Продольная упругая.' }, + { q:'В вакууме звук:', opts:['Распространяется быстрее','Распространяется медленнее','Не распространяется','Преломляется'], correct:2, explain:'Нет среды — нет звука.' }, + { q:'Громкость связана с:', opts:['Частотой','Амплитудой','Скоростью','Длиной волны'], correct:1, explain:'Амплитудой.' }, + { q:'Высота тона зависит от:', opts:['Амплитуды','Частоты','Скорости','Тембра'], correct:1, explain:'Частоты.' }, + { q:'Ультразвук — это:', opts:['$\\nu < 16$ Гц','$\\nu > 20$ кГц','Слышимый','Любой громкий звук'], correct:1, explain:'Выше слышимого диапазона.' } +]; + /* ===== Boss defs ===== */ const BOSS_DEFS = { b1: { title:'Босс §1 — Гарм. колебания', tag:'§1', xp:65, stages:[ @@ -879,6 +1171,55 @@ const BOSS_DEFS = { { q:'В точке $x = 0$:', type:'mc', opts:['$W_п = $ max','$W_к = $ max','$v = 0$','$W_{мех} = 0$'], correct:1, explain:'$x=0 \\Rightarrow W_п=0 \\Rightarrow W_к = $ max.' }, { q:'Удвоили $A$. Во сколько раз изменится $W_{мех}$?', type:'input', a:'4', explain:'$W \\propto A^2$.' }, { q:'При гарм. колебаниях $W_к + W_п = $ ?', type:'mc', opts:['$0$','$\\text{const}$','Зависит от $t$','$kA$'], correct:1, explain:'Сохранение полной механической энергии.' } + ]}, + b4: { title:'Босс §4 — Резонанс', tag:'§4', xp:70, stages:[ + { q:'Резонанс — это:', type:'mc', opts:['Затухание','Рост амплитуды при $\\omega \\to \\omega_0$','Спонтанные колеб.','Свободные колеб.'], correct:1, explain:'При совпадении частот.' }, + { q:'Реальные свободные колеб. всегда:', type:'mc', opts:['Растут','Затухают','Постоянны','Резонируют'], correct:1, explain:'Диссипация энергии.' }, + { q:'$\\omega_{рез} \\approx ?$ (при малом $\\gamma$)', type:'mc', opts:['$0$','$\\omega_0$','$2\\omega_0$','Бесконечно'], correct:1, explain:'$\\omega_{рез} \\approx \\omega_0 = \\sqrt{k/m}$.' }, + { q:'При $\\gamma \\to 0$ пик кривой $A(\\omega)$:', type:'mc', opts:['Низкий','Бесконечно высокий и узкий','Сглаживается','Двойной'], correct:1, explain:'Без затухания амплитуда неограничена.' }, + { q:'Вынужденные колеб. в устан. режиме идут с частотой:', type:'mc', opts:['Собственной $\\omega_0$','Вынуждающей $\\omega$','Любой','Двойной'], correct:1, explain:'Частота вынуждающей силы.' } + ]}, + b5: { title:'Босс §5 — Волны', tag:'§5', xp:70, stages:[ + { q:'$v = 340$ м/с, $\\nu = 1700$ Гц. $\\lambda$ (м)?', type:'input', a:'0.2', explain:'$\\lambda = 340/1700 = 0{,}2$ м.' }, + { q:'Звук в воздухе — волна:', type:'mc', opts:['Поперечная','Продольная','Стоячая','ЭМ'], correct:1, explain:'Продольная упругая.' }, + { q:'Свет — волна:', type:'mc', opts:['Продольная','Поперечная','Стоячая','Акустическая'], correct:1, explain:'Поперечная ЭМ.' }, + { q:'Волна переносит:', type:'mc', opts:['Вещество','Энергию','Массу','Импульс среды'], correct:1, explain:'Энергию.' }, + { q:'$T = 0{,}25$ с, $v = 4$ м/с. $\\lambda$ (м)?', type:'input', a:'1', explain:'$\\lambda = vT = 1$ м.' } + ]}, + b6: { title:'Босс §6 — Звук', tag:'§6', xp:65, stages:[ + { q:'$\\nu = 680$ Гц в воздухе. $\\lambda$ (м)?', type:'input', a:'0.5', explain:'$\\lambda = 340/680 = 0{,}5$ м.' }, + { q:'$v$ звука в воздухе $\\approx$ (м/с)?', type:'input', a:'340', explain:'340 м/с при $t = 20°$C.' }, + { q:'Ультразвук это $\\nu$:', type:'mc', opts:['$< 16$ Гц','16-20000 Гц','$> 20$ кГц','Любая'], correct:2, explain:'Выше слышимого.' }, + { q:'В вакууме звук:', type:'mc', opts:['Распространяется','Не распространяется','Усиливается','Преломляется'], correct:1, explain:'Нет среды.' }, + { q:'Высота тона зависит от:', type:'mc', opts:['Амплитуды','Частоты','Скорости','Тембра'], correct:1, explain:'Частоты.' } + ]} +}; + +const FINAL_BOSS_DEFS = { + f1: { title:'Финал · Колебания', tag:'Финал гл.1', xp:30, stages:[ + { q:'$T = 0{,}2$ с. $\\omega$ (рад/с, через $\\pi$)?', type:'input', a:['10π','10pi','31.4','31.42'], explain:'$\\omega = 2\\pi/T = 10\\pi$ рад/с.' }, + { q:'Уравнение гарм. колеб.:', type:'mc', opts:['$A/t$','$A\\cos(\\omega t + \\varphi_0)$','$At$','$Ae^{\\omega t}$'], correct:1, explain:'Косинусоидальный закон.' }, + { q:'Период зависит от амплитуды?', type:'mc', opts:['Да','Нет','Иногда'], correct:1, explain:'Для гарм. — нет.' }, + { q:'$\\nu = 25$ Гц. $T$ (с)?', type:'input', a:'0.04', explain:'$T = 1/25 = 0{,}04$ с.' } + ]}, + f2: { title:'Финал · Маятники + энергия', tag:'Финал гл.1', xp:35, stages:[ + { q:'$l = 9{,}81$ м, $g = 9{,}81$ м/с². $T$ (с)?', type:'input', a:['2π','2pi','6.28','6.3'], explain:'$T = 2\\pi\\sqrt{l/g} = 2\\pi$ с.' }, + { q:'$T$ пружинного зависит от:', type:'mc', opts:['$l, g$','$m, k$','$A$','$\\nu$'], correct:1, explain:'$2\\pi\\sqrt{m/k}$.' }, + { q:'$k = 200$ Н/м, $A = 0{,}1$ м. $W_{мех}$ (Дж)?', type:'input', a:'1', explain:'$200 \\cdot 0{,}01 / 2 = 1$ Дж.' }, + { q:'$W_к + W_п = $ ?', type:'mc', opts:['$0$','const','$kx$','Зависит от $t$'], correct:1, explain:'Сохранение полной энергии.' } + ]}, + f3: { title:'Финал · Резонанс', tag:'Финал гл.1', xp:30, stages:[ + { q:'Резонанс наступает при $\\omega = $ ?', type:'mc', opts:['$2\\omega_0$','$\\omega_0$','$0$','Любое'], correct:1, explain:'При совпадении вынуждающей и собственной частот.' }, + { q:'Свободные колеб. в реальности:', type:'mc', opts:['Растут','Затухают','Постоянны'], correct:1, explain:'Диссипация.' }, + { q:'При $\\gamma \\to 0$ резонансная амплитуда:', type:'mc', opts:['$\\to 0$','$\\to \\infty$','$\\to \\omega_0$','Не меняется'], correct:1, explain:'Без затухания неограничена.' }, + { q:'Раскачивание качелей — пример:', type:'mc', opts:['Свободных','Затухающих','Резонанса','Стоячих'], correct:2, explain:'Подталкиваем в такт.' } + ]}, + f4: { title:'Финал · Волны и звук', tag:'Финал гл.1', xp:45, stages:[ + { q:'$\\lambda = ?$ через $v, T$', type:'mc', opts:['$vT$','$v/T$','$v^2 T$','$\\sqrt{vT}$'], correct:0, explain:'$\\lambda = vT$.' }, + { q:'Поперечная волна — частицы колеб.:', type:'mc', opts:['$\\parallel$ распр.','$\\perp$ распр.','Случайно','По окружности'], correct:1, explain:'Перпендикулярно.' }, + { q:'$\\nu = 680$ Гц, воздух. $\\lambda$ (м)?', type:'input', a:'0.5', explain:'$340/680 = 0{,}5$.' }, + { q:'В вакууме звук:', type:'mc', opts:['Распространяется','Не распространяется','Зависит'], correct:1, explain:'Нет среды.' }, + { q:'Молния — гром через 5 с. Расстояние (м)?', type:'input', a:['1700','1700.0'], explain:'$340 \\cdot 5 = 1700$ м.' } ]} };