feat(phys11 ch7): Waves 11-12 — Глава 7 «Ядерная физика» (§35-§44 + Финал)

- phys-fx.js: PHYS.RadioactiveDecay (график N(t)=N₀·2^(-t/T))
- ch7 — розово-красная тема (--pri:#e11d48), 10 параграфов
- §35: протонно-нейтронная модель, нуклоны, изотопы, изобары, ядерные силы
- §36: ядерные реакции, законы сохранения,  = \Delta m c^2$
- §37: дефект массы, {св}$, удельная $\varepsilon$, максимум у Fe
- §38: радиоактивность (Беккерель), α/β/γ, проникающая способность
- §39: закон распада  = N_0 \cdot 2^{-t/T}$, активность (Бк), C-14
- §40: деление U-235, цепные реакции, $, критическая масса
- §41: ядерный реактор (Ферми 1942), замедлитель, стержни, ВВЭР/РБМК
- §42: термояд D+T, Солнце, ИТЭР, токамак
- §43: дозы (Грей, Зиверт), коэф. $, нормы радиационной безопасности
- §44: Стандартная модель — 6 кварков, 6 лептонов, бозоны, Хиггс (2012), 4 взаимодействия
- 20 квизов + 10 боссов + 5 интегральных финальных боссов
- Финал главы: +200 XP, ачивка ch7_master 'Магистр ядра'
This commit is contained in:
Maxim Dolgolyov
2026-05-29 19:26:16 +03:00
parent a6d86f4374
commit cef226c53e
2 changed files with 1038 additions and 190 deletions
+80
View File
@@ -2074,4 +2074,84 @@ class EnergyLevels {
}
P.EnergyLevels = EnergyLevels;
/* ============================================================ */
/* RadioactiveDecay — N(t) = N0 * 2^(-t/T) */
/* ============================================================ */
class RadioactiveDecay {
constructor(container, opts){
opts = opts || {};
this.el = (typeof container === 'string') ? document.querySelector(container) : container;
this.W = opts.width || 600;
this.H = opts.height || 300;
this.T = opts.T !== undefined ? opts.T : 2.0; /* период полураспада */
this.tMax = opts.tMax !== undefined ? opts.tMax : 10;
this.t = 0;
this.paused = false;
util.subscribe(this);
util.observe(this);
this._render();
}
setT(v){ this.T = Math.max(0.2, v); this.t = 0; }
reset(){ this.t = 0; }
update(dt){ this.t = (this.t + dt * 0.5) % this.tMax; }
render(){
if (!this.el) return;
const W = this.W, H = this.H;
const pad = 40, left = pad, right = W - pad - 100, top = 30, bot = H - 40;
let svg = util.svgFrame(W, H, {bg:'#fef9c3'});
/* Сетка */
svg += '<g stroke="#facc15" stroke-width="0.6" opacity="0.5">';
for (let i = 0; i <= 10; i++){
const x = left + i * (right - left) / 10;
svg += '<line x1="' + x + '" y1="' + top + '" x2="' + x + '" y2="' + bot + '"/>';
}
for (let i = 0; i <= 4; i++){
const y = top + i * (bot - top) / 4;
svg += '<line x1="' + left + '" y1="' + y + '" x2="' + right + '" y2="' + y + '"/>';
}
svg += '</g>';
svg += '<line x1="' + left + '" y1="' + bot + '" x2="' + right + '" y2="' + bot + '" stroke="#0f172a" stroke-width="1.4"/>';
svg += '<line x1="' + left + '" y1="' + top + '" x2="' + left + '" y2="' + bot + '" stroke="#0f172a" stroke-width="1.4"/>';
/* Кривая */
let pts = '';
for (let i = 0; i <= 100; i++){
const tau = i * this.tMax / 100;
const N = Math.pow(2, -tau / this.T);
const x = left + tau / this.tMax * (right - left);
const y = bot - N * (bot - top);
pts += x.toFixed(1) + ',' + y.toFixed(1) + ' ';
}
svg += '<polyline points="' + pts + '" fill="none" stroke="#dc2626" stroke-width="2.6"/>';
/* Точки полураспадов: 1T, 2T, 3T... */
for (let k = 1; k * this.T < this.tMax; k++){
const tau = k * this.T;
const N = Math.pow(2, -k);
const x = left + tau / this.tMax * (right - left);
const y = bot - N * (bot - top);
svg += '<circle cx="' + x.toFixed(1) + '" cy="' + y.toFixed(1) + '" r="3.5" fill="#0f172a"/>';
svg += '<line x1="' + x.toFixed(1) + '" y1="' + bot + '" x2="' + x.toFixed(1) + '" y2="' + y.toFixed(1) + '" stroke="#0f172a" stroke-width="0.8" stroke-dasharray="2 2"/>';
svg += '<text x="' + x.toFixed(1) + '" y="' + (bot + 12) + '" text-anchor="middle" font-family="JetBrains Mono,monospace" font-size="9" fill="#475569">' + k + 'T</text>';
}
/* Текущая точка t */
const Nt = Math.pow(2, -this.t / this.T);
const cx = left + this.t / this.tMax * (right - left);
const cy = bot - Nt * (bot - top);
svg += '<circle cx="' + cx.toFixed(1) + '" cy="' + cy.toFixed(1) + '" r="6" fill="#facc15" stroke="#92400e" stroke-width="1.8"/>';
/* Подписи */
svg += '<text x="' + (left - 4) + '" y="' + top + '" text-anchor="end" font-family="JetBrains Mono,monospace" font-size="10" fill="#475569">N₀</text>';
svg += '<text x="' + (left - 4) + '" y="' + (top + (bot - top) / 2 + 4) + '" text-anchor="end" font-family="JetBrains Mono,monospace" font-size="10" fill="#475569">N₀/2</text>';
/* Панель справа */
const px = right + 12;
svg += '<text x="' + px + '" y="' + (top + 14) + '" font-family="JetBrains Mono,monospace" font-size="11" fill="#dc2626" font-weight="700">N(t) = N₀ · 2^(-t/T)</text>';
svg += '<text x="' + px + '" y="' + (top + 34) + '" font-family="JetBrains Mono,monospace" font-size="11" fill="#0f172a">T = ' + this.T.toFixed(2) + '</text>';
svg += '<text x="' + px + '" y="' + (top + 50) + '" font-family="JetBrains Mono,monospace" font-size="11" fill="#0f172a">t = ' + this.t.toFixed(2) + '</text>';
svg += '<text x="' + px + '" y="' + (top + 66) + '" font-family="JetBrains Mono,monospace" font-size="11" fill="#92400e" font-weight="700">N/N₀ = ' + Nt.toFixed(3) + '</text>';
svg += '</svg>';
this.el.innerHTML = svg;
}
_render(){ this.render(); }
}
P.RadioactiveDecay = RadioactiveDecay;
})();
File diff suppressed because it is too large Load Diff