diff --git a/frontend/textbooks/geometry_8_ch3.html b/frontend/textbooks/geometry_8_ch3.html
index 97f27d1..5ce773e 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:()=>buildP8stub(),p9:()=>buildP9stub(),final3:()=>buildFinal3stub()};
+const BUILDERS={p1:()=>buildP1(),p2:()=>buildP2(),p3:()=>buildP3(),p4:()=>buildP4(),p5:()=>buildP5(),p6:()=>buildP6(),p7:()=>buildP7(),p8:()=>buildP8(),p9:()=>buildP9(),final3:()=>buildFinal3stub()};
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);}
@@ -3226,8 +3226,869 @@ function buildP7(){
renderMath(bossBox);
})();
}
-function buildP8stub(){ document.getElementById('p8-body').innerHTML='§8 — Волна 1 : содержимое появится в следующем обновлении.
'+secNav('p7','p9'); }
-function buildP9stub(){ document.getElementById('p9-body').innerHTML='§9 — Волна 1 : содержимое появится в следующем обновлении.
'+secNav('p8','final3'); }
+function buildP8(){
+ const box=document.getElementById('p8-body');
+ let html='';
+
+ /* ---- Theory cards ---- */
+ html+=makeCard('theory','Свойство биссектрисы треугольника','8.1',`
+ Теорема. Биссектриса угла треугольника делит противоположную сторону на отрезки, пропорциональные двум другим сторонам.
+ В $\\triangle ABC$, $AD$ — биссектриса $\\angle A$ ($D \\in BC$). Тогда:
+ $$\\dfrac{BD}{DC} = \\dfrac{AB}{AC} = \\dfrac{c}{b}$$
+ Здесь $c = AB$, $b = AC$. Биссектриса делит отрезок $BC$ в отношении смежных (прилежащих к нему) сторон.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ A
+ B
+ C
+ D
+
+ c=AB
+ b=AC
+
+ BD
+ DC
+
+ AD — биссектриса
+ BD/DC = AB/AC = c/b
+
+
`);
+
+ html+=makeCard('rule','Доказательство — через параллельную прямую','8.2',`
+ Метод доказательства: через точку $C$ проводим прямую, параллельную биссектрисе $AD$, до пересечения с продолжением стороны $AB$ в точке $E$.
+
+ $CE \\parallel AD$, $AD$ — биссектриса $\\angle A$ → $\\angle 1 = \\angle 2$ (смежно-внутренние при секущей $AB$).
+ $\\angle 2 = \\angle 3$ (вертикальные углы при пересечении $CE$ и $AB$ ... скорректировано: соответственные углы при параллельных). Значит $\\angle 1 = \\angle 3$, т.е. $\\triangle ACE$ — равнобедренный: $AE = AC = b$.
+ По теореме Фалеса (прямая $AD \\parallel CE$, секущие $BA$ и $BC$): $\\dfrac{BD}{DC} = \\dfrac{BA}{AE} = \\dfrac{c}{b}$.
+
+ Итог: $\\dfrac{BD}{DC} = \\dfrac{c}{b} = \\dfrac{AB}{AC}$. Теорема доказана.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ A
+ B
+ C
+ D
+ E
+ CE ∥ AD
+ BD/DC = BA/AE = c/b
+
+
`);
+
+ html+=makeCard('example','Примеры применения','8.3',`
+ Пример 1. В $\\triangle ABC$ биссектриса $\\angle A$ делит $BC$. $AB=6$, $AC=9$, $BC=15$. Найти $BD$ и $DC$.
+ $\\dfrac{BD}{DC} = \\dfrac{AB}{AC} = \\dfrac{6}{9} = \\dfrac{2}{3}$. Сумма $BD+DC=15$. Тогда $BD = \\dfrac{2}{5} \\cdot 15 = 6$, $DC = 9$.
+ Пример 2. $AB=8$, $AC=12$, $BD=4$. Найти $DC$.
+ $\\dfrac{4}{DC} = \\dfrac{8}{12}$ → $DC = \\dfrac{4 \\cdot 12}{8} = 6$.
+ Пример 3. $BD=5$, $DC=7$. Найти $AB$, если $AC=14$.
+ $\\dfrac{AB}{AC} = \\dfrac{BD}{DC} = \\dfrac{5}{7}$ → $AB = \\dfrac{5 \\cdot 14}{7} = 10$.
`);
+
+ /* ---- ИНТЕРАКТИВ 1: SVG с биссектрисой (слайдеры AB, AC) ---- */
+ html+=`
+
+
Меняй стороны $AB$ и $AC$ — точка $D$ автоматически делит $BC$ в отношении $AB:AC$. Цвета: BD — зелёный, DC — синий.
+
+ $AB = c$: 6
+
+
+ $AC = b$: 9
+
+
+ $BC$: 12
+
+
+
+
+
+
`;
+
+ /* ---- ИНТЕРАКТИВ 2: Пошаговое доказательство ---- */
+ html+=`
+
+
Нажимай «Далее» для каждого шага. Доказательство через параллельную прямую.
+
+
+
+ Далее
+ Сначала
+
+
`;
+
+ /* ---- ИНТЕРАКТИВ 3: Калькулятор биссектрисы ---- */
+ html+=`
+
+
Введи три стороны треугольника и получи отрезки $BD$, $DC$, которые образует биссектриса.
+
+
AB = c
+
AC = b
+
BC
+
Вычислить
+
+
+
`;
+
+ /* ---- ИНТЕРАКТИВ 4: Тренажёр ---- */
+ html+=`
+
+
5 задач на нахождение отрезков BD, DC и сторон по свойству биссектрисы.
+
Задача 1 / 5 Очки: 0
+
+
+
+ Проверить
+ Начать
+
+
+
`;
+
+ /* ---- ИНТЕРАКТИВ 5: DnD-сортер ---- */
+ html+=`
+
+
Перетащи каждую карточку: если биссектриса с данными $AB$, $AC$ действительно делит $BC$ в указанном отношении — в «Верно», иначе — «Неверно».
+
+
+
Проверить Сбросить
+
+
`;
+
+ /* ---- ИНТЕРАКТИВ 6: Босс §8 ---- */
+ html+=`
+
+
4 задачи — каждая верная даёт +5 XP.
+
+
`;
+
+ html+=`
+
+
+ Я прочитал §8 (+10 XP)
+
+
`;
+ html+=secNav('p7','p9');
+ box.innerHTML=html;
+ if(window.renderMathInElement) setTimeout(()=>renderMath(box),0);
+
+ /* == INIT ИНТЕРАКТИВ 1: живой SVG биссектрисы == */
+ (function(){
+ const cSl=document.getElementById('p8-c-sl');
+ const bSl=document.getElementById('p8-b-sl');
+ const aSl=document.getElementById('p8-a-sl');
+ const cVal=document.getElementById('p8-c-val');
+ const bVal=document.getElementById('p8-b-val');
+ const aVal=document.getElementById('p8-a-val');
+ const svgOut=document.getElementById('p8-svg-out');
+ const infoEl=document.getElementById('p8-svg-info');
+
+ function draw(){
+ const c=+cSl.value, b=+bSl.value, a=+aSl.value;
+ cVal.textContent=c; bVal.textContent=b; aVal.textContent=a;
+
+ // Triangle: B=(40,170), C=(40+a*16,170) — scaled horizontally
+ // A somewhere above — use fixed A position for clear view
+ // Place B at left, C at right on baseline, A above
+ const W=400, H=200;
+ const scale=Math.min(14, Math.floor(320/a));
+ const Bx=40, By=170;
+ const Cx=Bx+a*scale, Cy=170;
+ // A: place using sides c=AB, b=AC
+ // AB=c, AC=b. Place A using cosine rule for angle B:
+ // cos B = (c^2 + a^2 - b^2)/(2*c*a)
+ const cosB=(c*c+a*a-b*b)/(2*c*a);
+ if(cosB<-0.999||cosB>0.999||!isFinite(cosB)){
+ svgOut.innerHTML='Нарушено треугольное неравенство. Измени стороны.
';
+ infoEl.innerHTML='Некорректные стороны.';
+ return;
+ }
+ const sinB=Math.sqrt(1-cosB*cosB);
+ const Ax=Bx+c*scale*cosB;
+ const Ay=By-c*scale*sinB;
+
+ // D divides BC: BD/DC = c/b → BD = a*c/(b+c)
+ const BD=a*c/(b+c);
+ const DC=a*b/(b+c);
+ const Dx=Bx+BD*scale;
+ const Dy=By;
+
+ let s=``;
+ // triangle
+ s+=` `;
+ // BD segment green
+ s+=` `;
+ // DC segment blue
+ s+=` `;
+ // bisector AD
+ s+=` `;
+ // D point
+ s+=` `;
+ // Vertices
+ s+=` `;
+ s+=` `;
+ s+=` `;
+ // Labels
+ const ax=Ax, ay=Ay;
+ s+=`A `;
+ s+=`B `;
+ s+=`C `;
+ s+=`D `;
+ // Side labels
+ const mABx=(ax+Bx)/2, mABy=(ay+By)/2;
+ const mACx=(ax+Cx)/2, mACy=(ay+Cy)/2;
+ s+=`c=${c} `;
+ s+=`b=${b} `;
+ // BD DC midpoints
+ const mBDx=(Bx+Dx)/2, mDCx=(Dx+Cx)/2;
+ s+=`BD=${fmt(BD)} `;
+ s+=`DC=${fmt(DC)} `;
+ s+=`BD/DC = ${fmt(BD)}/${fmt(DC)} = ${fmt(c)}/${fmt(b)} = ${fmt(c/b)} `;
+ s+=' ';
+ svgOut.innerHTML=s;
+ infoEl.innerHTML=`$AB=c=${c}$, $AC=b=${b}$, $BC=${a}$. Биссектриса $AD$ делит $BC$: $BD=${fmt(BD)}$, $DC=${fmt(DC)}$. $\\dfrac{BD}{DC}=\\dfrac{${c}}{${b}}=${fmt(c/b)}$ — совпадает с $\\dfrac{AB}{AC}$.`;
+ renderMath(infoEl);
+ addXp(1,'p8-svg');
+ }
+ cSl.addEventListener('input',draw);
+ bSl.addEventListener('input',draw);
+ aSl.addEventListener('input',draw);
+ draw();
+ })();
+
+ /* == INIT ИНТЕРАКТИВ 2: пошаговое доказательство == */
+ (function(){
+ const steps=[
+ {desc:'Шаг 1. Дано: $\\triangle ABC$, $AD$ — биссектриса $\\angle A$ ($D \\in BC$). Нужно доказать: $\\dfrac{BD}{DC} = \\dfrac{AB}{AC}$.',
+ svg:`A B C D AD — биссектриса ∠A, D ∈ BC `},
+ {desc:'Шаг 2. Через вершину $C$ проводим прямую $CE \\parallel AD$ до пересечения с продолжением стороны $AB$ в точке $E$.',
+ svg:`A B C D E CE ∥ AD `},
+ {desc:'Шаг 3. Так как $CE \\parallel AD$ и $AD$ — биссектриса: $\\angle 1 = \\angle DAB$ (смежно-внутренние при секущей $AB$), $\\angle 2 = \\angle DAC$ (соответственные при секущей $AC$). Поскольку $\\angle DAB = \\angle DAC$ (биссектриса!), то $\\angle 1 = \\angle 2$. В $\\triangle ACE$: $\\angle AEC = \\angle 1$, $\\angle ACE = \\angle 2$ → $\\angle AEC = \\angle ACE$ → $\\triangle ACE$ равнобедренный, $AE = AC = b$.',
+ svg:`CE ∥ AD, AD — биссектриса ∠A ∠AEC = ∠ACE → △ACE равнобедренный AE = AC = b Ключевой шаг доказательства `},
+ {desc:'Шаг 4. По теореме Фалеса (параллельные $AD \\parallel CE$, секущие $BA$ и $BC$): $\\dfrac{BD}{DC} = \\dfrac{BA}{AE}$.',
+ svg:`Теорема Фалеса: AD ∥ CE BD/DC = BA/AE секущие BA и BC пересекают параллельные AD и CE Теорема Фалеса — §1 этой главы `},
+ {desc:'Шаг 5. Подставляем $AE = AC = b$ (шаг 3): $\\dfrac{BD}{DC} = \\dfrac{BA}{AE} = \\dfrac{c}{b} = \\dfrac{AB}{AC}$. Теорема доказана. ',
+ svg:`BD/DC = BA/AE = c/b = AB/AC Биссектриса делит BC в отношении AB:AC QED ∎ `},
+ ];
+ let step=0;
+ const svgEl=document.getElementById('p8-proof-svg');
+ const descEl=document.getElementById('p8-proof-desc');
+ function show(){svgEl.innerHTML=steps[step].svg;descEl.innerHTML=steps[step].desc;renderMath(descEl);}
+ document.getElementById('p8-proof-next').addEventListener('click',()=>{
+ if(step{step=0;show();});
+ show();
+ })();
+
+ /* == INIT ИНТЕРАКТИВ 3: калькулятор == */
+ (function(){
+ document.getElementById('p8-kcalc').addEventListener('click',()=>{
+ const c=parseFloat(document.getElementById('p8-kc').value);
+ const b=parseFloat(document.getElementById('p8-kb').value);
+ const a=parseFloat(document.getElementById('p8-ka').value);
+ const out=document.getElementById('p8-kcalc-out');
+ if([c,b,a].some(v=>!isFinite(v)||v<=0)){
+ out.style.display='block';out.innerHTML='Введи все три значения (положительные числа). ';return;
+ }
+ const BD=a*c/(b+c);
+ const DC=a*b/(b+c);
+ out.style.display='block';
+ out.innerHTML=`$\\dfrac{BD}{DC} = \\dfrac{AB}{AC} = \\dfrac{${fmt(c)}}{${fmt(b)}}$. $BC = ${fmt(a)}$, поэтому: $BD = \\dfrac{c}{b+c} \\cdot BC = \\dfrac{${fmt(c)}}{${fmt(b+c)}} \\cdot ${fmt(a)} = ${fmt(BD)} $. $DC = \\dfrac{b}{b+c} \\cdot BC = \\dfrac{${fmt(b)}}{${fmt(b+c)}} \\cdot ${fmt(a)} = ${fmt(DC)} $.`;
+ renderMath(out);
+ addXp(3,'p8-calc');bumpProgress('p8',5);
+ });
+ })();
+
+ /* == INIT ИНТЕРАКТИВ 4: тренажёр == */
+ (function(){
+ const tasks=[
+ {q:'$\\triangle ABC$: $AB=6$, $AC=9$, $BC=15$. Биссектриса $\\angle A$ делит $BC$ в точке $D$. Найди $BD$.',ans:6,hint:'BD/DC = AB/AC = 6/9 = 2/3. BD = 2/(2+3)·15 = 6.'},
+ {q:'$\\triangle ABC$: $AB=8$, $AC=12$, $BD=4$. Биссектриса $\\angle A$ делит $BC$ в точке $D$. Найди $DC$.',ans:6,hint:'BD/DC = AB/AC → 4/DC = 8/12 → DC = 4·12/8 = 6.'},
+ {q:'Биссектриса $\\angle A$ делит $BC$: $BD=5$, $DC=7$, $AC=14$. Найди $AB$.',ans:10,hint:'AB/AC = BD/DC = 5/7 → AB = 5·14/7 = 10.'},
+ {q:'$\\triangle ABC$: $AB=10$, $AC=15$, $BC=20$. Найди $DC$ (биссектриса $\\angle A$).',ans:12,hint:'DC = b/(b+c)·BC = 15/25·20 = 12.'},
+ {q:'Биссектриса $\\angle A$: $AB=4$, $AC=6$, $BD=8$. Найди $BC$.',ans:20,hint:'BD/DC = AB/AC = 4/6 = 2/3 → DC = BD·3/2 = 12. BC = BD+DC = 8+12 = 20.'},
+ ];
+ let idx=0,score=0;
+ function show(){
+ document.getElementById('p8-tr-i').textContent=idx+1;
+ const t=document.getElementById('p8-tr-task');
+ t.innerHTML=tasks[idx].q;
+ renderMath(t);
+ document.getElementById('p8-tr-ans').value='';
+ document.getElementById('p8-tr-fb').style.display='none';
+ }
+ document.getElementById('p8-tr-start').addEventListener('click',()=>{idx=0;score=0;document.getElementById('p8-tr-score').textContent=0;show();});
+ document.getElementById('p8-tr-go').addEventListener('click',()=>{
+ if(idx>=tasks.length)return;
+ const ans=+document.getElementById('p8-tr-ans').value;
+ const fb=document.getElementById('p8-tr-fb');
+ if(Math.abs(ans-tasks[idx].ans)<0.05){
+ score++;document.getElementById('p8-tr-score').textContent=score;
+ addXp(3,'p8-tr-'+idx);bumpProgress('p8',4);
+ if(idxshow(),900);}
+ else{feedback(fb,true,'Все задачи решены! +5 XP');addXp(5,'p8-tr-all');bumpProgress('p8',10);confetti();}
+ } else {
+ feedback(fb,false,'Неверно. '+tasks[idx].hint);
+ }
+ });
+ document.getElementById('p8-tr-ans').addEventListener('keydown',e=>{if(e.key==='Enter')document.getElementById('p8-tr-go').click();});
+ show();
+ })();
+
+ /* == INIT ИНТЕРАКТИВ 5: DnD-сортер == */
+ (function(){
+ const items=[
+ {text:'AB=6, AC=9, BD=4, DC=6',yes:true},
+ {text:'AB=5, AC=8, BD=5, DC=8',yes:true},
+ {text:'AB=4, AC=6, BD=3, DC=5',yes:false},
+ {text:'AB=10, AC=15, BD=8, DC=12',yes:true},
+ {text:'AB=3, AC=7, BD=3, DC=5',yes:false},
+ ];
+ const pool=document.getElementById('p8-dnd-pool');
+ const yesBox=document.getElementById('p8-drop-yes-items');
+ const noBox=document.getElementById('p8-drop-no-items');
+ let dragging=null;
+ function makeChip(it,i){
+ const chip=document.createElement('div');
+ chip.className='dnd-chip';chip.dataset.idx=i;chip.textContent=it.text;chip.draggable=true;
+ chip.addEventListener('dragstart',e=>{dragging=chip;chip.classList.add('dragging');e.dataTransfer.effectAllowed='move';});
+ chip.addEventListener('dragend',()=>{chip.classList.remove('dragging');dragging=null;});
+ return chip;
+ }
+ items.forEach((it,i)=>pool.appendChild(makeChip(it,i)));
+ [document.getElementById('p8-drop-yes'),document.getElementById('p8-drop-no'),pool].forEach(box=>{
+ box.addEventListener('dragover',e=>{e.preventDefault();box.classList.add('over');});
+ box.addEventListener('dragleave',()=>box.classList.remove('over'));
+ box.addEventListener('drop',e=>{
+ e.preventDefault();box.classList.remove('over');
+ if(!dragging)return;
+ const target=box===document.getElementById('p8-drop-yes')?yesBox:box===document.getElementById('p8-drop-no')?noBox:pool;
+ target.appendChild(dragging);
+ });
+ });
+ document.getElementById('p8-dnd-check').addEventListener('click',()=>{
+ const fb=document.getElementById('p8-dnd-fb');
+ const yChips=[...yesBox.querySelectorAll('.dnd-chip')];
+ const nChips=[...noBox.querySelectorAll('.dnd-chip')];
+ if(yChips.length+nChips.length{if(!items[+c.dataset.idx].yes)ok=false;});
+ nChips.forEach(c=>{if(items[+c.dataset.idx].yes)ok=false;});
+ if(ok){feedback(fb,true,'Верно! +5 XP');addXp(5,'p8-dnd');bumpProgress('p8',8);}
+ else{feedback(fb,false,'Есть ошибки. Проверь: BD/DC должно равняться AB/AC.');}
+ });
+ document.getElementById('p8-dnd-reset').addEventListener('click',()=>{
+ [...yesBox.children].forEach(c=>pool.appendChild(c));
+ [...noBox.children].forEach(c=>pool.appendChild(c));
+ document.getElementById('p8-dnd-fb').style.display='none';
+ });
+ })();
+
+ /* == INIT: Босс §8 == */
+ (function(){
+ const tasks=[
+ {q:'A B C D AB=9, AC=12, BC=21 $AB=9$, $AC=12$, $BC=21$. Биссектриса $\\angle A$ делит $BC$ в точке $D$. Найди $BD$.',ans:9,hint:'BD/DC = AB/AC = 9/12 = 3/4. BD = 3/7·21 = 9.'},
+ {q:'Биссектриса $\\angle A$ делит $BC$: $BD=6$, $DC=10$, $BC=16$. $AB=9$. Найди $AC$.',ans:15,hint:'BD/DC = AB/AC → 6/10 = 9/AC → AC = 9·10/6 = 15.'},
+ {q:'В $\\triangle ABC$: $AB=7$, $AC=14$, биссектриса $\\angle A$ делит $BC$ на $BD$ и $DC$. Чему равно $BD$, если $BC=12$?',ans:4,hint:'BD = AB/(AB+AC)·BC = 7/21·12 = 4.'},
+ {q:'Биссектриса $\\angle B$ треугольника $ABC$ делит сторону $AC$ в точке $E$: $AE=6$, $EC=9$. $BC=15$. Найди $AB$.',ans:10,hint:'AE/EC = AB/BC → 6/9 = AB/15 → AB = 6·15/9 = 10.'},
+ ];
+ const bossBox=document.getElementById('p8-boss-tasks');
+ bossBox.innerHTML=tasks.map((t,i)=>`
+
+
${t.q}
+
+
+ Проверить
+
+
+
`).join('');
+ window.p8BossSolved=new Set();
+ renderMath(bossBox);
+ })();
+}
+
+function buildP9(){
+ const box=document.getElementById('p9-body');
+ let html='';
+
+ /* ---- Theory cards ---- */
+ html+=makeCard('theory','Отношение площадей подобных треугольников','9.1',`
+ Теорема. Если $\\triangle ABC \\sim \\triangle A'B'C'$ с коэффициентом подобия $k$, то:
+ $$\\dfrac{S_{ABC}}{S_{A'B'C'}} = k^2$$
+ Площади подобных треугольников относятся как квадрат коэффициента подобия . Это означает: при увеличении сторон в $k$ раз площадь вырастает в $k^2$ раз.
+ Обобщение: отношение площадей любых подобных фигур (многоугольников, кругов) тоже равно $k^2$.
+
+
+
+
+ A
+ B
+ C
+ S₁
+
+
+
+
+
+ A'
+ B'
+ C'
+ S₂
+
+ k = 2: S₁/S₂ = k² = 4
+
+ k=2
+
+
`);
+
+ html+=makeCard('rule','Доказательство через формулу площади','9.2',`
+ Пусть $\\triangle ABC \\sim \\triangle A'B'C'$, коэффициент подобия $k$: $AB = k \\cdot A'B'$, $BC = k \\cdot B'C'$ и т.д.
+ Высоты подобных треугольников тоже относятся как $k$ (высота строится из вершины перпендикулярно к стороне, а все стороны уменьшены в $k$ раз). Обозначим $h$ и $h'$ — высоты к $BC$ и $B'C'$:
+ $$h = k \\cdot h'$$
+ Тогда:
+ $$\\dfrac{S_{ABC}}{S_{A'B'C'}} = \\dfrac{\\tfrac{1}{2} \\cdot BC \\cdot h}{\\tfrac{1}{2} \\cdot B'C' \\cdot h'} = \\dfrac{BC}{B'C'} \\cdot \\dfrac{h}{h'} = k \\cdot k = k^2$$
+ Обобщение: для любых подобных многоугольников с коэффициентом подобия $k$: $S_1/S_2 = k^2$.
`);
+
+ html+=makeCard('example','Примеры','9.3',`
+ Пример 1. $\\triangle ABC \\sim \\triangle A'B'C'$, $k=3$, $S_{A'B'C'} = 8$. Найти $S_{ABC}$.
+ $S_{ABC} = k^2 \\cdot S_{A'B'C'} = 9 \\cdot 8 = 72$.
+ Пример 2. Стороны двух подобных треугольников — $6$ и $10$. Площадь меньшего — $18$. Найти площадь большего.
+ $k = 10/6 = 5/3$. $S_2 = k^2 \\cdot S_1 = (5/3)^2 \\cdot 18 = 25/9 \\cdot 18 = 50$.
+ Пример 3. $S_1 = 48$, $S_2 = 75$. Найти $k = \\sqrt{S_1/S_2}$ ... нет, $k = \\sqrt{S_2/S_1} = \\sqrt{75/48} = \\sqrt{25/16} = 5/4 = 1{,}25$ (если $S_2$ у большего).
+ $k = \\sqrt{75/48} = \\sqrt{25/16} = 1{,}25$.
`);
+
+ /* ---- ИНТЕРАКТИВ 1: SVG два треугольника со слайдером k ---- */
+ html+=`
+
+
Меняй $k$ и наблюдай: второй треугольник подобен первому с коэффициентом $k$. Отношение площадей = $k^2$.
+
+ Коэффициент $k$: 2.0
+
+
+ Площадь $S_2$: 12
+
+
+
+
+
+
`;
+
+ /* ---- ИНТЕРАКТИВ 2: Пошаговое доказательство ---- */
+ html+=`
+
+
Нажимай «Далее» для каждого шага. Доказательство через формулу площади $S = \\frac{1}{2}ah$.
+
+
+
+ Далее
+ Сначала
+
+
`;
+
+ /* ---- ИНТЕРАКТИВ 3: Калькулятор ---- */
+ html+=`
+
+
Два режима: по $k$ и $S_2$ найти $S_1$; или по двум площадям найти $k$.
+
+ По $k$ и $S_2$ → $S_1$
+ По $S_1$, $S_2$ → $k$
+
+
+
Коэфф. $k$
+
$S_2$ (меньш.)
+
Найти $S_1$
+
+
+
$S_1$ (больш.)
+
$S_2$ (меньш.)
+
Найти $k$
+
+
+
`;
+
+ /* ---- ИНТЕРАКТИВ 4: Тренажёр ---- */
+ html+=`
+
+
5 задач на применение формулы $S_1/S_2 = k^2$.
+
Задача 1 / 5 Очки: 0
+
+
+
+ Проверить
+ Начать
+
+
+
`;
+
+ /* ---- ИНТЕРАКТИВ 5: DnD-сортер k → k² ---- */
+ html+=`
+
+
Перетащи каждую карточку $k$ в колонку с верным $k^2$. Две колонки: «$k^2 = 4$» и «$k^2 = 9$».
+
+
+
Проверить Сбросить
+
+
`;
+
+ /* ---- ИНТЕРАКТИВ 6: Мини-квиз ---- */
+ html+=`
+
+
5 вопросов о площадях подобных фигур. Выбери верный ответ.
+
+
Проверить
+
+
`;
+
+ /* ---- ИНТЕРАКТИВ 7: Босс §9 ---- */
+ html+=`
+
+
4 задачи — каждая верная даёт +5 XP.
+
+
`;
+
+ html+=`
+
+
+ Я прочитал §9 (+10 XP)
+
+
`;
+ html+=secNav('p8','final3');
+ box.innerHTML=html;
+ if(window.renderMathInElement) setTimeout(()=>renderMath(box),0);
+
+ /* == INIT ИНТЕРАКТИВ 1: SVG два подобных треугольника == */
+ (function(){
+ const kSl=document.getElementById('p9-k-sl');
+ const s2Sl=document.getElementById('p9-s2-sl');
+ const kVal=document.getElementById('p9-k-val');
+ const s2Val=document.getElementById('p9-s2-val');
+ const svgOut=document.getElementById('p9-svg-out');
+ const infoEl=document.getElementById('p9-svg-info');
+
+ function draw(){
+ const k=+kSl.value/10;
+ const S2=+s2Sl.value;
+ const S1=S2*k*k;
+ kVal.textContent=k.toFixed(1);
+ s2Val.textContent=S2;
+
+ const W=400, H=200;
+ // Triangle 2 (smaller): fixed base, height from S2 = 1/2 * base * height
+ // base2 = 120 px (scaled), height2 = 2*S2/base2 — but we use unit scale
+ // Use a fixed nice triangle shape, scale by k for the bigger one
+ // Small triangle T2: B2=(240,175), C2=(360,175), A2=(310, 175 - h2)
+ // base = 120, h2 = 60 px (display). S2 shown as text.
+ const base2=110;
+ const h2=60;
+ const B2x=240, B2y=175;
+ const C2x=B2x+base2, C2y=175;
+ const A2x=B2x+base2*0.55, A2y=B2y-h2;
+
+ // Large triangle T1 = k * T2, anchored at B1
+ const base1=base2*k;
+ const h1=h2*k;
+ // Place T1 on the left side
+ const B1x=20, B1y=175;
+ const C1x=B1x+base1, C1y=175;
+ const A1x=B1x+base1*0.55, A1y=B1y-h1;
+
+ // Safety: check bounds
+ const maxX=Math.max(C1x, C2x)+10;
+ const minY=Math.min(A1y, A2y)-14;
+
+ let s=``;
+ // T1 large
+ s+=` `;
+ // Height line T1 (from A1 perpendicular to B1C1)
+ s+=` `;
+ // right angle marker T1
+ s+=` `;
+ s+=`A `;
+ s+=`B `;
+ s+=`C `;
+ const mBC1x=(B1x+C1x)/2;
+ s+=`a·k `;
+ s+=`h·k `;
+ s+=`S₁=${fmt(S1)} `;
+
+ // T2 small
+ s+=` `;
+ s+=` `;
+ s+=` `;
+ s+=`A' `;
+ s+=`B' `;
+ s+=`C' `;
+ const mBC2x=(B2x+C2x)/2;
+ s+=`a `;
+ s+=`h `;
+ s+=`S₂=${S2} `;
+
+ // top label
+ s+=`k = ${k.toFixed(1)}, S₁/S₂ = k² = ${fmt(k*k)} `;
+ s+=' ';
+ svgOut.innerHTML=s;
+ infoEl.innerHTML=`$k=${k.toFixed(1)}$, $S_2=${S2}$. Тогда $S_1 = k^2 \\cdot S_2 = ${k.toFixed(1)}^2 \\cdot ${S2} = ${fmt(k*k)} \\cdot ${S2} = ${fmt(S1)}$. Стороны первого в $${k.toFixed(1)}$ раз больше, площадь — в $${fmt(k*k)}$ раз больше.`;
+ renderMath(infoEl);
+ addXp(1,'p9-svg');
+ }
+ kSl.addEventListener('input',draw);
+ s2Sl.addEventListener('input',draw);
+ draw();
+ })();
+
+ /* == INIT ИНТЕРАКТИВ 2: пошаговое доказательство == */
+ (function(){
+ const steps=[
+ {desc:'Шаг 1. Дано: $\\triangle ABC \\sim \\triangle A\'B\'C\'$, коэффициент подобия $k$. Нужно доказать: $\\dfrac{S_{ABC}}{S_{A\'B\'C\'}} = k^2$.',
+ svg:`A B C A\' B\' C\' △ABC ∼ △A\'B\'C\', коэфф. k `},
+ {desc:'Шаг 2. Из подобия: $BC = k \\cdot B\'C\'$ (основание). Проведём высоты $BH \\perp AC$ и $B\'H\' \\perp A\'C\'$. Так как $\\triangle ABH \\sim \\triangle A\'B\'H\'$ (тот же коэффициент $k$), то $BH = k \\cdot B\'H\'$.',
+ svg:`A B C h = k·h\' H BC = k·B\'C\', BH = k·B\'H\' `},
+ {desc:'Шаг 3. Запишем формулу площади для каждого треугольника: $S_{ABC} = \\dfrac{1}{2} \\cdot BC \\cdot h$, $S_{A\'B\'C\'} = \\dfrac{1}{2} \\cdot B\'C\' \\cdot h\'$.',
+ svg:`S = ½ · BC · h S\' = ½ · B\'C\' · h\' Формула площади треугольника через основание и высоту `},
+ {desc:'Шаг 4. Составим отношение: $\\dfrac{S_{ABC}}{S_{A\'B\'C\'}} = \\dfrac{\\frac{1}{2} \\cdot BC \\cdot h}{\\frac{1}{2} \\cdot B\'C\' \\cdot h\'} = \\dfrac{BC}{B\'C\'} \\cdot \\dfrac{h}{h\'} = k \\cdot k = k^2$.',
+ svg:`S₁/S₂ = (BC/B\'C\')·(h/h\') = k·k = k² BC = k·B\'C\' и h = k·h\' S₁/S₂ = k² `},
+ {desc:'Шаг 5. Обобщение: для любых подобных многоугольников с коэффициентом $k$ разбиваем их на треугольники с тем же коэффициентом подобия. Сумма площадей каждого треугольника второй фигуры умножена на $k^2$. Значит $S_1/S_2 = k^2$ — верно для любых подобных фигур. Теорема доказана. ',
+ svg:`S₁/S₂ = k² для подобных △ Обобщается на любые подобные фигуры QED ∎ `},
+ ];
+ let step=0;
+ const svgEl=document.getElementById('p9-proof-svg');
+ const descEl=document.getElementById('p9-proof-desc');
+ function show(){svgEl.innerHTML=steps[step].svg;descEl.innerHTML=steps[step].desc;renderMath(descEl);}
+ document.getElementById('p9-proof-next').addEventListener('click',()=>{
+ if(step{step=0;show();});
+ show();
+ })();
+
+ /* == INIT ИНТЕРАКТИВ 3: калькулятор == */
+ (function(){
+ document.querySelectorAll('input[name="p9-mode"]').forEach(r=>{
+ r.addEventListener('change',()=>{
+ const m=+r.value;
+ document.getElementById('p9-calc-mode0').style.display=m===0?'grid':'none';
+ document.getElementById('p9-calc-mode1').style.display=m===1?'grid':'none';
+ document.getElementById('p9-ccalc-out').style.display='none';
+ });
+ });
+ document.getElementById('p9-ccalc0').addEventListener('click',()=>{
+ const k=parseFloat(document.getElementById('p9-ck').value);
+ const s2=parseFloat(document.getElementById('p9-cs2').value);
+ const out=document.getElementById('p9-ccalc-out');
+ if(!isFinite(k)||k<=0||!isFinite(s2)||s2<=0){
+ out.style.display='block';out.innerHTML='Введи $k > 0$ и $S_2 > 0$. ';renderMath(out);return;
+ }
+ const s1=s2*k*k;
+ out.style.display='block';
+ out.innerHTML=`$k = ${fmt(k)}$, $S_2 = ${fmt(s2)}$. $S_1 = k^2 \\cdot S_2 = ${fmt(k)}^2 \\cdot ${fmt(s2)} = ${fmt(k*k)} \\cdot ${fmt(s2)} = ${fmt(s1)} $.`;
+ renderMath(out);addXp(3,'p9-calc0');bumpProgress('p9',5);
+ });
+ document.getElementById('p9-ccalc1').addEventListener('click',()=>{
+ const s1=parseFloat(document.getElementById('p9-cs1b').value);
+ const s2=parseFloat(document.getElementById('p9-cs2b').value);
+ const out=document.getElementById('p9-ccalc-out');
+ if(!isFinite(s1)||s1<=0||!isFinite(s2)||s2<=0){
+ out.style.display='block';out.innerHTML='Введи $S_1 > 0$ и $S_2 > 0$. ';renderMath(out);return;
+ }
+ const k=Math.sqrt(s1/s2);
+ out.style.display='block';
+ out.innerHTML=`$S_1 = ${fmt(s1)}$, $S_2 = ${fmt(s2)}$. $k = \\sqrt{S_1/S_2} = \\sqrt{${fmt(s1)}/${fmt(s2)}} = \\sqrt{${fmt(s1/s2)}} = ${fmt(k)} $.`;
+ renderMath(out);addXp(3,'p9-calc1');bumpProgress('p9',5);
+ });
+ })();
+
+ /* == INIT ИНТЕРАКТИВ 4: тренажёр == */
+ (function(){
+ const tasks=[
+ {q:'$\\triangle ABC \\sim \\triangle A\'B\'C\'$, $k=3$, $S_{A\'B\'C\'}=8$. Найди $S_{ABC}$.',ans:72,hint:'S = k²·S\' = 9·8 = 72.'},
+ {q:'$\\triangle ABC \\sim \\triangle A\'B\'C\'$, $S_{ABC}=50$, $S_{A\'B\'C\'}=8$. Найди $k$.',ans:2.5,hint:'k = √(S/S\') = √(50/8) = √(6.25) = 2.5.'},
+ {q:'Стороны двух подобных треугольников — $6$ и $10$. Площадь меньшего — $18$. Найди площадь большего.',ans:50,hint:'k = 10/6 = 5/3. S₁ = (5/3)²·18 = 25/9·18 = 50.'},
+ {q:'$\\triangle ABC \\sim \\triangle A\'B\'C\'$, $k=4$. На сколько $S_{ABC}$ больше $S_{A\'B\'C\'}$? (Во сколько раз — введи число.)',ans:16,hint:'S₁/S₂ = k² = 16. Площадь больше в 16 раз.'},
+ {q:'Площади двух подобных треугольников: $S_1=48$, $S_2=75$. Найди $k = \\sqrt{S_2/S_1}$ (большего к меньшему).',ans:1.25,hint:'k = √(75/48) = √(25/16) = 5/4 = 1.25.'},
+ ];
+ let idx=0,score=0;
+ function show(){
+ document.getElementById('p9-tr-i').textContent=idx+1;
+ const t=document.getElementById('p9-tr-task');
+ t.innerHTML=tasks[idx].q;
+ renderMath(t);
+ document.getElementById('p9-tr-ans').value='';
+ document.getElementById('p9-tr-fb').style.display='none';
+ }
+ document.getElementById('p9-tr-start').addEventListener('click',()=>{idx=0;score=0;document.getElementById('p9-tr-score').textContent=0;show();});
+ document.getElementById('p9-tr-go').addEventListener('click',()=>{
+ if(idx>=tasks.length)return;
+ const ans=+document.getElementById('p9-tr-ans').value;
+ const fb=document.getElementById('p9-tr-fb');
+ if(Math.abs(ans-tasks[idx].ans)<0.05){
+ score++;document.getElementById('p9-tr-score').textContent=score;
+ addXp(3,'p9-tr-'+idx);bumpProgress('p9',4);
+ if(idxshow(),900);}
+ else{feedback(fb,true,'Все задачи решены! +5 XP');addXp(5,'p9-tr-all');bumpProgress('p9',10);confetti();}
+ } else {
+ feedback(fb,false,'Неверно. '+tasks[idx].hint);
+ }
+ });
+ document.getElementById('p9-tr-ans').addEventListener('keydown',e=>{if(e.key==='Enter')document.getElementById('p9-tr-go').click();});
+ show();
+ })();
+
+ /* == INIT ИНТЕРАКТИВ 5: DnD-сортер k → k² == */
+ (function(){
+ // items: k value → which bucket k²=4 (k=2) or k²=9 (k=3)
+ const items=[
+ {text:'k = 2',group:4},
+ {text:'k = 3',group:9},
+ {text:'√4 = 2',group:4},
+ {text:'S₁/S₂ = 4',group:4},
+ {text:'S₁/S₂ = 9',group:9},
+ {text:'k = √9 = 3',group:9},
+ ];
+ const pool=document.getElementById('p9-dnd-pool');
+ const box4=document.getElementById('p9-drop-4-items');
+ const box9=document.getElementById('p9-drop-9-items');
+ let dragging=null;
+ function makeChip(it,i){
+ const chip=document.createElement('div');
+ chip.className='dnd-chip';chip.dataset.idx=i;chip.textContent=it.text;chip.draggable=true;
+ chip.addEventListener('dragstart',e=>{dragging=chip;chip.classList.add('dragging');e.dataTransfer.effectAllowed='move';});
+ chip.addEventListener('dragend',()=>{chip.classList.remove('dragging');dragging=null;});
+ return chip;
+ }
+ items.forEach((it,i)=>pool.appendChild(makeChip(it,i)));
+ [document.getElementById('p9-drop-4'),document.getElementById('p9-drop-9'),pool].forEach(box=>{
+ box.addEventListener('dragover',e=>{e.preventDefault();box.classList.add('over');});
+ box.addEventListener('dragleave',()=>box.classList.remove('over'));
+ box.addEventListener('drop',e=>{
+ e.preventDefault();box.classList.remove('over');
+ if(!dragging)return;
+ const target=box===document.getElementById('p9-drop-4')?box4:box===document.getElementById('p9-drop-9')?box9:pool;
+ target.appendChild(dragging);
+ });
+ });
+ document.getElementById('p9-dnd-check').addEventListener('click',()=>{
+ const fb=document.getElementById('p9-dnd-fb');
+ const chips4=[...box4.querySelectorAll('.dnd-chip')];
+ const chips9=[...box9.querySelectorAll('.dnd-chip')];
+ if(chips4.length+chips9.length{if(items[+c.dataset.idx].group!==4)ok=false;});
+ chips9.forEach(c=>{if(items[+c.dataset.idx].group!==9)ok=false;});
+ if(ok){feedback(fb,true,'Верно! +5 XP');addXp(5,'p9-dnd');bumpProgress('p9',8);}
+ else{feedback(fb,false,'Есть ошибки. $k=2$ → $k^2=4$; $k=3$ → $k^2=9$.');}
+ });
+ document.getElementById('p9-dnd-reset').addEventListener('click',()=>{
+ [...box4.children].forEach(c=>pool.appendChild(c));
+ [...box9.children].forEach(c=>pool.appendChild(c));
+ document.getElementById('p9-dnd-fb').style.display='none';
+ });
+ })();
+
+ /* == INIT ИНТЕРАКТИВ 6: мини-квиз == */
+ (function(){
+ const qs=[
+ {q:'Если коэффициент подобия треугольников $k=5$, то отношение их площадей равно...',opts:['5','10','25','$\\sqrt{5}$'],ans:2},
+ {q:'Площади двух подобных треугольников — $9$ и $36$. Чему равен коэффициент подобия?',opts:['4','2','$\\sqrt{3}$','$\\frac{1}{2}$'],ans:1},
+ {q:'При каком $k$ площадь первого треугольника вдвое больше площади второго?',opts:['$k = 2$','$k = \\sqrt{2}$','$k = 4$','$k = 0{,}5$'],ans:1},
+ {q:'Верно ли, что для любых подобных фигур (не только треугольников) $S_1/S_2 = k^2$?',opts:['Только для треугольников','Только для прямоугольников','Да, для любых подобных фигур','Нет, только для равнобедренных'],ans:2},
+ {q:'$\\triangle ABC \\sim \\triangle A\'B\'C\'$, $k = 3$. Периметр $\\triangle A\'B\'C\' = 12$. Периметр $\\triangle ABC$ равен...',opts:['36','108','4','144'],ans:0},
+ ];
+ const wrap=document.getElementById('p9-quiz-wrap');
+ wrap.innerHTML=qs.map((q,qi)=>`
+
+
${qi+1}. ${q.q}
+
+ ${q.opts.map((o,oi)=>` ${o} `).join('')}
+
+
`).join('');
+ renderMath(wrap);
+ document.getElementById('p9-quiz-check').addEventListener('click',()=>{
+ const fb=document.getElementById('p9-quiz-fb');
+ let correct=0;
+ qs.forEach((q,qi)=>{
+ const sel=document.querySelector(`input[name="p9q${qi}"]:checked`);
+ if(sel&&+sel.value===q.ans)correct++;
+ });
+ if(correct===qs.length){
+ feedback(fb,true,`Все ${qs.length} ответов верны! +8 XP`);
+ addXp(8,'p9-quiz');bumpProgress('p9',12);confetti();
+ } else {
+ feedback(fb,false,`Верных ответов: ${correct} из ${qs.length}. Повтори: $S_1/S_2 = k^2$.`);
+ }
+ });
+ })();
+
+ /* == INIT: Босс §9 == */
+ (function(){
+ const tasks=[
+ {q:'A B C A\' B\' C\' S₂=8, k=3 $\\triangle ABC \\sim \\triangle A\'B\'C\'$, $k=3$, $S_{A\'B\'C\'}=8$. Найди $S_{ABC}$.',ans:72,hint:'S₁ = k²·S₂ = 9·8 = 72.'},
+ {q:'Стороны двух подобных треугольников: первый $12$, второй $8$. Площадь первого $S_1=54$. Найди $S_2$.',ans:24,hint:'k = 12/8 = 1.5. S₂ = S₁/k² = 54/2.25 = 24.'},
+ {q:'$S_1 = 75$, $S_2 = 48$. Найди коэффициент подобия $k = \\sqrt{S_1/S_2}$ (Ответ в виде десятичной дроби).',ans:1.25,hint:'k = √(75/48) = √(25/16) = 5/4 = 1.25.'},
+ {q:'Прямоугольный треугольник с катетами $3$ и $4$. Подобный с $k=2$. Найди площадь большего треугольника.',ans:24,hint:'S_мал = 0.5·3·4 = 6. S_бол = k²·S_мал = 4·6 = 24.'},
+ ];
+ const bossBox=document.getElementById('p9-boss-tasks');
+ bossBox.innerHTML=tasks.map((t,i)=>`
+
+
${t.q}
+
+
+ Проверить
+
+
+
`).join('');
+ window.p9BossSolved=new Set();
+ renderMath(bossBox);
+ })();
+}
function buildFinal3stub(){ document.getElementById('final3-body').innerHTML='Финал главы 3 — Волна 1 : боссы и итоги появятся в следующем обновлении.
'+secNav('p9',null); }