From 15de0d914f69e3d9d6e9a0a94b8631777adeb6e1 Mon Sep 17 00:00:00 2001 From: Maxim Dolgolyov Date: Fri, 29 May 2026 14:26:11 +0300 Subject: [PATCH] =?UTF-8?q?feat(geom11=20ch2=20wave2):=20=C2=A74=20=C2=AB?= =?UTF-8?q?=D0=9A=D0=BE=D0=BD=D1=83=D1=81=C2=BB=20+=203D=20+=20=D1=80?= =?UTF-8?q?=D0=B0=D0=B7=D0=B2=D1=91=D1=80=D1=82=D0=BA=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/textbooks/geometry_11_ch2.html | 412 +++++++++++++++++++++++- 1 file changed, 409 insertions(+), 3 deletions(-) diff --git a/frontend/textbooks/geometry_11_ch2.html b/frontend/textbooks/geometry_11_ch2.html index 1b9e8f8..c69c71d 100644 --- a/frontend/textbooks/geometry_11_ch2.html +++ b/frontend/textbooks/geometry_11_ch2.html @@ -392,7 +392,7 @@ function buildParaSelector(){ } const BUILT=new Set(); -const BUILDERS = { p3:buildP3, p4:()=>buildStub('p4'), final2:()=>buildStub('final2') }; +const BUILDERS = { p3:buildP3, p4:buildP4, final2:()=>buildStub('final2') }; function ensureBuilt(id){ if(BUILT.has(id)) return; const fn=BUILDERS[id]; if(fn){ fn(); BUILT.add(id); } } function goTo(id){ STATE.current=id; ensureBuilt(id); @@ -417,13 +417,24 @@ const SIDEBARS = { ["Апофема","$l=\\\\sqrt{r^2+h^2}$"], ["Усечённая","$V=\\\\dfrac{h}{3}(S_1+S_2+\\\\sqrt{S_1 S_2})$"] ]}, - p4:{title:"Шпаргалка § 4", rows:[["Тема", "Конус"],["Формула","$S_{бок}=\\\\pi Rl$"]]}, + p4:{title:"Шпаргалка § 4", rows:[ + ["Конус","основание ($R$) + апекс"], + ["Связь","$l^2=R^2+h^2$"], + ["$S_{осн}$","$\\\\pi R^2$"], + ["$S_{бок}$","$\\\\pi R l$"], + ["$S_{полн}$","$\\\\pi R(R+l)$"], + ["$V$","$\\\\dfrac{1}{3}\\\\pi R^2 h$"], + ["Развёртка","сектор $r=l$, дуга $2\\\\pi R$"], + ["Угол развёртки","$\\\\varphi=\\\\dfrac{360°R}{l}$"], + ["Усечённый $V$","$\\\\dfrac{\\\\pi h}{3}(R_1^2+R_2^2+R_1R_2)$"], + ["Усечённый $S_{бок}$","$\\\\pi(R_1+R_2)l$"] + ]}, final2:{title:"Финал раздела 2", rows:[["§ 3–§ 4","теория раздела 2"],["Награда","+50 XP"]]} }; const TIPS=[ {sec:'p3',html:"Главное правило: $V=\\\\\\\\dfrac{1}{3}S_{осн}h$ для любой пирамиды. А для правильной — $S_{бок}=\\\\\\\\dfrac{1}{2}P_{осн}l$, где $l$ — апофема."}, - {sec:'p4',html:"§ 4 «Конус» — содержание в разработке. $S_{бок}=\\\\\\\\pi Rl$"}, + {sec:'p4',html:"Запомни связку: $l^2=R^2+h^2$. Все формулы конуса — это $\\\\\\\\pi R$ умноженное на соответствующий «множитель»: $R$ (основание), $l$ (боковая), $R+l$ (полная), $\\\\\\\\dfrac{Rh}{3}$ (объём)."}, {sec:'final2',html:"Финал раздела 2 — интегрированные задачи по разделу."} ]; @@ -986,6 +997,401 @@ function buildP3(){ wireReadBtn('p3'); } +/* ===== § 4 «Конус» — Wave 2 ===== */ + +function buildP4(){ + const box = document.getElementById('p4-body'); + if(!box) return; + let html = ''; + + /* === ТЕОРИЯ === */ + + html += makeCard('theory', 'Определение и элементы', '§ 4.1', + '

Конус (прямой круговой) — тело, образованное вращением прямоугольного треугольника вокруг одного из катетов.

' + + '

Элементы конуса:

' + + '' + + '

Главная связь (теорема Пифагора в осевом сечении):

' + + '

$$l^2 = R^2 + h^2$$

' + + '

Конус — «предельный» случай пирамиды: если у правильной $n$-угольной пирамиды устремить число сторон основания $n\\to\\infty$ при фиксированном радиусе описанной окружности, то получится конус. Поэтому формулы для конуса можно получать «по аналогии» с пирамидой, заменяя $P_{осн}$ на $2\\pi R$, а $S_{осн}$ на $\\pi R^2$.

'); + + html += makeCard('rule', 'Площадь и объём. Развёртка', '§ 4.2', + '

Основные формулы:

' + + '

$$S_{осн} = \\pi R^2$$

' + + '

$$S_{бок} = \\pi R l$$

' + + '

$$S_{полн} = \\pi R (R + l)$$

' + + '

$$V = \\dfrac{1}{3}\\pi R^2 h$$

' + + '

Развёртка боковой поверхности конуса — это круговой сектор радиуса $l$ (равного образующей), у которого длина дуги равна длине окружности основания $2\\pi R$.

' + + '

Угол развёртки:

' + + '

$$\\varphi = \\dfrac{2\\pi R}{l}\\;\\text{рад} = \\dfrac{360°\\cdot R}{l}$$

' + + '
Пример: конус $R=3$, $h=4$
' + + '
    ' + + '
  • $l=\\sqrt{R^2+h^2}=\\sqrt{9+16}=5$ — образующая.
  • ' + + '
  • $S_{осн}=\\pi R^2 = 9\\pi$.
  • ' + + '
  • $S_{бок}=\\pi R l = 15\\pi$.
  • ' + + '
  • $S_{полн}=\\pi R(R+l)= 3\\pi\\cdot 8 = 24\\pi\\approx 75{,}4$.
  • ' + + '
  • $V=\\dfrac{1}{3}\\pi R^2 h=\\dfrac{1}{3}\\cdot 9\\pi\\cdot 4 = 12\\pi\\approx 37{,}7$.
  • ' + + '
  • Угол развёртки: $\\varphi=\\dfrac{360°\\cdot 3}{5}=216°$.
  • ' + + '
' + + '
'); + + html += makeCard('example', 'Сечения. Усечённый конус', '§ 4.3', + '

Сечения конуса плоскостью:

' + + '' + + '

Усечённый конус — часть конуса, заключённая между основанием и плоскостью, параллельной основанию.

' + + '' + + '

$$V = \\dfrac{1}{3}\\pi h\\bigl(R_1^2 + R_2^2 + R_1 R_2\\bigr)$$

' + + '

$$S_{бок} = \\pi (R_1 + R_2)\\,l$$

' + + '
Пример: усечённый конус $R_1=5$, $R_2=3$, $h=4$
' + + '
    ' + + '
  • $l=\\sqrt{h^2+(R_1-R_2)^2}=\\sqrt{16+4}=\\sqrt{20}=2\\sqrt{5}\\approx 4{,}47$.
  • ' + + '
  • $S_{бок}=\\pi(R_1+R_2)l = 8\\pi\\cdot 2\\sqrt{5}=16\\pi\\sqrt{5}\\approx 112{,}4$.
  • ' + + '
  • $V=\\dfrac{1}{3}\\pi\\cdot 4\\cdot(25+9+15)=\\dfrac{196\\pi}{3}\\approx 205{,}3$.
  • ' + + '
' + + '
'); + + /* === ИНТЕРАКТИВ 1 — 3D-конструктор конуса === */ + html += '
' + + '
3D · конструктор
Конус: $R$, $h$ и все формулы
' + + '
Меняй радиус основания $R$ и высоту $h$. Вращай мышью или выбирай вид. После 4 разных конфигураций — +10 XP.
' + + '
' + + '' + + '' + + '
' + + '
' + + '' + + '' + + '' + + '' + + '
' + + '
' + + '
' + + '$l=$' + + '$S_{осн}=$' + + '$S_{бок}=$' + + '$S_{полн}=$' + + '$V=$' + + '$\\varphi=$' + + '
' + + '
Конфигураций изучено: 0 / 4
' + + '
'; + + /* === ИНТЕРАКТИВ 2 — Развёртка (2D-сектор) === */ + html += '
' + + '
2D · развёртка
Развёртка боковой поверхности
' + + '
Двигай $R$ и $h$ — увидишь, как меняется круговой сектор развёртки: его радиус равен $l$, длина дуги — $2\\pi R$, а угол — $\\varphi=\\dfrac{360°R}{l}$. После 4 конфигураций — +10 XP.
' + + '
' + + '' + + '' + + '
' + + '
' + + '
' + + '$l=$' + + 'дуга $=2\\pi R=$' + + 'угол $\\varphi=$' + + '
' + + '
Конфигураций изучено: 0 / 4
' + + '
'; + + /* === ИНТЕРАКТИВ 3 — Квикфайр «какое сечение?» === */ + html += '
' + + '
квикфайр · 6 заданий
Какое сечение конуса?
' + + '
Читай описание плоскости — выбирай форму сечения: круг, равнобедренный треугольник или эллипс.
' + + '
' + + '
Верно: 0 / 6
' + + '
'; + + /* === ИНТЕРАКТИВ 4 — Тренажёр V и S === */ + html += '
' + + '
тренажёр · 6 задач
$V$, $S$, $l$ и угол развёртки
' + + '
Введи числовой ответ. Используй $\\pi\\approx 3{,}14$. Допуск $\\pm 0{,}05$.
' + + '
' + + '
Решено: 0 / 6
' + + '
'; + + html += secNavFor('p4'); + html += readButton('p4'); + + box.innerHTML = html; + renderMath(box); + + /* ====== JS-логика интерактивов ====== */ + + /* IV1 — 3D-конструктор конуса */ + (function(){ + if(!window.G3D) return; + const svg = document.getElementById('p4-iv1-svg'); + const elR = document.getElementById('p4-iv1-R'); + const elH = document.getElementById('p4-iv1-h'); + const vR = document.getElementById('p4-iv1-R-v'); + const vH = document.getElementById('p4-iv1-h-v'); + const oL = document.getElementById('p4-iv1-l'); + const oSo = document.getElementById('p4-iv1-So'); + const oSb = document.getElementById('p4-iv1-Sb'); + const oSt = document.getElementById('p4-iv1-St'); + const oV = document.getElementById('p4-iv1-V'); + const oPhi = document.getElementById('p4-iv1-phi'); + const oCnt = document.getElementById('p4-iv1-cnt'); + if(!svg) return; + const PI = 3.14; + const scene = G3D.createScene({W:480, H:400, scale:50, camDist:8, rotX:-0.35, rotY:0.7}); + const seen = new Set(); + let xpGiven = false; + + function draw(){ + const R = +elR.value, h = +elH.value; + vR.textContent = R.toFixed(1); + vH.textContent = h.toFixed(1); + const mesh = G3D.coneMesh(R, h, 32); + const M = G3D.buildRotMatrix(scene); + svg.innerHTML = G3D.renderMesh(mesh, M, scene, { + fillBase:'rgba(252,231,243,.55)', + fillSide:'rgba(219,234,254,.55)', + strokeVisible:'#0f172a', + strokeHidden:'#94a3b8' + }); + const l = Math.sqrt(R*R + h*h); + const So = PI*R*R; + const Sb = PI*R*l; + const St = PI*R*(R + l); + const V = PI*R*R*h/3; + const phi = 360*R/l; + oL.textContent = l.toFixed(2); + oSo.textContent = So.toFixed(2); + oSb.textContent = Sb.toFixed(2); + oSt.textContent = St.toFixed(2); + oV.textContent = V.toFixed(2); + oPhi.textContent = phi.toFixed(1) + '°'; + const key = R.toFixed(1)+'|'+h.toFixed(1); + seen.add(key); + oCnt.textContent = Math.min(seen.size, 4); + if(seen.size >= 4 && !xpGiven){ + xpGiven = true; + addXp(10, 'p4-iv1'); + bumpProgress('p4', 15); + const note = document.createElement('div'); + note.className = 'feedback ok'; + note.innerHTML = '✓ +10 XP за изучение 4 разных конусов!'; + note.style.cssText = 'display:block;margin-top:8px'; + const host = document.getElementById('p4-iv1'); + if(host) host.appendChild(note); + setTimeout(function(){ try{ note.remove(); }catch(e){} }, 3000); + } + } + draw(); + G3D.attachOrbit(svg, scene, draw); + [elR, elH].forEach(function(el){ el.addEventListener('input', draw); }); + document.querySelectorAll('#p4-iv1 .g3d-tools .btn').forEach(function(b){ + b.addEventListener('click', function(){ G3D.presetView(scene, b.dataset.view, draw); }); + }); + })(); + + /* IV2 — Развёртка (2D-сектор) */ + (function(){ + const svg = document.getElementById('p4-iv2-svg'); + const elR = document.getElementById('p4-iv2-R'); + const elH = document.getElementById('p4-iv2-h'); + const vR = document.getElementById('p4-iv2-R-v'); + const vH = document.getElementById('p4-iv2-h-v'); + const oL = document.getElementById('p4-iv2-l'); + const oArc = document.getElementById('p4-iv2-arc'); + const oPhi = document.getElementById('p4-iv2-phi'); + const oCnt = document.getElementById('p4-iv2-cnt'); + if(!svg) return; + const PI = 3.14; + const W = 380, H = 320; + const cx = 190, cy = 180; + const seen = new Set(); + let xpGiven = false; + + function draw(){ + const R = +elR.value, h = +elH.value; + vR.textContent = R.toFixed(1); + vH.textContent = h.toFixed(1); + const l = Math.sqrt(R*R + h*h); + const arc = 2*PI*R; + const phiDeg = 360*R/l; + const phiRad = phiDeg * Math.PI / 180; + /* масштаб: подгоняем радиус сектора к ~120px на SVG */ + const scale = 120 / l; + const rPix = l * scale; + /* строим сектор: центр (cx,cy), от угла -phi/2 до +phi/2 (отсчёт от вертикали вверх) */ + const a0 = -Math.PI/2 - phiRad/2; + const a1 = -Math.PI/2 + phiRad/2; + const x0 = cx + rPix*Math.cos(a0), y0 = cy + rPix*Math.sin(a0); + const x1 = cx + rPix*Math.cos(a1), y1 = cy + rPix*Math.sin(a1); + const largeArc = phiRad > Math.PI ? 1 : 0; + let s = ''; + /* сетка для контекста */ + s += ''; + /* пунктирный круг полного радиуса l (показывает «целое» откуда вырезан сектор) */ + s += ''; + /* заливка сектора */ + s += ''; + /* радиус-метка слева (l) */ + s += ''; + const midR1x = (cx + x0)/2, midR1y = (cy + y0)/2; + s += 'l='+l.toFixed(2)+''; + /* радиус справа */ + s += ''; + /* подпись дуги */ + const midA = -Math.PI/2; + const labelR = rPix + 16; + const labX = cx + labelR*Math.cos(midA), labY = cy + labelR*Math.sin(midA); + s += 'дуга = 2πR ≈ '+arc.toFixed(2)+''; + /* центр и подпись угла φ */ + s += ''; + /* дуга индикатор угла маленькая */ + const angR = 26; + const ax0 = cx + angR*Math.cos(a0), ay0 = cy + angR*Math.sin(a0); + const ax1 = cx + angR*Math.cos(a1), ay1 = cy + angR*Math.sin(a1); + s += ''; + s += 'φ='+phiDeg.toFixed(1)+'°'; + svg.innerHTML = s; + oL.textContent = l.toFixed(2); + oArc.textContent = arc.toFixed(2); + oPhi.textContent = phiDeg.toFixed(1) + '°'; + const key = R.toFixed(1)+'|'+h.toFixed(1); + seen.add(key); + oCnt.textContent = Math.min(seen.size, 4); + if(seen.size >= 4 && !xpGiven){ + xpGiven = true; + addXp(10, 'p4-iv2'); + bumpProgress('p4', 15); + const note = document.createElement('div'); + note.className = 'feedback ok'; + note.innerHTML = '✓ +10 XP за изучение 4 разных развёрток!'; + note.style.cssText = 'display:block;margin-top:8px'; + const host = document.getElementById('p4-iv2'); + if(host) host.appendChild(note); + setTimeout(function(){ try{ note.remove(); }catch(e){} }, 3000); + } + } + draw(); + [elR, elH].forEach(function(el){ el.addEventListener('input', draw); }); + })(); + + /* IV3 — Квикфайр сечений */ + (function(){ + const tasks = [ + { q:'Плоскость перпендикулярна оси конуса и пересекает его.', a:'круг' }, + { q:'Осевое сечение — плоскость проходит через ось конуса.', a:'треугольник' }, + { q:'Плоскость параллельна основанию и не совпадает с ним.', a:'круг' }, + { q:'Плоскость проходит через апекс и пересекает основание по хорде.', a:'треугольник' }, + { q:'Плоскость наклонена к основанию под углом 30°, не проходит через апекс, пересекает все образующие.', a:'эллипс' }, + { q:'Плоскость параллельна основанию и проходит через середину высоты.', a:'круг' } + ]; + const list = document.getElementById('p4-iv3-list'); + const scoreEl = document.getElementById('p4-iv3-score'); + const solved = new Set(); + let xpGiven = false; + const NAMES = {'круг':'Круг', 'треугольник':'Равнобедренный треугольник', 'эллипс':'Эллипс'}; + list.innerHTML = tasks.map(function(t, i){ + return '
' + + '
Задание '+(i+1)+'. '+t.q+'
' + + '
' + + '' + + '' + + '' + + '
' + + '' + + '
'; + }).join(''); + renderMath(list); + list.querySelectorAll('button[data-i]').forEach(function(b){ + b.addEventListener('click', function(){ + const i = +b.dataset.i, v = b.dataset.v, t = tasks[i]; + const fb = document.getElementById('p4-iv3-fb-'+i); + if(solved.has(i)) return; + if(v === t.a){ + feedback(fb, true, '✓ Верно — это '+NAMES[t.a]+'.'); + solved.add(i); + scoreEl.textContent = solved.size; + if(solved.size === tasks.length && !xpGiven){ + xpGiven = true; + addXp(15, 'p4-iv3'); + bumpProgress('p4', 25); + } + } else { + feedback(fb, false, '✗ Не то. Подумай ещё раз — где плоскость пересекает образующие?'); + } + }); + }); + })(); + + /* IV4 — Тренажёр V, S, l, угол развёртки */ + (function(){ + const tasks = [ + { q:'Конус: $R=3$, $h=4$. Найди $V$ (с $\\pi\\approx 3{,}14$).', a:37.68, tol:0.1 }, + { q:'Тот же конус ($R=3$, $h=4$). Образующая $l=\\,?$', a:5, tol:0.05 }, + { q:'Тот же конус ($R=3$, $h=4$). $S_{бок}=\\,?$ (с $\\pi\\approx 3{,}14$)', a:47.1, tol:0.1 }, + { q:'Тот же конус ($R=3$, $h=4$). $S_{полн}=\\,?$ (с $\\pi\\approx 3{,}14$)', a:75.36, tol:0.1 }, + { q:'Конус: $R=6$, $l=10$. Высота $h=\\,?$', a:8, tol:0.05 }, + { q:'Конус $R=3$, $l=6$. Угол развёртки $\\varphi=\\,?$ (в градусах)', a:180, tol:0.5 } + ]; + const list = document.getElementById('p4-iv4-list'); + const scoreEl = document.getElementById('p4-iv4-score'); + const solved = new Set(); + let xpGiven = false; + list.innerHTML = tasks.map(function(t, i){ + return '
' + + '
Задача '+(i+1)+'. '+t.q+'
' + + '
' + + '' + + '' + + '
' + + '' + + '
'; + }).join(''); + renderMath(list); + list.querySelectorAll('button[data-i]').forEach(function(b){ + b.addEventListener('click', function(){ + const i = +b.dataset.i, t = tasks[i]; + const inp = document.getElementById('p4-iv4-inp-'+i); + const fb = document.getElementById('p4-iv4-fb-'+i); + const raw = (inp.value || '').replace(',', '.').trim(); + const val = parseFloat(raw); + if(!isFinite(val)){ feedback(fb, false, '✗ Введи число'); return; } + if(Math.abs(val - t.a) <= t.tol){ + feedback(fb, true, '✓ Верно!'); + if(!solved.has(i)){ + solved.add(i); + scoreEl.textContent = solved.size; + if(solved.size === tasks.length && !xpGiven){ + xpGiven = true; + addXp(15, 'p4-iv4'); + bumpProgress('p4', 25); + setTimeout(function(){ achievement('p4_done'); }, 400); + } + } + } else { + feedback(fb, false, '✗ Не точно. Пересчитай аккуратно (используй $\\pi\\approx 3{,}14$).'); + } + }); + }); + })(); + + wireReadBtn('p4'); +} + /* ===== STUB BUILDER — единый для всех параграфов раздела (Phase 0) ===== */ function buildStub(id){