Фаза A раунда «Конструктор» (под ученика-самоучку). Прямая по 2 точкам
(имена a,b,c…) и плоскость по 3 точкам (имена α,β,γ…) как именованные
объекты сцены. Плоскость рисует полупрозрачный квад + пунктирную рамку +
сечение тела этой плоскостью (через _sliceByPlane) — сразу осмысленна.
- StereoSim: _lines/_planes (сериализуемые {x,y,z}), _constructGroup,
setLineMode/setPlaneMode, _onConstructClick, _createLine/_createPlane,
_rebuildConstructions/_drawLineObject/_drawPlaneObject, removeLast/clear,
getConstructions (с уравнением плоскости). Сброс в setFigure, очистка в
dispose, перерисовка подписей в toggleLabels, счётчик в info().
- Панель «Построения» в labs-bodies.html + glue (stereoLineMode/PlaneMode/
ConstructUndo/Clear, _stereoUpdateConstructList); интеграция в
_stereoDeactivateTools и _stereoUpdateUI.
- План: Фазы A и C в plans/STEREO_3D_IMPROVEMENT.md.
Верификация: node --check OK; headless-смоук 35/35 (создание/имена/нормаль/
коллинеарность/rebuild/summary/remove-last/clear/click-путь/setFigure-сброс/
dispose); эмодзи/eval/new Function — 0.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
14 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 Подписи вершин сечения буквами (K, L, M…) в наклонном/произвольном сечении и сечении-по-3-точкам (для настоящих многоугольников ≤12 вершин). Пошаговый режим сечения-по-3-точкам уже был. (Полное «построение по следам» — в бэклоге, крупная отдельная фича.)
- 3.2 Точки на произвольной точке грани:
_raycastFace()— в режиме «точки» клик по грани (не у ребра/вершины) ставит точку на поверхности. Через произвольное сечение (3 кастомные точки) это даёт плоскость через внутренние точки граней. - 3.3 Live-readout overlay (
#stereo-readout, низ-слева): тип сечения, площадь S, периметр P, последнее измерение. Обновляется черезinfo().readoutпри любом изменении сечения/измерения.
Бэклог: полное «построение сечения по следам» (продление рёбер, след на грани); readout углов (двугранный/линия-плоскость) — сейчас угол только в 3D-метке.
Фаза 4 — Визуал — ГОТОВО (см. бэклог)
- 4.1 Свечение вершин (мягкий additive-ореол без текстур, безопасно с
_clearGroup); рёбра контрастнее (opacity 0.9,renderOrderповерх полупрозрачного тела), вершины поверх рёбер. (Подсветка грани по ховеру отложена — текущий centroid-пикинг граней грубоват для плавного hover.) - 4.2 Подписи осей X/Y/Z, цвета совпадают с AxesHelper (X крас., Y зел., Z син.).
Бэклог: подсветка грани по ховеру (нужен точный raycast по логическим граням); градиентный/бумажный фон (учесть захват в скриншоте).
Фаза 5 — Интеграция и архитектура — ГОТОВО (без дробления файла, по решению пользователя)
- [~] 5.1 Дробление
stereo.jsна модули — отложено по решению пользователя (риск регрессий, не видно пользователю). Остаётся в бэклоге. - 5.2 Deep-link фигуры из учебников без изменения общего hash-роутера:
openSim('stereo:<figure>')и/lab?stereofig=<figure>#sim/stereo._openStereo(figureType)применяет фигуру и подсвечивает кнопку. Допустимые: cube, parallelepiped, prism, pyramid, truncpyramid, tetrahedron, octahedron, icosahedron, dodecahedron, cylinder, cone, trunccone, sphere. - 5.3 a11y: клавиатурная навигация по сфокусированному canvas — стрелки (орбита), +/− (зум), R/Home (сброс);
tabindex/role/aria-labelна canvas (Фаза 0),aria-pressed/aria-labelна кнопках вида (Фаза 1),aria-liveна readout.
Бэклог Фазы 5: модульное дробление файла; deep-link конкретного сечения/инструмента (не только фигуры).
Фаза 6 — Построение сечения «по следам» (метод следов) — ГОТОВО (путь b)
Реализован гибрид: финальный полигон считается надёжно (Фаза 2), а след и вспомогательные точки выводятся аналитически — без риска несходимости конструктивного алгоритма. Scope: тела с основанием (куб, параллелепипед, призма, пирамида, усеч. пирамида, тетраэдр).
- 6.1
_hasBase()+_traceLine(data)— след = π ∩ плоскость основания (y=0):n.x·x + n.z·z + D = 0; возвращает{p0, dir}или null (плоскость параллельна основанию). Проверено численно (точка следа на плоскости, остаток 0). - 6.2
_auxiliaryPoints(polygon)— продление боковых сторон сечения до y=0; точка пересечения лежит ровно на следе (численно dist=0). Сортировка по «дальности продления», берём 2 ближайшие. - 6.3 Настоящий пошаговый
_drawSection3PStep(заменил бутафорию): 6 подписанных шагов — 3 точки → стороны в одной грани (_sameFace) → след → вспом. точки T₁,T₂ → вершины+замыкание → итог. В step-режиме финальное сечение скрыто до шага 5 (showFull), пиковые линии тоже скрыты. Подписи шагов в#sect3p-hintчерез_stepCaption. Для тел без основания — деградация к простым шагам с пояснением. - bump stereo.js?v=9
Бэклог Фазы 6: «честный» конструктивный алгоритм (шаг по граням через след для поиска каждой новой вершины); анимация перехода между шагами; ветка для плоскости, параллельной основанию.
Раунд «Конструктор» (2026-06-17) — упор на ученика-самоучку (песочница)
Цель: превратить отличный визуализатор в полноценный конструктор для самостоятельных построений. Приоритеты, выбранные пользователем: Фаза A (конструкторное ядро) и Фаза C (сечения+). A — фундамент C (сечение через прямую+точку, параллельно прямой/плоскости опираются на объекты-прямые/плоскости).
Фаза A — Конструкторное ядро
Прямые и плоскости как объекты первого класса + пересечения + параллели/перпендикуляры + общий undo/redo + дерево именованных объектов.
- [~] A1 — Объектная модель + базовые построения.
_lines[](имена a,b,c…),_planes[](имена α,β,γ…), группа_constructGroup, сериализуемое хранение{x,y,z}. Инструменты «Прямая по 2 точкам» и «Плоскость по 3 точкам» (пикинг вершин/точек). Плоскость рисует полупрозрачный квад + пунктирную рамку + сечение тела этой плоскостью (через_sliceByPlane, делает плоскость осмысленной сразу). Панель «Построения», список объектов с уравнением плоскости. - A2 — Пересечения (прямая∩плоскость → точка; плоскость∩плоскость → прямая; прямая∩прямая → точка) + именованное дерево с удалением/цветом/видимостью отдельных объектов.
- A3 — Параллели/перпендикуляры (прямая ∥ прямой через точку; прямая ⟂ плоскости; плоскость ∥ плоскости; плоскость ⟂ прямой = «плоскость по точке и нормали» — мост к Фазе C) + общий undo/redo (снапшот всех пользовательских массивов построения, Ctrl+Z/Ctrl+Shift+Z).
Фаза C — Сечения+
- C1 — Сечение плоскостью-объектом (из Фазы A): «показать как сечение» с площадью/периметром.
- C2 — Сечение, параллельное прямой/плоскости; сечение через прямую и точку.
- C3 — «Натуральная величина» сечения (разворот многоугольника сечения в плоскость экрана, отдельная мини-панель) + штриховка.
- C4 — Честный конструктивный алгоритм следов с анимацией перехода между шагами (из бэклога Ф6).
История: создан 2026-05-30. Фаза 6 добавлена 2026-05-30. Раунд «Конструктор» (Фазы A,C) — 2026-06-17.