From 48158ea88d856915a827924b3767e7718f0c7713 Mon Sep 17 00:00:00 2001 From: Maxim Dolgolyov Date: Wed, 24 Jun 2026 10:51:55 +0300 Subject: [PATCH] =?UTF-8?q?feat(trigcircle):=20=D0=A4=D0=B0=D0=B7=D0=B0=20?= =?UTF-8?q?5=20=E2=80=94=20=D1=87=D1=91=D1=82=D0=BD=D0=BE=D1=81=D1=82?= =?UTF-8?q?=D1=8C/=D0=BD=D0=B5=D1=87=D1=91=D1=82=D0=BD=D0=BE=D1=81=D1=82?= =?UTF-8?q?=D1=8C=20(=E2=88=92=CE=B1)=20+=20=D0=BF=D0=B5=D1=80=D0=B8=D0=BE?= =?UTF-8?q?=D0=B4=D1=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Тумблер «Чётность (−α)»: на окружности рисуется зеркальная точка −α (отражение через ось Ox, пунктир P↔−α) — наглядно нечётность sin и чётность cos. Блок-справка на KaTeX (строится один раз): sin(−α)=−sin α, cos(−α)=cos α, tg(−α)=−tg α, периоды T_sin=T_cos=2π, T_tg=T_ctg=π. (Формулы приведения для текущего угла — уже Фаза 2.) Аддитивно: this.showParity + _drawParity + хук в draw(); glue trigToggleParity; тумблер + #trig-parity в панели. Verified: node --check; headless-смоук 9/9 (_drawParity без throw для 30/150/210/300; toggle строит блок один раз с верными тождествами+периодами, показ/скрытие). Эмодзи нет. Co-Authored-By: Claude Opus 4.8 (1M context) --- frontend/js/labs/trigcircle.js | 37 ++++++++++++++++++++++++++++++++++ frontend/labs-bodies.html | 9 +++++++++ 2 files changed, 46 insertions(+) diff --git a/frontend/js/labs/trigcircle.js b/frontend/js/labs/trigcircle.js index 0af8ea6..8d7db74 100644 --- a/frontend/js/labs/trigcircle.js +++ b/frontend/js/labs/trigcircle.js @@ -54,6 +54,7 @@ class TrigCircleSim { this.snapToNotable = true; this.animating = false; this.eq = null; // режим уравнения: { fn:'sin'|'cos'|'tg', a:Number, sols:[рад] } | null + this.showParity = false; // показать зеркальную точку −α (чётность/нечётность) this._cx = 0; this._cy = 0; this._r = 0; this._gx = 0; this._gw = 0; this._gh = 0; this._gy = 0; @@ -98,6 +99,7 @@ class TrigCircleSim { this._drawBg(c); this._drawCircle(c); if (this.eq) this._drawEquation(c); + if (this.showParity) this._drawParity(c); if (this.showGraph) { this._drawDivider(c); this._drawGraph(c); } this._drawParticles(c); if (window.LabFX) LabFX.particles.draw(c); @@ -153,6 +155,22 @@ class TrigCircleSim { c.restore(); } + /* Зеркальная точка −α (отражение через ось Ox): наглядно чётность cos и нечётность sin. */ + _drawParity(c) { + const cx = this._cx, cy = this._cy, r = this._r, a = this.angle; + const px = cx + r * Math.cos(a), py = cy - r * Math.sin(a); + const mx = cx + r * Math.cos(-a), my = cy - r * Math.sin(-a); + c.save(); + c.strokeStyle = _tcRgba(_TC.violet, 0.4); c.setLineDash([4, 4]); c.lineWidth = 1; + c.beginPath(); c.moveTo(px, py); c.lineTo(mx, my); c.stroke(); c.setLineDash([]); + c.strokeStyle = _TC.violet; c.lineWidth = 2; c.fillStyle = 'rgba(155,93,229,0.15)'; + c.beginPath(); c.arc(mx, my, 6, 0, Math.PI * 2); c.fill(); c.stroke(); + c.font = 'bold 11px Manrope,sans-serif'; c.fillStyle = _TC.violet; + c.textAlign = 'center'; c.textBaseline = 'middle'; + c.fillText('-α', mx + (Math.cos(-a) >= 0 ? 14 : -14), my); + c.restore(); + } + goToAngle(rad) { this._animTarget = this._norm(rad); if (!this.animating) this._startAnim(); @@ -1194,6 +1212,25 @@ if (typeof window !== 'undefined') window.TrigCircleSim = TrigCircleSim; else el.style.display = 'none'; } + /* ── Чётность/нечётность + периоды (статический KaTeX-блок, строится один раз) ── */ + function trigToggleParity(rowEl) { + if (!trigSim) return; + const on = rowEl.classList.toggle('active'); + trigSim.showParity = on; + trigSim.draw(); + const pEl = document.getElementById('trig-parity'); + if (!pEl) return; + pEl.style.display = on ? '' : 'none'; + if (on && !pEl.dataset.built) { + pEl.innerHTML = + `
${_tex('\\sin(-\\alpha) = -\\sin\\alpha')}
` + + `
${_tex('\\cos(-\\alpha) = \\cos\\alpha')}
` + + `
${_tex('\\operatorname{tg}(-\\alpha) = -\\operatorname{tg}\\alpha')}
` + + `
${_tex('T_{\\sin}=T_{\\cos}=2\\pi,\\quad T_{\\operatorname{tg}}=T_{\\operatorname{ctg}}=\\pi')}
`; + pEl.dataset.built = '1'; + } + } + function _trigUpdateUI(s) { const _f = v => { if (v === undefined) return '—'; diff --git a/frontend/labs-bodies.html b/frontend/labs-bodies.html index f736cc1..ed2a4a4 100644 --- a/frontend/labs-bodies.html +++ b/frontend/labs-bodies.html @@ -608,6 +608,15 @@ + + + +
Табличные углы