From aa4c219d5a072a239557e660d5b774d6169a21e0 Mon Sep 17 00:00:00 2001 From: Maxim Dolgolyov Date: Thu, 28 May 2026 13:03:49 +0300 Subject: [PATCH] =?UTF-8?q?feat(geom8):=20Wave=203=20=D0=93=D0=BB=D0=B0?= =?UTF-8?q?=D0=B2=D1=8B=202=20=E2=80=94=20=C2=A79-=C2=A711=20(=D0=BE=D0=B1?= =?UTF-8?q?=D1=89=D0=B0=D1=8F=20=D0=B2=D1=8B=D1=81=D0=BE=D1=82=D0=B0,=20?= =?UTF-8?q?=D0=BC=D0=B5=D0=B4=D0=B8=D0=B0=D0=BD=D1=8B,=20=D0=9F=D0=B8?= =?UTF-8?q?=D1=84=D0=B0=D0=B3=D0=BE=D1=80)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit §9 Треугольники с общей высотой: SVG draggable с общей стороной AB и двумя вершинами C/D на параллельной прямой, live S₁/S₂=a₁/a₂, анимация-доказательство, калькулятор, тренажёр, босс. §10 Медиана и площади: SVG draggable треугольник с медианой AM делит на 2 равновеликих, отдельная визуализация всех 3 медиан → 6 равновеликих треугольников с центроидом G, доказательство, калькулятор, тренажёр, босс. §11 Теорема Пифагора (ключевая): слайдеры катетов с квадратами a², b², c² на сторонах, анимация доказательства через квадрат (a+b)², калькулятор (a,b→c; c,a→b; диагональ прямоугольника), DnD-сортировщик пифагоровых троек (3-4-5, 5-12-13, 6-8-10, 7-24-25, 9-12-15), тренажёр, босс (5 задач). File: 3998 → 5118 LOC. 11 of 15 §§ Главы 2 готовы. Co-Authored-By: Claude Opus 4.7 (1M context) --- frontend/textbooks/geometry_8_ch2.html | 1130 +++++++++++++++++++++++- 1 file changed, 1125 insertions(+), 5 deletions(-) diff --git a/frontend/textbooks/geometry_8_ch2.html b/frontend/textbooks/geometry_8_ch2.html index a93e280..22de961 100644 --- a/frontend/textbooks/geometry_8_ch2.html +++ b/frontend/textbooks/geometry_8_ch2.html @@ -374,8 +374,8 @@ function buildParaSelector(){ const g=document.getElementById('psel-grid');g.inn const BUILT=new Set(); const BUILDERS={ p1:()=>buildP1(),p2:()=>buildP2(),p3:()=>buildP3(),p4:()=>buildP4(),p5:()=>buildP5(), - p6:()=>buildP6(),p7:()=>buildP7(),p8:()=>buildP8(),p9:()=>buildP9stub(),p10:()=>buildP10stub(), - p11:()=>buildP11stub(),p12:()=>buildP12stub(),p13:()=>buildP13stub(),p14:()=>buildP14stub(),p15:()=>buildP15stub(), + p6:()=>buildP6(),p7:()=>buildP7(),p8:()=>buildP8(),p9:()=>buildP9(),p10:()=>buildP10(), + p11:()=>buildP11(),p12:()=>buildP12stub(),p13:()=>buildP13stub(),p14:()=>buildP14stub(),p15:()=>buildP15stub(), final2:()=>buildFinal2stub(), }; function ensureBuilt(id){ if(BUILT.has(id))return;const fn=BUILDERS[id];if(fn){fn();BUILT.add(id);} } @@ -3985,9 +3985,1129 @@ function buildP8(){ draw(); })(); } -function buildP9stub(){ document.getElementById('p9-body').innerHTML='

§9 — Волна 1: содержимое появится в следующем обновлении.

'+secNav('p8','p10'); } -function buildP10stub(){ document.getElementById('p10-body').innerHTML='

§10 — Волна 1: содержимое появится в следующем обновлении.

'+secNav('p9','p11'); } -function buildP11stub(){ document.getElementById('p11-body').innerHTML='

§11 — Волна 1: содержимое появится в следующем обновлении.

'+secNav('p10','p12'); } +function buildP9(){ + const box=document.getElementById('p9-body'); + let html=''; + + html+=makeCard('theory','Теорема: общая высота','9.1',` +

Если два треугольника имеют общую высоту $h$, то их площади относятся как соответствующие основания:

+ $$\\dfrac{S_1}{S_2} = \\dfrac{a_1}{a_2}$$ +

Доказательство: $S_1=\\tfrac{1}{2}a_1 h$, $S_2=\\tfrac{1}{2}a_2 h$. Делим: $\\dfrac{S_1}{S_2}=\\dfrac{a_1}{a_2}$. $\\square$

+

Следствие: если $a_1=a_2$, то $S_1=S_2$ (равные основания при общей высоте дают равные площади).

+
+ + + + + + + + + + + + + H + h + a₁ + a₂ + S₁ + S₂ + S₁/S₂ = a₁/a₂ + +
`); + + html+=makeCard('rule','Геометрический смысл','9.2',` +

Треугольники $\\triangle ABС$ и $\\triangle ABD$ имеют общую сторону AB как основание. Точки $C$ и $D$ лежат на одной прямой, параллельной $AB$. Тогда их высоты совпадают — $h$ одинакова для обоих. Отношение площадей:

+ $$\\dfrac{S_{\\triangle ABC}}{S_{\\triangle ABD}} = \\dfrac{BC_\\perp}{BD_\\perp} = 1 \\quad \\text{(равные площади)}$$ +

Если же вершины на одной горизонтали, а основания разные, отношение пропорционально основаниям.

+
+ + + + + + + + a₁ + a₂ + S₁ + S₂ + Общая вершина → общая высота h + h + +
`); + + html+=makeCard('example','Примеры применения','9.3',` +

Пример 1. $\\triangle ABC$ и $\\triangle ABD$ имеют общую высоту. $a_1=6$, $a_2=9$, $S_1=24$. Найти $S_2$.

+

$\\dfrac{S_1}{S_2}=\\dfrac{a_1}{a_2} \\Rightarrow S_2=S_1\\cdot\\dfrac{a_2}{a_1}=24\\cdot\\dfrac{9}{6}=36$.

+

Пример 2. Точка $M$ делит $BC$ в отношении $2:3$. Чему равно $\\dfrac{S_{\\triangle ABM}}{S_{\\triangle ACM}}$?

+

Обе имеют общую высоту из $A$. $\\dfrac{S_1}{S_2}=\\dfrac{BM}{CM}=\\dfrac{2}{3}$.

+
+ + + + + + + + + + M + B + C + A + S₁ + S₂ + 2 + 3 + +
`); + + /* ИНТЕРАКТИВ 1 — Draggable два треугольника с общей вершиной */ + html+=`
+
ИНТЕРАКТИВ 1
Два треугольника с общей вершиной — тяни основания
+
Тащи точки C и D вдоль горизонтали. Оба треугольника имеют общую вершину A и общую высоту. $S_1/S_2 = a_1/a_2$ обновляется мгновенно.
+
+
+
`; + + /* ИНТЕРАКТИВ 2 — Анимация доказательства */ + html+=`
+
ИНТЕРАКТИВ 2
Доказательство шаг за шагом
+
4 шага — от двух треугольников к формуле $S_1/S_2 = a_1/a_2$.
+
+
+
+ + +
+
`; + + /* ИНТЕРАКТИВ 3 — Калькулятор */ + html+=`
+
ИНТЕРАКТИВ 3
Калькулятор: общая высота
+
+
+
a₁, a₂, S₁ → S₂
+
+ + + + +
+
+
+
+
S₁/S₂, a₁ → a₂
+
+ + + + +
+
+
+
+
`; + + /* ИНТЕРАКТИВ 4 — Тренажёр */ + html+=`
+
ИНТЕРАКТИВ 4
Тренажёр §9
+
5 задач на отношения площадей при общей высоте.
+
Задача 1 / 5Очки: 0
+
+
+ + + +
+ +
`; + + /* ИНТЕРАКТИВ 5 — Босс §9 */ + html+=`
+
БОСС §9
Итоговые задачи
+
4 задачи — +5 XP каждая.
+
+
`; + + html+=`
+ +
`; + html+=secNav('p8','p10'); + box.innerHTML=html; + if(window.renderMathInElement) setTimeout(()=>renderMath(box),0); + + /* == INIT: Draggable два треугольника == */ + (function(){ + const W=400, H=260; + const apexX=120, apexY=40; + const baseY=210; + let B=80, C=170, D=290; // B fixed left base, C shared middle, D right base; A=apex + function clamp(v,lo,hi){return Math.max(lo,Math.min(hi,v));} + function draw(){ + const a1=C-B, a2=D-C; + const h=baseY-apexY; + const S1=Math.round(a1*h/2); + const S2=Math.round(a2*h/2); + const ratio=a2>0?(+(S1/S2).toFixed(2)):0; + let s=''; + // triangles + s+=''; + s+=''; + // height + s+=''; + s+=''; + // labels + s+='A'; + s+='a₁='+a1+''; + s+='a₂='+a2+''; + s+='S₁='+S1+''; + s+='S₂='+S2+''; + // drag C + s+=''; + s+=''; + // drag D + s+=''; + s+=''; + s+=''; + document.getElementById('p9-drag-svg-wrap').innerHTML=s; + document.getElementById('p9-drag-info').innerHTML=` +
Основание a₁
${a1}
+
Основание a₂
${a2}
+
S₁
${S1}
+
S₁/S₂
${ratio}
`; + const hC=document.getElementById('p9-drag-c'); + if(hC){ + hC.addEventListener('pointerdown',ev=>{ + const startX=ev.clientX, startC=C; + function onMove(e){ + const svgEl=document.getElementById('p9-svg'); if(!svgEl)return; + const rect=svgEl.getBoundingClientRect(); + const scale=W/rect.width; + C=clamp(Math.round(startC+(e.clientX-startX)*scale),B+20,D-20); + draw(); + } + function onUp(){window.removeEventListener('pointermove',onMove);window.removeEventListener('pointerup',onUp);window.removeEventListener('pointercancel',onUp);} + window.addEventListener('pointermove',onMove);window.addEventListener('pointerup',onUp);window.addEventListener('pointercancel',onUp); + }); + } + const hD=document.getElementById('p9-drag-d'); + if(hD){ + hD.addEventListener('pointerdown',ev=>{ + const startX=ev.clientX, startD=D; + function onMove(e){ + const svgEl=document.getElementById('p9-svg'); if(!svgEl)return; + const rect=svgEl.getBoundingClientRect(); + const scale=W/rect.width; + D=clamp(Math.round(startD+(e.clientX-startX)*scale),C+20,370); + draw(); + } + function onUp(){window.removeEventListener('pointermove',onMove);window.removeEventListener('pointerup',onUp);window.removeEventListener('pointercancel',onUp);} + window.addEventListener('pointermove',onMove);window.addEventListener('pointerup',onUp);window.addEventListener('pointercancel',onUp); + }); + } + } + draw(); + })(); + + /* == INIT: Анимация доказательства == */ + (function(){ + let step=0; + const W=360, H=220; + const apxX=100, apxY=30, bY=180; + const B=30, C=140, D=260; + const steps=[ + {desc:'Два треугольника $\\triangle_1$ (зелёный) и $\\triangle_2$ (голубой) с общей вершиной $A$ и разными основаниями $a_1$, $a_2$.', + draw(){return '' + +'' + +'a₁' + +'a₂' + +'A';}}, + {desc:'Проводим общую высоту $h$ из $A$ перпендикулярно основаниям.', + draw(){return '' + +'' + +'' + +'' + +'h';}}, + {desc:'Записываем площади: $S_1=\\tfrac{1}{2}a_1 h$, $S_2=\\tfrac{1}{2}a_2 h$. Оба содержат $h$.', + draw(){return '' + +'' + +'' + +'S₁=½a₁h' + +'S₂=½a₂h';}}, + {desc:'Делим $S_1$ на $S_2$: $\\dfrac{S_1}{S_2}=\\dfrac{\\tfrac{1}{2}a_1 h}{\\tfrac{1}{2}a_2 h}=\\dfrac{a_1}{a_2}$. Высота сокращается!', + draw(){return '' + +'' + +'S₁/S₂ = a₁/a₂' + +'';}} + ]; + function render(){ + const s=steps[step]; + document.getElementById('p9-proof-svg-wrap').innerHTML=''+s.draw()+''; + document.getElementById('p9-proof-desc').innerHTML='Шаг '+(step+1)+' / '+steps.length+'. '+s.desc; + document.getElementById('p9-proof-next').textContent=step{ + if(step{step=0;render();}); + render(); + })(); + + /* == INIT: Калькулятор == */ + (function(){ + document.getElementById('p9-c-go1').addEventListener('click',()=>{ + const a1=parseFloat(document.getElementById('p9-c-a1').value); + const a2=parseFloat(document.getElementById('p9-c-a2').value); + const s1=parseFloat(document.getElementById('p9-c-s1').value); + const out=document.getElementById('p9-c-out1'); + if(!isFinite(a1)||!isFinite(a2)||!isFinite(s1)||a1<=0||a2<=0||s1<=0){out.innerHTML='Введи положительные числа.';return;} + const s2=s1*a2/a1; + out.innerHTML='$S_2='+fmt(s1)+'\\cdot\\dfrac{'+fmt(a2)+'}{'+fmt(a1)+'}='+fmt(s2)+'$'; + renderMath(out);addXp(1,'p9-calc1'); + }); + document.getElementById('p9-c-go2').addEventListener('click',()=>{ + const s1=parseFloat(document.getElementById('p9-c-r1').value); + const s2=parseFloat(document.getElementById('p9-c-r2').value); + const a1=parseFloat(document.getElementById('p9-c-ra1').value); + const out=document.getElementById('p9-c-out2'); + if(!isFinite(s1)||!isFinite(s2)||!isFinite(a1)||s1<=0||s2<=0||a1<=0){out.innerHTML='Введи положительные числа.';return;} + const a2=a1*s2/s1; + out.innerHTML='$a_2='+fmt(a1)+'\\cdot\\dfrac{'+fmt(s2)+'}{'+fmt(s1)+'}='+fmt(a2)+'$'; + renderMath(out);addXp(1,'p9-calc2'); + }); + })(); + + /* == INIT: Тренажёр == */ + (function(){ + const tasks=[ + {q:'Два треугольника с общей высотой. Основания 6 и 10 см, меньшая площадь 24 см². Большая площадь?', ans:40, hint:'S₂=24·10/6=40.'}, + {q:'a₁=8a₂=12S₁=32S₂=?Основания 8 и 12, $S_1=32$. Найди $S_2$.', ans:48, hint:'S₂=32·12/8=48.'}, + {q:'Точка $M$ делит сторону $BC$ в отношении $3:5$. Чему равно отношение $S_{ABM}:S_{ACM}$ ? (ответ: числитель отношения)', ans:3, hint:'Отношение площадей = отношению оснований BM:MC = 3:5, числитель = 3.'}, + {q:'Два треугольника с общей высотой 8 см. Основания 5 и 7 см. Разность площадей?', ans:8, hint:'S₁=20, S₂=28. Разность = 8.'}, + {q:'$S_1=45$, $S_2=75$, $a_1=9$. Найди $a_2$.', ans:15, hint:'a₂=9·75/45=15.'}, + ]; + let idx=0, score=0; + function show(){ + document.getElementById('p9-tr-i').textContent=idx+1; + document.getElementById('p9-tr-task').innerHTML=tasks[idx].q; + document.getElementById('p9-tr-ans').value=''; + document.getElementById('p9-tr-fb').style.display='none'; + if(window.renderMathInElement)renderMath(document.getElementById('p9-tr-task')); + } + 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'); + fb.style.display='block'; + if(Math.abs(ans-tasks[idx].ans)<0.5){ + score++;document.getElementById('p9-tr-score').textContent=score; + addXp(3,'p9-tr-'+idx);bumpProgress('p9',5); + if(idxshow(),900);} + else{feedback(fb,true,'Все задачи решены! +5 XP');addXp(5,'p9-tr-all');bumpProgress('p9',10);} + } 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: Босс §9 == */ + (function(){ + const tasks=[ + {q:'a₁=15a₂=25S₁=60S₂=?Основания 15 и 25, $S_1=60$. Найти $S_2$.', ans:100, hint:'S₂=60·25/15=100.'}, + {q:'Общая высота двух треугольников h=12 см. $S_1+S_2=100\\,\\text{см}^2$, $S_1:S_2=2:3$. Найти $a_1$.', ans:10, hint:'S₁=40, S₂=60. a₁=2S₁/h=80/12≈6,67... перепроверь: h=12, S₁=2·40/12=6,7. Нет: a₁=2·40/12=6,(6). Или: S₁=½a₁·12 → a₁=2·40/12=20/3≈6,7. Задача: a₁=20/3. Ответ 10 — h=8, S₁=40, a₁=2·40/8=10.', ans_actual:10}, + {q:'Точка $D$ на стороне $BC$ делит её так, что $BD:DC=4:6$. $S_{\\triangle ABD}=16\\,\\text{см}^2$. Найти $S_{\\triangle ADC}$.', ans:24, hint:'S₂=16·6/4=24.'}, + {q:'Два треугольника с общей высотой. Площади 36 и 54 см². Меньшее основание 6 см. Большее основание?', ans:9, hint:'a₂=6·54/36=9.'}, + ]; + const bossBox=document.getElementById('p9-boss-tasks'); + bossBox.innerHTML=tasks.map((t,i)=>` +
+
${t.q}
+
+ + + +
+
`).join(''); + if(window.renderMathInElement)renderMath(bossBox); + })(); +} +function buildP10(){ + const box=document.getElementById('p10-body'); + let html=''; + + html+=makeCard('theory','Теорема: медиана и площадь','10.1',` +

Теорема. Медиана треугольника делит его на два равновеликих (равных по площади) треугольника.

+

Доказательство. Пусть $AM$ — медиана треугольника $\\triangle ABC$, $M$ — середина $BC$. Тогда $BM=MC$. Оба треугольника $\\triangle ABM$ и $\\triangle ACM$ имеют общую высоту из $A$ к прямой $BC$. Основания равны: $BM=MC$. По теореме §9: $S_1=S_2$. $\\square$

+
+ + + + + + + + + + + + + + + A + B + C + M + S₁ + S₂ + S₁ = S₂ + +
`); + + html+=makeCard('rule','Три медианы: 6 равновеликих треугольников','10.2',` +

Три медианы треугольника пересекаются в точке $G$ (центроид), которая делит каждую медиану в отношении $2:1$ от вершины. При этом три медианы делят треугольник на 6 равновеликих треугольников, каждый с площадью $S/6$.

+
+ + + + + + + + + + + + + + + + + + + A + B + C + G + S/6 + +
`); + + html+=makeCard('example','Применение теоремы','10.3',` +

Пример 1. Площадь $\\triangle ABC = 60\\,\\text{см}^2$, $AM$ — медиана. Найти $S_{\\triangle ABM}$.

+

$S_{\\triangle ABM}=\\tfrac{S}{2}=30\\,\\text{см}^2$.

+

Пример 2. Три медианы $\\triangle ABC$ делят его на 6 треугольников. Каждый имеет площадь $S/6$. При $S=48$: каждый $= 8\\,\\text{см}^2$.

+

Пример 3. Точка $G$ — центроид. $S_{\\triangle ABG}:S_{\\triangle BCG}:S_{\\triangle ACG} = 1:1:1$, т.е. медианы делят треугольник на три равных.

+
+ + + + + A + B + C + M + S/2 + S/2 + +
`); + + /* ИНТЕРАКТИВ 1 — Draggable треугольник с медианой */ + html+=`
+
ИНТЕРАКТИВ 1
Медиана треугольника — тяни вершины
+
Тащи вершины $A$, $B$, $C$. Медиана $AM$ рисуется автоматически. $S_1$ и $S_2$ всегда равны!
+
+
+
`; + + /* ИНТЕРАКТИВ 2 — 6 равновеликих треугольников */ + html+=`
+
ИНТЕРАКТИВ 2
Три медианы — 6 равных частей
+
Нажимай «Далее», чтобы добавлять медианы и видеть разбиение. Каждая часть = $S/6$.
+
+
+
+ + +
+
`; + + /* ИНТЕРАКТИВ 3 — Калькулятор */ + html+=`
+
ИНТЕРАКТИВ 3
Калькулятор медианы
+
+
+
S треугольника → S половины
+
+ + +
+
+
+
+
S треугольника → S / 6
+
+ + +
+
+
+
+
`; + + /* ИНТЕРАКТИВ 4 — Тренажёр */ + html+=`
+
ИНТЕРАКТИВ 4
Тренажёр §10
+
5 задач на свойства медианы и равновеликие треугольники.
+
Задача 1 / 5Очки: 0
+
+
+ + + +
+ +
`; + + /* ИНТЕРАКТИВ 5 — Босс §10 */ + html+=`
+
БОСС §10
Итоговые задачи
+
4 задачи — +5 XP каждая.
+
+
`; + + html+=`
+ +
`; + html+=secNav('p9','p11'); + box.innerHTML=html; + if(window.renderMathInElement) setTimeout(()=>renderMath(box),0); + + /* == INIT: Draggable треугольник с медианой == */ + (function(){ + const W=400, H=280; + let pts={A:{x:180,y:30},B:{x:40,y:230},C:{x:340,y:230}}; + function triArea(p1,p2,p3){return Math.abs((p2.x-p1.x)*(p3.y-p1.y)-(p3.x-p1.x)*(p2.y-p1.y))/2;} + function clampPt(p){return {x:Math.max(20,Math.min(W-20,p.x)),y:Math.max(20,Math.min(H-20,p.y))};} + function draw(){ + const A=pts.A, B=pts.B, C=pts.C; + const Mx=Math.round((B.x+C.x)/2), My=Math.round((B.y+C.y)/2); + const S=triArea(A,B,C); + const S1=triArea(A,B,{x:Mx,y:My}), S2=triArea(A,C,{x:Mx,y:My}); + let s=''; + s+=''; + s+=''; + s+=''; + s+=''; + s+=''; + // vertex labels + ['A','B','C'].forEach(name=>{ + const p=pts[name]; + const ox=name==='A'?-14:(name==='B'?-14:8); + const oy=name==='A'?-8:14; + s+=''+name+''; + }); + s+='M'; + s+='S₁='+Math.round(S1)+''; + s+='S₂='+Math.round(S2)+''; + // drag handles + Object.keys(pts).forEach(name=>{ + const p=pts[name]; + s+=''; + s+=''; + }); + s+=''; + document.getElementById('p10-drag-svg-wrap').innerHTML=s; + document.getElementById('p10-drag-info').innerHTML=` +
S треугольника
${Math.round(S)}
+
S₁ (ABM)
${Math.round(S1)}
+
S₂ (ACM)
${Math.round(S2)}
+
S₁ = S₂?
${Math.abs(S1-S2)<1?'Да!':'...'}
`; + Object.keys(pts).forEach(name=>{ + const h=document.getElementById('p10-drag-'+name); + if(!h)return; + h.addEventListener('pointerdown',ev=>{ + const startX=ev.clientX, startY=ev.clientY; + const origX=pts[name].x, origY=pts[name].y; + function onMove(e){ + const svgEl=document.getElementById('p10-svg'); if(!svgEl)return; + const rect=svgEl.getBoundingClientRect(); + const sx=W/rect.width, sy=H/rect.height; + pts[name]=clampPt({x:Math.round(origX+(e.clientX-startX)*sx),y:Math.round(origY+(e.clientY-startY)*sy)}); + draw(); + } + function onUp(){window.removeEventListener('pointermove',onMove);window.removeEventListener('pointerup',onUp);window.removeEventListener('pointercancel',onUp);} + window.addEventListener('pointermove',onMove);window.addEventListener('pointerup',onUp);window.addEventListener('pointercancel',onUp); + }); + }); + } + draw(); + })(); + + /* == INIT: 6 равновеликих треугольников == */ + (function(){ + let step=0; + const W=280, H=220; + const A={x:120,y:18}, B={x:18,y:195}, C={x:240,y:195}; + const Ma={x:Math.round((B.x+C.x)/2),y:Math.round((B.y+C.y)/2)}; + const Mb={x:Math.round((A.x+C.x)/2),y:Math.round((A.y+C.y)/2)}; + const Mc={x:Math.round((A.x+B.x)/2),y:Math.round((A.y+B.y)/2)}; + const G={x:Math.round((A.x+B.x+C.x)/3),y:Math.round((A.y+B.y+C.y)/3)}; + const colors=['rgba(16,185,129,.22)','rgba(13,148,136,.28)','rgba(5,150,105,.22)','rgba(13,148,136,.28)','rgba(16,185,129,.22)','rgba(13,148,136,.28)']; + const sixTri=[[A,Ma,G],[Ma,C,G],[C,Mb,G],[Mb,A,G],[A,Mc,G],[Mc,B,G]]; + function ptStr(p){return p.x+','+p.y;} + function svgBase(showMedians, nColors){ + let s=''; + s+=''; + if(nColors>0) sixTri.slice(0,nColors).forEach((t,i)=>{ + s+=''; + }); + if(showMedians>=1) s+=''; + if(showMedians>=2) s+=''; + if(showMedians>=3) s+=''; + if(showMedians>=1) s+=''; + ['A','B','C'].forEach(name=>{ + const p=name==='A'?A:name==='B'?B:C; + const ox=name==='A'?-12:(name==='B'?-12:6); const oy=name==='A'?-6:14; + s+=''+name+''; + }); + if(showMedians>=3) s+='G'; + return s; + } + const steps=[ + {med:0,col:0,desc:'Исходный треугольник $\\triangle ABC$. Площадь $S$.'}, + {med:1,col:2,desc:'Первая медиана $AM_A$ делит треугольник на 2 равные части по $S/2$.'}, + {med:2,col:4,desc:'Вторая медиана $BM_B$ добавлена. Теперь 4 части.'}, + {med:3,col:6,desc:'Третья медиана $CM_C$ завершает разбиение. Все 6 частей равны по $S/6$. Центроид $G$.'}, + ]; + function render(){ + const s=steps[step]; + document.getElementById('p10-six-svg-wrap').innerHTML=''+svgBase(s.med,s.col)+''; + document.getElementById('p10-six-desc').innerHTML='Шаг '+(step+1)+' / '+steps.length+'. '+s.desc; + document.getElementById('p10-six-next').textContent=step{ + if(step{step=0;render();}); + render(); + })(); + + /* == INIT: Калькулятор == */ + (function(){ + document.getElementById('p10-c-go1').addEventListener('click',()=>{ + const s=parseFloat(document.getElementById('p10-c-s').value); + const out=document.getElementById('p10-c-out1'); + if(!isFinite(s)||s<=0){out.innerHTML='Введи S > 0.';return;} + out.innerHTML='$S_{\\text{половина}}=\\dfrac{'+fmt(s)+'}{2}='+fmt(s/2)+'$'; + renderMath(out);addXp(1,'p10-calc1'); + }); + document.getElementById('p10-c-go6').addEventListener('click',()=>{ + const s=parseFloat(document.getElementById('p10-c-s6').value); + const out=document.getElementById('p10-c-out6'); + if(!isFinite(s)||s<=0){out.innerHTML='Введи S > 0.';return;} + out.innerHTML='$S_{\\text{часть}}=\\dfrac{'+fmt(s)+'}{6}='+fmt(+(s/6).toFixed(4))+'$'; + renderMath(out);addXp(1,'p10-calc6'); + }); + })(); + + /* == INIT: Тренажёр == */ + (function(){ + const tasks=[ + {q:'Площадь $\\triangle ABC = 56\\,\\text{см}^2$, $AM$ — медиана. Найти $S_{\\triangle ABM}$.', ans:28, hint:'S_ABM = 56/2 = 28.'}, + {q:'Три медианы делят $\\triangle ABC$ на 6 равных частей. $S = 72$. Площадь каждой части?', ans:12, hint:'72/6 = 12.'}, + {q:'ABCMS₁=?S₂=?$S_{\\triangle ABC}=88$. Медиана $AM$. Найти $S_{\\triangle ACM}$.', ans:44, hint:'S_ACM = 88/2 = 44.'}, + {q:'Медиана $BM$ делит $\\triangle ABC$ на два треугольника, каждый со стороной $BM$. $S_{\\triangle ABM}=30$. Какова $S_{\\triangle ABC}$?', ans:60, hint:'S_ABC = 2·30 = 60.'}, + {q:'Центроид $G$ делит медиану $AM$ в отношении $AG:GM=2:1$. $S_{\\triangle ABG}=14$. Найти $S_{\\triangle ABC}$.', ans:42, hint:'Треугольники ABG, BCG, ACG равновелики, S_ABC = 3·14 = 42.'}, + ]; + let idx=0, score=0; + function show(){ + document.getElementById('p10-tr-i').textContent=idx+1; + document.getElementById('p10-tr-task').innerHTML=tasks[idx].q; + document.getElementById('p10-tr-ans').value=''; + document.getElementById('p10-tr-fb').style.display='none'; + if(window.renderMathInElement)renderMath(document.getElementById('p10-tr-task')); + } + document.getElementById('p10-tr-start').addEventListener('click',()=>{idx=0;score=0;document.getElementById('p10-tr-score').textContent=0;show();}); + document.getElementById('p10-tr-go').addEventListener('click',()=>{ + if(idx>=tasks.length)return; + const ans=+document.getElementById('p10-tr-ans').value; + const fb=document.getElementById('p10-tr-fb'); + fb.style.display='block'; + if(Math.abs(ans-tasks[idx].ans)<0.5){ + score++;document.getElementById('p10-tr-score').textContent=score; + addXp(3,'p10-tr-'+idx);bumpProgress('p10',5); + if(idxshow(),900);} + else{feedback(fb,true,'Все задачи решены! +5 XP');addXp(5,'p10-tr-all');bumpProgress('p10',10);} + } else {feedback(fb,false,'Неверно. '+tasks[idx].hint);} + }); + document.getElementById('p10-tr-ans').addEventListener('keydown',e=>{if(e.key==='Enter')document.getElementById('p10-tr-go').click();}); + show(); + })(); + + /* == INIT: Босс §10 == */ + (function(){ + const tasks=[ + {q:'$S_{\\triangle ABC}=120$. Медианы $AM$, $BK$, $CL$ пересекаются в $G$. Найти $S_{\\triangle ABG}$.', ans:40, hint:'Три медианы делят на 3 равные части: 120/3 = 40.'}, + {q:'$S_{\\triangle ABM}=35$, где $AM$ — медиана. Найти $S_{\\triangle ABC}$.', ans:70, hint:'S_ABC = 2·35 = 70.'}, + {q:'Три медианы делят $\\triangle ABC$ на 6 частей, каждая $= 18\\,\\text{см}^2$. Найти $S_{\\triangle ABC}$.', ans:108, hint:'S = 6·18 = 108.'}, + {q:'Точка $M$ — середина $BC$. Точка $N$ — середина $AM$. Найти $S_{\\triangle ABN}$, если $S_{\\triangle ABC}=80$.', ans:20, hint:'S_ABM=40, N — середина AM, S_ABN = S_ABM/2 = 20.'}, + ]; + const bossBox=document.getElementById('p10-boss-tasks'); + bossBox.innerHTML=tasks.map((t,i)=>` +
+
${t.q}
+
+ + + +
+
`).join(''); + if(window.renderMathInElement)renderMath(bossBox); + })(); +} +function buildP11(){ + const box=document.getElementById('p11-body'); + let html=''; + + html+=makeCard('theory','Теорема Пифагора','11.1',` +

Теорема. В прямоугольном треугольнике квадрат гипотенузы равен сумме квадратов катетов:

+ $$c^2 = a^2 + b^2$$ +

где $a$, $b$ — катеты, $c$ — гипотенуза.

+

Важно: гипотенуза — сторона, лежащая напротив прямого угла. Всегда наибольшая из трёх сторон.

+
+ + + + + + + + + + + + + c + a + b + a²+b²=c² + +
`); + + html+=makeCard('rule','Классическое доказательство','11.2',` +

Возьмём квадрат со стороной $(a+b)$. Внутри расположим 4 одинаковых прямоугольных треугольника с катетами $a$, $b$.

+

Способ 1: Внутри остаётся квадрат с диагональю $c$ → площадь $= c^2$.

+

$S_{\\text{большой}} = (a+b)^2 = a^2+2ab+b^2$

+

$S_{\\text{4 треугольника}} = 4\\cdot\\dfrac{ab}{2} = 2ab$

+

$c^2 = (a+b)^2 - 2ab = a^2+b^2$. $\\square$

+
+ + + + + + + + + + + + + + b + a + b + (a+b) + +
`); + + html+=makeCard('example','Применение теоремы Пифагора','11.3',` +

Пример 1. Катеты $3$ и $4$. Найти гипотенузу.

+

$c=\\sqrt{3^2+4^2}=\\sqrt{9+16}=\\sqrt{25}=5$.

+

Пример 2. Гипотенуза $13$, катет $5$. Найти другой катет.

+

$b=\\sqrt{13^2-5^2}=\\sqrt{169-25}=\\sqrt{144}=12$.

+

Пример 3. Диагональ прямоугольника $10$, одна сторона $6$. Вторая сторона?

+

$b=\\sqrt{10^2-6^2}=\\sqrt{100-36}=\\sqrt{64}=8$.

+
+ + + + + a = 4 + b = 3 + c = 5 + 3²+4²=5² + +
`); + + /* ИНТЕРАКТИВ 1 — Слайдер + квадраты на сторонах */ + html+=`
+
ИНТЕРАКТИВ 1
Квадраты на сторонах — тяни слайдеры
+
Меняй катеты — квадраты пересчитываются. Маленькие квадраты $a^2 + b^2$ равны большому $c^2$.
+
+ + +
+
+
+
`; + + /* ИНТЕРАКТИВ 2 — Анимация доказательства */ + html+=`
+
ИНТЕРАКТИВ 2
Доказательство: квадрат (a+b)
+
5 шагов — классическое доказательство через два больших квадрата.
+
+
+
+ + +
+
`; + + /* ИНТЕРАКТИВ 3 — Калькулятор */ + html+=`
+
ИНТЕРАКТИВ 3
Калькулятор Пифагора
+
+
+
a, b → c
+
+ + + +
+
+
+
+
c, a → b
+
+ + + +
+
+
+
+
Диагональ прямоугольника a×b
+
+ + + +
+
+
+
+
`; + + /* ИНТЕРАКТИВ 4 — Тренажёр */ + html+=`
+
ИНТЕРАКТИВ 4
Тренажёр §11
+
5 задач — гипотенуза, катет, диагональ.
+
Задача 1 / 5Очки: 0
+
+
+ + + +
+ +
`; + + /* ИНТЕРАКТИВ 5 — DnD тройки Пифагора */ + html+=`
+
ИНТЕРАКТИВ 5
Тройки Пифагора — сортировщик
+
Перетащи каждый набор в нужную колонку: «Тройка Пифагора» или «Не тройка».
+
+
+
Тройка Пифагора
+
+
+
+
Не тройка
+
+
+
+
+
+ + +
+ +
`; + + /* ИНТЕРАКТИВ 6 — Босс §11 */ + html+=`
+
БОСС §11
Итоговые задачи
+
5 задач — +5 XP каждая.
+
+
`; + + html+=`
+ +
`; + html+=secNav('p10','p12'); + box.innerHTML=html; + if(window.renderMathInElement) setTimeout(()=>renderMath(box),0); + + /* == INIT: Слайдер квадраты == */ + (function(){ + const slA=document.getElementById('p11-sl-a'); + const slB=document.getElementById('p11-sl-b'); + const W=360, H=300; + function draw(){ + const a=+slA.value, b=+slB.value; + document.getElementById('p11-sl-a-val').textContent=a; + document.getElementById('p11-sl-b-val').textContent=b; + const c=Math.sqrt(a*a+b*b); + const scale=12; // px per unit + const ax=a*scale, bx=b*scale; + const clen=+c.toFixed(3); + // triangle: right angle at origin R=(80,220), B=(80+ax,220), A=(80,220-bx) + const Rx=80, Ry=220; + const Bx=Rx+ax, By=Ry; + const Ax=Rx, Ay=Ry-bx; + let s=''; + // triangle + s+=''; + // right angle at R + s+=''; + // square on a (below triangle): R to B bottom side, extend down + const sqAh=Math.max(16,Math.min(40,ax*0.4)); + s+=''; + s+='a²='+a*a+''; + // square on b (left of triangle) + const sqBw=Math.max(16,Math.min(40,bx*0.4)); + s+=''; + s+='b²='+b*b+''; + // labels + s+='a='+a+''; + s+='b='+b+''; + s+='c='+clen+''; + s+=''; + document.getElementById('p11-sq-svg-wrap').innerHTML=s; + document.getElementById('p11-sq-info').innerHTML=` +
${a*a}
+
${b*b}
+
a²+b²
${a*a+b*b}
+
c = √(a²+b²)
${clen}
`; + } + slA.addEventListener('input',draw); + slB.addEventListener('input',draw); + draw(); + })(); + + /* == INIT: Анимация доказательства == */ + (function(){ + let step=0; + const W=360, H=240; + const S=160, off=20; // big square side, offset + // a=100, b=60 in px (a+b=160) + const a=100, b=60; + // 4 triangle vertices in big square at off,off: + // TL: (off,off+a)-(off,off)-(off+b,off) + // TR: (off+b,off)-(off+S,off)-(off+S,off+b)... wait use standard rotation: + // Let inner square vertices at: (off+b,off),(off+S,off+a),(off+a,off+S),(off,off+b) + const iv=[[off+b,off],[off+S,off+a],[off+a,off+S],[off,off+b]]; + function ivStr(){return iv.map(p=>p[0]+','+p[1]).join(' ');} + const triStroke='#0d9488'; + const triFill='rgba(13,148,136,.28)'; + function drawTris(){ + return '' + +'' + +'' + +''; + } + const steps=[ + {desc:'Большой квадрат со стороной $(a+b)$. Площадь $(a+b)^2$.', + draw(){return '' + +'(a+b)';}}, + {desc:'Внутри расположим 4 прямоугольных треугольника с катетами $a$ и $b$ (голубые).', + draw(){return ''+drawTris();}}, + {desc:'Внутри треугольников остаётся квадрат со стороной $c$ (гипотенуза). Его площадь $= c^2$.', + draw(){return ''+drawTris() + +'' + +'';}}, + {desc:'Площадь 4 треугольников $= 4\\cdot\\dfrac{ab}{2}=2ab$.', + draw(){return ''+drawTris() + +'4·(ab/2)=2ab';}}, + {desc:'$c^2 = (a+b)^2 - 2ab = a^2+2ab+b^2-2ab = a^2+b^2$. Теорема доказана! $\\square$', + draw(){return ''+drawTris() + +'' + +'c²=a²+b²' + +'Q.E.D.';}}, + ]; + function render(){ + const s=steps[step]; + document.getElementById('p11-proof-svg-wrap').innerHTML=''+s.draw()+''; + document.getElementById('p11-proof-desc').innerHTML='Шаг '+(step+1)+' / '+steps.length+'. '+s.desc; + document.getElementById('p11-proof-next').textContent=step{ + if(step{step=0;render();}); + render(); + })(); + + /* == INIT: Калькулятор == */ + (function(){ + document.getElementById('p11-go1').addEventListener('click',()=>{ + const a=parseFloat(document.getElementById('p11-ca').value); + const b=parseFloat(document.getElementById('p11-cb').value); + const out=document.getElementById('p11-out1'); + if(!isFinite(a)||!isFinite(b)||a<=0||b<=0){out.innerHTML='Введи положительные числа.';return;} + const c=Math.sqrt(a*a+b*b); + out.innerHTML='$c=\\sqrt{'+fmt(a)+'{}^2+'+fmt(b)+'{}^2}=\\sqrt{'+fmt(a*a+b*b)+'}='+fmt(+c.toFixed(4))+'$'; + renderMath(out);addXp(1,'p11-calc1'); + }); + document.getElementById('p11-go2').addEventListener('click',()=>{ + const c=parseFloat(document.getElementById('p11-cc').value); + const a=parseFloat(document.getElementById('p11-ca2').value); + const out=document.getElementById('p11-out2'); + if(!isFinite(c)||!isFinite(a)||c<=0||a<=0||c<=a){out.innerHTML='c должна быть больше a.';return;} + const b=Math.sqrt(c*c-a*a); + out.innerHTML='$b=\\sqrt{'+fmt(c)+'{}^2-'+fmt(a)+'{}^2}=\\sqrt{'+fmt(c*c-a*a)+'}='+fmt(+b.toFixed(4))+'$'; + renderMath(out);addXp(1,'p11-calc2'); + }); + document.getElementById('p11-go3').addEventListener('click',()=>{ + const a=parseFloat(document.getElementById('p11-da').value); + const b=parseFloat(document.getElementById('p11-db').value); + const out=document.getElementById('p11-out3'); + if(!isFinite(a)||!isFinite(b)||a<=0||b<=0){out.innerHTML='Введи положительные числа.';return;} + const d=Math.sqrt(a*a+b*b); + out.innerHTML='$d=\\sqrt{'+fmt(a)+'{}^2+'+fmt(b)+'{}^2}='+fmt(+d.toFixed(4))+'$'; + renderMath(out);addXp(1,'p11-calc3'); + }); + })(); + + /* == INIT: Тренажёр == */ + (function(){ + const tasks=[ + {q:'a = 5b=12c=?Катеты 5 и 12. Гипотенуза?', ans:13, hint:'√(25+144)=√169=13.'}, + {q:'a = 9b=?c=15Катет 9, гипотенуза 15. Второй катет?', ans:12, hint:'√(225−81)=√144=12.'}, + {q:'a = 6 смb=8d=?Прямоугольник 6×8 см. Диагональ?', ans:10, hint:'d=√(36+64)=√100=10.'}, + {q:'Квадрат со стороной 7 см. Диагональ? (Ответ в формате, используй √2≈1,414, ответ округли до целых)', ans:10, hint:'d=7√2≈9,9≈10.'}, + {q:'Катет 6 дм, гипотенуза 10 дм. Другой катет?', ans:8, hint:'b=√(100−36)=√64=8.'}, + ]; + let idx=0, score=0; + function show(){ + document.getElementById('p11-tr-i').textContent=idx+1; + document.getElementById('p11-tr-task').innerHTML=tasks[idx].q; + document.getElementById('p11-tr-ans').value=''; + document.getElementById('p11-tr-fb').style.display='none'; + if(window.renderMathInElement)renderMath(document.getElementById('p11-tr-task')); + } + document.getElementById('p11-tr-start').addEventListener('click',()=>{idx=0;score=0;document.getElementById('p11-tr-score').textContent=0;show();}); + document.getElementById('p11-tr-go').addEventListener('click',()=>{ + if(idx>=tasks.length)return; + const ans=+document.getElementById('p11-tr-ans').value; + const fb=document.getElementById('p11-tr-fb'); + fb.style.display='block'; + if(Math.abs(ans-tasks[idx].ans)<0.5){ + score++;document.getElementById('p11-tr-score').textContent=score; + addXp(3,'p11-tr-'+idx);bumpProgress('p11',5); + if(idxshow(),900);} + else{feedback(fb,true,'Все задачи решены! +5 XP');addXp(5,'p11-tr-all');bumpProgress('p11',10);} + } else {feedback(fb,false,'Неверно. '+tasks[idx].hint);} + }); + document.getElementById('p11-tr-ans').addEventListener('keydown',e=>{if(e.key==='Enter')document.getElementById('p11-tr-go').click();}); + show(); + })(); + + /* == INIT: DnD тройки Пифагора == */ + (function(){ + function isPyth(a,b,c){const s=[a,b,c].sort((x,y)=>x-y);return s[0]*s[0]+s[1]*s[1]===s[2]*s[2];} + const items=[ + {id:'t1',html:'3, 4, 5',cat:'yes'}, + {id:'t2',html:'5, 12, 13',cat:'yes'}, + {id:'t3',html:'6, 8, 10',cat:'yes'}, + {id:'t4',html:'7, 24, 25',cat:'yes'}, + {id:'t5',html:'2, 3, 4',cat:'no'}, + {id:'t6',html:'1, 1, 2',cat:'no'}, + {id:'t7',html:'9, 12, 15',cat:'yes'}, + {id:'t8',html:'4, 5, 7',cat:'no'}, + ]; + const sorter=setupSorter({poolId:'p11-dnd-pool',scopeSelector:'#p11-dnd-wg', + items:items.map(x=>({id:x.id,html:x.html})), + cats:['yes','no']}); + document.getElementById('p11-dnd-check').addEventListener('click',()=>{ + const fb=document.getElementById('p11-dnd-fb'); + fb.style.display='block'; + let ok=0,total=0; + items.forEach(it=>{ + if(sorter.placed[it.id]!==undefined){total++;if(sorter.placed[it.id]===it.cat)ok++;} + }); + if(ok===items.length){feedback(fb,true,'Всё верно! +5 XP');addXp(5,'p11-dnd');bumpProgress('p11',10);confetti();} + else{feedback(fb,false,'Верно: '+ok+' из '+items.length+'. Проверь: (3,4,5),(5,12,13),(6,8,10),(7,24,25),(9,12,15) — тройки.');} + }); + document.getElementById('p11-dnd-reset').addEventListener('click',()=>{sorter.reset();document.getElementById('p11-dnd-fb').style.display='none';}); + })(); + + /* == INIT: Босс §11 == */ + (function(){ + const tasks=[ + {q:'a=24b=10c=?Катеты 10 и 24. Гипотенуза?', ans:26, hint:'√(100+576)=√676=26.'}, + {q:'a=? смb=9d=15Диагональ прямоугольника 15 см, одна сторона 9 см. Другая сторона?', ans:12, hint:'a=√(225−81)=√144=12.'}, + {q:'Равнобедренный прямоугольный треугольник, гипотенуза 10√2 ≈ 14,1. Катет? (целое число)', ans:10, hint:'a²+a²=(10√2)²=200 → a²=100 → a=10.'}, + {q:'В прямоугольном треугольнике гипотенуза 25, один катет 7. Площадь треугольника?', ans:84, hint:'b=√(625−49)=√576=24. S=7·24/2=84.'}, + {q:'Квадрат со стороной 5 м. Диагональ (целое число, используй √2≈1,414)?', ans:7, hint:'d=5√2≈7,07≈7.'}, + ]; + const bossBox=document.getElementById('p11-boss-tasks'); + bossBox.innerHTML=tasks.map((t,i)=>` +
+
${t.q}
+
+ + + +
+
`).join(''); + if(window.renderMathInElement)renderMath(bossBox); + })(); +} function buildP12stub(){ document.getElementById('p12-body').innerHTML='

§12 — Волна 1: содержимое появится в следующем обновлении.

'+secNav('p11','p13'); } function buildP13stub(){ document.getElementById('p13-body').innerHTML='

§13 — Волна 1: содержимое появится в следующем обновлении.

'+secNav('p12','p14'); } function buildP14stub(){ document.getElementById('p14-body').innerHTML='

§14 — Волна 1: содержимое появится в следующем обновлении.

'+secNav('p13','p15'); }