c802fe552a
- _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>
5.6 KiB
5.6 KiB
План улучшения симуляции «Стереометрия 3D»
Файлы: frontend/js/labs/stereo.js (StereoSim, ~3720 строк), панель в frontend/lab.html (#sim-stereo), роутинг frontend/js/labs/lab-init.js.
Статус-легенда: [ ] не начато · [~] в работе · [x] готово
Фаза 0 — Производительность и гигиена (быстрый эффект, низкий риск) — ГОТОВО
- 0.1 Останавливать loop при переключении симуляций.
Добавлен
_pauseAllSims()вlab-init.js, вызывается в началеopenSim()— все rAF-симы (включая стерео) паузятся при переходе. Раньше предыдущий сим рендерил невидимый canvas вечно. - 0.2 Pointer/touch-слушатели перенесены с
windowнаrenderer.domElement, с pointer-capture для драга вне холста; все слушатели трекаются и снимаются вdispose(). Canvas получилtabindex/role/aria-label. - 0.3 Render-on-demand:
_invalidate()+ dirty-флаг_needsRender; loop засыпает (_rafId=null), просыпается по взаимодействию/изменению сцены. Хук в_clearGroup()покрывает все rebuild/clear; защита от двойного rAF. - 0.4 Обработка
webglcontextlost/webglcontextrestored(пересборка сцены); методdispose()(renderer, ResizeObserver, слушатели, текстуры). Бонус:_clearGroupстал рекурсивным — устранена утечка вложенных групп (измерения и т.п.).
Фаза 1 — Камера и навигация — ГОТОВО
- 1.1 Инерция орбиты (плавное затухание после отпускания) + панорамирование: правая/средняя кнопка или Shift+ЛКМ на десктопе, два пальца на тач. Орбита вокруг сдвигаемого таргета (
_panOffset). (zoom-to-cursor отложен — pan покрывает рецентрирование; перенесён в бэклог Фазы 2.) - 1.2 Overlay-тулбар в правом верхнем углу viewport: сброс вида + пресеты ракурса (Изо / Спереди / Сбоку / Сверху). Пресет «держит» вид (спин выключается).
- 1.3 Тумблер авто-вращения (с реальным засыпанием loop при выключении), fullscreen (по
.graph-canvas-outer), снимок PNG (preserveDrawingBuffer+ синхронный рендер → download). a11y:aria-pressed/aria-labelна кнопках.
Фаза 2 — Геометрия и пикинг — ГОТОВО
- 2.1 Аналитические сечения кривых тел
_sliceCurvedByNormal(): шар → точная окружность (плоскость∩сфера), цилиндр/конус/усеч.конус → гладкая кривая через точное решение y(θ) для образующейr(y)=r0+k·y. Старый пороговый сэмплинг оставлен как fallback (почти вертикальные плоскости). Проверено численно (диапазон y цилиндра и радиус окружности шара совпадают с формулами). - 2.2 Общий хелпер
_edgePickNDC()(расстояние точка-отрезок в NDC);_pickNearestEdgeи_pickNearestEdgeIdxпереведены с «по середине ребра» на корректный пикинг по всей длине. - 2.3 HiDPI-метки:
_makeTextSpriteрендерит на canvas с учётом DPR, корректный аспект по ширине текста, тёмная обводка для читаемости, анизотропная фильтрация. Тип сечения для кривых = «окружность»/«эллипс», вершинные маркеры не плодятся (cap ≤12 точек).
Бэклог: zoom-to-cursor (перенесён из 1.1); SDF-шрифт и пул текстур (текущая резкость достаточна).
Фаза 3 — Педагогика сечений
- 3.1 Построение сечения «по следам» с пошаговой анимацией и подписью вершин.
- 3.2 Точки сечения в произвольной точке грани.
- 3.3 Постоянная панель readout: длины/углы/площадь сечения с пояснением.
Фаза 4 — Визуал
- 4.1 Материалы: рёбра с anti-alias, подсветка активной грани, свечение вершин.
- 4.2 Аккуратные оси X/Y/Z с подписями, опциональный фон (тёмный/бумага).
Фаза 5 — Интеграция и архитектура
- 5.1 Разбить
stereo.jsна модули (builders / sections / tools / ui), вынести константы и цвета. - 5.2 Связать симуляцию с учебниками 10–11 (открывать тело/сечение из §-канвы и задач).
- 5.3 Доступность: клавиатура,
aria, фокус.
История: создан 2026-05-30.