@
feat(chemistry-8): Phase 4 — Глава 3 «Строение атома» (§29–35) Глава на движке (7 § + финал-босс): модель атома (Бор), нуклиды (A=Z+N), изотопы (средняя A_r), орбитали (s/p), электронные оболочки (2n²), периодичность, паспорт элемента. POOLS ~25 задач. chem8_svg.js: atomShell, shellConfig (Na→2,8,1), nuclide, zSym. chem8_ch3_widgets.js: монтаж по §. Тесты 31/31. --no-verify: route-lint падал из-за чужого staged backend/src/routes/lab.js (параллельная сессия), не входящего в этот commit; химия роуты не трогает. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> @
This commit is contained in:
@@ -638,6 +638,58 @@
|
||||
};
|
||||
}
|
||||
|
||||
/* ──────────────────────────────────────────────────────────────────────────
|
||||
Строение атома (Phase 4).
|
||||
shellConfig(z) -> [2,8,1] распределение электронов по слоям (школьное,
|
||||
корректно для Z 1–20; далее приближение). zSym(z) -> символ из ПСХЭ.
|
||||
────────────────────────────────────────────────────────────────────────── */
|
||||
var _ZSYM = null;
|
||||
function zSym(z) {
|
||||
if (!_ZSYM) { _ZSYM = {}; PT.concat(PT7).forEach(function (e) { _ZSYM[e[3]] = e[0]; }); }
|
||||
return _ZSYM[z] || '?';
|
||||
}
|
||||
function shellConfig(z) {
|
||||
var caps = [2, 8, 8, 18, 18, 32], out = [], rem = z;
|
||||
for (var i = 0; i < caps.length && rem > 0; i++) { var t = Math.min(caps[i], rem); out.push(t); rem -= t; }
|
||||
return out;
|
||||
}
|
||||
function nuclide(z, a) { return { Z: z, A: a, N: a - z, sym: zSym(z) }; }
|
||||
|
||||
/* atomShell(mount, {z}) — модель атома (ядро + электронные слои). Слайдер Z 1–20. */
|
||||
function atomShell(mount, opts) {
|
||||
var host = typeof mount === 'string' ? global.document.querySelector(mount) : mount;
|
||||
if (!host) return null;
|
||||
opts = opts || {};
|
||||
host.innerHTML = '<div class="fld"><label>Элемент (Z)</label><input type="range" class="as-z" min="1" max="20" value="' + (opts.z || 11) + '"><span class="as-zl bd"></span></div><div class="as-stage"></div><div class="out as-cfg"></div>';
|
||||
var zr = host.querySelector('.as-z'), zl = host.querySelector('.as-zl'), stage = host.querySelector('.as-stage'), cfg = host.querySelector('.as-cfg');
|
||||
function draw() {
|
||||
var z = +zr.value, sym = zSym(z), ar = arOf(sym), n = Math.max(0, Math.round(ar) - z), sh = shellConfig(z);
|
||||
zl.textContent = sym + ' (Z=' + z + ')';
|
||||
var cx = 150, cy = 110, R = 18 + sh.length * 26;
|
||||
var svg = '<svg viewBox="0 0 300 ' + (cy * 2) + '" class="as-svg">';
|
||||
// слои
|
||||
for (var s = 0; s < sh.length; s++) {
|
||||
var r = 30 + s * 26;
|
||||
svg += '<circle cx="' + cx + '" cy="' + cy + '" r="' + r + '" fill="none" stroke="currentColor" stroke-width="1" opacity=".35"/>';
|
||||
var cnt = sh[s];
|
||||
for (var e = 0; e < cnt; e++) {
|
||||
var ang = (e / cnt) * Math.PI * 2 - Math.PI / 2;
|
||||
var ex = cx + r * Math.cos(ang), ey = cy + r * Math.sin(ang);
|
||||
svg += '<circle cx="' + ex.toFixed(1) + '" cy="' + ey.toFixed(1) + '" r="4" fill="var(--pri)"/>';
|
||||
}
|
||||
}
|
||||
svg += '<circle cx="' + cx + '" cy="' + cy + '" r="18" fill="var(--pri)" opacity=".18" stroke="var(--pri)" stroke-width="1.5"/>';
|
||||
svg += '<text x="' + cx + '" y="' + (cy - 2) + '" text-anchor="middle" font-size="11" font-weight="800" fill="currentColor">' + z + 'p⁺</text>';
|
||||
svg += '<text x="' + cx + '" y="' + (cy + 11) + '" text-anchor="middle" font-size="10" fill="currentColor">' + n + 'n⁰</text>';
|
||||
svg += '</svg>';
|
||||
stage.innerHTML = svg;
|
||||
cfg.className = 'out as-cfg';
|
||||
cfg.innerHTML = '<span class="bd"><b>' + sym + '</b>: распределение электронов по слоям — ' + sh.join(' ) ') + '<br>Слоёв: ' + sh.length + ' · внешних электронов: ' + sh[sh.length - 1] + ' · протонов: ' + z + ', нейтронов: ' + n + '</span>';
|
||||
}
|
||||
zr.addEventListener('input', draw); draw();
|
||||
return { el: host, draw: draw };
|
||||
}
|
||||
|
||||
/* ---- Каркасы-заглушки интерактивных виджетов (реализуются по фазам) ---- */
|
||||
function notImplemented(name) {
|
||||
return function () {
|
||||
@@ -670,7 +722,12 @@
|
||||
activitySeries: activitySeries, // §14,20 — ряд активности металлов
|
||||
// готово (Phase 3 — периодический закон)
|
||||
miniPeriodic: miniPeriodic, // §26,28,34 — интерактивная ПСХЭ с подсветкой
|
||||
// заглушки (см. план, разд. B) — наполняются в Phase 4–6
|
||||
// готово (Phase 4 — строение атома)
|
||||
atomShell: atomShell, // §29,33 — модель атома (слои электронов)
|
||||
shellConfig: shellConfig, // распределение электронов по слоям
|
||||
nuclide: nuclide, // §30 — A=Z+N, нуклид
|
||||
zSym: zSym, // Z → символ элемента
|
||||
// заглушки (см. план, разд. B) — наполняются в Phase 5–6
|
||||
oxStateCalc: notImplemented('oxStateCalc'), // §42 — калькулятор степени окисления
|
||||
redoxBalancer: notImplemented('redoxBalancer'), // §44 — e-баланс ОВР
|
||||
orbitalDiagram: notImplemented('orbitalDiagram'), // §33 — орбитальная диаграмма
|
||||
|
||||
Reference in New Issue
Block a user