lab.html подключает _pilots.js; файл попал в предыдущий коммит как удаление
(был в общем индексе от параллельной сессии). Возвращаю, чтобы не ломать
ссылку. Впредь коммичу строго по путям.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- источник «Предмет»: тумблер «Характ. лучи» (по умолчанию) / «Пучок»
- характеристические: 3 луча от вершины (параллельный→F', через центр,
через F→параллельно) + осевой от основания — как в учебнике; проверено
численно (F'=lensX+f, центр прямо, через F выход параллелен)
- пучок: прежний физичный веер + ползунок «Лучей» (густота) и «Раствор»
- setSource: rayMode как строковый ключ; bump opticsbench.js?v=9
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- источник можно двигать по вертикали: слайдер «Положение ↕» (для любого
типа) + вертикальное перетаскивание; эмиссия/отрисовка/хит-тест через _sy()
- фикс бага: FX-вспышка рисовалась на ay−source.h даже для точечного
источника (h оставалась 70) → «звезда» улетала вверх; теперь FX привязан
к реальной точке источника (поднятая вершина только у стрелки-предмета)
- object «Высота» → «Размер стрелки» (чтобы не путать с вертик. положением)
- bump opticsbench.js?v=8
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Ветка feature/lab-content-engine отделилась до Фазы 4 оптики, из-за чего
кнопки «+ Граница/+ Пластина» были без логики. Принёс полную Фазу 4
opticsbench.js с master (граница сред со Снеллиусом/ПВО, пластина, источники
луч/лазер, отсечение апертурой, F/2F, числовые слайдеры) и заново наложил
фикс выбора источника: постоянный чип «Источник» + выбор по умолчанию.
bump opticsbench.js?v=7
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- подключён _registry.js в lab.html (был отсутствует -> LabRegistry был undefined)
- регистрация 3 пилотов в _pilots.js (graph/quadratic/pendulum), подключён последним
- loadTheory (lab-glue.js) адаптирован: реестр в приоритете, иначе THEORY
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- выбор источника теперь всегда доступен: чип «Источник» в списке схемы
(раньше — только кликом по точке на холсте); источник выбран по умолчанию
- восстановлены потерянные кнопки палитры «+ Граница» / «+ Пластина»
- bump opticsbench.js?v=6
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Два дефекта, из-за которых 3D читался как плоская диаграмма:
- painter-сортировка была по возрастанию z (ближние первыми) — дальние
атомы рисовались поверх ближних. Теперь единый список примитивов
(атомы + половинки связей) сортируется по убыванию z (дальние первыми).
- связи были тонкими плоскими линиями. Теперь — затенённые «цилиндры»:
толстый штрих с поперечным градиентом (центр светлее, края темнее),
двухцветные (каждая половина под цвет своего атома) — фирменный вид
ball-and-stick. Ширина зависит от перспективы (ближе — толще).
- усилена перспектива (fov 900→700), добавлен тёмный ободок сфер для объёма.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- _drawScreenHits: светящиеся пятна (additive) в точках попадания лучей на
экран, по длине волны — видно формирование изображения и спектр
- benchExportPng + кнопка «Снимок PNG»; подсказка про λ/белый свет
- bump opticsbench.js?v=4
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- _prismInteract: тонкопризменное отклонение δ=(n−1)·A к основанию +
хроматическая дисперсия n(λ) через _nAtWavelength
- белый свет: пучки по OB_SPECTRAL, каждый луч красится по длине волны
(до призмы совпадают, после — расходятся в спектр); управление общим λ-баром
- _obRedraw для freebuild переключён на benchSim (был freeSim)
- сферические зеркала уже из Фазы 1; проверено численно (фиолет>красный)
- bump opticsbench.js?v=3
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Режим «Цепочка линз» → «Конструктор» на базе нового класса BenchSim:
- общий 2D-трассировщик: линза, зеркало (плоск./вогн./выпукл.), диафрагма,
экран; источники предмет/точка/параллель; лимит отражений
- фокус линзы в x+f и терминация зеркала проверены численно
- динамический инспектор: палитра элементов, список схемы, свойства
выбранного, удаление; слайдеры перерисовывают только холст (не ломают drag)
- pointer-слушатели на canvas (capture, dispose), выбор/перетаскивание
- пресеты: микроскоп/телескоп/проектор/зеркальная; сохранение состояния
в снимок (_obGetState/_obApplyState); bump opticsbench.js?v=2
- призма — пока грубый placeholder (Снеллиус/дисперсия в Фазе 2)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- _traceLine: p0 = основание перпендикуляра из начала координат (след
рисуется у фигуры, а не у далёкого пересечения с осью)
- фикс: после сброса/смены фигуры в пошаговом режиме step мог стать 0 →
сечение скрыто и шаги не рисуются; нормализация step≥1 в _drawSection3P
- подпись шага обновляется сразу после 3-го клика (в step-режиме)
- bump stereo.js?v=10
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Путь (b): надёжный полигон (есть) + аналитический след и вспом. точки.
- _traceLine(): след = π ∩ плоскость основания y=0 (проверено численно)
- _auxiliaryPoints(): продление сторон сечения до следа (dist=0 на следе)
- _hasBase()/_sameFace(): топология тел с основанием
- настоящий пошаговый _drawSection3PStep: 6 подписанных шагов, финал скрыт
до шага 5 (showFull); подписи в #sect3p-hint через _stepCaption
- scope: куб, параллелепипед, призма, пирамида, усеч. пирамида, тетраэдр
- bump stereo.js?v=9
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- openSim('stereo:<figure>') и /lab?stereofig=<figure> открывают нужное тело
(без изменения общего hash-роутера)
- клавиатура на canvas: стрелки=орбита, +/-=зум, R/Home=сброс
- aria-live на readout; bump stereo.js?v=8
- дробление файла на модули отложено по решению пользователя (в бэклоге)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- live-readout overlay: тип сечения, площадь, периметр, последнее измерение
(через info().readout; _notify добавлен в section/measure-пути)
- _raycastFace(): в режиме точек клик по грани ставит точку на поверхности
- подписи вершин сечения буквами K,L,M… (наклонное/произвольное/3-точки, ≤12 вершин)
- bump stereo.js?v=6
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- _sliceCurvedByNormal(): аналитическое сечение шара (окружность) и
цилиндра/конуса/усеч.конуса (гладкая кривая через точное y(θ)); старый
сэмплинг оставлен fallback'ом для почти вертикальных плоскостей
- _edgePickNDC(): корректный пикинг ребра по всей длине (было — по середине)
- _makeTextSprite: DPR-aware, аспект по тексту, обводка, анизотропия
- тип сечения кривых = окружность/эллипс; вершинные маркеры cap ≤12 точек
- bump stereo.js?v=5
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- lab-init: _pauseAllSims() паузит активный rAF-сим при переключении (раньше стерео рендерило невидимый canvas вечно)
- stereo: render-on-demand через _invalidate()/_needsRender, loop засыпает и просыпается по взаимодействию
- pointer/touch-слушатели перенесены с window на canvas (pointer-capture), трекаются и снимаются в dispose()
- обработка webglcontextlost/restored + метод dispose()
- _clearGroup стал рекурсивным (устранена утечка вложенных групп), a11y-атрибуты на canvas
- bump stereo.js?v=3
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Причины 'один луч, работает неправильно':
1. tangDir = efVec/efLen давал тангенциальное направление, при котором преломлённый луч внутри призмы уходил вниз в основание (sFace > 1), а не в выходную правую грань → внешнего луча не было
2. По умолчанию был включён моно-режим — пользователь видел один луч без дисперсии
Исправлено:
- tangDir = 90° по часовой от efNorm (efNorm.y, -efNorm.x) — теперь падающий луч при стандартных углах попадает в выходную грань правильно
- При первом входе в режим призмы window._obWhiteLight = true → 6 спектральных лучей сразу видны (расхождение цветов)
- Добавлена кнопка 'Белый / Моно' в панель призмы для переключения
PrismSim был сломан в 3 местах:
1. incDir строился с -efNorm (наружу), а не efNorm (внутрь) → падающий луч рисовался не с той стороны
2. cosI = -(incDir·efNorm) с уже-перевёрнутым incDir давал противоречивые знаки
3. Формула Снелла rDir имела + вместо - на коэффициенте efNorm
Итог: при incAngle≈0 преломлённый луч уходил в обратную сторону, точка пересечения с выходной гранью не находилась (tRay<0), и наружный луч с дисперсией не отрисовывался → визуально 'призма не работает'.
Теперь incDir — направление распространения (внутрь призмы), cosI = +(incDir·efNorm), формула: r = (1/n)·l + (cosR − cosI/n)·n
- Менделеев: clamp() для font-size символа элемента (2.4rem..4.4rem) + padding-top 28px → символ не обрезается на узких панелях
- Качественные реакции: в Свободно/Тренировке Проб1-4 содержат известные ионы (видна подпись), в Тренировке Образец — отдельный неизвестный; в Экзамене можно переключаться между пробирками и ответить отдельно для каждой (verdict сохраняется)
- Стехиометрия: непрерывный анимационный цикл — волна на поверхности жидкости, пузырьки в газах/растворах, пульсирующая красная рамка + ЛИМИТ-лейбл у лимитирующего реагента, искры вдоль стрелки реакции, glow на стрелке во время реакции
- Стехиометрия → 4-шаговый wizard (Реакция → Количества → Лимит → Продукты), KaTeX в displayMode, крупные карточки
- Качественные реакции → центрированная сцена с большой пробиркой, журнал справа 290px, нижняя полка реагентов, убран список ионов
- Контраст: основной текст rgba(.92), вторичный (.7), шрифты от .85rem
ВОЛНА A — Расширенная база данных:
- Новый файл _periodic_data.js (~70 KB): PERIODIC_EXT_DATA + ISOTOPES + SPECTRA
- 30 элементов полностью (H..Au): радиусы, ионизация, теплоёмкость, теплопроводность,
кристалл, распространённость, биология, токсичность, пламя, применения, история,
этимология, минералы, типичные реакции
- 9 элементов с минимумом (Sc, Ti, V, As, Se, Kr, Hg, Pb, I)
- 60 изотопов в 20 элементах (включая ¹³¹I, ¹³⁷Cs, ⁶⁰Co, ⁹⁰Sr, ¹⁴C, ³H, U-235/238)
- 43 эмиссионных линий для 8 элементов (H, He, Li, Na, K, Ne, Ar, Hg)
ВОЛНА B — Визуальные режимы:
- Heatmap по 9 свойствам (En, mass, density, melt, boil, discovered + расширенные)
с jet-colormap, lin/log toggle, легендой, анимацией 400ms
- 3D-таблица через Three.js: bar / wave / stack modes, orbit camera, raycaster hover
- Морф между формами таблицы: standard / long (32-col, f-block inline) / short (8-col)
с staggered fade-in 800ms
- Тренды стрелками: радиус / ЭО / ИЕ / металличность с градиентными arrows
ВОЛНА C — Карточка элемента 2.0 (11 табов):
- Обзор (hero 96px символ + Z + категория-бейдж + quick stats)
- Свойства (17-row таблица расширенных параметров)
- Электроника (Bohr + статичная конфигурация)
- Изотопы (список + bar chart + weighted average mass)
- История (timeline + этимология)
- Применения (15 SVG иконок-сфер + текст)
- Биология (badge: macro/micro/trace/toxic/inert/radioactive)
- Минералы (формулы)
- Спектр (rainbow 380-780nm + линии эмиссии)
- Пламя (цвет + название)
- Реакции (типовые уравнения по типу элемента)
- Hero header с цветом типа; smooth fade transitions между табами
ВОЛНА D — Интерактивные режимы:
- Бинарные соединения: drag 2 элемента → формула (NaCl, Fe₂O₃) + тип связи (ΔЭО)
- Сравнить до 4 элементов: side-by-side + min/max highlight + chart
- Ряд активности металлов: 28 элементов от Li до Au, разделитель H
- Таблица Менделеева 1869: 63 элемента + 4 предсказанных (Ga, Sc, Ge, Tc)
с popup «предсказано vs реально»
- Таймлайн открытий 1660-2024 с slider и auto-play
ВОЛНА G — Электронные конфигурации углубление:
- Orbital filling diagram: квадратики с электронами по Хунду/Паули, glow на валентном
- Aufbau diagram с slider Z 1-118 и анимированным указателем порядка заполнения
- Квантовые числа (n, l, m_l, m_s) — hover на электрон → tooltip
- Возбуждение электронов: click на электрон в Bohr → выбор уровня → анимация
перехода с фотоном (цвет ∝ длине волны через ΔE = 13.6 eV × ...)
periodic.js: 750 → 3239 строк. Все 5 волн ADDITIVE — старая база сохранена.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Hydrostatics использовал P_SANDBOX как у dynamics — оба показывали одну
и ту же карточку с блоком/шаром и силами. Добавлен P_HYDRO: мензурка
с погруженным телом + F_A, U-образный манометр с Δh, сообщающиеся сосуды.
Геометрия (планиметрия):
- Живые измерения как объекты: длина / угол / площадь — 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>
lab.html 4324L → 3499L (-825L). 824 lines of glue code moved.
Position preserved: lab-glue.js loads after lab-init.js, before
newton.js / forcesandbox.js / etc. — same execution order as inline.
node --check passes. /lab returns 200. /js/labs/lab-glue.js returns 200.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Hardcoded inline <svg class="ic"> markers used as arrow replacements
(left over from emoji removal) were displayed as raw HTML text where
the consumer used textContent or canvas fillText:
- chemsandbox: csbar-v5 (Продукты cell) used textContent → SVG visible.
Switched to innerHTML for consistency with eq/ionNet cells.
Quiz question (qEl.textContent) and answer also receiving SVG —
cleaned via _csClean at source.
- reactions: modeTxt drawn via canvas fillText — replaced SVG with →.
- ionexchange: REACTIONS data + canvas labels — bulk SVG → Unicode arrows.
- newton: action button labels used textContent → switched to innerHTML;
canvas arrow labels: SVG → Unicode →/↓.
- collision: 'KE сохранена' canvas label — SVG checkmark → ✓.
- projectile: canvas badges + textContent wind label — SVG → Unicode ←/→/↩.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
lab.html: 9273 → 5180 lines (-44%)
frontend/js/labs/lab-init.js: new file, 4098 lines
All 34 _open*() functions + sim instance vars + openSim/closeSim/
_addTouchSupport/_simShow + THEORY data extracted to lab-init.js.
Shared globals (FN_COLORS, ALL_SIM_BODIES, ALL_CTRL_BARS, sim vars)
converted from const/let to var for cross-script accessibility.
Three vars in lab.html made global: _disabledSimIds, _theoryOpen, _embedMode.
Load order preserved: lab-init.js added before main <script> block.
- Добавлены фигуры: усечённая пирамида, октаэдр, икосаэдр, додекаэдр
- Формулы V, S, r_вп, R_оп для всех новых фигур
- Инструмент '∠ скрещ. прям.' — угол и расстояние между скрещивающимися прямыми (4 клика)
- Для икосаэдра/додекаэдра — THREE.IcosahedronGeometry/DodecahedronGeometry с извлечением рёбер
- Вписанная/описанная сфера поддерживает октаэдр, икосаэдр, додекаэдр
- Параметр n добавлен для пирамиды
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- arcmark: рисуется всегда (не только при showAngles=true)
- altitude/median: 1 клик на вершину треугольника (авто-определение)
- centroid/orthocenter: 1 клик внутри/на треугольник
- thales: 3 клика O, A, B → A'B' параллельно AB, коэф. k
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>