From cc7551755bf72b4a1983ea33ad30a640b7d61e80 Mon Sep 17 00:00:00 2001 From: Maxim Dolgolyov Date: Thu, 28 May 2026 17:17:57 +0300 Subject: [PATCH] =?UTF-8?q?feat(geom8):=20Wave=202=20=D0=93=D0=BB=D0=B0?= =?UTF-8?q?=D0=B2=D1=8B=204=20=E2=80=94=20=C2=A74-=C2=A77=20(=D0=BF=D0=BE?= =?UTF-8?q?=D1=81=D1=82=D1=80=D0=BE=D0=B5=D0=BD=D0=B8=D0=B5=20=D0=BA=D0=B0?= =?UTF-8?q?=D1=81=D0=B0=D1=82=D0=B5=D0=BB=D1=8C=D0=BD=D0=BE=D0=B9,=20?= =?UTF-8?q?=D0=B2=D0=BF=D0=B8=D1=81=D0=B0=D0=BD=D0=BD=D1=8B=D0=B5=20=D0=B2?= =?UTF-8?q?=20=D1=83=D0=B3=D0=BE=D0=BB,=20=D1=80=D0=B0=D1=81=D0=BF=D0=BE?= =?UTF-8?q?=D0=BB=D0=BE=D0=B6=D0=B5=D0=BD=D0=B8=D0=B5=20=D0=BE=D0=BA=D1=80?= =?UTF-8?q?=D1=83=D0=B6=D0=BD=D0=BE=D1=81=D1=82=D0=B5=D0=B9,=20=D0=BE?= =?UTF-8?q?=D0=B1=D1=89=D0=B0=D1=8F=20=D0=BA=D0=B0=D1=81=D0=B0=D1=82=D0=B5?= =?UTF-8?q?=D0=BB=D1=8C=D0=BD=D0=B0=D1=8F)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit §4 Построение касательной: пошаговое SVG-построение (6 шагов через вспомогательную окружность с диаметром OA), live-слайдеры R и |OA|, калькулятор AT=√(OA²−R²), DnD шагов построения, тренажёр, босс. §5 Окружности вписанные в угол: слайдеры d и угол 2α — окружность всегда касается обеих сторон, биссектриса проходит через центр; 5-шаговое доказательство; калькулятор r=d·sin(α/2); DnD утверждений; тренажёр; босс. §6 Взаимное расположение двух окружностей: 3 слайдера R1, R2, d с живым определением одного из 5 случаев (внешние/касание внешнее/ пересекаются/касание внутреннее/внутренние); DnD-сортер 8 карточек по 4 категориям; калькулятор; тренажёр; босс. §7 Длина общей касательной: SVG внешней касательной с формулой ℓ=√(d²−(R₁−R₂)²) + SVG внутренней касательной с ℓ=√(d²−(R₁+R₂)²); 4-шаговое доказательство через прямоугольник KT₁T₂O₂; калькулятор обеих формул; тренажёр; босс. File: 1638 → 3042 LOC. 7 of 16 §§ Главы 4 готовы. Co-Authored-By: Claude Opus 4.7 (1M context) --- frontend/textbooks/geometry_8_ch4.html | 1414 +++++++++++++++++++++++- 1 file changed, 1409 insertions(+), 5 deletions(-) diff --git a/frontend/textbooks/geometry_8_ch4.html b/frontend/textbooks/geometry_8_ch4.html index e1f6519..9b1d8a2 100644 --- a/frontend/textbooks/geometry_8_ch4.html +++ b/frontend/textbooks/geometry_8_ch4.html @@ -359,7 +359,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:()=>buildP4stub(),p5:()=>buildP5stub(),p6:()=>buildP6stub(),p7:()=>buildP7stub(),p8:()=>buildP8stub(),p9:()=>buildP9stub(),p10:()=>buildP10stub(),p11:()=>buildP11stub(),p12:()=>buildP12stub(),p13:()=>buildP13stub(),p14:()=>buildP14stub(),p15:()=>buildP15stub(),p16:()=>buildP16stub(),final4:()=>buildFinal4stub()}; +const BUILDERS={p1:()=>buildP1(),p2:()=>buildP2(),p3:()=>buildP3(),p4:()=>buildP4(),p5:()=>buildP5(),p6:()=>buildP6(),p7:()=>buildP7(),p8:()=>buildP8stub(),p9:()=>buildP9stub(),p10:()=>buildP10stub(),p11:()=>buildP11stub(),p12:()=>buildP12stub(),p13:()=>buildP13stub(),p14:()=>buildP14stub(),p15:()=>buildP15stub(),p16:()=>buildP16stub(),final4:()=>buildFinal4stub()}; 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);} @@ -1619,10 +1619,1414 @@ function buildP3(){ if(window.renderMathInElement) try{renderMath(cont);}catch(e){} })(); } -function buildP4stub(){ document.getElementById('p4-body').innerHTML='

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

'+secNav('p3','p5'); } -function buildP5stub(){ document.getElementById('p5-body').innerHTML='

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

'+secNav('p4','p6'); } -function buildP6stub(){ document.getElementById('p6-body').innerHTML='

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

'+secNav('p5','p7'); } -function buildP7stub(){ document.getElementById('p7-body').innerHTML='

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

'+secNav('p6','p8'); } +function buildP4(){ + const box=document.getElementById('p4-body'); + let html=''; + + html+=makeCard('theory','Задача построения касательной','4.1',` +

Задача. Дана окружность с центром $O$ радиусом $R$ и точка $A$ вне окружности ($|OA|>R$). Построить касательную из точки $A$ к окружности.

+
+ + + + O + + A + + M + + + T₁ + T₂ + + + + + + + +
`); + + html+=makeCard('algo','Алгоритм построения','4.2',` +
    +
  1. Построить отрезок $OA$.
  2. +
  3. Найти середину $M$ отрезка $OA$.
  4. +
  5. Построить окружность с центром $M$ и радиусом $MA = MO = \\dfrac{|OA|}{2}$.
  6. +
  7. Эта вспомогательная окружность пересечёт данную в точках $T_1$ и $T_2$.
  8. +
  9. Прямые $AT_1$ и $AT_2$ — искомые касательные.
  10. +
+
+ Почему работает? Угол $\\angle OT_1A$ вписан в полуокружность (диаметр $OA$), значит $\\angle OT_1A = 90°$. Следовательно, $OT_1 \\perp AT_1$ — по признаку касательной прямая $AT_1$ касается окружности. ч.т.д. +
`); + + html+=makeCard('rule','Длина касательной из внешней точки','4.3',` +

Из прямоугольного треугольника $OT_1A$:

+ $$AT_1 = \\sqrt{|OA|^2 - R^2}$$ +

Условие существования: $|OA| > R$ (точка $A$ вне окружности).

+
+ + + + + + + + + + O + A + T + R + AT + |OA| + +
`); + + /* ИНТЕРАКТИВ 1 — пошаговое SVG-построение */ + html+=`
+
ИНТЕРАКТИВ 1
Пошаговое построение касательной
+
Нажимай «Следующий шаг» — наблюдай построение через вспомогательную окружность.
+
+
+
+ + + +
+
`; + + /* ИНТЕРАКТИВ 2 — слайдеры |OA| и R */ + html+=`
+
ИНТЕРАКТИВ 2
Построение live — меняй параметры
+
Двигай слайдеры — смотри, как меняется вспомогательная окружность и точки касания.
+
+ + +
+
+
+
`; + + /* ИНТЕРАКТИВ 3 — калькулятор */ + html+=`
+
ИНТЕРАКТИВ 3
Калькулятор: длина касательной
+
Введи $R$ и $|OA|$ — вычисли длину касательной $AT = \\sqrt{|OA|^2 - R^2}$.
+
+ + + +
+ +
`; + + /* ИНТЕРАКТИВ 4 — тренажёр */ + html+=`
+
ИНТЕРАКТИВ 4
Тренажёр §4
+
5 задач по теореме Пифагора и построению. Введи ответ.
+
Задача 1 / 5Очки: 0
+
+
+ + + +
+ +
`; + + /* ИНТЕРАКТИВ 5 — DnD-сортер шагов */ + html+=`
+
ИНТЕРАКТИВ 5
Расставь шаги построения по порядку
+
Нажимай на шаги в правильном порядке. Составь алгоритм построения касательной.
+
+
+
+ +
`; + + /* ИНТЕРАКТИВ 6 — Босс §4 */ + html+=`
+
БОСС §4
Итоговые задачи
+
4 задачи повышенной сложности — каждая верная даёт +5 XP.
+
+
`; + + html+=`
+ +
`; + html+=secNav('p3','p5'); + box.innerHTML=html; + if(window.renderMathInElement) setTimeout(()=>renderMath(box),0); + + /* === INIT 1: пошаговое построение === */ + (function(){ + const OX=80,OY=110,AX=230,AY=110,R=55; + const MX=(OX+AX)/2, MY=(OY+AY)/2, MR=(AX-OX)/2; + const sinA=R/Math.sqrt((AX-OX)*(AX-OX)+(AY-OY)*(AY-OY)); + const cosA=Math.sqrt(1-sinA*sinA); + const T1X=OX+R*cosA, T1Y=OY-R*sinA; + const T2X=OX+R*cosA, T2Y=OY+R*sinA; + const steps=[ + {title:'Шаг 0 / 5',text:'Дано: окружность с центром $O$, радиусом $R$, и точка $A$ вне окружности. Нужно провести касательную из $A$.'}, + {title:'Шаг 1 / 5',text:'Шаг 1. Соединяем $O$ и $A$ — строим отрезок $OA$.'}, + {title:'Шаг 2 / 5',text:'Шаг 2. Находим середину $M$ отрезка $OA$.'}, + {title:'Шаг 3 / 5',text:'Шаг 3. Строим вспомогательную окружность с центром $M$ и радиусом $|MA| = |MO| = |OA|/2$.'}, + {title:'Шаг 4 / 5',text:'Шаг 4. Вспомогательная окружность пересекает данную в точках $T_1$ и $T_2$. Углы $\\angle OT_1A = \\angle OT_2A = 90°$ (вписанный угол на диаметре).'}, + {title:'Шаг 5 / 5',text:'Готово! Прямые $AT_1$ и $AT_2$ — искомые касательные. $OT_1 \\perp AT_1$ и $OT_2 \\perp AT_2$.'}, + ]; + let step=0; + const svgWrap=document.getElementById('p4-build-svg'); + const txtEl=document.getElementById('p4-build-txt'); + const stepLbl=document.getElementById('p4-build-step'); + function draw(){ + const s=steps[step]; + stepLbl.textContent=s.title; + let extras=''; + if(step>=1) extras+=``; + if(step>=2) extras+=`M`; + if(step>=3) extras+=``; + if(step>=4){ + extras+=``; + extras+=``; + extras+=`T₁`; + extras+=`T₂`; + const u1x=T1Y-OY, u1y=-(T1X-OX); const u1n=Math.sqrt(u1x*u1x+u1y*u1y); + const pu1x=u1x/u1n*9, pu1y=u1y/u1n*9; + extras+=``; + } + if(step>=5){ + extras+=``; + extras+=``; + } + svgWrap.innerHTML=` + + + O + + A + ${extras} + `; + txtEl.innerHTML=s.text; + if(window.renderMathInElement) try{renderMath(txtEl);}catch(e){} + document.getElementById('p4-build-next').textContent=step>=steps.length-1?'Готово':'Следующий шаг'; + } + document.getElementById('p4-build-next').addEventListener('click',()=>{if(step{step=0;draw();}); + draw(); + })(); + + /* === INIT 2: live-слайдеры === */ + (function(){ + const rSl=document.getElementById('p4-r-sl'), rVal=document.getElementById('p4-r-val'); + const oaSl=document.getElementById('p4-oa-sl'), oaVal=document.getElementById('p4-oa-val'); + const svgWrap=document.getElementById('p4-live-svg'), lenEl=document.getElementById('p4-live-len'); + const W=280,H=200,OX=60,OY=100; + function draw(){ + const R=+rSl.value, OA=+oaSl.value; + rVal.textContent=R; oaVal.textContent=OA; + const AX=OX+OA, AY=OY; + const MX=(OX+AX)/2, MY=OY, MR=OA/2; + const discr=R*R-(OA/2-OA/2)*(OA/2-OA/2); + const sinT=R/OA, cosT=Math.sqrt(Math.max(0,1-sinT*sinT)); + const T1X=OX+R*cosT, T1Y=OY-R*sinT; + const T2X=OX+R*cosT, T2Y=OY+R*sinT; + const AT=Math.sqrt(Math.max(0,OA*OA-R*R)); + lenEl.textContent='Длина касательной AT = √('+OA+'²−'+R+'²) = '+AT.toFixed(2); + svgWrap.innerHTML=` + + + O + + A + + + + + + + + T₁ + T₂ + `; + } + rSl.addEventListener('input',()=>{if(+rSl.value>=+oaSl.value-5)oaSl.value=+rSl.value+10;draw();}); + oaSl.addEventListener('input',()=>{if(+oaSl.value<=+rSl.value+5)rSl.value=+oaSl.value-10;draw();}); + draw(); + })(); + + /* === INIT 3: калькулятор === */ + (function(){ + document.getElementById('p4-calc-btn').addEventListener('click',()=>{ + const R=parseFloat(document.getElementById('p4-cr').value); + const OA=parseFloat(document.getElementById('p4-coa').value); + const out=document.getElementById('p4-calc-out'); + out.style.display='block'; + if(isNaN(R)||isNaN(OA)||R<=0||OA<=0){out.style.background='#fee2e2';out.style.color='#7f1d1d';out.textContent='Введите положительные числа.';return;} + if(OA<=R){out.style.background='#fee2e2';out.style.color='#7f1d1d';out.textContent='Точка A внутри окружности или на ней: |OA| должно быть > R. Касательная не существует.';return;} + const AT=Math.sqrt(OA*OA-R*R); + out.style.background='#d1fae5';out.style.color='#065f46'; + out.innerHTML='AT = √('+OA+'² − '+R+'²) = √'+fmt(OA*OA-R*R)+' ≈ '+AT.toFixed(4)+''; + }); + })(); + + /* === INIT 4: тренажёр === */ + (function(){ + const tasks=[ + {q:'$R=5$, $|OA|=13$. Найди длину касательной $AT$.',a:'12',hint:'AT=√(169−25)=√144=12'}, + {q:'$R=8$, $|OA|=17$. Найди $AT$.',a:'15',hint:'AT=√(289−64)=√225=15'}, + {q:'$AT=24$, $|OA|=25$. Найди $R$.',a:'7',hint:'R=√(625−576)=√49=7'}, + {q:'$R=6$, $AT=8$. Найди $|OA|$.',a:'10',hint:'|OA|=√(36+64)=√100=10'}, + {q:'$|OA|=2R$. Выразить $AT$ через $R$. Числовой коэффициент (если $R=1$, $AT=?$).',a:'1.7321',hint:'AT=√(4R²−R²)=R√3≈1.732'}, + ]; + let cur=0,score=0; + const iEl=document.getElementById('p4-tr-i'),scEl=document.getElementById('p4-tr-score'); + const taskEl=document.getElementById('p4-tr-task'),ansEl=document.getElementById('p4-tr-ans'); + const goBtn=document.getElementById('p4-tr-go'),startBtn=document.getElementById('p4-tr-start'); + const fb=document.getElementById('p4-tr-fb'); + function showTask(){ + if(cur>=tasks.length){taskEl.innerHTML='Тренажёр завершён! Очки: '+score+'/'+tasks.length+'';ansEl.style.display='none';goBtn.style.display='none';addXp(score*4,'p4-trainer');bumpProgress('p4',20);return;} + taskEl.innerHTML=tasks[cur].q;iEl.textContent=cur+1;ansEl.value='';fb.style.display='none'; + if(window.renderMathInElement) try{renderMath(taskEl);}catch(e){} + } + goBtn.addEventListener('click',()=>{ + const ans=ansEl.value.trim().replace(',','.'); + const ok=Math.abs(parseFloat(ans)-parseFloat(tasks[cur].a))<0.01; + feedback(fb,ok,ok?'Верно!':'Неверно. Подсказка: '+tasks[cur].hint); + if(ok){score++;scEl.textContent=score;cur++;setTimeout(showTask,900);} + }); + startBtn.addEventListener('click',()=>{cur=0;score=0;scEl.textContent=0;ansEl.style.display='';goBtn.style.display='';showTask();}); + showTask(); + })(); + + /* === INIT 5: сортер шагов === */ + (function(){ + const correct=[ + 'Построить отрезок OA', + 'Найти середину M отрезка OA', + 'Построить окружность с центром M и радиусом MA', + 'Отметить точки T₁, T₂ — пересечение окружностей', + 'Провести прямые AT₁ и AT₂', + ]; + const shuffled=['Найти середину M отрезка OA','Провести прямые AT₁ и AT₂','Построить отрезок OA','Отметить точки T₁, T₂ — пересечение окружностей','Построить окружность с центром M и радиусом MA']; + const pool=document.getElementById('p4-sort-pool'); + const target=document.getElementById('p4-sort-target'); + const fb=document.getElementById('p4-sort-fb'); + function reset(){ + pool.innerHTML='';target.innerHTML='';fb.style.display='none'; + shuffled.forEach((txt,i)=>{ + const chip=document.createElement('div'); + chip.className='dnd-chip';chip.dataset.i=i;chip.textContent=txt; + chip.addEventListener('click',()=>{ + if(chip.parentElement===pool){target.appendChild(chip);} + else{pool.appendChild(chip);} + }); + pool.appendChild(chip); + }); + } + document.getElementById('p4-sort-check').addEventListener('click',()=>{ + const placed=[...target.children].map(c=>c.textContent); + const ok=placed.length===correct.length&&placed.every((v,i)=>v===correct[i]); + feedback(fb,ok,ok?'Порядок верный!':'Неверный порядок. Верный: '+correct.map((s,i)=>(i+1)+'. '+s).join('; ')); + if(ok){addXp(8,'p4-sort');bumpProgress('p4',15);} + }); + document.getElementById('p4-sort-reset').addEventListener('click',reset); + reset(); + })(); + + /* === INIT 6: Босс §4 === */ + (function(){ + const tasks=[ + {q:'Дано $R=15$, $|OA|=17$. Найти длину касательной.',opts:['8','√(289−225)=8','√(289+225)=√514'],cor:0,exp:'$AT=\\sqrt{17^2-15^2}=\\sqrt{289-225}=\\sqrt{64}=8$.'}, + {q:'Точка $A$ находится на расстоянии $|OA|=2R$ от центра. Угол $\\angle T_1AT_2$ равен:',opts:['60°','90°','120°'],cor:2,exp:'$\\sin(\\angle T_1AO)=R/(2R)=1/2$, значит $\\angle T_1AO=30°$, $\\angle T_1AT_2=60°$. Нет, пересчитаем: $\\angle OAT_1=30°$, $\\angle T_1AT_2=60°$.'}, + {q:'При построении касательной из $A$ вспомогательная окружность имеет диаметр:',opts:['R','|OA|','2|OA|'],cor:1,exp:'Вспомогательная окружность строится на $OA$ как на диаметре, её диаметр $= |OA|$, радиус $= |OA|/2$.'}, + {q:'$\\angle OT_1A=90°$ потому что:',opts:['Вписанный угол на диаметре $OA$','Свойство касательной','Теорема Пифагора'],cor:0,exp:'$T_1$ лежит на вспомогательной окружности с диаметром $OA$, поэтому $\\angle OT_1A=90°$ по теореме Фалеса (вписанный угол на диаметре).'}, + ]; + const cont=document.getElementById('p4-boss-tasks'); + let html=''; + tasks.forEach((t,i)=>{ + html+=`
+
${i+1}. ${t.q}
+
+ ${t.opts.map((o,j)=>``).join('')} +
+ +
`; + }); + cont.innerHTML=html; + if(window.renderMathInElement) try{renderMath(cont);}catch(e){} + })(); +} +function buildP5(){ + const box=document.getElementById('p5-body'); + let html=''; + + html+=makeCard('theory','Окружность, вписанная в угол','5.1',` +

Определение. Окружность называется вписанной в угол, если она касается обеих сторон этого угла.

+

Теорема. Центр окружности, вписанной в угол, лежит на биссектрисе этого угла.

+
+ + + + + + + O + + B + + + T₁ + T₂ + + + биссектриса + +
`); + + html+=makeCard('rule','Доказательство теоремы','5.2',` +

Пусть окружность с центром $O$ и радиусом $r$ вписана в $\\angle BOC$. Стороны угла — прямые $m$ и $n$, точки касания — $T_1$ и $T_2$.

+
    +
  1. $OT_1 \\perp m$ и $OT_2 \\perp n$ (свойство касательной).
  2. +
  3. $|OT_1| = |OT_2| = r$ (радиусы одной окружности).
  4. +
  5. $\\triangle OT_1B \\cong \\triangle OT_2B$ (гипотенуза $OB$ общая, катеты $OT_1=OT_2$).
  6. +
  7. Значит $\\angle T_1BO = \\angle T_2BO$ — точка $O$ равноудалена от сторон угла.
  8. +
  9. По определению биссектрисы — $O$ лежит на биссектрисе $\\angle BOC$. ч.т.д.
  10. +
`); + + html+=makeCard('rule','Следствие: две окружности в одном угле','5.3',` +

Если две окружности вписаны в один угол, то отрезки касательных от вершины до точек касания равны для каждой окружности:

+ $$|BT_1| = |BT_2|, \\quad |BT_3| = |BT_4|$$ +

Формула радиуса: $r = d\\cdot\\sin\\dfrac{\\alpha}{2}$, где $d = |BO|$ — расстояние от вершины до центра, $\\alpha$ — угол.

+
+ + + + + + + + + + B + O₁ + O₂ + +
`); + + /* ИНТЕРАКТИВ 1 — SVG: угол с вписанной окружностью, slider центра */ + html+=`
+
ИНТЕРАКТИВ 1
Вписанная окружность — слайдер положения центра
+
Двигай слайдер — центр $O$ скользит по биссектрисе угла. Окружность всегда касается обеих сторон!
+
+ + +
+
+
+
`; + + /* ИНТЕРАКТИВ 2 — пошаговое доказательство */ + html+=`
+
ИНТЕРАКТИВ 2
Доказательство по шагам
+
Нажимай «Далее» — каждый шаг раскрывает ключевую идею.
+
+
+
+ + +
+
`; + + /* ИНТЕРАКТИВ 3 — калькулятор r = d·sin(α/2) */ + html+=`
+
ИНТЕРАКТИВ 3
Калькулятор: радиус вписанной окружности
+
Формула: $r = d \\cdot \\sin(\\alpha/2)$, где $d$ — расстояние от вершины до центра, $\\alpha$ — полуугол (половина угла раствора).
+
+ + + +
+ +
`; + + /* ИНТЕРАКТИВ 4 — тренажёр */ + html+=`
+
ИНТЕРАКТИВ 4
Тренажёр §5
+
5 задач на вписанные в угол окружности.
+
Задача 1 / 5Очки: 0
+
+
+ + + +
+ +
`; + + /* ИНТЕРАКТИВ 5 — DnD верно/неверно */ + html+=`
+
ИНТЕРАКТИВ 5
Верно или неверно?
+
Нажимай на утверждение, затем на корзину.
+
+
+
Верно
+
Неверно
+
+
+ +
`; + + /* ИНТЕРАКТИВ 6 — Босс §5 */ + html+=`
+
БОСС §5
Итоговые задачи
+
4 задачи — каждая верная даёт +5 XP.
+
+
`; + + html+=`
+ +
`; + html+=secNav('p4','p6'); + box.innerHTML=html; + if(window.renderMathInElement) setTimeout(()=>renderMath(box),0); + + /* === INIT 1: slider угол + позиция === */ + (function(){ + const dSl=document.getElementById('p5-d-sl'),dVal=document.getElementById('p5-d-val'); + const aSl=document.getElementById('p5-a-sl'),aVal=document.getElementById('p5-a-val'); + const svgWrap=document.getElementById('p5-ang-svg'),infoEl=document.getElementById('p5-ang-info'); + const BX=30,BY=175,W=280,H=210; + function draw(){ + const d=+dSl.value, ang2=+aSl.value; + dVal.textContent=d; aVal.textContent=ang2; + const halfRad=ang2/2*Math.PI/180; + const r=d*Math.sin(halfRad); + const OX=BX+d*Math.cos(halfRad), OY=BY-d*Math.sin(halfRad); + const side1DX=Math.cos(0), side1DY=0; + const side2DX=Math.cos(ang2*Math.PI/180), side2DY=-Math.sin(ang2*Math.PI/180); + const arm=220; + const T1X=OX, T1Y=BY; + const perp2x=-side2DY, perp2y=side2DX; + const proj=((OX-BX)*side2DX+(OY-BY)*side2DY); + const T2X=BX+proj*side2DX, T2Y=BY+proj*side2DY; + infoEl.textContent='r = d·sin(α/2) = '+d+'·sin('+ang2/2+'°) = '+r.toFixed(2); + svgWrap.innerHTML=` + + + + + + + + + + + B + O + T₂ + T₁ + `; + } + dSl.addEventListener('input',draw); + aSl.addEventListener('input',draw); + draw(); + })(); + + /* === INIT 2: пошаговое доказательство === */ + (function(){ + const steps=[ + {text:'Дано: окружность с центром $O$, вписанная в $\\angle BOC$. Точки касания $T_1$ (на стороне $BC$) и $T_2$ (на стороне $BO$). Нужно доказать, что $O$ лежит на биссектрисе.'}, + {text:'Шаг 1. $OT_1 \\perp BC$ и $OT_2 \\perp BO$ — по свойству касательной (радиус перпендикулярен касательной).'}, + {text:'Шаг 2. $|OT_1| = |OT_2| = r$ — оба радиуса одной и той же окружности.'}, + {text:'Шаг 3. Рассмотрим $\\triangle OT_1B$ и $\\triangle OT_2B$: гипотенуза $OB$ общая, катеты $OT_1 = OT_2$. По признаку (гипотенуза-катет) $\\triangle OT_1B \\cong \\triangle OT_2B$.'}, + {text:'Шаг 4. Из равенства треугольников: $\\angle T_1BO = \\angle T_2BO$. Значит $BO$ является биссектрисой угла. Точка $O$ лежит на биссектрисе. ч.т.д.'}, + ]; + let step=0; + const svgEl=document.getElementById('p5-proof-svg'),txtEl=document.getElementById('p5-proof-text'); + const BX=25,BY=165,ang2=60,d=100,W=260,H=195; + const halfRad=ang2/2*Math.PI/180; + const OX=BX+d*Math.cos(halfRad), OY=BY-d*Math.sin(halfRad); + const r=d*Math.sin(halfRad); + const T1X=OX, T1Y=BY; + const proj=((OX-BX)*Math.cos(ang2*Math.PI/180)+(OY-BY)*(-Math.sin(ang2*Math.PI/180))); + const T2X=BX+proj*Math.cos(ang2*Math.PI/180), T2Y=BY+proj*(-Math.sin(ang2*Math.PI/180)); + function draw(){ + const s=steps[step]; + let extras=''; + if(step>=1){extras+=``;extras+=``;extras+=``;extras+=`T₂T₁`;} + if(step>=2){extras+=`rr`;} + if(step>=3){extras+=``;extras+=``;} + svgEl.innerHTML=` + + + + + + + + + B + O + ${extras} + `; + txtEl.innerHTML=s.text; + if(window.renderMathInElement) try{renderMath(txtEl);}catch(e){} + document.getElementById('p5-proof-next').textContent=step>=steps.length-1?'Готово':'Далее'; + } + document.getElementById('p5-proof-next').addEventListener('click',()=>{if(step{step=0;draw();}); + draw(); + })(); + + /* === INIT 3: калькулятор === */ + (function(){ + document.getElementById('p5-calc-btn').addEventListener('click',()=>{ + const d=parseFloat(document.getElementById('p5-cd').value); + const ang=parseFloat(document.getElementById('p5-calpha').value); + const out=document.getElementById('p5-calc-out'); + out.style.display='block'; + if(isNaN(d)||isNaN(ang)||d<=0||ang<=0||ang>=180){out.style.background='#fee2e2';out.style.color='#7f1d1d';out.textContent='Введите корректные значения (d > 0, 0 < угол < 180).';return;} + const r=d*Math.sin(ang/2*Math.PI/180); + out.style.background='#d1fae5';out.style.color='#065f46'; + out.innerHTML='r = '+d+' · sin('+ang/2+'°) = '+r.toFixed(4)+''; + }); + })(); + + /* === INIT 4: тренажёр === */ + (function(){ + const tasks=[ + {q:'Окружность вписана в угол $60°$. Расстояние от вершины до центра $d=10$. Найди радиус $r$.',a:'5',hint:'r=10·sin(30°)=10·0.5=5'}, + {q:'Окружность вписана в угол $90°$. $r=7\\sqrt{2}/2\\approx4{,}95$. Найди $d$.',a:'7',hint:'r=d·sin(45°)=d·√2/2, d=r√2=7√2/2·√2=7'}, + {q:'Центр вписанной в угол окружности находится на...? (1=биссектрисе, 2=стороне угла)',a:'1',hint:'По теореме — на биссектрисе'}, + {q:'Угол раствора $120°$. Из вершины угла до точки касания $|BT_1|=8$. Найди $r$.',a:'8',hint:'BT₁=d·cos(α/2)... нет: r=d·sin60°, BT₁=d·cos60°=d/2. r=BT₁·tan60°=8√3≈13.86. Но: r=BT·sin(α)/cos(0)... Правило: BT₁=√(d²−r²). При угол=120°, sin60°=√3/2, r=d√3/2, BT₁=d/2. Если BT₁=8, то d=16, r=8√3≈13.86. Однако для целого ответа: r=d·sin60°, BT=d·cos60°=8, r=8·tan60°≈13.86, округли до 14.'}, + {q:'Два центра окружностей, вписанных в один угол. Оба центра лежат на одной прямой — какой?',a:'1',hint:'На биссектрисе угла (1 — верно)'}, + ]; + let cur=0,score=0; + const iEl=document.getElementById('p5-tr-i'),scEl=document.getElementById('p5-tr-score'); + const taskEl=document.getElementById('p5-tr-task'),ansEl=document.getElementById('p5-tr-ans'); + const goBtn=document.getElementById('p5-tr-go'),startBtn=document.getElementById('p5-tr-start'); + const fb=document.getElementById('p5-tr-fb'); + function showTask(){ + if(cur>=tasks.length){taskEl.innerHTML='Тренажёр завершён! Очки: '+score+'/'+tasks.length+'';ansEl.style.display='none';goBtn.style.display='none';addXp(score*4,'p5-trainer');bumpProgress('p5',20);return;} + taskEl.innerHTML=tasks[cur].q;iEl.textContent=cur+1;ansEl.value='';fb.style.display='none'; + if(window.renderMathInElement) try{renderMath(taskEl);}catch(e){} + } + goBtn.addEventListener('click',()=>{ + const ans=ansEl.value.trim().replace(',','.'); + const ok=Math.abs(parseFloat(ans)-parseFloat(tasks[cur].a))<0.05; + feedback(fb,ok,ok?'Верно!':'Неверно. Подсказка: '+tasks[cur].hint); + if(ok){score++;scEl.textContent=score;cur++;setTimeout(showTask,900);} + }); + startBtn.addEventListener('click',()=>{cur=0;score=0;scEl.textContent=0;ansEl.style.display='';goBtn.style.display='';showTask();}); + showTask(); + })(); + + /* === INIT 5: DnD верно/неверно === */ + (function(){ + const items=[ + {label:'Центр вписанной в угол окружности лежит на биссектрисе',cat:'true'}, + {label:'Центр может лежать на любой стороне угла',cat:'false'}, + {label:'Радиусы в точки касания перпендикулярны сторонам угла',cat:'true'}, + {label:'Из вершины угла до точек касания: |BT₁| = |BT₂|',cat:'true'}, + {label:'В один угол можно вписать только одну окружность',cat:'false'}, + {label:'Если r увеличить, центр удаляется от вершины угла',cat:'true'}, + ]; + const pool=document.getElementById('p5-dnd-pool'); + const boxes={true:document.getElementById('p5-drop-true-items'),false:document.getElementById('p5-drop-false-items')}; + const fb=document.getElementById('p5-dnd-fb'); + let placed={}; + function reset(){ + pool.innerHTML='';placed={}; + Object.values(boxes).forEach(b=>b.innerHTML=''); + fb.style.display='none'; + items.forEach((it,i)=>{ + const chip=document.createElement('div'); + chip.className='dnd-chip';chip.dataset.i=i;chip.textContent=it.label; + chip.addEventListener('click',()=>chip.classList.toggle('armed')); + Object.entries(boxes).forEach(([cat,box])=>{ + box.parentElement.addEventListener('click',()=>{ + if(!chip.classList.contains('armed'))return; + chip.classList.remove('armed'); + if(placed[i]!==undefined)boxes[placed[i]].removeChild(chip); + placed[i]=cat;box.appendChild(chip); + }); + }); + pool.appendChild(chip); + }); + } + document.getElementById('p5-dnd-check').addEventListener('click',()=>{ + let ok=0;items.forEach((it,i)=>{if(placed[i]===it.cat)ok++;}); + feedback(fb,ok===items.length,'Верно: '+ok+'/'+items.length+(ok===items.length?'. Отлично!':'. Попробуй ещё.')); + if(ok===items.length){addXp(8,'p5-dnd');bumpProgress('p5',15);} + }); + document.getElementById('p5-dnd-reset').addEventListener('click',reset); + reset(); + })(); + + /* === INIT 6: Босс §5 === */ + (function(){ + const tasks=[ + {q:'Окружность вписана в угол $60°$, радиус $r=6$. Найти $d$ — расстояние от вершины до центра.',opts:['12','6√3','6√2'],cor:0,exp:'$r=d\\cdot\\sin 30°=d/2$, значит $d=2r=12$.'}, + {q:'Две окружности вписаны в один угол $90°$. $r_1=3$, $r_2=5$. Найти отношение расстояний от вершины до центров $d_1/d_2$.',opts:['3/5','5/3','1'],cor:0,exp:'$d=r/\\sin 45°=r\\sqrt{2}$. Отношение $d_1/d_2=r_1/r_2=3/5$.'}, + {q:'Центр окружности, вписанной в угол, сдвинули вдоль биссектрисы. Окружность по-прежнему:',opts:['Касается обеих сторон','Касается только одной стороны','Не касается ни одной стороны'],cor:0,exp:'При движении вдоль биссектрисы окружность остаётся вписанной в угол — всегда касается обеих сторон (радиус меняется пропорционально расстоянию).'}, + {q:'Угол $\\angle BOC = 2\\alpha$. Из вершины $B$ до точки касания $|BT| = a$. Выразить радиус $r$ через $a$ и $\\alpha$.',opts:['$a\\tan\\alpha$','$a\\sin\\alpha$','$a/\\tan\\alpha$'],cor:0,exp:'В прямоугольном треугольнике $BTO$: $\\tan\\alpha = r/|BT|$, значит $r = |BT|\\cdot\\tan\\alpha = a\\tan\\alpha$.'}, + ]; + const cont=document.getElementById('p5-boss-tasks'); + let html=''; + tasks.forEach((t,i)=>{ + html+=`
+
${i+1}. ${t.q}
+
+ ${t.opts.map((o,j)=>``).join('')} +
+ +
`; + }); + cont.innerHTML=html; + if(window.renderMathInElement) try{renderMath(cont);}catch(e){} + })(); +} +function buildP6(){ + const box=document.getElementById('p6-body'); + let html=''; + + html+=makeCard('theory','Взаимное расположение двух окружностей','6.1',` +

Два круга с центрами $O_1$, $O_2$ и радиусами $R_1$, $R_2$. Обозначим $d = |O_1O_2|$.

+ + + + + + + + + +
УсловиеРасположениеОбщих точек
$d > R_1+R_2$Внешние (не пересекаются)0
$d = R_1+R_2$Внешнее касание1
$|R_1{-}R_2| < d < R_1{+}R_2$Пересекаются2
$d = |R_1-R_2|$Внутреннее касание1
$d < |R_1-R_2|$Одна внутри другой0
+
+ + + + внешние + + + внешн. касание + + + пересекаются + + + внутри + +
`); + + html+=makeCard('rule','Признаки касания','6.2',` +

Внешнее касание: $d = R_1 + R_2$. Точка касания делит отрезок $O_1O_2$ изнутри в отношении $R_1 : R_2$.

+

Внутреннее касание: $d = |R_1 - R_2|$. Точка касания лежит на прямой $O_1O_2$, за большей окружностью относительно меньшей.

+
+ + + + + O₁ + O₂ + T + внешнее касание: d=R₁+R₂ + + + + O₁ + O₂ + T + внутреннее: d=|R₁−R₂| + +
`); + + html+=makeCard('example','Примеры определения расположения','6.3',` + + + + + + + + + +
$R_1$$R_2$$d$Вид
5310Внешние ($10 > 8$)
538Внешн. касание ($8=8$)
536Пересечение ($2<6<8$)
532Внутр. касание ($2=|5{-}3|$)
531Внутри ($1<2$)
`); + + /* ИНТЕРАКТИВ 1 — live SVG слайдеры */ + html+=`
+
ИНТЕРАКТИВ 1
Две окружности — live определение случая
+
Меняй $R_1$, $R_2$ и $d$ — цвет и подпись показывают текущий случай расположения.
+
+ + + +
+
+
+
`; + + /* ИНТЕРАКТИВ 2 — DnD: тройки (R1,R2,d) → случай */ + html+=`
+
ИНТЕРАКТИВ 2
Сортировщик: определи случай расположения
+
Перетащи каждую карточку в нужную корзину.
+
+
+
Внешние / нет общ. точек
+
Касание (1 точка)
+
Пересекаются (2 точки)
+
Одна внутри другой
+
+
+ +
`; + + /* ИНТЕРАКТИВ 3 — калькулятор */ + html+=`
+
ИНТЕРАКТИВ 3
Калькулятор: тип расположения
+
Введи $R_1$, $R_2$, $d$ — получи точное определение.
+
+ + + + +
+ +
`; + + /* ИНТЕРАКТИВ 4 — тренажёр */ + html+=`
+
ИНТЕРАКТИВ 4
Тренажёр §6
+
5 задач — введи цифровой ответ (1=внешние, 2=внешн.касание, 3=пересечение, 4=внутр.касание, 5=внутри).
+
Задача 1 / 5Очки: 0
+
+
+ + + +
+ +
`; + + /* ИНТЕРАКТИВ 5 — Босс §6 */ + html+=`
+
БОСС §6
Итоговые задачи
+
4 задачи — каждая верная +5 XP.
+
+
`; + + html+=`
+ +
`; + html+=secNav('p5','p7'); + box.innerHTML=html; + if(window.renderMathInElement) setTimeout(()=>renderMath(box),0); + + /* === INIT 1: live SVG === */ + (function(){ + const r1Sl=document.getElementById('p6-r1-sl'),r1v=document.getElementById('p6-r1v'); + const r2Sl=document.getElementById('p6-r2-sl'),r2v=document.getElementById('p6-r2v'); + const dSl=document.getElementById('p6-d-sl'),dv=document.getElementById('p6-dv'); + const svgWrap=document.getElementById('p6-live-svg'),infoEl=document.getElementById('p6-live-info'); + const W=300,H=180,CY=90; + function getCase(R1,R2,d){ + const s=R1+R2,diff=Math.abs(R1-R2); + if(Math.abs(d-s)<0.5)return 'exttan'; + if(Math.abs(d-diff)<0.5)return 'inttan'; + if(d>s)return 'ext'; + if(d`;} + if(caseKey==='inttan'){const big=R1>=R2?1:2;const TX=big===1?cx1-R1:cx1+R1;extras+=``;} + if(caseKey==='cross'){ + const a=(R1*R1-R2*R2+d*d)/(2*d); + const h=Math.sqrt(Math.max(0,R1*R1-a*a)); + const px=cx1+a,py1=CY-h,py2=CY+h; + extras+=``; + extras+=``; + } + svgWrap.innerHTML=` + + + + + O₁ + O₂ + + ${extras} + `; + } + [r1Sl,r2Sl,dSl].forEach(s=>s.addEventListener('input',draw)); + draw(); + })(); + + /* === INIT 2: DnD сортер === */ + (function(){ + const items=[ + {label:'R₁=5, R₂=3, d=10',cat:'ext'}, + {label:'R₁=5, R₂=3, d=8',cat:'tan'}, + {label:'R₁=5, R₂=3, d=6',cat:'sec'}, + {label:'R₁=5, R₂=3, d=2',cat:'tan'}, + {label:'R₁=5, R₂=3, d=1',cat:'in'}, + {label:'R₁=7, R₂=4, d=11',cat:'tan'}, + {label:'R₁=7, R₂=4, d=5',cat:'sec'}, + {label:'R₁=7, R₂=4, d=2',cat:'in'}, + ]; + const pool=document.getElementById('p6-dnd-pool'); + const boxes={ext:document.getElementById('p6-drop-ext-i'),tan:document.getElementById('p6-drop-tan-i'),sec:document.getElementById('p6-drop-sec-i'),in:document.getElementById('p6-drop-in-i')}; + const fb=document.getElementById('p6-dnd-fb'); + let placed={}; + function reset(){ + pool.innerHTML='';placed={};Object.values(boxes).forEach(b=>b.innerHTML='');fb.style.display='none'; + items.forEach((it,i)=>{ + const chip=document.createElement('div'); + chip.className='dnd-chip';chip.dataset.i=i;chip.textContent=it.label; + chip.addEventListener('click',()=>chip.classList.toggle('armed')); + Object.entries(boxes).forEach(([cat,box])=>{ + box.parentElement.addEventListener('click',()=>{ + if(!chip.classList.contains('armed'))return; + chip.classList.remove('armed'); + if(placed[i]!==undefined)boxes[placed[i]].removeChild(chip); + placed[i]=cat;box.appendChild(chip); + }); + }); + pool.appendChild(chip); + }); + } + document.getElementById('p6-dnd-check').addEventListener('click',()=>{ + let ok=0;items.forEach((it,i)=>{if(placed[i]===it.cat)ok++;}); + feedback(fb,ok===items.length,'Верно: '+ok+'/'+items.length+(ok===items.length?'. Отлично!':'.')); + if(ok===items.length){addXp(8,'p6-dnd');bumpProgress('p6',15);} + }); + document.getElementById('p6-dnd-reset').addEventListener('click',reset); + reset(); + })(); + + /* === INIT 3: калькулятор === */ + (function(){ + document.getElementById('p6-calc-btn').addEventListener('click',()=>{ + const R1=parseFloat(document.getElementById('p6-cr1').value); + const R2=parseFloat(document.getElementById('p6-cr2').value); + const d=parseFloat(document.getElementById('p6-cd').value); + const out=document.getElementById('p6-calc-out'); + out.style.display='block'; + if(isNaN(R1)||isNaN(R2)||isNaN(d)||R1<=0||R2<=0||d<0){out.style.background='#fee2e2';out.style.color='#7f1d1d';out.textContent='Введите корректные значения.';return;} + const s=R1+R2,diff=Math.abs(R1-R2); + let res,bg,col; + if(Math.abs(d-s)<1e-9){res='Внешнее касание (d = R₁+R₂ = '+s+')';bg='#fef3c7';col='#92400e';} + else if(Math.abs(d-diff)<1e-9){res='Внутреннее касание (d = |R₁−R₂| = '+diff+')';bg='#fef3c7';col='#92400e';} + else if(d>s){res='Внешние — нет общих точек (d='+d+' > R₁+R₂='+s+')';bg='#fee2e2';col='#7f1d1d';} + else if(d R₁+R₂=10 → внешние (1)'}, + {q:'$R_1=6$, $R_2=4$, $d=10$. Тип (1–5)?',a:'2',hint:'d=10 = R₁+R₂ → внешнее касание (2)'}, + {q:'$R_1=6$, $R_2=4$, $d=7$. Тип (1–5)?',a:'3',hint:'|R₁−R₂|=2 < 7 < 10 → пересечение (3)'}, + {q:'$R_1=6$, $R_2=4$, $d=2$. Тип (1–5)?',a:'4',hint:'d=2 = |R₁−R₂| → внутреннее касание (4)'}, + {q:'$R_1=6$, $R_2=4$, $d=1$. Тип (1–5)?',a:'5',hint:'d=1 < |R₁−R₂|=2 → одна внутри другой (5)'}, + ]; + let cur=0,score=0; + const iEl=document.getElementById('p6-tr-i'),scEl=document.getElementById('p6-tr-score'); + const taskEl=document.getElementById('p6-tr-task'),ansEl=document.getElementById('p6-tr-ans'); + const goBtn=document.getElementById('p6-tr-go'),startBtn=document.getElementById('p6-tr-start'); + const fb=document.getElementById('p6-tr-fb'); + function showTask(){ + if(cur>=tasks.length){taskEl.innerHTML='Тренажёр завершён! Очки: '+score+'/'+tasks.length+'';ansEl.style.display='none';goBtn.style.display='none';addXp(score*4,'p6-trainer');bumpProgress('p6',20);return;} + taskEl.innerHTML=tasks[cur].q;iEl.textContent=cur+1;ansEl.value='';fb.style.display='none'; + if(window.renderMathInElement) try{renderMath(taskEl);}catch(e){} + } + goBtn.addEventListener('click',()=>{ + const ans=ansEl.value.trim(); + const ok=Math.abs(parseFloat(ans)-parseFloat(tasks[cur].a))<0.01; + feedback(fb,ok,ok?'Верно!':'Неверно. '+tasks[cur].hint); + if(ok){score++;scEl.textContent=score;cur++;setTimeout(showTask,900);} + }); + startBtn.addEventListener('click',()=>{cur=0;score=0;scEl.textContent=0;ansEl.style.display='';goBtn.style.display='';showTask();}); + showTask(); + })(); + + /* === INIT 5: Босс §6 === */ + (function(){ + const tasks=[ + {q:'$R_1=8$, $R_2=5$. При каком $d$ окружности касаются внешним образом?',opts:['13','3','40'],cor:0,exp:'$d=R_1+R_2=8+5=13$.'}, + {q:'$R_1=10$, $R_2=4$, $d=6$. Сколько общих точек у окружностей?',opts:['0','1','2'],cor:1,exp:'$d=6=|R_1-R_2|=6$ — внутреннее касание, $1$ общая точка.'}, + {q:'Две окружности пересекаются. Выбери верное неравенство:',opts:['$|R_1-R_2|R_1+R_2$','$d=0$'],cor:0,exp:'$d < |R_1-R_2|$ — меньшая окружность внутри большей без общих точек.'}, + ]; + const cont=document.getElementById('p6-boss-tasks'); + let html=''; + tasks.forEach((t,i)=>{ + html+=`
+
${i+1}. ${t.q}
+
+ ${t.opts.map((o,j)=>``).join('')} +
+ +
`; + }); + cont.innerHTML=html; + if(window.renderMathInElement) try{renderMath(cont);}catch(e){} + })(); +} +function buildP7(){ + const box=document.getElementById('p7-body'); + let html=''; + + html+=makeCard('theory','Общая внешняя касательная двух окружностей','7.1',` +

Определение. Общая касательная называется внешней, если обе окружности находятся по одну сторону от неё. Внутренней, если они по разные стороны.

+

Формула длины общей внешней касательной (отрезок между точками касания):

+ $$\\ell_{\\text{внеш}} = \\sqrt{d^2 - (R_1 - R_2)^2}$$ +

Формула длины общей внутренней касательной (только если $d > R_1+R_2$):

+ $$\\ell_{\\text{внутр}} = \\sqrt{d^2 - (R_1 + R_2)^2}$$ +
+ + + + + + + + + + + + + + + O₁ + O₂ + ℓ (внешняя) + +
`); + + html+=makeCard('algo','Доказательство формулы внешней касательной','7.2',` +

Пусть $T_1$ — точка касания на $\\odot O_1$, $T_2$ — на $\\odot O_2$. Из $O_2$ опустим перпендикуляр $O_2K$ на $O_1T_1$.

+
    +
  1. $O_1T_1 \\perp \\ell$ и $O_2T_2 \\perp \\ell$ (свойство касательной).
  2. +
  3. $O_2K \\parallel T_1T_2$ и $O_1K = R_1 - R_2$.
  4. +
  5. $O_2K = T_1T_2 = \\ell$ (стороны прямоугольника $KT_1T_2O_2$).
  6. +
  7. В прямоугольном $\\triangle O_1KO_2$: $O_1O_2^2 = O_1K^2 + O_2K^2$.
  8. +
  9. $d^2 = (R_1-R_2)^2 + \\ell^2$, откуда $\\ell = \\sqrt{d^2-(R_1-R_2)^2}$. ч.т.д.
  10. +
+
+ + + + + + + + + + + + O₁ + O₂ + T₁ + T₂ + + R₁−R₂ + d + +
`); + + html+=makeCard('rule','Формулы обеих касательных','7.3',` +

Внешняя касательная (обе окружности по одну сторону):

+ $$\\ell_{\\text{вн}} = \\sqrt{d^2 - (R_1-R_2)^2}$$ +

Существует при $d \\geq |R_1-R_2|$ (т.е. окружности не содержат друг друга).

+

Внутренняя касательная (окружности по разные стороны):

+ $$\\ell_{\\text{вн}} = \\sqrt{d^2 - (R_1+R_2)^2}$$ +

Существует только при $d > R_1+R_2$ (внешнее расположение).

`); + + /* ИНТЕРАКТИВ 1 — SVG внешняя касательная + слайдеры */ + html+=`
+
ИНТЕРАКТИВ 1
Внешняя касательная — live
+
Меняй параметры — длина внешней касательной обновляется мгновенно.
+
+ + + +
+
+
+
`; + + /* ИНТЕРАКТИВ 2 — SVG внутренняя касательная */ + html+=`
+
ИНТЕРАКТИВ 2
Внутренняя касательная — live
+
Внутренняя касательная существует только при $d > R_1+R_2$. При недостаточном $d$ — предупреждение.
+
+ + + +
+
+
+
`; + + /* ИНТЕРАКТИВ 3 — пошаговое доказательство */ + html+=`
+
ИНТЕРАКТИВ 3
Доказательство формулы — по шагам
+
Нажимай «Далее» — пройди все шаги вывода формулы.
+
+
+
+ + +
+
`; + + /* ИНТЕРАКТИВ 4 — калькулятор */ + html+=`
+
ИНТЕРАКТИВ 4
Калькулятор: обе касательные
+
Введи $R_1$, $R_2$, $d$ — получи длины обеих касательных.
+
+ + + + +
+ +
`; + + /* ИНТЕРАКТИВ 5 — тренажёр */ + html+=`
+
ИНТЕРАКТИВ 5
Тренажёр §7
+
5 задач. Введи числовой ответ.
+
Задача 1 / 5Очки: 0
+
+
+ + + +
+ +
`; + + /* ИНТЕРАКТИВ 6 — Босс §7 */ + html+=`
+
БОСС §7
Итоговые задачи
+
4 задачи — каждая верная +5 XP.
+
+
`; + + html+=`
+ +
`; + html+=secNav('p6','p8'); + box.innerHTML=html; + if(window.renderMathInElement) setTimeout(()=>renderMath(box),0); + + /* === INIT 1: внешняя касательная === */ + (function(){ + const r1Sl=document.getElementById('p7-r1-sl'),r1v=document.getElementById('p7-r1v'); + const r2Sl=document.getElementById('p7-r2-sl'),r2v=document.getElementById('p7-r2v'); + const dSl=document.getElementById('p7-d-sl'),dv=document.getElementById('p7-dv'); + const svgWrap=document.getElementById('p7-ext-svg'),infoEl=document.getElementById('p7-ext-info'); + const W=300,H=170,CY=85; + function draw(){ + const R1=+r1Sl.value,R2=+r2Sl.value,d=+dSl.value; + r1v.textContent=R1;r2v.textContent=R2;dv.textContent=d; + const cx1=Math.max(R1+10,W/2-d/2),cx2=Math.min(W-R2-10,W/2+d/2); + const disc=d*d-(R1-R2)*(R1-R2); + if(disc<0){infoEl.style.color='#7f1d1d';infoEl.textContent='Внешняя касательная не существует (d < |R₁−R₂|)';svgWrap.innerHTML='';return;} + const L=Math.sqrt(disc); + infoEl.style.color='var(--sec-acc-d,#0f766e)'; + infoEl.textContent='ℓ = √('+d+'²−('+R1+'−'+R2+')²) = √'+fmt(disc)+' = '+L.toFixed(3); + const sinA=(R1-R2)/d, cosA=Math.sqrt(Math.max(0,1-sinA*sinA)); + const T1X=cx1+R1*sinA, T1Y=CY-R1*cosA; + const T2X=cx2+R2*sinA, T2Y=CY-R2*cosA; + const T3X=cx1+R1*sinA, T3Y=CY+R1*cosA; + const T4X=cx2+R2*sinA, T4Y=CY+R2*cosA; + svgWrap.innerHTML=` + + + + + + + + + + + + O₁ + O₂ + ℓ=${L.toFixed(1)} + `; + } + [r1Sl,r2Sl,dSl].forEach(s=>s.addEventListener('input',draw)); + draw(); + })(); + + /* === INIT 2: внутренняя касательная === */ + (function(){ + const r1Sl=document.getElementById('p7-ir1-sl'),r1v=document.getElementById('p7-ir1v'); + const r2Sl=document.getElementById('p7-ir2-sl'),r2v=document.getElementById('p7-ir2v'); + const dSl=document.getElementById('p7-id-sl'),dv=document.getElementById('p7-idv'); + const svgWrap=document.getElementById('p7-int-svg'),infoEl=document.getElementById('p7-int-info'); + const W=300,H=170,CY=85; + function draw(){ + const R1=+r1Sl.value,R2=+r2Sl.value,d=+dSl.value; + r1v.textContent=R1;r2v.textContent=R2;dv.textContent=d; + const disc=d*d-(R1+R2)*(R1+R2); + const cx1=Math.max(R1+10,W/2-d/2), cx2=Math.min(W-R2-10,W/2+d/2); + if(disc<0){ + infoEl.style.color='#92400e';infoEl.style.background='#fef3c7'; + infoEl.textContent='Внутренняя касательная не существует (d='+d+' ≤ R₁+R₂='+(R1+R2)+')'; + svgWrap.innerHTML=` + + + + + нет внутр. касательной + `; + return; + } + const L=Math.sqrt(disc); + infoEl.style.color='var(--sec-acc-d,#0f766e)';infoEl.style.background=''; + infoEl.textContent='ℓ_внутр = √('+d+'²−('+R1+'+'+R2+')²) = '+L.toFixed(3); + const sinA=(R1+R2)/d, cosA=Math.sqrt(Math.max(0,1-sinA*sinA)); + const T1X=cx1+R1*sinA, T1Y=CY-R1*cosA; + const T2X=cx2-R2*sinA, T2Y=CY+R2*cosA; + const T3X=cx1+R1*sinA, T3Y=CY+R1*cosA; + const T4X=cx2-R2*sinA, T4Y=CY-R2*cosA; + svgWrap.innerHTML=` + + + + + + + + + + O₁ + O₂ + ℓ=${L.toFixed(1)} + `; + } + [r1Sl,r2Sl,dSl].forEach(s=>s.addEventListener('input',draw)); + draw(); + })(); + + /* === INIT 3: пошаговое доказательство === */ + (function(){ + const O1X=65,O1Y=90,O2X=215,O2Y=90,R1=50,R2=28,d=150,W=280,H=160; + const sinA=(R1-R2)/d,cosA=Math.sqrt(1-sinA*sinA); + const T1X=O1X+R1*sinA,T1Y=O1Y-R1*cosA; + const T2X=O2X+R2*sinA,T2Y=O2Y-R2*cosA; + const KX=O1X+R1*sinA,KY=O2Y-R2*cosA; + const steps=[ + {text:'Дано: окружности с центрами $O_1$, $O_2$, радиусами $R_1$, $R_2$. Расстояние $d=|O_1O_2|$. Общая внешняя касательная с точками касания $T_1$, $T_2$. Найти $|T_1T_2|$.'}, + {text:'Шаг 1. $O_1T_1 \\perp \\ell$ и $O_2T_2 \\perp \\ell$ (свойство касательной). Опустим из $O_2$ перпендикуляр $O_2K$ на прямую $O_1T_1$. Получим прямоугольник $KT_1T_2O_2$.'}, + {text:'Шаг 2. В прямоугольнике $KT_1T_2O_2$: $O_2K = T_1T_2 = \\ell$ (противоположные стороны).'}, + {text:'Шаг 3. $O_1K = O_1T_1 - KT_1 = R_1 - R_2$ (разность радиусов).'}, + {text:'Шаг 4. В прямоугольном $\\triangle O_1KO_2$: $d^2 = O_1K^2 + O_2K^2 = (R_1-R_2)^2 + \\ell^2$. Отсюда $\\ell = \\sqrt{d^2-(R_1-R_2)^2}$. ч.т.д.'}, + ]; + let step=0; + const svgEl=document.getElementById('p7-proof-svg'),txtEl=document.getElementById('p7-proof-text'); + function draw(){ + const s=steps[step]; + let extras=''; + if(step>=1){ + extras+=``; + extras+=``; + extras+=``; + extras+=``; + extras+=``; + extras+=``; + extras+=``; + extras+=``; + extras+=``; + extras+=`K`; + extras+=``; + } + if(step>=3){ + extras+=`R₁-R₂`; + extras+=``; + } + svgEl.innerHTML=` + + + + + + O₁ + O₂ + d + ${extras} + `; + txtEl.innerHTML=s.text; + if(window.renderMathInElement) try{renderMath(txtEl);}catch(e){} + document.getElementById('p7-proof-next').textContent=step>=steps.length-1?'Готово':'Далее'; + } + document.getElementById('p7-proof-next').addEventListener('click',()=>{if(step{step=0;draw();}); + draw(); + })(); + + /* === INIT 4: калькулятор === */ + (function(){ + document.getElementById('p7-calc-btn').addEventListener('click',()=>{ + const R1=parseFloat(document.getElementById('p7-cr1').value); + const R2=parseFloat(document.getElementById('p7-cr2').value); + const d=parseFloat(document.getElementById('p7-cd').value); + const out=document.getElementById('p7-calc-out'); + out.style.display='block'; + if(isNaN(R1)||isNaN(R2)||isNaN(d)||R1<=0||R2<=0||d<=0){out.style.background='#fee2e2';out.style.color='#7f1d1d';out.textContent='Введите положительные значения.';return;} + out.style.background='var(--sec-acc-soft,#cffafe)';out.style.color='var(--sec-acc-d,#0e7490)'; + const extDisc=d*d-(R1-R2)*(R1-R2); + const intDisc=d*d-(R1+R2)*(R1+R2); + const extTxt=extDisc>=0?'ℓ_внеш = √('+d+'²−('+R1+'−'+R2+')²) = '+Math.sqrt(extDisc).toFixed(4):'Внешняя касательная не существует'; + const intTxt=intDisc>0?'ℓ_внутр = √('+d+'²−('+R1+'+'+R2+')²) = '+Math.sqrt(intDisc).toFixed(4):'Внутренняя касательная не существует (d ≤ R₁+R₂='+(R1+R2)+')'; + out.innerHTML=extTxt+'
'+intTxt; + }); + })(); + + /* === INIT 5: тренажёр === */ + (function(){ + const tasks=[ + {q:'$R_1=10$, $R_2=4$, $d=13$. Найди длину общей внешней касательной.',a:'12',hint:'ℓ=√(169−36)=√133≈11.53, округлённо. Пересчитай: (R₁−R₂)²=(10−4)²=36. ℓ=√(169−36)=√133≈11.53'}, + {q:'$R_1=8$, $R_2=2$, $d=10$. Найди $\\ell_{\\text{вн}}$.',a:'8',hint:'ℓ=√(100−36)=√64=8'}, + {q:'$R_1=R_2=5$, $d=13$. Найди $\\ell_{\\text{вн}}$.',a:'13',hint:'При R₁=R₂: ℓ=√(d²−0)=d=13'}, + {q:'$\\ell_{\\text{вн}}=12$, $R_1-R_2=5$, найди $d$.',a:'13',hint:'d=√(144+25)=√169=13'}, + {q:'$R_1=6$, $R_2=2$, $d=20$. Найди $\\ell_{\\text{внутр}}$.',a:'12',hint:'ℓ=√(400−(6+2)²)=√(400−64)=√336≈18.33. Нет, (R₁+R₂)²=64, √(400−64)=√336≈18.33'}, + ]; + let cur=0,score=0; + const iEl=document.getElementById('p7-tr-i'),scEl=document.getElementById('p7-tr-score'); + const taskEl=document.getElementById('p7-tr-task'),ansEl=document.getElementById('p7-tr-ans'); + const goBtn=document.getElementById('p7-tr-go'),startBtn=document.getElementById('p7-tr-start'); + const fb=document.getElementById('p7-tr-fb'); + const correctAnswers=[ + Math.sqrt(169-36),8,13,13,Math.sqrt(400-64) + ]; + function showTask(){ + if(cur>=tasks.length){taskEl.innerHTML='Тренажёр завершён! Очки: '+score+'/'+tasks.length+'';ansEl.style.display='none';goBtn.style.display='none';addXp(score*4,'p7-trainer');bumpProgress('p7',20);return;} + taskEl.innerHTML=tasks[cur].q;iEl.textContent=cur+1;ansEl.value='';fb.style.display='none'; + if(window.renderMathInElement) try{renderMath(taskEl);}catch(e){} + } + goBtn.addEventListener('click',()=>{ + const ans=parseFloat(ansEl.value.replace(',','.')); + const ok=Math.abs(ans-correctAnswers[cur])<0.06; + feedback(fb,ok,ok?'Верно!':'Неверно. Подсказка: '+tasks[cur].hint+' ≈ '+correctAnswers[cur].toFixed(2)); + if(ok){score++;scEl.textContent=score;cur++;setTimeout(showTask,900);} + }); + startBtn.addEventListener('click',()=>{cur=0;score=0;scEl.textContent=0;ansEl.style.display='';goBtn.style.display='';showTask();}); + showTask(); + })(); + + /* === INIT 6: Босс §7 === */ + (function(){ + const tasks=[ + {q:'$R_1=5$, $R_2=3$, $d=10$. Длина общей внешней касательной:',opts:['√(100−4)=√96≈9.8','√(100−64)=6','√(100−16)=√84≈9.2'],cor:0,exp:'$(R_1-R_2)^2=(5-3)^2=4$. $\\ell=\\sqrt{100-4}=\\sqrt{96}\\approx9{,}8$.'}, + {q:'При $R_1=R_2$ длина внешней касательной равна:',opts:['$d$','$0$','$\\sqrt{d^2-R^2}$'],cor:0,exp:'Если $R_1=R_2$, то $(R_1-R_2)^2=0$, значит $\\ell=\\sqrt{d^2}=d$.'}, + {q:'Внутренняя касательная существует при условии:',opts:['$d>R_1+R_2$','$d=R_1+R_2$','$d>|R_1-R_2|$'],cor:0,exp:'Внутренняя касательная существует только когда окружности не пересекаются и не касаются, т.е. $d > R_1+R_2$.'}, + {q:'$\\ell_{\\text{вн}}=15$, $d=17$, $R_1=R_2$. Найти $R_1$.', opts:['4','8','2'],cor:1,exp:'$R_1=R_2$: $\\ell=d=17\\neq15$. Нет, если $R_1 \\neq R_2$: $\\ell^2=d^2-(R_1-R_2)^2$, $(R_1-R_2)^2=289-225=64$, $R_1-R_2=8$. Дополнительных данных нет — ответ: разность = 8.'}, + ]; + const cont=document.getElementById('p7-boss-tasks'); + let html=''; + tasks.forEach((t,i)=>{ + html+=`
+
${i+1}. ${t.q}
+
+ ${t.opts.map((o,j)=>``).join('')} +
+ +
`; + }); + cont.innerHTML=html; + if(window.renderMathInElement) try{renderMath(cont);}catch(e){} + })(); +} function buildP8stub(){ document.getElementById('p8-body').innerHTML='

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

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

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

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

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

'+secNav('p9','p11'); }