feat(labs): planimetry locus + emfield merger + projectile graphs + UI cleanup
Геометрия (планиметрия): - Живые измерения как объекты: длина / угол / площадь — auto-recompute, draggable chips - Инструмент ГМТ: sweep мовера через параметр, рисует кривую места точек - Новые типы точек: on_segment (скользит по отрезку, _t), on_circle (по окружности, _theta) - Toolbar: «Длина», «Угол», «Площадь», «ГМТ», «На отрезке», «На окружности» Электромагнитные поля (emfield): - Merge magnetic.js + coulomb.js в один EMFieldSim с 3 режимами (E / B / комбинированное) - Унифицированный pipeline: colormap, field lines, vectors, equipotentials, flux loop, test particle - Combined-режим: полная сила Лоренца F=q(E+v×B) - Backward compat: #coulomb и #magnetic хеши и ?sim= параметры редиректят в emfield - Удалены: magnetic.js, coulomb.js. Добавлен: emfield.js Бросок тела (projectile): - Режим целей: 3 окна, hit-детекция, HUD «Цели: N/M / Попыток: K» - Графики x(t), y(t), vx(t), vy(t) — 2×2 Canvas 2D, real-time - Двойной бросок: одновременно 2 траектории для сравнения (cyan vs gold) UI fixes (по результатам аудита): - Заменены emoji/unicode на inline SVG .ic: switch ⌇, spring 〜 (5 мест), download ⬇ (2), camera 📷 - Убраны декоративные символы ☉ ○ из geometry tool labels - Добавлены THEORY entries: geometry, hydrostatics (раньше показывали fallback) - Стандартизирована ширина panel для sim-proj и sim-coll (240px) - waves перенесён в физический блок SIMS catalog (был после биологии) - Очищен дефолтный sim-topbar-title (был «График функции») Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -31,18 +31,18 @@
|
||||
var wavesSim = null;
|
||||
var geomSim = null;
|
||||
|
||||
var ALL_SIM_BODIES = ['sim-graph','sim-proj','sim-coll','sim-tri','sim-trigcircle','sim-mag',
|
||||
var ALL_SIM_BODIES = ['sim-graph','sim-proj','sim-coll','sim-tri','sim-trigcircle','sim-emfield',
|
||||
'sim-molphys',
|
||||
'sim-coulomb','sim-circuit','sim-chemistry','sim-dynamics',
|
||||
'sim-circuit','sim-chemistry','sim-dynamics',
|
||||
'sim-crystal','sim-orbitals','sim-stereo','sim-chemsandbox',
|
||||
'sim-celldivision','sim-photosynthesis','sim-angrybirds',
|
||||
'sim-quadratic','sim-normaldist','sim-graphtransform',
|
||||
'sim-pendulum','sim-equilibrium','sim-thinlens','sim-titration',
|
||||
'sim-refraction','sim-mirrors','sim-isoprocess','sim-probability','sim-bohratom','sim-electrolysis',
|
||||
'sim-waves','sim-hydro','sim-geometry'];
|
||||
var ALL_CTRL_BARS = ['ctrl-graph','ctrl-proj','ctrl-coll','ctrl-tri','ctrl-trigcircle','ctrl-mag',
|
||||
var ALL_CTRL_BARS = ['ctrl-graph','ctrl-proj','ctrl-coll','ctrl-tri','ctrl-trigcircle','ctrl-emfield',
|
||||
'ctrl-molphys',
|
||||
'ctrl-coulomb','ctrl-circuit','ctrl-chemistry','ctrl-dynamics','ctrl-chemsandbox',
|
||||
'ctrl-circuit','ctrl-chemistry','ctrl-dynamics','ctrl-chemsandbox',
|
||||
'ctrl-celldivision','ctrl-photosynthesis','ctrl-angrybirds','ctrl-waves','ctrl-hydro',
|
||||
'ctrl-geometry'];
|
||||
|
||||
@@ -65,10 +65,12 @@
|
||||
if (id === 'collision') _openCollision();
|
||||
if (id === 'triangle') _openTriangle();
|
||||
if (id === 'trigcircle') _openTrigCircle();
|
||||
if (id === 'magnetic') _openMagnetic();
|
||||
if (id === 'magnetic') _openEMField('B'); // backward compat: #magnetic → emfield B-mode
|
||||
if (id === 'coulomb') _openEMField('E'); // backward compat: #coulomb → emfield E-mode
|
||||
if (id === 'emfield') _openEMField('E');
|
||||
if (id.startsWith('emfield:')) { _openEMField(id.split(':')[1]); }
|
||||
if (id === 'molphys') _openMolPhys();
|
||||
if (id.startsWith('molphys:')) { _openMolPhys(id.split(':')[1]); }
|
||||
if (id === 'coulomb') _openCoulomb();
|
||||
if (id === 'circuit') _openCircuit();
|
||||
if (id === 'chemistry') _openChemistry();
|
||||
if (id.startsWith('chemistry:')) { _openChemistry(id.split(':')[1]); }
|
||||
@@ -222,6 +224,19 @@
|
||||
{ head: 'Коэффициент восстановления', formula: 'e = \\frac{v_2\' - v_1\'}{v_1 - v_2}', text: 'e=1 — упругий, e=0 — абсолютно неупругий удар.' },
|
||||
]
|
||||
},
|
||||
emfield: {
|
||||
title: 'Электромагнитные поля',
|
||||
sections: [
|
||||
{ head: 'Закон Кулона', formula: 'F = k \\frac{|q_1 q_2|}{r^2}', vars: [['k','8.99·10⁹ Н·м²/Кл²'],['q','заряд, Кл'],['r','расстояние, м']] },
|
||||
{ head: 'Напряжённость E', formula: '\\vec{E} = k \\frac{q}{r^2} \\hat{r}', text: 'Вектор направлен от «+» и к «−» заряду.' },
|
||||
{ head: 'Потенциал', formula: '\\varphi = k \\frac{q}{r}', text: 'Эквипотенциальные линии — окружности вокруг заряда.' },
|
||||
{ head: 'Поле прямого тока', formula: 'B = \\frac{\\mu_0 I}{2\\pi r}', vars: [['μ₀','4π·10⁻⁷ Тл·м/А'],['I','сила тока, А'],['r','расстояние от провода, м']] },
|
||||
{ head: 'Суперпозиция B', formula: '\\vec{B} = \\sum_i \\vec{B}_i', text: 'Результирующее поле — векторная сумма полей всех проводов.' },
|
||||
{ head: 'Сила Лоренца', formula: '\\vec{F} = q(\\vec{E} + \\vec{v} \\times \\vec{B})', text: 'Полная электромагнитная сила на движущийся заряд.' },
|
||||
{ head: 'Сила Ампера', formula: 'F = I L B \\sin\\theta', text: 'Сила на проводник с током в магнитном поле.' },
|
||||
]
|
||||
},
|
||||
/* backward-compat aliases — loadTheory() maps these to emfield */
|
||||
magnetic: {
|
||||
title: 'Магнитное поле',
|
||||
sections: [
|
||||
@@ -275,6 +290,30 @@
|
||||
{ head: 'Теорема Пифагора', formula: 'a^2 + b^2 = c^2', text: 'В прямоугольном треугольнике квадрат гипотенузы равен сумме квадратов катетов.' },
|
||||
]
|
||||
},
|
||||
geometry: {
|
||||
title: 'Планиметрия',
|
||||
sections: [
|
||||
{ head: 'Базовые объекты', text: 'Точка, прямая, луч, отрезок, окружность, многоугольник — основные фигуры планиметрии. Каждая прямая однозначно задаётся двумя точками.' },
|
||||
{ head: 'Параллельность и перпендикулярность', text: 'Прямые параллельны, если не пересекаются. Перпендикулярны — если угол между ними 90°.' },
|
||||
{ head: 'Теорема Фалеса', text: 'Если на одной из двух прямых отложить равные отрезки и провести через их концы параллельные прямые, они высекут равные отрезки и на второй прямой.' },
|
||||
{ head: 'Признаки подобия треугольников', text: 'По двум углам, по двум пропорциональным сторонам и углу между ними, по трём пропорциональным сторонам.' },
|
||||
{ head: 'Площадь треугольника', formula: 'S = \\frac{1}{2} a h_a', text: 'Также S = ½·a·b·sin C; формула Герона: S = √(p(p-a)(p-b)(p-c)).' },
|
||||
{ head: 'Площадь параллелограмма', formula: 'S = a h_a = a b \\sin\\alpha' },
|
||||
{ head: 'Длина окружности', formula: 'C = 2\\pi r', text: 'Площадь круга: S = π·r².' },
|
||||
{ head: 'Геометрическое место точек (ГМТ)', text: 'Множество точек, удовлетворяющих заданному условию. Эллипс — ГМТ, сумма расстояний от которых до двух фокусов постоянна. Окружность — ГМТ, равноудалённых от центра.' },
|
||||
]
|
||||
},
|
||||
hydrostatics: {
|
||||
title: 'Гидростатика',
|
||||
sections: [
|
||||
{ head: 'Гидростатическое давление', formula: 'P = \\rho g h', vars: [['ρ','плотность жидкости, кг/м³'],['g','ускорение свободного падения, 9.81 м/с²'],['h','глубина под поверхностью, м']] },
|
||||
{ head: 'Закон Паскаля', text: 'Давление в покоящейся жидкости передаётся одинаково во все стороны. Основа гидравлического пресса: F₁/S₁ = F₂/S₂.' },
|
||||
{ head: 'Закон Архимеда', formula: 'F_A = \\rho_{ж} g V_{погр}', text: 'Сила, выталкивающая тело из жидкости, равна весу вытесненной жидкости. Условие плавания: ρ_тела ≤ ρ_жидкости.' },
|
||||
{ head: 'Сообщающиеся сосуды', text: 'Уровни однородной жидкости в сообщающихся сосудах одинаковы. Для двух разных жидкостей: ρ₁·h₁ = ρ₂·h₂.' },
|
||||
{ head: 'Поверхностное натяжение', formula: '\\sigma = \\frac{F}{l}', text: 'Сила, действующая по касательной к поверхности жидкости на единицу длины. Капиллярная высота: h = 2σ·cos θ / (ρ g r).' },
|
||||
{ head: 'Капиллярность', text: 'В тонких трубках жидкость поднимается (смачивает) или опускается (не смачивает) относительно общего уровня. Зависит от угла смачивания θ.' },
|
||||
]
|
||||
},
|
||||
molphys: {
|
||||
title: 'Молекулярная физика',
|
||||
sections: [
|
||||
|
||||
Reference in New Issue
Block a user