diff --git a/frontend/textbooks/geometry_8_ch4.html b/frontend/textbooks/geometry_8_ch4.html index 4bd65ce..e1f6519 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:()=>buildP1stub(),p2:()=>buildP2stub(),p3:()=>buildP3stub(),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:()=>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()}; 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);} @@ -416,8 +416,10 @@ let _confettiCanvas=null,_confettiParticles=[],_confettiRaf=null; function confetti(){if(!_confettiCanvas){_confettiCanvas=document.createElement('canvas');_confettiCanvas.style.cssText='position:fixed;top:0;left:0;width:100%;height:100%;pointer-events:none;z-index:9999';document.body.appendChild(_confettiCanvas);}const c=_confettiCanvas;c.width=window.innerWidth;c.height=window.innerHeight;const ctx=c.getContext('2d');const colors=['#0891b2','#06b6d4','#22d3ee','#f59e0b','#10b981'];for(let i=0;i<80;i++){_confettiParticles.push({x:window.innerWidth/2+(Math.random()-.5)*200,y:window.innerHeight/2,vx:(Math.random()-.5)*14,vy:-10-Math.random()*10,g:.4,life:100,color:colors[i%colors.length],r:4+Math.random()*4,rot:0,vRot:(Math.random()-.5)*.3});}if(_confettiRaf)cancelAnimationFrame(_confettiRaf);function frame(){ctx.clearRect(0,0,c.width,c.height);_confettiParticles=_confettiParticles.filter(p=>{p.x+=p.vx;p.y+=p.vy;p.vy+=p.g;p.life--;p.rot+=p.vRot;ctx.save();ctx.translate(p.x,p.y);ctx.rotate(p.rot);ctx.fillStyle=p.color;ctx.fillRect(-p.r,-p.r/2,p.r*2,p.r);ctx.restore();return p.life>0&&p.y0)_confettiRaf=requestAnimationFrame(frame);else{ctx.clearRect(0,0,c.width,c.height);_confettiRaf=null;}}frame();} const GLOSSARY=[ - {term:'касательная',def:'Прямая, имеющая с окружностью ровно одну общую точку (точку касания), и перпендикулярная радиусу в этой точке.',sec:'p1',aliases:['касательная','касательной','касательную','касательных','касательными']}, - {term:'секущая',def:'Прямая, пересекающая окружность в двух точках.',sec:'p14',aliases:['секущая','секущей','секущую','секущих','секущими']}, + {term:'касательная',def:'Прямая, имеющая с окружностью ровно одну общую точку (точку касания). Признак: прямая перпендикулярна радиусу в точке касания.',sec:'p1',aliases:['касательная','касательной','касательную','касательных','касательными']}, + {term:'точка касания',def:'Единственная общая точка касательной и окружности.',sec:'p1',aliases:['точка касания','точки касания','точку касания','точек касания']}, + {term:'секущая',def:'Прямая, пересекающая окружность в двух точках.',sec:'p1',aliases:['секущая','секущей','секущую','секущих','секущими']}, + {term:'радиус',def:'Отрезок от центра окружности до любой её точки; также длина этого отрезка.',sec:'p1',aliases:['радиус','радиуса','радиусу','радиусом','радиусы','радиусов']}, {term:'хорда',def:'Отрезок, соединяющий две точки окружности.',sec:'p13',aliases:['хорда','хорды','хорде','хорду','хорд','хордами']}, {term:'центральный угол',def:'Угол с вершиной в центре окружности, стороны которого — радиусы.',sec:'p8',aliases:['центральный угол','центрального угла','центральному углу','центральные углы']}, {term:'вписанный угол',def:'Угол с вершиной на окружности, стороны которого — хорды.',sec:'p8',aliases:['вписанный угол','вписанного угла','вписанному углу','вписанные углы','вписанных углов']}, @@ -447,9 +449,1176 @@ function initSidebarToggle(){const side=document.getElementById('col-side'),back function init(){loadProgress();initTheme();initSidebarToggle();initGlossaryTip();initSearch();buildParaSelector();refreshProgressUI();loadServerReadState();goTo('p1');setTimeout(()=>achievement('start','Начало главы 4!'),600);if(window.LS&&window.LS.xp){window.LS.xp.load().then(function(s){if(s&&s.xp>STATE.xp){STATE.xp=s.xp;STATE.level=calcLevel(STATE.xp);saveProgress();refreshProgressUI();if(STATE.current)buildSidebar(STATE.current);}});}} document.addEventListener('DOMContentLoaded',init); -function buildP1stub(){ document.getElementById('p1-body').innerHTML='

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

'+secNav(null,'p2'); } -function buildP2stub(){ document.getElementById('p2-body').innerHTML='

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

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

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

'+secNav('p2','p4'); } +function buildP1(){ + const box=document.getElementById('p1-body'); + let html=''; + + html+=makeCard('theory','Касательная к окружности','1.1',` +

Определение. Прямая называется касательной к окружности, если она имеет с окружностью ровно одну общую точку. Эта общая точка называется точкой касания.

+

Прямая может быть расположена относительно окружности тремя способами:

+ +
+ + + + + + + + секущая + d < R + + + + + касательная + d = R + + + + не пересекает + d > R + +
`); + + html+=makeCard('rule','Признак касательной','1.2',` +

Теорема (признак касательной). Если прямая проходит через точку окружности и перпендикулярна радиусу, проведённому в эту точку, то эта прямая является касательной к окружности.

+ $$OT \\perp \\ell \\implies \\ell \\text{ — касательная в точке } T$$ +

Расстояние от центра до касательной равно радиусу: $d(O,\\ell) = R$.

+
+ + + + + + + + R + T + O + + +
`); + + html+=makeCard('example','Пример','1.3',` +

Задача. Радиус окружности $R = 5$. Расстояние от центра $O$ до прямой $\ell$ равно $d$. Является ли прямая касательной, секущей или не пересекает окружность при:

+ + + + + + + +
$d$Вид прямой
$3$секущая ($3 < 5$)
$5$касательная ($5 = 5$)
$7$не пересекает ($7 > 5$)
`); + + /* ИНТЕРАКТИВ 1 — слайдер d */ + html+=`
+
ИНТЕРАКТИВ 1
Расположение прямой относительно окружности
+
Двигай слайдер — наблюдай, как меняется расположение прямой. При $d = R$ прямая становится касательной!
+
+ +
+
+
+
`; + + /* ИНТЕРАКТИВ 2 — Пошаговое доказательство признака */ + html+=`
+
ИНТЕРАКТИВ 2
Доказательство признака — по шагам
+
Нажимай «Далее» — каждый шаг раскрывает ключевую идею доказательства.
+
+
+
+ + +
+
`; + + /* ИНТЕРАКТИВ 3 — Калькулятор */ + html+=`
+
ИНТЕРАКТИВ 3
Калькулятор: проверка типа прямой
+
Введи радиус $R$ и расстояние $d$ от центра до прямой — узнай её вид.
+
+ + + +
+ +
`; + + /* ИНТЕРАКТИВ 4 — DnD-сортер */ + html+=`
+
ИНТЕРАКТИВ 4
Сортировщик: касательная, секущая или нет?
+
Перетащи каждую карточку в нужную корзину. Дано R и d.
+
+
+
Секущая
+
Касательная
+
Не пересекает
+
+
+ +
`; + + /* ИНТЕРАКТИВ 5 — Тренажёр */ + html+=`
+
ИНТЕРАКТИВ 5
Тренажёр §1
+
5 задач на распознавание и вычисление. Введи ответ и нажми «Проверить».
+
Задача 1 / 5Очки: 0
+
+
+ + + +
+ +
`; + + /* ИНТЕРАКТИВ 6 — Босс §1 */ + html+=`
+
БОСС §1
Итоговые задачи
+
4 задачи повышенной сложности — каждая верная даёт +5 XP.
+
+
`; + + html+=`
+ +
`; + html+=secNav(null,'p2'); + box.innerHTML=html; + if(window.renderMathInElement) setTimeout(()=>renderMath(box),0); + + /* === INIT ИНТЕРАКТИВ 1: слайдер d === */ + (function(){ + const sl=document.getElementById('p1-d-sl'); + const dVal=document.getElementById('p1-d-val'); + const svgWrap=document.getElementById('p1-dist-svg'); + const info=document.getElementById('p1-dist-info'); + const R=60, cx=140, cy=100, W=280, H=200; + function draw(){ + const d=+sl.value; + dVal.textContent=d; + const lineY=cy-d; + const hasIntersect=d`; + } else if(hasIntersect){ + pts=``; + } + const lineColor=isTan?'#10b981':hasIntersect?'#0891b2':'#ef4444'; + const dLineX1=cx, dLineY1=cy, dLineX2=cx, dLineY2=lineY; + const svgStr=` + + + O + + + d=${d} + ${pts} + ${tanMark} + `; + svgWrap.innerHTML=svgStr; + if(isTan){ + info.style.background='#d1fae5';info.style.color='#065f46'; + info.textContent='d = R = '+R+' — прямая КАСАТЕЛЬНАЯ (1 общая точка)'; + } else if(hasIntersect){ + info.style.background='var(--sec-acc-soft,#cffafe)';info.style.color='#0e7490'; + info.textContent='d = '+d+' < R = '+R+' — прямая СЕКУЩАЯ (2 общие точки)'; + } else { + info.style.background='#fee2e2';info.style.color='#7f1d1d'; + info.textContent='d = '+d+' > R = '+R+' — прямая НЕ ПЕРЕСЕКАЕТ окружность'; + } + } + sl.addEventListener('input',draw); + draw(); + })(); + + /* === INIT ИНТЕРАКТИВ 2: пошаговое доказательство === */ + (function(){ + const steps=[ + {text:'Дано: окружность с центром $O$, точка $T$ на окружности, прямая $\\ell$ проходит через $T$ и $OT \\perp \\ell$. Нужно доказать, что $\\ell$ — касательная.', + highlight:'none'}, + {text:'Шаг 1. Возьмём произвольную точку $M \\neq T$ на прямой $\\ell$. Нам нужно показать, что $M$ лежит вне окружности, то есть $OM > R$.', + highlight:'M'}, + {text:'Шаг 2. В прямоугольном треугольнике $OTM$ гипотенуза $OM$ больше любого катета. Поскольку $OT = R$ является катетом, то $OM > OT = R$.', + highlight:'triangle'}, + {text:'Шаг 3. Значит, любая точка $M \\neq T$ на прямой $\\ell$ лежит вне окружности. Следовательно, прямая $\\ell$ имеет с окружностью только одну общую точку $T$.', + highlight:'conclude'}, + {text:'По определению, прямая с единственной общей точкой с окружностью является касательной. ч.т.д.', + highlight:'done'}, + ]; + let step=0; + const svgEl=document.getElementById('p1-proof-svg'); + const txtEl=document.getElementById('p1-proof-text'); + const nextBtn=document.getElementById('p1-proof-next'); + const resetBtn=document.getElementById('p1-proof-reset'); + const cx=130, cy=110, R=70; + function drawProof(s){ + const h=s.highlight; + const Tx=cx, Ty=cy-R; + const Mx=cx+80, My=Ty; + let extras=''; + if(h==='M'||h==='triangle'||h==='conclude'||h==='done'){ + extras+=``; + extras+=`M`; + extras+=``; + } + if(h==='triangle'||h==='conclude'||h==='done'){ + extras+=``; + extras+=``; + } + const lineColor=h==='done'?'#10b981':'#0891b2'; + const svg=` + + + + + + O + T + + R + ${extras} + `; + svgEl.innerHTML=svg; + txtEl.innerHTML=steps[s.idx].text; + if(window.renderMathInElement) try{renderMath(txtEl);}catch(e){} + nextBtn.textContent=step>=steps.length-1?'Готово':'Далее'; + } + steps.forEach((s,i)=>s.idx=i); + function go(){ + drawProof(steps[step]); + if(step{step=0;go();}); + go(); + })(); + + /* === INIT ИНТЕРАКТИВ 3: калькулятор === */ + (function(){ + const btn=document.getElementById('p1-calc-btn'); + const out=document.getElementById('p1-calc-out'); + btn.addEventListener('click',()=>{ + const R=parseFloat(document.getElementById('p1-cr').value); + const d=parseFloat(document.getElementById('p1-cd').value); + if(isNaN(R)||isNaN(d)||R<=0||d<0){out.style.display='block';out.style.background='#fee2e2';out.style.color='#7f1d1d';out.textContent='Введите корректные значения (R > 0, d ≥ 0)';return;} + out.style.display='block'; + if(Math.abs(d-R)<1e-9){out.style.background='#d1fae5';out.style.color='#065f46';out.textContent='d = R = '+fmt(R)+' → прямая КАСАТЕЛЬНАЯ';} + else if(d R = '+fmt(R)+' → прямая НЕ ПЕРЕСЕКАЕТ окружность';} + }); + })(); + + /* === INIT ИНТЕРАКТИВ 4: DnD === */ + (function(){ + const items=[ + {label:'R=5, d=3',cat:'sec'},{label:'R=8, d=8',cat:'tan'},{label:'R=6, d=9',cat:'none'}, + {label:'R=10, d=7',cat:'sec'},{label:'R=4, d=4',cat:'tan'},{label:'R=3, d=5',cat:'none'}, + ]; + const pool=document.getElementById('p1-dnd-pool'); + const boxes={sec:document.getElementById('p1-drop-sec-items'),tan:document.getElementById('p1-drop-tan-items'),none:document.getElementById('p1-drop-none-items')}; + const fb=document.getElementById('p1-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; + setupChip(chip,i); + pool.appendChild(chip); + }); + } + function setupChip(chip,i){ + chip.addEventListener('click',()=>{ + if(placed[i]!==undefined){ + boxes[placed[i]].removeChild(chip); + delete placed[i]; + chip.querySelector('.dnd-x')&&chip.querySelector('.dnd-x').remove(); + pool.appendChild(chip); + return; + } + chip.classList.add('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; + const x=document.createElement('span');x.className='dnd-x';x.textContent='×'; + x.addEventListener('click',e=>{e.stopPropagation();boxes[cat].removeChild(chip);delete placed[i];x.remove();pool.appendChild(chip);}); + chip.appendChild(x); + box.appendChild(chip); + }); + }); + } + document.getElementById('p1-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,'p1-dnd');bumpProgress('p1',15);} + }); + document.getElementById('p1-dnd-reset').addEventListener('click',reset); + reset(); + })(); + + /* === INIT ИНТЕРАКТИВ 5: Тренажёр === */ + (function(){ + const tasks=[ + {q:'Радиус окружности $R = 13$. Расстояние от центра до прямой $d = 5$. Сколько общих точек у прямой с окружностью?',a:'2',hint:'d < R → секущая → 2 точки'}, + {q:'Радиус $R = 7$. Прямая касается окружности. Расстояние от центра до прямой равно?',a:'7',hint:'При касании d = R = 7'}, + {q:'От центра до прямой $d = 10$, радиус $R = 6$. Сколько общих точек?',a:'0',hint:'d > R → 0 точек'}, + {q:'Прямая перпендикулярна радиусу $OT = 4$ в точке $T$ на окружности. Расстояние от центра до прямой равно?',a:'4',hint:'Признак касательной: расстояние = R = 4'}, + {q:'Прямая касается окружности радиуса $R = 9$. Каково расстояние от центра до точки касания?',a:'9',hint:'Расстояние от центра до точки касания = R'}, + ]; + let cur=0,score=0; + const iEl=document.getElementById('p1-tr-i'); + const scEl=document.getElementById('p1-tr-score'); + const taskEl=document.getElementById('p1-tr-task'); + const ansEl=document.getElementById('p1-tr-ans'); + const goBtn=document.getElementById('p1-tr-go'); + const startBtn=document.getElementById('p1-tr-start'); + const fb=document.getElementById('p1-tr-fb'); + function showTask(){ + if(cur>=tasks.length){taskEl.innerHTML='Тренажёр завершён! Очки: '+score+'/'+tasks.length+'';ansEl.style.display='none';goBtn.style.display='none';addXp(score*4,'p1-trainer');bumpProgress('p1',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 ИНТЕРАКТИВ 6: Босс §1 === */ + (function(){ + const tasks=[ + {q:'Прямая проходит через точку $A(6, 0)$ и параллельна оси $Oy$. Центр окружности $O(0,0)$, радиус $R = 6$. Является ли прямая касательной?', + opts:['Да, касательная','Нет, секущая','Нет, не пересекает'],cor:0, + exp:'Расстояние от центра $(0,0)$ до прямой $x=6$ равно $6 = R$. Прямая является касательной.'}, + {q:'Из точки $M$ вне окружности расстояние до центра $|OM| = 10$, радиус $R = 6$. Прямая $MN$ перпендикулярна $OM$. Является ли $MN$ касательной?', + opts:['Да','Нет, секущая','Нет, не пересекает'],cor:2, + exp:'$MN \\perp OM$, значит расстояние от $O$ до $MN$ равно $|OM| = 10 > R = 6$. Прямая не пересекает окружность.'}, + {q:'Прямая $\\ell$ перпендикулярна радиусу $OR$ в точке $R$ на окружности. Выбери верное утверждение:', + opts:['$\\ell$ — касательная в точке $R$','$\\ell$ — секущая','$\\ell$ не пересекает окружность'],cor:0, + exp:'По признаку касательной: прямая, проходящая через точку окружности и перпендикулярная радиусу в этой точке, является касательной.'}, + {q:'Расстояние от центра окружности до прямой равно диаметру. Прямая является:', + opts:['касательной','секущей','не пересекает окружность'],cor:2, + exp:'Диаметр $= 2R > R$, значит $d > R$ — прямая не пересекает окружность.'}, + ]; + const cont=document.getElementById('p1-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 buildP2(){ + const box=document.getElementById('p2-body'); + let html=''; + + html+=makeCard('theory','Свойство касательной','2.1',` +

Теорема (свойство касательной). Касательная к окружности перпендикулярна радиусу, проведённому в точку касания.

+ $$OT \\perp \\ell$$ +

где $O$ — центр, $T$ — точка касания, $\\ell$ — касательная.

+

Доказательство — от противного. Предположим, что $OT$ не перпендикулярно $\\ell$. Тогда из $O$ можно опустить перпендикуляр на $\\ell$ в точку $H \\neq T$, и $OH < OT = R$. Значит, $H$ лежит внутри окружности. Но тогда прямая $\\ell$ пересекает окружность в двух точках — противоречие с тем, что $\\ell$ касательная. Следовательно, $OT \\perp \\ell$. ч.т.д.

+
+ + + + + + + + R + T + O + + ∠OTℓ = 90° + +
`); + + html+=makeCard('rule','Следствие: длина касательной из внешней точки','2.2',` +

Если из внешней точки $A$ проведена касательная до точки касания $T$, то:

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

Это следует из теоремы Пифагора для прямоугольного треугольника $OAT$: $|OA|^2 = R^2 + AT^2$.

+
+ + + + + + + + + R + T + O + A + AT + |OA| + +
`); + + html+=makeCard('example','Пример','2.3',` +

Задача. Радиус окружности $R = 5$, расстояние от внешней точки $A$ до центра $|OA| = 13$. Найти длину касательной $AT$.

+

Решение: $AT = \\sqrt{|OA|^2 - R^2} = \\sqrt{169 - 25} = \\sqrt{144} = 12$.

+

Ответ: $AT = 12$.

`); + + /* ИНТЕРАКТИВ 1 — SVG с угловым маркером перпендикулярности */ + html+=`
+
ИНТЕРАКТИВ 1
Касательная всегда перпендикулярна радиусу
+
Перемещай точку касания $T$ по окружности — касательная и радиус $OT$ всегда перпендикулярны. Угловой маркер 90° следует за $T$.
+
+ +
+
+
∠OTℓ = 90° всегда
+
`; + + /* ИНТЕРАКТИВ 2 — Пошаговое доказательство от противного */ + html+=`
+
ИНТЕРАКТИВ 2
Доказательство от противного — по шагам
+
Нажимай «Далее» чтобы пройти доказательство методом от противного.
+
+
+
+ + +
+
`; + + /* ИНТЕРАКТИВ 3 — Калькулятор длины касательной */ + html+=`
+
ИНТЕРАКТИВ 3
Калькулятор: длина касательной из внешней точки
+
Дано $R$ и $|OA|$ — найди $AT = \\sqrt{|OA|^2 - R^2}$.
+
+ + + +
+ +
`; + + /* ИНТЕРАКТИВ 4 — Тренажёр */ + html+=`
+
ИНТЕРАКТИВ 4
Тренажёр §2
+
5 задач на применение свойства касательной. Введи ответ.
+
Задача 1 / 5Очки: 0
+
+
+ + + +
+ +
`; + + /* ИНТЕРАКТИВ 5 — DnD верные/неверные утверждения */ + html+=`
+
ИНТЕРАКТИВ 5
Верно или неверно о касательной?
+
Перетащи утверждение в нужную колонку.
+
+
+
Верно
+
Неверно
+
+
+ +
`; + + /* ИНТЕРАКТИВ 6 — Босс §2 */ + html+=`
+
БОСС §2
Итоговые задачи
+
4 задачи — каждая верная даёт +5 XP.
+
+
`; + + html+=`
+ +
`; + html+=secNav('p1','p3'); + box.innerHTML=html; + if(window.renderMathInElement) setTimeout(()=>renderMath(box),0); + + /* === INIT ИНТЕРАКТИВ 1: вращение T по окружности === */ + (function(){ + const sl=document.getElementById('p2-t-sl'); + const tVal=document.getElementById('p2-t-val'); + const svgWrap=document.getElementById('p2-perp-svg'); + const cx=140, cy=110, R=70, W=280, H=210; + function draw(){ + const angDeg=+sl.value; + tVal.textContent=angDeg; + const angRad=(angDeg-90)*Math.PI/180; + const Tx=cx+R*Math.cos(angRad); + const Ty=cy+R*Math.sin(angRad); + // unit vectors + const urx=(Tx-cx)/R, ury=(Ty-cy)/R; + const utx=-ury, uty=urx; // tangent unit vector (perp to radius) + const tLen=80; + const lx1=Tx-utx*tLen, ly1=Ty-uty*tLen; + const lx2=Tx+utx*tLen, ly2=Ty+uty*tLen; + // right angle marker at T: 9px square + const s=9; + const mx1=Tx+urx*s, my1=Ty+ury*s; + const mx2=Tx+urx*s+utx*s, my2=Ty+ury*s+uty*s; + const mx3=Tx+utx*s, my3=Ty+uty*s; + const svg=` + + + + + + + O + T + ℓ (касательная) + ∠OTℓ = 90° + `; + svgWrap.innerHTML=svg; + } + sl.addEventListener('input',draw); + draw(); + })(); + + /* === INIT ИНТЕРАКТИВ 2: доказательство от противного === */ + (function(){ + const steps=[ + {text:'Дано: окружность с центром $O$ и радиусом $R$; прямая $\\ell$ касается окружности в точке $T$ ($\\ell$ имеет с окружностью ровно одну общую точку). Доказать: $OT \\perp \\ell$.', + phase:'given'}, + {text:'Допущение (от противного). Предположим, что $OT$ не перпендикулярно $\\ell$. Тогда из $O$ можно опустить перпендикуляр $OH$ на $\\ell$, где $H \\neq T$.', + phase:'contra'}, + {text:'Шаг 2. В прямоугольном треугольнике $OHT$ гипотенуза $OT = R$, катет $OH < OT$. Значит, $OH < R$ — точка $H$ лежит внутри окружности.', + phase:'inside'}, + {text:'Шаг 3. Прямая $\\ell$, проходящая через точку $H$ внутри окружности, обязана пересекать окружность в двух точках. Но $\\ell$ — касательная (одна общая точка). Противоречие!', + phase:'contradiction'}, + {text:'Вывод. Допущение неверно. Следовательно, $OT \\perp \\ell$. ч.т.д.', + phase:'done'}, + ]; + let step=0; + const svgEl=document.getElementById('p2-proof-svg'); + const txtEl=document.getElementById('p2-proof-text'); + const nextBtn=document.getElementById('p2-proof-next'); + const resetBtn=document.getElementById('p2-proof-reset'); + const cx=130, cy=100, R=65; + function drawProof(ph){ + const Tx=cx, Ty=cy-R; + let extras=''; + if(ph==='contra'||ph==='inside'||ph==='contradiction'||ph==='done'){ + const Hx=cx+40, Hy=Ty; + extras+=``; + extras+=`H`; + extras+=``; + if(ph==='inside'||ph==='contradiction'){ + extras+=``; + } + } + const color=ph==='done'?'#10b981':'#06b6d4'; + const svg=` + + + + + + + O + T + + ${extras} + `; + svgEl.innerHTML=svg; + txtEl.innerHTML=steps.find(s=>s.phase===ph).text; + if(window.renderMathInElement) try{renderMath(txtEl);}catch(e){} + } + const phases=steps.map(s=>s.phase); + function go(){ + drawProof(phases[step]); + nextBtn.textContent=step>=phases.length-1?'Готово':'Далее'; + if(step{step=0;go();}); + go(); + })(); + + /* === INIT ИНТЕРАКТИВ 3: калькулятор === */ + (function(){ + const btn=document.getElementById('p2-calc-btn'); + const out=document.getElementById('p2-calc-out'); + btn.addEventListener('click',()=>{ + const R=parseFloat(document.getElementById('p2-cr').value); + const OA=parseFloat(document.getElementById('p2-coa').value); + 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'+fmt(AT)+''; + }); + })(); + + /* === INIT ИНТЕРАКТИВ 4: Тренажёр === */ + (function(){ + const tasks=[ + {q:'Радиус $R = 5$, $|OA| = 13$. Найди длину касательной $AT$.',a:'12',hint:'AT = √(169 − 25) = √144 = 12'}, + {q:'Радиус $R = 8$, $|OA| = 10$. Найди $AT$.',a:'6',hint:'AT = √(100 − 64) = √36 = 6'}, + {q:'Касательная $AT = 24$, $|OA| = 26$. Найди радиус $R$.',a:'10',hint:'R = √(26² − 24²) = √(676−576) = √100 = 10'}, + {q:'Касательная $AT = 15$, радиус $R = 9$. Найди $|OA|$.',a:'√306',hint:'OA = √(225 + 81) = √306 ≈ 17,49. Введи 306 (под корнем)'}, + {q:'Угол между радиусом $OT$ и прямой $OA$ равен 60°, $|OA| = 10$. Найди радиус $R = |OT|$.',a:'5',hint:'OT = OA·cos60° = 10·0,5 = 5 (касательная AT ⊥ OT)'}, + ]; + let cur=0,score=0; + const iEl=document.getElementById('p2-tr-i'); + const scEl=document.getElementById('p2-tr-score'); + const taskEl=document.getElementById('p2-tr-task'); + const ansEl=document.getElementById('p2-tr-ans'); + const goBtn=document.getElementById('p2-tr-go'); + const startBtn=document.getElementById('p2-tr-start'); + const fb=document.getElementById('p2-tr-fb'); + const numAnswers={'√306':Math.sqrt(306)}; + function showTask(){ + if(cur>=tasks.length){taskEl.innerHTML='Тренажёр завершён! Очки: '+score+'/'+tasks.length+'';ansEl.style.display='none';goBtn.style.display='none';addXp(score*4,'p2-trainer');bumpProgress('p2',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 raw=ansEl.value.trim().replace(',','.'); + const expected=tasks[cur].a; + const expNum=numAnswers[expected]!==undefined?numAnswers[expected]:parseFloat(expected); + const ansNum=parseFloat(raw); + const ok=Math.abs(ansNum-expNum)<0.5; + 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:'Расстояние от центра до касательной = R',cat:'true'}, + {label:'Из внешней точки можно провести только одну касательную',cat:'false'}, + {label:'AT = √(|OA|² − R²)',cat:'true'}, + {label:'AT > |OA|',cat:'false'}, + ]; + const pool=document.getElementById('p2-dnd-pool'); + const boxes={true:document.getElementById('p2-drop-true-items'),false:document.getElementById('p2-drop-false-items')}; + const fb=document.getElementById('p2-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('p2-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,'p2-dnd');bumpProgress('p2',15);} + }); + document.getElementById('p2-dnd-reset').addEventListener('click',reset); + reset(); + })(); + + /* === INIT ИНТЕРАКТИВ 6: Босс §2 === */ + (function(){ + const tasks=[ + {q:'Касательная $AT = 24$, радиус $R = 7$. Найти $|OA|$.', + opts:['25','√(576+49)=√625=25','√(24²−7²)=√527'],cor:1, + exp:'$|OA| = \\sqrt{AT^2 + R^2} = \\sqrt{576 + 49} = \\sqrt{625} = 25$.'}, + {q:'Угол $\\angle TOA = 30°$, $|OA| = 20$. Найти длину касательной $AT$.', + opts:['10','10√3','20√3'],cor:1, + exp:'В прямоугольном треугольнике $OAT$: $AT = OA \\cdot \\sin 30° \\cdot ...$. Нет: $\\angle OTA = 90°$, поэтому $AT = OA \\cdot \\sin(\\angle AOT) \\cdot ...$. Точнее: $\\cos(\\angle TAO) = AT/OA$, $\\angle OAT + \\angle AOT = 90°$, $\\angle OAT = 60°$, $AT = OA \\cdot \\sin 60° = 20 \\cdot \\dfrac{\\sqrt{3}}{2} = 10\\sqrt{3}$.'}, + {q:'Точка $A$ находится вне окружности. Из $A$ проведены касательные $AT_1$ и $AT_2$. Угол $\\angle T_1OT_2 = 120°$. Найти $\\angle T_1AT_2$.', + opts:['30°','60°','120°'],cor:1, + exp:'Четырёхугольник $AT_1OT_2$ имеет $\\angle T_1 = \\angle T_2 = 90°$, сумма углов $360°$. Значит $\\angle A + \\angle O = 180°$: $\\angle A = 60°$.'}, + {q:'Радиус $R = 10$, касательная $AT = 10\\sqrt{3}$. Найти $|OA|$.', + opts:['10','20','10√2'],cor:1, + exp:'$|OA| = \\sqrt{R^2 + AT^2} = \\sqrt{100 + 300} = \\sqrt{400} = 20$.'}, + ]; + const cont=document.getElementById('p2-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 buildP3(){ + const box=document.getElementById('p3-body'); + let html=''; + + html+=makeCard('theory','Свойство касательных из одной точки','3.1',` +

Теорема. Если из внешней точки $A$ к окружности проведены две касательные с точками касания $T_1$ и $T_2$, то:

+
    +
  • Равенство отрезков: $|AT_1| = |AT_2|$
  • +
  • Биссектриса: прямая $OA$ является биссектрисой угла $T_1AT_2$ (и угла $T_1OT_2$).
  • +
+
+ + + + + + + + + + + + O + T₁ + T₂ + A + AT₁ + AT₂ + AT₁ = AT₂ + +
`); + + html+=makeCard('rule','Доказательство через равные треугольники','3.2',` +

Рассмотрим треугольники $\\triangle OAT_1$ и $\\triangle OAT_2$:

+
    +
  • $OT_1 = OT_2 = R$ (оба радиусы)
  • +
  • $OA = OA$ (общая гипотенуза)
  • +
  • $\\angle OT_1A = \\angle OT_2A = 90°$ (свойство касательной)
  • +
+

По признаку равенства прямоугольных треугольников (по гипотенузе и катету): $\\triangle OAT_1 = \\triangle OAT_2$.

+

Следовательно, $AT_1 = AT_2$ и $\\angle T_1AO = \\angle T_2AO$. ч.т.д.

`); + + html+=makeCard('example','Пример','3.3',` +

Задача. Из точки $A$ проведены касательные к окружности радиуса $R = 8$. Расстояние от $A$ до центра $|OA| = 17$. Найти длины касательных.

+

Решение: $AT_1 = AT_2 = \\sqrt{|OA|^2 - R^2} = \\sqrt{289 - 64} = \\sqrt{225} = 15$.

+

Ответ: $AT_1 = AT_2 = 15$.

`); + + /* ИНТЕРАКТИВ 1 — SVG с двумя касательными из внешней точки A */ + html+=`
+
ИНТЕРАКТИВ 1
Две касательные из внешней точки
+
Двигай слайдер — меняй положение точки $A$. Отрезки $AT_1$ и $AT_2$ всегда равны!
+
+ +
+
+
+
`; + + /* ИНТЕРАКТИВ 2 — Пошаговое доказательство */ + html+=`
+
ИНТЕРАКТИВ 2
Доказательство равенства касательных — по шагам
+
Нажимай «Далее» чтобы пройти доказательство через равенство прямоугольных треугольников.
+
+
+
+ + +
+
`; + + /* ИНТЕРАКТИВ 3 — Калькулятор */ + html+=`
+
ИНТЕРАКТИВ 3
Калькулятор: длина двух касательных из одной точки
+
Дано $R$ и $|OA|$ — найди $|AT| = \\sqrt{|OA|^2 - R^2}$.
+
+ + + +
+ +
`; + + /* ИНТЕРАКТИВ 4 — Тренажёр */ + html+=`
+
ИНТЕРАКТИВ 4
Тренажёр §3
+
5 задач на свойство двух касательных. Введи ответ.
+
Задача 1 / 5Очки: 0
+
+
+ + + +
+ +
`; + + /* ИНТЕРАКТИВ 5 — DnD верные/неверные утверждения о двух касательных */ + html+=`
+
ИНТЕРАКТИВ 5
Верно или неверно о двух касательных?
+
Перетащи утверждение в нужную колонку.
+
+
+
Верно
+
Неверно
+
+
+ +
`; + + /* ИНТЕРАКТИВ 6 — Босс §3 */ + html+=`
+
БОСС §3
Итоговые задачи
+
4 задачи — каждая верная даёт +5 XP.
+
+
`; + + html+=`
+ +
`; + html+=secNav('p2','p4'); + box.innerHTML=html; + if(window.renderMathInElement) setTimeout(()=>renderMath(box),0); + + /* === INIT ИНТЕРАКТИВ 1: две касательные из A === */ + (function(){ + const sl=document.getElementById('p3-oa-sl'); + const oaVal=document.getElementById('p3-oa-val'); + const svgWrap=document.getElementById('p3-two-svg'); + const info=document.getElementById('p3-two-info'); + const R=65, cx=100, cy=130, W=280, H=240; + function draw(){ + const OA=+sl.value; + oaVal.textContent=OA; + const Ax=cx+OA, Ay=cy; + const AT=Math.sqrt(OA*OA-R*R); + const sinA=R/OA, cosA=AT/OA; + const T1x=cx+R*cosA, T1y=cy-R*sinA; + const T2x=cx+R*cosA, T2y=cy+R*sinA; + // right angle markers + const ur1x=(T1x-cx)/R, ur1y=(T1y-cy)/R; + const ut1x=-(ur1y), ut1y=ur1x; + const s=8; + const rm1=`${(T1x+ur1x*s).toFixed(1)},${(T1y+ur1y*s).toFixed(1)} ${(T1x+ur1x*s+ut1x*s).toFixed(1)},${(T1y+ur1y*s+ut1y*s).toFixed(1)} ${(T1x+ut1x*s).toFixed(1)},${(T1y+ut1y*s).toFixed(1)}`; + const ur2x=(T2x-cx)/R, ur2y=(T2y-cy)/R; + const ut2x=-(ur2y), ut2y=ur2x; + const rm2=`${(T2x+ur2x*s).toFixed(1)},${(T2y+ur2y*s).toFixed(1)} ${(T2x+ur2x*s+ut2x*s).toFixed(1)},${(T2y+ur2y*s+ut2y*s).toFixed(1)} ${(T2x+ut2x*s).toFixed(1)},${(T2y+ut2y*s).toFixed(1)}`; + const svg=` + + + + + + + + + + + + + T₁ + T₂ + O + A + ${fmt(AT)} + ${fmt(AT)} + `; + svgWrap.innerHTML=svg; + info.textContent='AT₁ = AT₂ = '+fmt(AT)+' (при R = '+R+', |OA| = '+OA+')'; + } + sl.addEventListener('input',draw); + draw(); + })(); + + /* === INIT ИНТЕРАКТИВ 2: пошаговое доказательство === */ + (function(){ + const steps=[ + {text:'Дано: окружность с центром $O$, радиусом $R$; из внешней точки $A$ проведены касательные $AT_1$ и $AT_2$ с точками касания $T_1$ и $T_2$. Доказать: $AT_1 = AT_2$.', + phase:'given'}, + {text:'Шаг 1. По свойству касательной: $OT_1 \\perp AT_1$ и $OT_2 \\perp AT_2$, то есть $\\angle OT_1A = \\angle OT_2A = 90°$. Треугольники $\\triangle OAT_1$ и $\\triangle OAT_2$ — прямоугольные.', + phase:'right'}, + {text:'Шаг 2. Выпишем элементы для признака равенства: $OA = OA$ (общая гипотенуза), $OT_1 = OT_2 = R$ (катеты — радиусы одной окружности).', + phase:'elements'}, + {text:'Шаг 3. По признаку равенства прямоугольных треугольников (по гипотенузе и катету): $\\triangle OAT_1 = \\triangle OAT_2$.', + phase:'equal'}, + {text:'Вывод. Из равенства треугольников: $AT_1 = AT_2$ (соответственные катеты) и $\\angle T_1AO = \\angle T_2AO$ (прямая $OA$ — биссектриса). ч.т.д.', + phase:'done'}, + ]; + let step=0; + const svgEl=document.getElementById('p3-proof-svg'); + const txtEl=document.getElementById('p3-proof-text'); + const nextBtn=document.getElementById('p3-proof-next'); + const resetBtn=document.getElementById('p3-proof-reset'); + const R=55, cx=100, cy=105; + const OA=130; + const AT=Math.sqrt(OA*OA-R*R); + const sinA=R/OA, cosA=AT/OA; + const T1x=cx+R*cosA, T1y=cy-R*sinA; + const T2x=cx+R*cosA, T2y=cy+R*sinA; + const Ax=cx+OA, Ay=cy; + function drawProof(ph){ + let tri1='',tri2='',equal=''; + if(ph==='right'||ph==='elements'||ph==='equal'||ph==='done'){ + tri1=``; + tri2=``; + const s=7; + const ur1x=(T1x-cx)/R, ur1y=(T1y-cy)/R; + const ut1x=-(ur1y), ut1y=ur1x; + const rm1=`${(T1x+ur1x*s).toFixed(1)},${(T1y+ur1y*s).toFixed(1)} ${(T1x+ur1x*s+ut1x*s).toFixed(1)},${(T1y+ur1y*s+ut1y*s).toFixed(1)} ${(T1x+ut1x*s).toFixed(1)},${(T1y+ut1y*s).toFixed(1)}`; + const ur2x=(T2x-cx)/R, ur2y=(T2y-cy)/R; + const ut2x=-(ur2y), ut2y=ur2x; + const rm2=`${(T2x+ur2x*s).toFixed(1)},${(T2y+ur2y*s).toFixed(1)} ${(T2x+ur2x*s+ut2x*s).toFixed(1)},${(T2y+ur2y*s+ut2y*s).toFixed(1)} ${(T2x+ut2x*s).toFixed(1)},${(T2y+ut2y*s).toFixed(1)}`; + equal=``; + } + if(ph==='done'||ph==='equal'){ + equal+=``; + equal+=``; + } + const mainColor=ph==='done'?'#10b981':'#0284c7'; + const svg=` + + ${tri1}${tri2} + + + + + + ${equal} + + + + + O + T₁ + T₂ + A + `; + svgEl.innerHTML=svg; + txtEl.innerHTML=steps.find(s=>s.phase===ph).text; + if(window.renderMathInElement) try{renderMath(txtEl);}catch(e){} + } + const phases=steps.map(s=>s.phase); + function go(){ + drawProof(phases[step]); + nextBtn.textContent=step>=phases.length-1?'Готово':'Далее'; + if(step{step=0;go();}); + go(); + })(); + + /* === INIT ИНТЕРАКТИВ 3: калькулятор === */ + (function(){ + const btn=document.getElementById('p3-calc-btn'); + const out=document.getElementById('p3-calc-out'); + btn.addEventListener('click',()=>{ + const R=parseFloat(document.getElementById('p3-cr').value); + const OA=parseFloat(document.getElementById('p3-coa').value); + 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='|OA| должно быть больше R';return;} + const AT=Math.sqrt(OA*OA-R*R); + out.style.background='#d1fae5';out.style.color='#065f46'; + out.innerHTML='|AT₁| = |AT₂| = √('+fmt(OA)+'² − '+fmt(R)+'²) = √'+fmt(OA*OA-R*R)+' = '+fmt(AT)+''; + }); + })(); + + /* === INIT ИНТЕРАКТИВ 4: Тренажёр === */ + (function(){ + const tasks=[ + {q:'Из точки $A$ проведены касательные к окружности радиуса $R = 6$, $|OA| = 10$. Найти длину каждой касательной.',a:'8',hint:'AT = √(100 − 36) = √64 = 8'}, + {q:'Касательная $AT_1 = 15$, $R = 9$. Найти $|OA|$.',a:'√306',hint:'OA = √(225 + 81) = √306. Введи приближение: 17'}, + {q:'Из точки $A$ проведены две касательные. $AT_1 = 12$, $AT_2 = ?$',a:'12',hint:'Два отрезка касательных из одной точки равны'}, + {q:'$|OA| = 25$, $AT = 24$. Найти $R$.',a:'7',hint:'R = √(25² − 24²) = √(625−576) = √49 = 7'}, + {q:'Угол между двумя касательными из точки $A$ равен $60°$. Угол $\\angle T_1OT_2 = ?$ (в градусах)',a:'120',hint:'Сумма углов A и O в четырёхугольнике AT₁OT₂ равна 180°'}, + ]; + let cur=0,score=0; + const iEl=document.getElementById('p3-tr-i'); + const scEl=document.getElementById('p3-tr-score'); + const taskEl=document.getElementById('p3-tr-task'); + const ansEl=document.getElementById('p3-tr-ans'); + const goBtn=document.getElementById('p3-tr-go'); + const startBtn=document.getElementById('p3-tr-start'); + const fb=document.getElementById('p3-tr-fb'); + function numOf(s){if(s==='√306')return Math.sqrt(306);return parseFloat(s);} + function showTask(){ + if(cur>=tasks.length){taskEl.innerHTML='Тренажёр завершён! Очки: '+score+'/'+tasks.length+'';ansEl.style.display='none';goBtn.style.display='none';addXp(score*4,'p3-trainer');bumpProgress('p3',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 raw=ansEl.value.trim().replace(',','.'); + const ok=Math.abs(parseFloat(raw)-numOf(tasks[cur].a))<0.6; + 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:'AT₁ = AT₂ (из одной внешней точки)',cat:'true'}, + {label:'AT₁ > AT₂ если T₁ выше T₂',cat:'false'}, + {label:'OA — биссектриса угла T₁AT₂',cat:'true'}, + {label:'∠OT₁A = 90°',cat:'true'}, + {label:'Из одной точки можно провести 3 касательных',cat:'false'}, + {label:'△OAT₁ = △OAT₂',cat:'true'}, + ]; + const pool=document.getElementById('p3-dnd-pool'); + const boxes={true:document.getElementById('p3-drop-true-items'),false:document.getElementById('p3-drop-false-items')}; + const fb=document.getElementById('p3-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('p3-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,'p3-dnd');bumpProgress('p3',15);} + }); + document.getElementById('p3-dnd-reset').addEventListener('click',reset); + reset(); + })(); + + /* === INIT ИНТЕРАКТИВ 6: Босс §3 === */ + (function(){ + const tasks=[ + {q:'Из точки $A$ проведены касательные к окружности с центром $O$. $\\angle T_1AT_2 = 60°$, $AT_1 = 6\\sqrt{3}$. Найти $R$.', + opts:['6','3√3','6√3'],cor:0, + exp:'$\\angle T_1AO = 30°$ (биссектриса), $\\tan 30° = R / AT_1$, значит $R = AT_1 \\cdot \\tan 30° = 6\\sqrt{3} \\cdot \\dfrac{1}{\\sqrt{3}} = 6$.'}, + {q:'Две касательные из $A$, $|OA| = 10$, $R = 8$. Найти периметр четырёхугольника $OT_1AT_2$.', + opts:['12+16=28','6+12+6+8=32','6·4=24'],cor:0, + exp:'$AT_1 = AT_2 = \\sqrt{100-64} = 6$. $OT_1 = OT_2 = 8$. Периметр $= 6+8+6+8 = 28$.'}, + {q:'Из точки $P$ проведены касательные, угол между касательными $90°$. $|OP| = 5\\sqrt{2}$. Найти $R$.', + opts:['5','5√2','10'],cor:0, + exp:'$\\angle T_1PO = 45°$ (половина 90°). $\\sin 45° = R/|OP|$, значит $R = 5\\sqrt{2} \\cdot \\dfrac{\\sqrt{2}}{2} = 5$.'}, + {q:'Два отрезка касательных из одной точки равны по теореме, доказанной через:', + opts:['Равенство прямоугольных треугольников (гипотенуза и катет)','Теорему Пифагора','Теорему Фалеса'],cor:0, + exp:'Доказывается через признак равенства прямоугольных треугольников: гипотенуза $OA$ общая, катет $OT_1 = OT_2 = R$.'}, + ]; + const cont=document.getElementById('p3-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 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'); }