From cefb5e0836c49b377ce469e54177cdfc671a2bb3 Mon Sep 17 00:00:00 2001 From: Maxim Dolgolyov Date: Wed, 24 Jun 2026 10:35:25 +0300 Subject: [PATCH] =?UTF-8?q?feat(trigcircle):=20=D1=80=D0=B5=D0=BD=D0=B4?= =?UTF-8?q?=D0=B5=D1=80=20=D1=84=D0=BE=D1=80=D0=BC=D1=83=D0=BB=20=D1=87?= =?UTF-8?q?=D0=B5=D1=80=D0=B5=D0=B7=20KaTeX?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Блок «Точные значения · приведение» теперь рендерится KaTeX (katex.renderToString, как в graph.js/_sim_engine), с фолбэком на сырой LaTeX если katex ещё не загрузился. Добавлен _latexVal (точное значение → LaTeX: \tfrac{1}{2}, \tfrac{\sqrt{3}}{2}, …), функции \sin/\cos/\operatorname{tg}/\operatorname{ctg}, цвет наследуется от CSS-цвета контейнера (без \textcolor). Формула приведения и значения — те же (проверено). Verified: node --check; headless-смоук LaTeX-вывода (дамп + проверки) — 150°=180°−30° sin=½ cos=−√3/2 tg=−√3/3; 45° без приведения √2/2; 90° tg «не опр.»; 210°=180°+30°; 300°=360°−60°; 137° нетабличный. Эмодзи нет. Co-Authored-By: Claude Opus 4.8 (1M context) --- frontend/js/labs/trigcircle.js | 35 ++++++++++++++++++++++++++-------- 1 file changed, 27 insertions(+), 8 deletions(-) diff --git a/frontend/js/labs/trigcircle.js b/frontend/js/labs/trigcircle.js index cadb45b..d609728 100644 --- a/frontend/js/labs/trigcircle.js +++ b/frontend/js/labs/trigcircle.js @@ -1106,18 +1106,23 @@ if (typeof window !== 'undefined') window.TrigCircleSim = TrigCircleSim; fEl.innerHTML = 'Нетабличный угол — точных значений нет, см. приближённые выше.'; } else { const reduce = (s.quadrant !== 1) && (beta === 30 || beta === 45 || beta === 60); - let head = ''; + const K = window.katex; + const tex = latex => (K ? K.renderToString(latex, { throwOnError: false, strict: false, displayMode: false }) : latex); + const FN = { sin: '\\sin', cos: '\\cos', tg: '\\operatorname{tg}', ctg: '\\operatorname{ctg}' }; + let html = ''; if (reduce) { - const wrap = s.quadrant === 2 ? `180° − ${beta}°` : s.quadrant === 3 ? `180° + ${beta}°` : `360° − ${beta}°`; - head = `
${degR}° = ${wrap} → приведение к ${beta}°
`; + const wrap = s.quadrant === 2 ? `180^\\circ - ${beta}^\\circ` + : s.quadrant === 3 ? `180^\\circ + ${beta}^\\circ` + : `360^\\circ - ${beta}^\\circ`; + html += `
${tex(`${degR}^\\circ = ${wrap}`)}
`; } - const sgStr = v => (v !== undefined && v < -1e-9) ? '−' : ''; const line = (nm, color, val) => { - const mid = reduce ? ` = ${sgStr(val)}${nm} ${beta}°` : ''; - return `
` + - `${nm} ${degR}°${mid}${_f(val)}
`; + const sgn = (val !== undefined && val < -1e-9) ? '-' : ''; + const mid = reduce ? ` = ${sgn}${FN[nm]}\\,${beta}^\\circ` : ''; + // KaTeX наследует CSS-цвет родителя → красим div, формулу не трогаем. + return `
${tex(`${FN[nm]}\\,${degR}^\\circ${mid} = ${_latexVal(val)}`)}
`; }; - fEl.innerHTML = head + line('sin', '#EF476F', s.sin) + line('cos', '#06D6E0', s.cos) + + fEl.innerHTML = html + line('sin', '#EF476F', s.sin) + line('cos', '#06D6E0', s.cos) + line('tg', '#FFD166', s.tan) + line('ctg', '#7BF5A4', s.cot); } } @@ -1131,6 +1136,20 @@ if (typeof window !== 'undefined') window.TrigCircleSim = TrigCircleSim; document.getElementById('trigbar-quad').textContent = ['I', 'II', 'III', 'IV'][s.quadrant - 1]; } + /* Точное значение → LaTeX (зеркалит _f, но для KaTeX). undefined → «—». */ + function _latexVal(v) { + if (v === undefined) return '\\text{не опр.}'; + const a = Math.abs(v), sg = v < -1e-9 ? '-' : ''; + if (a < 5e-4) return '0'; + if (Math.abs(a - 0.5) < 1e-3) return sg + '\\tfrac{1}{2}'; + if (Math.abs(a - Math.SQRT2 / 2) < 1e-3) return sg + '\\tfrac{\\sqrt{2}}{2}'; + if (Math.abs(a - Math.sqrt(3) / 2) < 1e-3) return sg + '\\tfrac{\\sqrt{3}}{2}'; + if (Math.abs(a - Math.sqrt(3) / 3) < 1e-3) return sg + '\\tfrac{\\sqrt{3}}{3}'; + if (Math.abs(a - 1) < 1e-3) return sg + '1'; + if (Math.abs(a - Math.sqrt(3)) < 1e-3) return sg + '\\sqrt{3}'; + return v.toFixed(3); + } + /* ── KaTeX live preview ── */ /** Convert user ascii expression LaTeX string for KaTeX preview */