From 70c6fe0054fff2261cede4f138d721e611251027 Mon Sep 17 00:00:00 2001 From: Maxim Dolgolyov Date: Thu, 28 May 2026 15:14:59 +0300 Subject: [PATCH] =?UTF-8?q?feat(geom8):=20Wave=205=20=E2=80=94=20=D1=84?= =?UTF-8?q?=D0=B8=D0=BD=D0=B0=D0=BB=20=D0=93=D0=BB=D0=B0=D0=B2=D1=8B=203?= =?UTF-8?q?=20(=D1=88=D0=BF=D0=B0=D1=80=D0=B3=D0=B0=D0=BB=D0=BA=D0=B0,=20?= =?UTF-8?q?=D0=BA=D0=B0=D1=80=D1=82=D0=B0=20=D1=81=D0=B2=D1=8F=D0=B7=D0=B5?= =?UTF-8?q?=D0=B9,=207=20=D0=B1=D0=BE=D1=81=D1=81=D0=BE=D0=B2)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Часть 1 — Итоговая шпаргалка: 9 mini-cards с SVG-иконкой и формулой в KaTeX для каждого § (от Фалеса до отношения площадей). Часть 2 — Интерактивная карта связей (SVG 620×340): центральный узел 'Подобие треугольников' → 3 признака (УУ, СУС, ССС) → следствия (Фалес, прямая||стороне, биссектриса, площади, m:n). Клик подсвечивает связи и показывает описание с KaTeX. Часть 3 — 7 боссов (по 10 XP): Босс 1: параллель MN — k=8/12, AN=12 Босс 2: биссектриса AB=15 AC=10 BC=14 — BD=8.4, DC=5.6 Босс 3: УУ+площади k=1.5, S=12 — S'=27 Босс 4: деление 20 см в 3:2 — AC=12, CB=8 Босс 5: СУС+косинус AB=8 AC=12 ∠=60° k=1.5 — A'B'=12, A'C'=18, BC≈11 Босс 6: высоты и площади k=2 — h'=3, S=36 Босс 7: средняя линия M середина AB, MN∥BC — MN=10.5, AN/NC=1, ratio=0.25 Часть 4 — Финальная плашка: confetti + achievement 'Мастер подобия Главы 3' + 50 XP бонус + кнопка перехода к Главе 4. File: 4095 → 4709 LOC. ГЛАВА 3 ПОЛНОСТЬЮ ЗАВЕРШЕНА. Co-Authored-By: Claude Opus 4.7 (1M context) --- frontend/textbooks/geometry_8_ch3.html | 617 ++++++++++++++++++++++++- 1 file changed, 615 insertions(+), 2 deletions(-) diff --git a/frontend/textbooks/geometry_8_ch3.html b/frontend/textbooks/geometry_8_ch3.html index 5ce773e..77fb371 100644 --- a/frontend/textbooks/geometry_8_ch3.html +++ b/frontend/textbooks/geometry_8_ch3.html @@ -339,7 +339,7 @@ const PARAS=[ function buildParaSelector(){const g=document.getElementById('psel-grid');g.innerHTML='';PARAS.forEach(p=>{const card=document.createElement('div');card.className='psel-card'+(p.final?' final':'');card.dataset.id=p.id;card.dataset.progCard=p.id;card.innerHTML=`
${p.num}
${p.name}
`;card.addEventListener('click',()=>goTo(p.id));g.appendChild(card);});} const BUILT=new Set(); -const BUILDERS={p1:()=>buildP1(),p2:()=>buildP2(),p3:()=>buildP3(),p4:()=>buildP4(),p5:()=>buildP5(),p6:()=>buildP6(),p7:()=>buildP7(),p8:()=>buildP8(),p9:()=>buildP9(),final3:()=>buildFinal3stub()}; +const BUILDERS={p1:()=>buildP1(),p2:()=>buildP2(),p3:()=>buildP3(),p4:()=>buildP4(),p5:()=>buildP5(),p6:()=>buildP6(),p7:()=>buildP7(),p8:()=>buildP8(),p9:()=>buildP9(),final3:()=>buildFinal3()}; 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);document.querySelectorAll('.sec').forEach(s=>s.classList.remove('active'));const el=document.getElementById('sec-'+id);if(el)el.classList.add('active');document.querySelectorAll('.psel-card').forEach(c=>c.classList.toggle('active',c.dataset.id===id));buildSidebar(id);window.scrollTo({top:0,behavior:'smooth'});if((STATE.progress[id]||0)<10)bumpProgress(id,10);if(window.renderMathInElement)setTimeout(()=>renderMath(el),0);setTimeout(()=>{try{wrapGlossary(el);}catch(e){}},60);markLastPara(id);} @@ -4089,7 +4089,620 @@ function buildP9(){ renderMath(bossBox); })(); } -function buildFinal3stub(){ document.getElementById('final3-body').innerHTML='

Финал главы 3 — Волна 1: боссы и итоги появятся в следующем обновлении.

'+secNav('p9',null); } +function buildFinal3(){ + const box = document.getElementById('final3-body'); + let html = ''; + + /* === ЧАСТЬ 1: Итоговая шпаргалка === */ + html += `
+
+
+ +
+
Итоговая шпаргалка · Вся Глава 3 «Подобные треугольники»
+
+
+
+ +
+
§1 Теорема Фалеса
+
+ + + + + + + A + B + C + +
+

$\dfrac{AB}{BC} = \dfrac{A'B'}{B'C'}$

+

параллельные прямые

+
+
+
+ +
+
§2 Деление m:n
+
+ + + + + + A + C + B + m + n + +
+

$AC = \dfrac{m}{m+n}\cdot AB$

+

$C$ делит $AB$ в $m{:}n$

+
+
+
+ +
+
§3 Подобие треугольников
+
+

$\triangle ABC \sim \triangle A'B'C'$

+

$\dfrac{a}{a'} = \dfrac{b}{b'} = \dfrac{c}{c'} = k$

+

углы попарно равны

+
+
+ +
+
§4 Прямая || стороне
+
+ + + + + + A + B + C + M + N + +
+

$MN \parallel BC$

+

$\Rightarrow \triangle AMN \sim \triangle ABC$

+

$k = AM/AB$

+
+
+
+ +
+
§5 Признак УУ (AA)
+
+ + + + A + B + C + +
+

$\angle A = \angle A'$

+

$\angle B = \angle B'$

+

$\Rightarrow$ подобны

+
+
+
+ +
+
§6 Признак СУС (SAS)
+
+

$\dfrac{AB}{A'B'} = \dfrac{AC}{A'C'}$

+

$\angle A = \angle A'$

+

$\Rightarrow$ подобны (СУС)

+
+
+ +
+
§7 Признак ССС (SSS)
+
+

$\dfrac{a}{a'} = \dfrac{b}{b'} = \dfrac{c}{c'}$

+

$\Rightarrow$ подобны (ССС)

+

три пары сторон

+
+
+ +
+
§8 Биссектриса
+
+ + + + + A + B + C + D + +
+

$\dfrac{BD}{DC} = \dfrac{AB}{AC}$

+

$AD$ — биссектриса $\angle A$

+
+
+
+ +
+
§9 Площади подобных
+
+

$\dfrac{S_1}{S_2} = k^2$

+

$k$ — коэффициент подобия

+

площади ~ квадрату $k$

+
+
+ +
+
+
`; + + /* === ЧАСТЬ 2: Карта связей === */ + html += `
+
КАРТА СВЯЗЕЙ
Признаки подобия и следствия
+
Нажми на узел, чтобы увидеть формулировку и способ применения.
+
+
Нажми на узел в схеме выше
+
`; + + /* === ЧАСТЬ 3: 7 боссов главы === */ + html += `
+
+ 7 БОССОВ ГЛАВЫ 3 +
Интегрированные задачи
+
+
Каждая задача объединяет 2–3 темы главы. +10 XP за каждого побеждённого босса. Победи всех семерых — получишь +50 XP и достижение «Мастер подобия Главы 3»!
+
+
`; + + /* === ЧАСТЬ 4: Финальная плашка === */ + html += ``; + + html += `
+ +
`; + + html += secNav('p9', null); + box.innerHTML = html; + + /* === JS: Карта связей SVG === */ + (function(){ + const W = 620, H = 340; + const nodes = [ + { id:'sim', x:310, y:28, rx:62, label:'Подобие треугольников', + props:'Два треугольника подобны, если углы попарно равны и стороны пропорциональны. $\\triangle ABC \\sim \\triangle A\'B\'C\'$, коэффициент $k$.' }, + { id:'aa', x:100, y:120, rx:54, label:'УУ (AA)', + props:'§5: Если два угла одного треугольника равны двум углам другого — треугольники подобны. Наиболее часто применяемый признак.' }, + { id:'sas', x:310, y:120, rx:54, label:'СУС (SAS)', + props:'§6: Два треугольника подобны, если две стороны пропорциональны и угол между ними равен: $\\dfrac{AB}{A\'B\'} = \\dfrac{AC}{A\'C\'}$, $\\angle A = \\angle A\'$.' }, + { id:'sss', x:510, y:120, rx:54, label:'ССС (SSS)', + props:'§7: Три треугольника подобны, если все три пары сторон пропорциональны: $\\dfrac{a}{a\'} = \\dfrac{b}{b\'} = \\dfrac{c}{c\'}$.' }, + { id:'fales', x:80, y:230, rx:52, label:'Теорема Фалеса', + props:'§1: Параллельные прямые отсекают пропорциональные отрезки на двух секущих. $\\dfrac{AB}{BC} = \\dfrac{A\'B\'}{B\'C\'}$.' }, + { id:'paral', x:230, y:230, rx:52, label:'Прямая || стороне', + props:'§4: $MN \\parallel BC \\Rightarrow \\triangle AMN \\sim \\triangle ABC$ с $k = AM/AB$. Следует из теоремы Фалеса + признак УУ.' }, + { id:'biss', x:390, y:230, rx:52, label:'Биссектриса', + props:'§8: Биссектриса $AD$ треугольника $ABC$ делит сторону $BC$ в отношении: $\\dfrac{BD}{DC} = \\dfrac{AB}{AC}$. Доказывается через подобие.' }, + { id:'areas', x:540, y:230, rx:52, label:'Площади $S_1/S_2$', + props:'§9: Отношение площадей подобных треугольников равно квадрату коэффициента подобия: $\\dfrac{S_1}{S_2} = k^2$.' }, + { id:'div', x:150, y:310, rx:50, label:'Деление m:n', + props:'§2: Точка $C$ делит $AB$ в отношении $m:n$: $AC = \\dfrac{m}{m+n}\\cdot AB$, $CB = \\dfrac{n}{m+n}\\cdot AB$.' }, + ]; + const edges = [ + ['sim','aa'],['sim','sas'],['sim','sss'], + ['aa','paral'],['fales','paral'],['aa','biss'], + ['sim','areas'],['paral','div'], + ]; + let sel = null; + function draw(selId){ + const colors = { sim:'#7c3aed', aa:'#4f46e5', sas:'#8b5cf6', sss:'#6366f1', fales:'#2563eb', paral:'#0891b2', biss:'#c026d3', areas:'#059669', div:'#d97706' }; + let s = ``; + s += ``; + edges.forEach(([a,b])=>{ + const na=nodes.find(n=>n.id===a), nb=nodes.find(n=>n.id===b); + if(!na||!nb) return; + const dx=nb.x-na.x, dy=nb.y-na.y, len=Math.sqrt(dx*dx+dy*dy); + if(len<1) return; + const sy_r=na.rx*0.52; + const sx=na.x+dx/len*na.rx, sy2=na.y+dy/len*sy_r; + const ex=nb.x-dx/len*(nb.rx+7), ey=nb.y-dy/len*(nb.rx*0.52+7); + const isAct = selId===a||selId===b; + s += ``; + }); + nodes.forEach(n=>{ + const isS = selId===n.id; + const col = colors[n.id] || '#7c3aed'; + const ry = n.rx * 0.52; + s += ``; + const words = n.label.split(' '); + const line1 = words.slice(0,2).join(' '), line2 = words.slice(2).join(' '); + const tc = isS ? '#fff' : col; + if(line2){ + s += `${line1}`; + s += `${line2}`; + } else { + s += `${line1}`; + } + }); + s += ''; + document.getElementById('final3-map-svg').innerHTML = s; + document.getElementById('final3-map-svg').querySelector('svg').addEventListener('click', function(e){ + const el = e.target.closest('[data-nid]'); + if(!el) return; + const nid = el.dataset.nid; + sel = (sel===nid) ? null : nid; + const nd = nodes.find(n=>n.id===nid); + if(sel && nd){ document.getElementById('final3-map-info').innerHTML = '' + nd.label + ': ' + nd.props; renderMath(document.getElementById('final3-map-info')); } + else document.getElementById('final3-map-info').textContent = 'Нажми на узел в схеме выше'; + draw(sel); + }); + } + draw(null); + })(); + + /* === JS: 7 боссов === */ + (function(){ + const bosses = [ + { + n: 1, + title: 'Параллель и пропорция', + color: '#4f46e5', + svg: ` + + + + + + + + + + + + + + A + B + C + M + N + + AB=12 + AM=8 + AC=18 + MN=? + `, + cond: 'В $\\triangle ABC$: $AB = 12$, $AC = 18$, $MN \\parallel BC$, $AM = 8$. (§1, §4)', + parts: [ + { label: 'Найди коэффициент подобия $k = AM/AB$.', ans: 0.667, tol: 0.005, hint: '$k = AM/AB = 8/12 = 2/3 \\approx 0{,}667$' }, + { label: 'Найди $AN$ (используй $AN/AC = k$).', ans: 12, hint: '$AN = k \\cdot AC = \\dfrac{2}{3} \\cdot 18 = 12$' }, + ], + }, + { + n: 2, + title: 'Биссектриса треугольника', + color: '#c026d3', + svg: ` + + + + + + + + + + A + B + C + D + + + + AB=15 + AC=10 + BC=14 + D=? + `, + cond: 'В $\\triangle ABC$: $AB = 15$, $AC = 10$, $BC = 14$. $AD$ — биссектриса угла $A$. (§8)', + parts: [ + { label: 'Найди $BD$ (используй $BD/DC = AB/AC = 15/10$, $BD + DC = 14$).', ans: 8.4, tol: 0.05, hint: '$BD/DC = 3/2$, $BD = 14 \\cdot 3/5 = 8{,}4$' }, + { label: 'Найди $DC$.', ans: 5.6, tol: 0.05, hint: '$DC = 14 - BD = 14 - 8{,}4 = 5{,}6$' }, + ], + }, + { + n: 3, + title: 'Признак УУ и площади', + color: '#059669', + svg: ` + + + + + + + + + + + + + A + B + C + + A' + B' + C' + + AB=6 + A'B'=9 + S=12 + `, + cond: '$\\triangle ABC \\sim \\triangle A\'B\'C\'$ по двум углам. $AB = 6$, $A\'B\' = 9$, $S_{\\triangle ABC} = 12$ см². (§5, §9)', + parts: [ + { label: 'Найди коэффициент подобия $k = A\'B\'/AB$.', ans: 1.5, tol: 0.01, hint: '$k = 9/6 = 1{,}5$' }, + { label: 'Найди $S_{\\triangle A\'B\'C\'}$ (используй $S\'/S = k^2$).', ans: 27, hint: '$S\' = k^2 \\cdot S = 2{,}25 \\cdot 12 = 27$ см²' }, + ], + }, + { + n: 4, + title: 'Деление отрезка в отношении', + color: '#d97706', + svg: ` + + + + + + + + + + + A + C + B + + AC=? + CB=? + + 3 + 2 + AB = 20 см, AC:CB = 3:2 + `, + cond: 'Отрезок $AB = 20$ см. Точка $C$ делит $AB$ в отношении $AC{:}CB = 3{:}2$. (§2)', + parts: [ + { label: 'Найди $AC$ (см).', ans: 12, hint: '$AC = \\dfrac{3}{3+2} \\cdot 20 = 12$ см' }, + { label: 'Найди $CB$ (см).', ans: 8, hint: '$CB = \\dfrac{2}{5} \\cdot 20 = 8$ см' }, + ], + }, + { + n: 5, + title: 'СУС: стороны и косинус', + color: '#8b5cf6', + svg: ` + + + + + 60° + + + + + + A + B + C + + AB=8 + AC=12 + + k=1.5 + A'B'=? + A'C'=? + B'C'=? + `, + cond: '$\\triangle ABC \\sim \\triangle A\'B\'C\'$ (по СУС). $AB = 8$, $AC = 12$, $\\angle A = 60°$, $k = 1{,}5$. (§6)', + parts: [ + { label: 'Найди $A\'B\'$ (см).', ans: 12, hint: '$A\'B\' = k \\cdot AB = 1{,}5 \\cdot 8 = 12$' }, + { label: 'Найди $A\'C\'$ (см).', ans: 18, hint: '$A\'C\' = k \\cdot AC = 1{,}5 \\cdot 12 = 18$' }, + { label: 'Найди $BC$ по теореме косинусов: $BC^2 = AB^2+AC^2-2\\cdot AB\\cdot AC\\cdot\\cos60°$. Введи $BC$ (целое).', ans: 4, tol: 0.5, hint: '$BC^2 = 64+144-2\\cdot8\\cdot12\\cdot0{,}5 = 208-96=112$. Нет, пересчитаем: $BC^2=64+144-96=112 \\Rightarrow BC\\approx 10{,}58$. Округли до $11$.', _override: true, _ans_exact: 11, _tol_exact: 0.5, _hint_fix: 'По теореме косинусов: $BC^2 = 8^2+12^2-2\\cdot8\\cdot12\\cdot\\cos60° = 64+144-96=112$, $BC=\\sqrt{112}\\approx 10{,}58 \\approx 11$' }, + ], + }, + { + n: 6, + title: 'Высоты и площади подобных', + color: '#0891b2', + svg: ` + + + + + + + + + + + + + + + + + + + + + A + B + C + + A' + B' + C' + + h=6 + h'=? + S'=9 + S=? + k=2 + `, + cond: '$\\triangle ABC \\sim \\triangle A\'B\'C\'$ с коэффициентом $k = 2$ (большой к малому). Высота $h_{ABC} = 6$ см, $S_{A\'B\'C\'} = 9$ см². (§9)', + parts: [ + { label: 'Найди $h\'$ (высоту малого треугольника).', ans: 3, hint: '$h\' = h/k = 6/2 = 3$ см (высоты подобных ~ $k$)' }, + { label: 'Найди $S_{ABC}$ (площадь большего треугольника).', ans: 36, hint: '$S/S\' = k^2 = 4 \\Rightarrow S = 4 \\cdot 9 = 36$ см²' }, + ], + }, + { + n: 7, + title: 'Средняя линия и площади', + color: '#16a34a', + svg: ` + + + + + + + + + + + + + + A + B + C + M + N + + AB=14 + BC=21 + MN=? + `, + cond: 'В $\\triangle ABC$: $AB = 14$, $BC = 21$. $M$ — середина $AB$, $N$ на $AC$ так, что $MN \\parallel BC$. (§4, §9)', + parts: [ + { label: 'Найди $MN$ (используй $k = AM/AB = 1/2$, $MN = k \\cdot BC$).', ans: 10.5, tol: 0.05, hint: '$k = 7/14 = 1/2$, $MN = 1/2 \\cdot 21 = 10{,}5$ см' }, + { label: 'Найди $AN/NC$ (какое оно?).', ans: 1, hint: '$M$ — середина $AB \\Rightarrow k = 1/2 \\Rightarrow AN/NC = AM/MB = 1/1$, т.е. $N$ — середина $AC$' }, + { label: 'Найди отношение $S_{\\triangle AMN}/S_{\\triangle ABC}$ (введи как десятичную дробь).', ans: 0.25, tol: 0.01, hint: '$S_{AMN}/S_{ABC} = k^2 = (1/2)^2 = 0{,}25$' }, + ], + }, + ]; + + window.final3BossSolved = new Set(); + const bossBox = document.getElementById('final3-bosses'); + bossBox.innerHTML = bosses.map(b => { + const partsHtml = b.parts.map((p,pi) => { + return `
+
${p.label}
+
+ + + +
+ +
`; + }).join(''); + + const svgHtml = b.svg ? `
${b.svg}
` : ''; + + return `
+
+ БОСС ${b.n} + ${b.title} + +
+
${b.cond}
+ ${svgHtml} + ${partsHtml} +
`; + }).join(''); + + function checkPart(bi, pi){ + const boss = bosses[bi]; + const part = boss.parts[pi]; + const inp = bossBox.querySelector(`.final3-boss-inp[data-b="${bi}"][data-p="${pi}"]`); + const fb = bossBox.querySelector(`.final3-boss-fb[data-b="${bi}"][data-p="${pi}"]`); + const ok = bossBox.querySelector(`.final3-boss-ok[data-b="${bi}"][data-p="${pi}"]`); + if(!inp) return; + const val = parseFloat(inp.value); + const useExact = part._override && part._ans_exact !== undefined; + const ansCheck = useExact ? part._ans_exact : part.ans; + const tolCheck = useExact ? part._tol_exact : (part.tol !== undefined ? part.tol : 0); + const hintText = useExact ? part._hint_fix : part.hint; + if(Math.abs(val - ansCheck) <= tolCheck){ + feedback(fb, true, 'Верно! ' + (hintText ? '
' + hintText + '' : '')); + inp.disabled = true; + const btn = bossBox.querySelector(`.final3-boss-check[data-b="${bi}"][data-p="${pi}"]`); + if(btn) btn.disabled = true; + if(ok) ok.style.display = 'inline'; + const allDone = boss.parts.every((_,pj) => { + const el = bossBox.querySelector(`.final3-boss-inp[data-b="${bi}"][data-p="${pj}"]`); + return el && el.disabled; + }); + if(allDone && !window.final3BossSolved.has(bi)){ + window.final3BossSolved.add(bi); + addXp(10, 'final3-boss-' + (bi+1)); + const xpBadge = document.getElementById('final3-boss-xp-' + bi); + if(xpBadge) xpBadge.style.display = 'inline'; + bumpProgress('final3', 8); + if(window.final3BossSolved.size === bosses.length){ + setTimeout(()=>{ + confetti(); + if(!STATE.achievements.has('final3-master')){ + STATE.achievements.set('final3-master', 'Мастер подобия Главы 3'); + saveProgress(); + const pop = document.getElementById('ach-popup'); + if(pop){ document.getElementById('ach-text').textContent = 'Мастер подобия Главы 3!'; pop.classList.add('show'); setTimeout(()=>pop.classList.remove('show'), 4000); } + } + addXp(50, 'final3-all-bosses'); + bumpProgress('final3', 20); + const fin = document.getElementById('final3-finish'); + if(fin) fin.style.display = 'block'; + }, 500); + } + } + } else { + feedback(fb, false, 'Неверно. Подсказка: ' + (hintText || part.hint)); + } + } + + bossBox.querySelectorAll('.final3-boss-check').forEach(btn=>{ + btn.addEventListener('click', ()=>{ checkPart(+btn.dataset.b, +btn.dataset.p); }); + }); + bossBox.querySelectorAll('.final3-boss-inp').forEach(inp=>{ + inp.addEventListener('keydown', e=>{ if(e.key==='Enter'){ const btn=bossBox.querySelector(`.final3-boss-check[data-b="${inp.dataset.b}"][data-p="${inp.dataset.p}"]`); if(btn)btn.click(); } }); + }); + })(); + + renderMath(box); +}