From d395e1083becbf2ea6892cd3c71539c554a94d26 Mon Sep 17 00:00:00 2001 From: Maxim Dolgolyov Date: Wed, 24 Jun 2026 10:23:31 +0300 Subject: [PATCH] =?UTF-8?q?feat(trigcircle):=20=D0=A4=D0=B0=D0=B7=D0=B0=20?= =?UTF-8?q?1=20=E2=80=94=20=D1=80=D0=B0=D0=B1=D0=BE=D1=82=D0=B0=20=D1=81?= =?UTF-8?q?=20=D1=83=D0=B3=D0=BB=D0=B0=D0=BC=D0=B8=20+=20=D0=BE=D0=B1?= =?UTF-8?q?=D0=B7=D0=BE=D1=80=20(=D1=82=D1=80=D0=B5=D0=BD=D0=B0=D0=B6?= =?UTF-8?q?=D1=91=D1=80=20=D1=82=D1=80=D0=B8=D0=B3=D0=BE=D0=BD=D0=BE=D0=BC?= =?UTF-8?q?=D0=B5=D1=82=D1=80=D0=B8=D0=B8)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit План тренажёра в plans/trig-circle/PLAN.md (всё по теме на окружности, кроме графиков функций). Фаза 1 (аддитивно к рабочему режиму): - Ввод угла в градусах (поле + Enter/кнопка) → goToAngle (нормализует, показывает котерминальность). Подсказка «+360°·k» в бейдже угла. - Тумблер «График/функции» — скрыть график (тема «функции») → круг на всю ширину (переиспользует существующий слой graph + _layout). - Полная сетка табличных углов (16: 0…330°) вместо 8. - Опорный (острый) угол к оси Ox в выводе (основа формул приведения) + знаки sin/cos/tg по текущей четверти. stats() расширен полями refAngle/refDeg. Verified: node --check; headless-смоук (vm + canvas-Proxy) 9/9 — опорный угол 30/150/210→30°, 300→60°, 90→90°, 0→0; знаки по четвертям (II: sin+ cos− tg−; IV: sin− cos+); новые глобальные glue-функции определены. Эмодзи нет (стрелка — inline SVG .ic, tg-неопр. — em-dash). Co-Authored-By: Claude Opus 4.8 (1M context) --- frontend/js/labs/trigcircle.js | 48 +++++++++++++++++++++++++++++++--- frontend/labs-bodies.html | 39 ++++++++++++++++++++++++--- plans/trig-circle/PLAN.md | 35 +++++++++++++++++++++++++ 3 files changed, 116 insertions(+), 6 deletions(-) create mode 100644 plans/trig-circle/PLAN.md diff --git a/frontend/js/labs/trigcircle.js b/frontend/js/labs/trigcircle.js index 1c4a0dc..7381563 100644 --- a/frontend/js/labs/trigcircle.js +++ b/frontend/js/labs/trigcircle.js @@ -130,7 +130,16 @@ class TrigCircleSim { const ct = Math.abs(s) > 1e-9 ? co / s : undefined; const deg = a * 180 / Math.PI; const q = a < Math.PI/2 ? 1 : a < Math.PI ? 2 : a < 3*Math.PI/2 ? 3 : 4; - return { angle: a, deg, radLabel: this._radLbl(a), sin: s, cos: co, tan: t, cot: ct, quadrant: q }; + // Опорный (острый) угол — к ближайшей оси Ox: основа формул приведения. + let ref; + if (a <= Math.PI / 2) ref = a; + else if (a <= Math.PI) ref = Math.PI - a; + else if (a <= 3 * Math.PI/2) ref = a - Math.PI; + else ref = 2 * Math.PI - a; + return { + angle: a, deg, radLabel: this._radLbl(a), sin: s, cos: co, tan: t, cot: ct, quadrant: q, + refAngle: ref, refDeg: ref * 180 / Math.PI, + }; } /* ═══ Layout ═══════════════════════════════════════════════════════ */ @@ -1029,6 +1038,26 @@ if (typeof window !== 'undefined') window.TrigCircleSim = TrigCircleSim; if (window.LabFX) LabFX.sound.play('click'); } + /* Ввод угла в градусах (поле + Enter/кнопка). Принимает любое число (включая <0 и >360), + goToAngle нормализует — заодно демонстрирует котерминальность. */ + function trigSetAngleDeg(inp) { + if (!trigSim || !inp) return; + const v = parseFloat(String(inp.value || '').replace(',', '.')); + if (!isFinite(v)) return; + trigSim.goToAngle(v * Math.PI / 180); + } + function trigAngleKey(e, inp) { if (e && (e.key === 'Enter' || e.keyCode === 13)) trigSetAngleDeg(inp); } + + /* Показать/скрыть график функций (тема «функции» — по умолчанию можно убрать, + круг займёт всю ширину). Переиспользует существующий слой 'graph'. */ + function trigToggleGraph(rowEl) { + if (!trigSim) return; + const on = rowEl.classList.toggle('active'); + trigSim.toggleLayer('graph', on); + const fns = document.getElementById('trig-graph-fns'); + if (fns) fns.style.display = on ? '' : 'none'; + } + function _trigUpdateUI(s) { const _f = v => { if (v === undefined) return '—'; @@ -1050,9 +1079,22 @@ if (typeof window !== 'undefined') window.TrigCircleSim = TrigCircleSim; document.getElementById('trig-v-tan').textContent = _f(s.tan); document.getElementById('trig-v-cot').textContent = _f(s.cot); - // Angle badge + // Angle badge + котерминальные углы (+360°·k) document.getElementById('trig-angle-badge').innerHTML = - `${degStr} = ${s.radLabel}
${s.angle.toFixed(4)} рад`; + `${degStr} = ${s.radLabel}
${s.angle.toFixed(4)} рад` + + `
+ 360°·k (котерминальные)`; + + // Опорный (острый) угол — guarded (панель может не иметь элемента) + const refEl = document.getElementById('trig-ref'); + if (refEl) refEl.textContent = (Math.round(s.refDeg * 10) / 10) + '°'; + // Знаки функций в текущей четверти + const signsEl = document.getElementById('trig-signs'); + if (signsEl) { + const sg = v => (v > 1e-9 ? '+' : v < -1e-9 ? '−' : '0'); + signsEl.innerHTML = + `sin ${sg(s.sin)} · cos ${sg(s.cos)} · ` + + `tg ${s.tan === undefined ? '—' : sg(s.tan)}`; + } // Stats bar (nice fractions) document.getElementById('trigbar-angle').textContent = degStr; diff --git a/frontend/labs-bodies.html b/frontend/labs-bodies.html index dcf3bea..b7cebcf 100644 --- a/frontend/labs-bodies.html +++ b/frontend/labs-bodies.html @@ -506,6 +506,16 @@
+ +
Угол, °
+
+ + +
+
Отрезки
@@ -535,9 +545,14 @@
- -
График
-
+ + +
@@ -553,6 +568,16 @@ ctg
+ +
Опорный угол · знаки
+
+
+ острый угол к оси + +
+
+
+
Табличные углы
@@ -562,8 +587,16 @@ + + + + + + + +
diff --git a/plans/trig-circle/PLAN.md b/plans/trig-circle/PLAN.md new file mode 100644 index 0000000..4e34fc1 --- /dev/null +++ b/plans/trig-circle/PLAN.md @@ -0,0 +1,35 @@ +# Тригонометрическая окружность — план улучшения (тренажёр темы, без функций) + +Цель: симуляция `frontend/js/labs/trigcircle.js` + панель `frontend/labs-bodies.html` (#sim-trigcircle) +покрывает всю школьную тригонометрию НА ОКРУЖНОСТИ. Графики y=f(x) («функции») — вне темы: +существующий showGraph оставляем опциональным/скрываемым. + +Архитектура: рукописный canvas-sim (класс TrigCircleSim) + HTML-панель в labs-bodies.html + +glue-функции (`_openTrigCircle`, `trigToggle`, `trigGoTo`, `trigReset`, `_trigUpdateUI`) внизу +trigcircle.js; регистрация в `_register-all.js` (`trigcircle`). KaTeX, LabFX, _tasks.js доступны. +⛔ без eval, без эмодзи (inline SVG .ic), всё аддитивно (не ломать текущий режим). + +## Уже есть +Окружность, перетаскиваемая точка, угол °/рад (метки π/6…), sin/cos/tan/cot отрезками (слои), +треугольник sin-cos, касательная/котангенс, 16 табличных углов + snap, подсветка четверти, +значения дробями (½,√2/2,√3/2,√3/3,√3), stat-bar, опциональный график (= «функции»). + +## Фазы +- **Ф1 — Углы и обзор**: тумблер скрыть график (фокус на круге); ввод угла (° и π-доли); + полная сетка табличных кнопок (16); опорный (острый) угол; знаки по четвертям в выводе; + подсказка котерминальности (+360°k / +2πk). +- **Ф2 — Определения / 6 функций**: подписи sin=y, cos=x на осях; слой sec/csc; Пифагор + sin²+cos²=1 (гипотенуза=1) с формулой; тумблер «формула значения» (KaTeX). +- **Ф3 — Знаки**: режим со знаками +/− sin/cos/tg по четвертям, мнемоника, таблица. +- **Ф4 — Особые углы / таблица значений**: оверлей-таблица 0/30/45/60/90… с подсветкой текущего. +- **Ф5 — Симметрии и формулы приведения**: чётность (α→−α), приведение (π±α, π/2±α, 2π−α) + с анимацией отражения/поворота + KaTeX; период tg/ctg = π. +- **Ф6 — Простейшие уравнения**: задаёшь значение → все решения на круге + общая формула + (sin α=½ → π/6+2πk, 5π/6+2πk); для tg — шаг π; связка с arcsin/arccos геометрически. +- **Ф7 — Два угла (опц.)**: вторая точка β → α±β, формулы сложения. +- **Сквозное**: режимы-вкладки (Углы·Определения·Знаки·Особые·Приведение·Уравнения) с краткой + теорией и кнопкой «Задание» через _tasks.js; шпаргалка (значения+знаки+тождества+приведение). + +## Проверка каждой фазы +node --check; headless-смоук математики (опорный угол, знаки, решения уравнений, приведение) +в vm с стабом canvas; коммит+push, без эмодзи, lint.