diff --git a/frontend/textbooks/geometry_9_ch1.html b/frontend/textbooks/geometry_9_ch1.html index 1797a27..a4e8d80 100644 --- a/frontend/textbooks/geometry_9_ch1.html +++ b/frontend/textbooks/geometry_9_ch1.html @@ -1809,8 +1809,590 @@ function buildP4(){ wireReadBtn('p4'); } -function buildP5(){ _stubBuilder('p5', '§5', 'Формулы площади', 'p4', 'p6'); } -function buildP6(){ _stubBuilder('p6', '§6', 'Среднее геометрическое', 'p5', 'final1'); } +/* ===== §5 Формулы площади ===== */ +function buildP5(){ + const box = document.getElementById('p5-body'); + let html = ''; + + html += makeCard('theory', 'Площадь треугольника через две стороны и угол', '5.1', ` +

Площадь треугольника можно вычислить, зная две стороны и угол между ними:

+

$\\boxed{\\,S_\\triangle = \\dfrac{1}{2} a b \\sin C\\,}$

+

Здесь $a$ и $b$ — две стороны треугольника, а $C$ — угол между ними (то есть угол при общей вершине этих сторон).

+
Откуда берётся $\\sin C$?
+

Опустим высоту $h$ из вершины $A$ на сторону $a = BC$. В прямоугольном треугольнике с гипотенузой $b$ и острым углом $C$ имеем:

+

$h = b \\sin C$.

+

Тогда классическая формула $S = \\dfrac{1}{2} \\cdot a \\cdot h$ превращается в:

+

$S = \\dfrac{1}{2} a \\cdot b \\sin C = \\dfrac{1}{2} a b \\sin C$.

+

Формула работает и для тупого угла $C$: тогда высота попадает на продолжение стороны, но $\\sin C$ всё равно положителен (из §4 знаем: $\\sin(180^\\circ - \\alpha) = \\sin \\alpha$).

+
`); + + html += makeCard('rule', 'Площадь параллелограмма', '5.2', ` +

Аналогичная формула — для параллелограмма:

+

$\\boxed{\\,S_{\\text{пар}} = a b \\sin \\alpha\\,}$

+

Здесь $a, b$ — смежные стороны параллелограмма, $\\alpha$ — угол между ними.

+

Почему такая формула? Диагональ параллелограмма делит его на два равных треугольника. Площадь каждого по формуле §5.1 равна $\\dfrac{1}{2}ab\\sin\\alpha$, значит площадь всего параллелограмма — вдвое больше:

+

$S_{\\text{пар}} = 2 \\cdot \\dfrac{1}{2} ab \\sin \\alpha = ab \\sin \\alpha$.

+

Частные случаи:

+ `); + + html += makeCard('example', 'Площадь четырёхугольника через диагонали', '5.3', ` +

Для любого выпуклого четырёхугольника есть «универсальная» формула — через диагонали и угол между ними:

+

$\\boxed{\\,S_{4} = \\dfrac{1}{2} d_1 d_2 \\sin \\varphi\\,}$

+

где $d_1, d_2$ — диагонали, $\\varphi$ — угол между ними.

+

Примеры применения:

+ +
Подсказка по выбору формулы
+ +
`); + + /* IV1 — SVG визуализатор «Площадь треугольника по углу» */ + html += `
+
ИНТЕРАКТИВ 1
Площадь треугольника по углу
+
Двигай ползунки сторон $a, b$ и угла $A$ — треугольник перестраивается, а площадь пересчитывается по формуле $S = \\tfrac{1}{2} a b \\sin A$.
+
+ + + +
+
+ +
+
+
`; + + /* IV2 — Калькулятор параллелограмма */ + html += `
+
ИНТЕРАКТИВ 2
Калькулятор площади параллелограмма
+
Введи смежные стороны $a, b$ и угол $\\alpha$ между ними — найдём площадь по формуле $S = a b \\sin \\alpha$. При $\\alpha = 90^\\circ$ это просто прямоугольник.
+
+ $a$ = + + $b$ = + + $\\alpha$ = + + ° + +
+
+
+
`; + + /* IV3 — DnD сортер «Подбери формулу» */ + html += `
+
ИНТЕРАКТИВ 3
Подбери формулу
+
Распредели 6 фигур по трём «формульным ящикам». Тапни карточку, потом — нужный ящик (или перетащи).
+
6 фигур — 3 формулы
+
+
+
$S = \\tfrac{1}{2}ab\\sin C$
+
$S = ab\\sin\\alpha$
+
$S = \\tfrac{1}{2}d_1 d_2 \\sin\\varphi$
+
+
+
+
`; + + /* IV4 — Тренажёр площади */ + html += `
+
ИНТЕРАКТИВ 4
Тренажёр площади
+
Реши задачу и введи число (целое или округлённое до целых).
+
Задача 1 / 6Очки: 0 / 6
+
+
+ $S$ = + + + +
+
+
`; + + html += secNav('p4', 'p6'); + html += readButton('p5'); + + box.innerHTML = html; + renderMath(box); + + /* IV1 — SVG визуализатор */ + (function(){ + const slA = document.getElementById('p5-iv1-a'); + const slB = document.getElementById('p5-iv1-b'); + const slAng = document.getElementById('p5-iv1-A'); + const labA = document.getElementById('p5-iv1-aval'); + const labB = document.getElementById('p5-iv1-bval'); + const labAng = document.getElementById('p5-iv1-Aval'); + const svg = document.getElementById('p5-iv1-svg'); + const out = document.getElementById('p5-iv1-out'); + const seen = new Set(); + function draw(){ + const a = +slA.value, b = +slB.value, Adeg = +slAng.value; + labA.textContent = a; labB.textContent = b; labAng.textContent = Adeg; + const aRad = deg2rad(Adeg); + // В пикселях: множитель 20 на единицу + const k = 20; + const aPx = a * k, bPx = b * k; + // A в (80, 240), B справа по горизонтали, C — поворот на угол A вокруг A. + const A = {x: 80, y: 240}; + const B = {x: 80 + aPx, y: 240}; + const C = {x: 80 + bPx * Math.cos(aRad), y: 240 - bPx * Math.sin(aRad)}; + // векторы в A: вдоль AB и вдоль AC + const uAB = unitVec(A, B); + const uAC = unitVec(A, C); + let s = ''; + s += ''; + s += ''; + // дуга угла A + s += ''; + // подпись угла A + const halfRad = aRad / 2; + const tx = A.x + 52*Math.cos(halfRad); + const ty = A.y - 52*Math.sin(halfRad); + s += 'A='+Adeg+'°'; + // вершины + s += ''; + s += ''; + s += ''; + s += 'A'; + s += 'B'; + s += 'C'; + // подписи сторон + s += 'a='+a+''; + const midAC = {x:(A.x+C.x)/2, y:(A.y+C.y)/2}; + // нормаль к AC, направленная "наружу" треугольника (от B) + const nAC = {x:-(C.y-A.y), y:(C.x-A.x)}; + const nL = Math.sqrt(nAC.x*nAC.x+nAC.y*nAC.y)||1; + // выбираем сторону, противоположную B + const sign = ((B.x-A.x)*nAC.x + (B.y-A.y)*nAC.y) > 0 ? -1 : 1; + const labP = {x: midAC.x + sign*14*nAC.x/nL, y: midAC.y + sign*14*nAC.y/nL}; + s += 'b='+b+''; + svg.innerHTML = s; + // расчёт площади + const S = 0.5 * a * b * Math.sin(aRad); + out.innerHTML = '$S = \\dfrac{1}{2} \\cdot a \\cdot b \\cdot \\sin A = \\dfrac{1}{2} \\cdot '+a+' \\cdot '+b+' \\cdot \\sin '+Adeg+'^\\circ \\approx '+S.toFixed(2)+'$'; + renderMath(out); + seen.add(a+'_'+b+'_'+Adeg); + if(seen.size >= 5 && !seen.has('done')){ addXp(10,'p5-iv1'); bumpProgress('p5', 15); seen.add('done'); } + } + [slA, slB, slAng].forEach(sl => sl.addEventListener('input', draw)); + draw(); + })(); + + /* IV2 — Калькулятор параллелограмма */ + (function(){ + const aI = document.getElementById('p5-iv2-a'); + const bI = document.getElementById('p5-iv2-b'); + const AI = document.getElementById('p5-iv2-A'); + const go = document.getElementById('p5-iv2-go'); + const out = document.getElementById('p5-iv2-out'); + const fb = document.getElementById('p5-iv2-fb'); + let solved = 0; + function calc(){ + const a = parseFloat(aI.value), b = parseFloat(bI.value), Adeg = parseFloat(AI.value); + if(isNaN(a) || isNaN(b) || isNaN(Adeg)){ feedback(fb, false, '✗ Введи все три числа.'); return; } + if(a<=0 || b<=0){ feedback(fb, false, '✗ Стороны должны быть положительны.'); return; } + if(Adeg<=0 || Adeg>=180){ feedback(fb, false, '✗ Угол должен быть в диапазоне (0°; 180°).'); return; } + const r = deg2rad(Adeg); + const S = a * b * Math.sin(r); + let html = '$S = a \\cdot b \\cdot \\sin \\alpha = '+a+' \\cdot '+b+' \\cdot \\sin '+Adeg+'^\\circ \\approx '+S.toFixed(2)+'$'; + if(Math.abs(Adeg - 90) < 1e-9){ + html += '
Особый случай: $\\alpha = 90^\\circ$ — это прямоугольник, $S = a b = '+(a*b).toFixed(2)+'$.'; + } + out.innerHTML = html; + renderMath(out); + feedback(fb, true, '✓ Площадь найдена.'); + solved++; + if(solved === 1){ addXp(10,'p5-iv2'); bumpProgress('p5', 15); } + } + go.addEventListener('click', calc); + calc(); + })(); + + /* IV3 — DnD сортер */ + (function(){ + const items = [ + { id:'f1', cat:'t', html:'треугольник со сторонами $a, b$ и углом $C$ между ними' }, + { id:'f2', cat:'p', html:'параллелограмм со сторонами $a, b$ и углом $\\alpha$' }, + { id:'f3', cat:'p', html:'прямоугольник со сторонами $a, b$ ($\\alpha=90^\\circ$)' }, + { id:'f4', cat:'d', html:'ромб с диагоналями $d_1, d_2$' }, + { id:'f5', cat:'d', html:'трапеция с диагоналями $d_1, d_2$ и углом $\\varphi$' }, + { id:'f6', cat:'t', html:'равносторонний треугольник со стороной $a$ ($C = 60^\\circ$)' }, + ]; + const sorter = setupSorter({ + poolId:'p5-iv3-pool', + scopeSelector:'#p5-iv3', + items: items, + cats:['t','p','d'], + columnLayout:true, + }); + document.getElementById('p5-iv3-check').addEventListener('click', ()=>{ + const fb = document.getElementById('p5-iv3-fb'); + const placedCount = items.filter(it => sorter.placed[it.id]).length; + const correct = items.filter(it => sorter.placed[it.id] === it.cat).length; + if(placedCount < items.length){ feedback(fb, false, '✗ Размести все 6 фигур.'); return; } + if(correct === items.length){ feedback(fb, true, '✓ Все 6 на месте! +15 XP'); addXp(15,'p5-iv3'); bumpProgress('p5', 25); } + else feedback(fb, false, '✗ Правильно ' + correct + ' из 6. Попробуй ещё.'); + }); + document.getElementById('p5-iv3-reset').addEventListener('click', ()=>{ sorter.reset(); document.getElementById('p5-iv3-fb').style.display = 'none'; }); + })(); + + /* IV4 — Тренажёр */ + (function(){ + const Q = [ + { q:'Треугольник: $a = 5$, $b = 8$, $C = 30^\\circ$. Найди $S$.', ans:10, tol:0.2, hint:'$S = \\tfrac{1}{2} \\cdot 5 \\cdot 8 \\cdot \\sin 30^\\circ = 20 \\cdot 0{,}5 = 10$' }, + { q:'Параллелограмм: $a = 6$, $b = 10$, $\\alpha = 90^\\circ$. Найди $S$.', ans:60, tol:0.2, hint:'$\\sin 90^\\circ = 1$, $S = a b = 60$' }, + { q:'Ромб с диагоналями $12$ и $16$. Найди $S$.', ans:96, tol:0.2, hint:'диагонали ромба перпендикулярны: $S = \\tfrac{1}{2} \\cdot 12 \\cdot 16 = 96$' }, + { q:'Треугольник: $a = b = 4$, $C = 60^\\circ$. Найди $S$ (округли до целого).', ans:7, tol:0.5, hint:'$S = \\tfrac{1}{2} \\cdot 16 \\cdot \\sin 60^\\circ = 8 \\cdot \\tfrac{\\sqrt{3}}{2} = 4\\sqrt{3} \\approx 6{,}93 \\approx 7$' }, + { q:'Прямоугольник со сторонами $7$ и $12$. Найди $S$.', ans:84, tol:0.2, hint:'$S = 7 \\cdot 12 = 84$' }, + { q:'Треугольник: $a = 10$, $b = 10$, $C = 90^\\circ$. Найди $S$.', ans:50, tol:0.2, hint:'$S = \\tfrac{1}{2} \\cdot 100 \\cdot \\sin 90^\\circ = 50$' }, + ]; + let i = 0, score = 0; + function show(){ + if(i >= Q.length){ + document.getElementById('p5-iv4-q').innerHTML = 'Готово! Результат: ' + score + ' / ' + Q.length; + if(score === Q.length){ addXp(15,'p5-iv4'); bumpProgress('p5', 25); achievement('p5_done'); } + else if(score >= 4){ addXp(8,'p5-iv4'); bumpProgress('p5', 15); } + return; + } + document.getElementById('p5-iv4-i').textContent = (i+1); + document.getElementById('p5-iv4-s').textContent = score; + document.getElementById('p5-iv4-q').innerHTML = Q[i].q; + document.getElementById('p5-iv4-ans').value = ''; + renderMath(document.getElementById('p5-iv4-q')); + document.getElementById('p5-iv4-fb').style.display = 'none'; + } + function go(){ + if(i >= Q.length) return; + const fb = document.getElementById('p5-iv4-fb'); + const ans = parseFloat(document.getElementById('p5-iv4-ans').value); + if(isNaN(ans)){ feedback(fb, false, '✗ Введи число.'); return; } + if(Math.abs(ans - Q[i].ans) <= Q[i].tol){ score++; feedback(fb, true, '✓ Верно! '+Q[i].hint+'. Дальше ▶'); } + else feedback(fb, false, '✗ Неверно. Ответ: '+Q[i].ans+' ('+Q[i].hint+'). Дальше ▶'); + document.getElementById('p5-iv4-s').textContent = score; + i++; + setTimeout(show, 1400); + } + document.getElementById('p5-iv4-go').addEventListener('click', go); + document.getElementById('p5-iv4-ans').addEventListener('keydown', e=>{ if(e.key==='Enter') go(); }); + document.getElementById('p5-iv4-start').addEventListener('click', ()=>{ i=0; score=0; show(); }); + show(); + })(); + + wireReadBtn('p5'); +} + +/* ===== §6 Среднее геометрическое в прямоугольном треугольнике ===== */ +function buildP6(){ + const box = document.getElementById('p6-body'); + let html = ''; + + html += makeCard('theory', 'Высота к гипотенузе и проекции катетов', '6.1', ` +

Рассмотрим прямоугольный треугольник $ABC$ с прямым углом $C$. Из вершины $C$ опустим высоту $h = CH$ на гипотенузу $c = AB$. Эта высота делит гипотенузу на два отрезка: $AH = b_1$ и $BH = a_1$, причём $a_1 + b_1 = c$.

+

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

+

$\\boxed{\\,h^2 = a_1 b_1,\\qquad a^2 = c \\cdot a_1,\\qquad b^2 = c \\cdot b_1\\,}$

+

Здесь $a, b$ — катеты ($a = BC$ напротив $A$, $b = AC$ напротив $B$), $h$ — высота к гипотенузе, $a_1$ — проекция катета $a$ на гипотенузу (отрезок $BH$), $b_1$ — проекция катета $b$ на гипотенузу (отрезок $AH$).

+
Откуда берутся эти соотношения?
+

Высота $CH$ разбивает $\\triangle ABC$ на два маленьких прямоугольных треугольника — $\\triangle ACH$ и $\\triangle CBH$. Все три треугольника подобны друг другу (имеют по два равных угла).

+

Из подобия $\\triangle ACH \\sim \\triangle CBH$ получаем $\\dfrac{AH}{CH} = \\dfrac{CH}{BH}$, то есть $\\dfrac{b_1}{h} = \\dfrac{h}{a_1}$, откуда $h^2 = a_1 b_1$.

+

Из подобия $\\triangle ABC \\sim \\triangle ACH$ получаем $\\dfrac{AB}{AC} = \\dfrac{AC}{AH}$, то есть $\\dfrac{c}{b} = \\dfrac{b}{b_1}$, откуда $b^2 = c b_1$. Аналогично — третье соотношение.

+
`); + + html += makeCard('rule', 'Среднее геометрическое', '6.2', ` +

Эти три формулы — это среднее геометрическое в действии. Среднее геометрическое чисел $x, y$ — это $\\sqrt{xy}$. Получаем:

+
    +
  • $h = \\sqrt{a_1 b_1}$ — высота к гипотенузе есть среднее геометрическое проекций катетов.
  • +
  • $a = \\sqrt{c \\cdot a_1}$ — катет $a$ есть среднее геометрическое гипотенузы и проекции этого катета.
  • +
  • $b = \\sqrt{c \\cdot b_1}$ — катет $b$ есть среднее геометрическое гипотенузы и проекции этого катета.
  • +
+

Эти три факта называют метрическими соотношениями в прямоугольном треугольнике, и они моментально решают задачи, в которых заданы какие-то «куски» гипотенузы.

+
Почему «среднее геометрическое»?
+

Запись $h^2 = a_1 b_1$ означает, что $h$ — такое число, квадрат которого равен произведению $a_1$ и $b_1$. Это и есть классическое определение среднего геометрического двух положительных чисел: $h = \\sqrt{a_1 b_1}$.

+
`); + + html += makeCard('example', 'Примеры применения', '6.3', ` +

Пример 1. $c = 10$, проекции $a_1 = 4$, $b_1 = 6$. Найти $h, a, b$.

+
    +
  • $h = \\sqrt{a_1 b_1} = \\sqrt{4 \\cdot 6} = \\sqrt{24} = 2\\sqrt{6} \\approx 4{,}9$
  • +
  • $a = \\sqrt{c \\cdot a_1} = \\sqrt{40} = 2\\sqrt{10}$
  • +
  • $b = \\sqrt{c \\cdot b_1} = \\sqrt{60} = 2\\sqrt{15}$
  • +
+

Пример 2. Треугольник $6$–$8$–$10$ (3–4–5, умноженное на $2$). Найти $h, a_1, b_1$.

+
    +
  • $a = 6$, $c = 10 \\Rightarrow a_1 = \\dfrac{a^2}{c} = \\dfrac{36}{10} = 3{,}6$
  • +
  • $b = 8$, $c = 10 \\Rightarrow b_1 = \\dfrac{b^2}{c} = \\dfrac{64}{10} = 6{,}4$
  • +
  • Проверка: $a_1 + b_1 = 3{,}6 + 6{,}4 = 10 = c$ ✓
  • +
  • $h = \\sqrt{a_1 b_1} = \\sqrt{3{,}6 \\cdot 6{,}4} = \\sqrt{23{,}04} = 4{,}8$
  • +
+

Сверка площадей: $S = \\tfrac{1}{2} a b = \\tfrac{1}{2} \\cdot 6 \\cdot 8 = 24$ и $S = \\tfrac{1}{2} c h = \\tfrac{1}{2} \\cdot 10 \\cdot 4{,}8 = 24$. Совпало — соотношение работает.

`); + + /* IV1 — SVG визуализатор */ + html += `
+
ИНТЕРАКТИВ 1
Конструктор соотношений
+
Меняй угол $A$ — точка $H$ перемещается по гипотенузе, проекции $a_1, b_1$ меняются, и три соотношения $h^2 = a_1 b_1$, $a^2 = c a_1$, $b^2 = c b_1$ всё время выполняются.
+
+ +
+
+ +
+
+
`; + + /* IV2 — Калькулятор h */ + html += `
+
ИНТЕРАКТИВ 2
Калькулятор $h$ и $c$
+
Введи проекции катетов $a_1, b_1$ — найдём высоту $h$, гипотенузу $c$, катеты $a, b$ и площадь $S$.
+
+ $a_1$ = + + $b_1$ = + + +
+
+ +
`; + + /* IV3 — Какое соотношение? */ + html += `
+
ИНТЕРАКТИВ 3
Какое соотношение применить?
+
Даны какие-то элементы прямоугольного треугольника — выбери, какое из трёх соотношений поможет найти искомую величину.
+
Задача 1 / 6Очки: 0 / 6
+
+
+ + + +
+ +
`; + + /* IV4 — Тренажёр */ + html += `
+
ИНТЕРАКТИВ 4
Тренажёр среднего геометрического
+
Реши задачу и введи число (целое или округлённое до сотых).
+
Задача 1 / 6Очки: 0 / 6
+
+
+ ответ = + + + +
+ +
`; + + html += secNav('p5', 'final1'); + html += readButton('p6'); + + box.innerHTML = html; + renderMath(box); + + /* IV1 — SVG */ + (function(){ + const sl = document.getElementById('p6-iv1-a'); + const lab = document.getElementById('p6-iv1-aval'); + const svg = document.getElementById('p6-iv1-svg'); + const out = document.getElementById('p6-iv1-out'); + const seen = new Set(); + function draw(){ + const Adeg = +sl.value; + lab.textContent = Adeg; + const Arad = deg2rad(Adeg); + // Гипотенуза AB длиной 300px по низу. + const cPx = 300; + const A = {x: 90, y: 260}; + const B = {x: 90 + cPx, y: 260}; + // Точка C — над гипотенузой, угол при A равен Adeg, угол при B равен 90 - Adeg. + // AC = c * cos A, BC = c * sin A. Из A под углом Adeg вверх. + const ACpx = cPx * Math.cos(Arad); + // Координаты C: от A на расстояние AC под углом Adeg к AB (вверх) + const C = {x: A.x + ACpx * Math.cos(Arad), y: A.y - ACpx * Math.sin(Arad)}; + // H — основание высоты из C на AB. + const H = {x: C.x, y: A.y}; + // длины + const a1 = Math.abs(H.x - B.x); // BH (проекция BC) + const b1 = Math.abs(H.x - A.x); // AH (проекция AC) + const hPx = Math.abs(C.y - H.y); + const aPx = Math.sqrt((B.x-C.x)*(B.x-C.x) + (B.y-C.y)*(B.y-C.y)); + const bPx = Math.sqrt((A.x-C.x)*(A.x-C.x) + (A.y-C.y)*(A.y-C.y)); + // в "единичных" единицах (делим px на 30) + const sc = 30; + const a = aPx/sc, b = bPx/sc, c = cPx/sc, h = hPx/sc, _a1 = a1/sc, _b1 = b1/sc; + let s = ''; + s += ''; + // подсветка маленьких треугольников + s += ''; + s += ''; + // основной треугольник (контур) + s += ''; + // высота CH + s += ''; + // маркер прямого угла при C (катеты CA и CB) + const uCA = unitVec(C, A); + const uCB = unitVec(C, B); + s += ''; + // маркер прямого угла при H (CH и HB) + const uHC = unitVec(H, C); + const uHB = unitVec(H, B); + s += ''; + // вершины + s += ''; + s += ''; + s += ''; + s += ''; + s += 'A'; + s += 'B'; + s += 'C'; + s += 'H'; + // подписи отрезков + s += 'b₁='+b1.toFixed(0)+''; + s += 'a₁='+a1.toFixed(0)+''; + s += 'h='+hPx.toFixed(0)+''; + s += 'b='+bPx.toFixed(0)+''; + s += 'a='+aPx.toFixed(0)+''; + svg.innerHTML = s; + // соотношения (в пикселях — но проверка работает в любых единицах) + out.innerHTML = 'Три соотношения (в пикселях):
' + + '$h^2 = '+hPx.toFixed(0)+'^2 \\approx '+(hPx*hPx).toFixed(0)+'$,   $a_1 \\cdot b_1 = '+a1.toFixed(0)+' \\cdot '+b1.toFixed(0)+' \\approx '+(a1*b1).toFixed(0)+'$  ✓
' + + '$a^2 = '+aPx.toFixed(0)+'^2 \\approx '+(aPx*aPx).toFixed(0)+'$,   $c \\cdot a_1 = '+cPx+' \\cdot '+a1.toFixed(0)+' \\approx '+(cPx*a1).toFixed(0)+'$  ✓
' + + '$b^2 = '+bPx.toFixed(0)+'^2 \\approx '+(bPx*bPx).toFixed(0)+'$,   $c \\cdot b_1 = '+cPx+' \\cdot '+b1.toFixed(0)+' \\approx '+(cPx*b1).toFixed(0)+'$  ✓'; + renderMath(out); + seen.add(Adeg); + if(seen.size >= 5 && !seen.has('done')){ addXp(10,'p6-iv1'); bumpProgress('p6', 15); seen.add('done'); } + } + sl.addEventListener('input', draw); + draw(); + })(); + + /* IV2 — Калькулятор */ + (function(){ + const aI = document.getElementById('p6-iv2-a1'); + const bI = document.getElementById('p6-iv2-b1'); + const go = document.getElementById('p6-iv2-go'); + const out = document.getElementById('p6-iv2-out'); + const fb = document.getElementById('p6-iv2-fb'); + let solved = 0; + function calc(){ + const a1 = parseFloat(aI.value), b1 = parseFloat(bI.value); + if(isNaN(a1) || isNaN(b1)){ feedback(fb, false, '✗ Введи оба числа.'); return; } + if(a1<=0 || b1<=0){ feedback(fb, false, '✗ Проекции должны быть положительны.'); return; } + const c = a1 + b1; + const h = Math.sqrt(a1 * b1); + const a = Math.sqrt(c * a1); + const b = Math.sqrt(c * b1); + const S = 0.5 * c * h; + out.innerHTML = '$c = a_1 + b_1 = '+a1+' + '+b1+' = '+c+'$
' + + '$h = \\sqrt{a_1 \\cdot b_1} = \\sqrt{'+a1+' \\cdot '+b1+'} = \\sqrt{'+(a1*b1)+'} \\approx '+h.toFixed(2)+'$
' + + '$a = \\sqrt{c \\cdot a_1} = \\sqrt{'+(c*a1)+'} \\approx '+a.toFixed(2)+'$
' + + '$b = \\sqrt{c \\cdot b_1} = \\sqrt{'+(c*b1)+'} \\approx '+b.toFixed(2)+'$
' + + '$S = \\dfrac{1}{2} c h \\approx '+S.toFixed(2)+'$  (сверка: $\\tfrac{1}{2}ab \\approx '+(0.5*a*b).toFixed(2)+'$)'; + renderMath(out); + feedback(fb, true, '✓ Все элементы найдены.'); + solved++; + if(solved === 1){ addXp(10,'p6-iv2'); bumpProgress('p6', 15); } + } + go.addEventListener('click', calc); + calc(); + })(); + + /* IV3 — Какое соотношение? */ + (function(){ + const Q = [ + { expr:'Известно $c = 10$, $a_1 = 4$. Найти катет $a$.', ans:'a', why:'$a^2 = c \\cdot a_1 = 40 \\Rightarrow a = \\sqrt{40}$' }, + { expr:'Известно $a_1 = 9$, $b_1 = 16$. Найти высоту $h$.', ans:'h', why:'$h^2 = a_1 \\cdot b_1 = 144 \\Rightarrow h = 12$' }, + { expr:'Известно $c = 25$, $b_1 = 9$. Найти катет $b$.', ans:'b', why:'$b^2 = c \\cdot b_1 = 225 \\Rightarrow b = 15$' }, + { expr:'Известно $a = 6$, $c = 9$. Найти $a_1$.', ans:'a', why:'из $a^2 = c \\cdot a_1$: $a_1 = a^2/c = 36/9 = 4$' }, + { expr:'Известно $h = 6$, $a_1 = 4$. Найти $b_1$.', ans:'h', why:'из $h^2 = a_1 b_1$: $b_1 = h^2/a_1 = 36/4 = 9$' }, + { expr:'Известно $b = 8$, $c = 16$. Найти $b_1$.', ans:'b', why:'из $b^2 = c \\cdot b_1$: $b_1 = b^2/c = 64/16 = 4$' }, + ]; + let i = 0, score = 0; + function show(){ + if(i >= Q.length){ + document.getElementById('p6-iv3-q').innerHTML = 'Готово! Результат: ' + score + ' / ' + Q.length; + if(score === Q.length){ addXp(15,'p6-iv3'); bumpProgress('p6', 25); } + else if(score >= Q.length - 1){ addXp(8,'p6-iv3'); bumpProgress('p6', 15); } + return; + } + document.getElementById('p6-iv3-i').textContent = (i+1); + document.getElementById('p6-iv3-s').textContent = score; + document.getElementById('p6-iv3-q').innerHTML = Q[i].expr; + renderMath(document.getElementById('p6-iv3-q')); + document.getElementById('p6-iv3-fb').style.display = 'none'; + } + function answer(a){ + if(i >= Q.length) return; + const fb = document.getElementById('p6-iv3-fb'); + if(a === Q[i].ans){ score++; feedback(fb, true, '✓ Верно! '+Q[i].why+'. Дальше ▶'); } + else feedback(fb, false, '✗ Нет. Нужно: '+Q[i].why+'. Дальше ▶'); + document.getElementById('p6-iv3-s').textContent = score; + i++; + setTimeout(show, 1200); + } + ['h','a','b'].forEach(k=>{ + const btn = document.getElementById('p6-iv3-'+k); if(btn) btn.addEventListener('click', ()=>answer(k)); + }); + show(); + })(); + + /* IV4 — Тренажёр */ + (function(){ + const Q = [ + { q:'$a_1 = 4$, $b_1 = 9$. Найти $h$.', ans:6, tol:0.05, hint:'$h = \\sqrt{4 \\cdot 9} = \\sqrt{36} = 6$' }, + { q:'$c = 20$, $b_1 = 5$. Найти $b$.', ans:10, tol:0.05, hint:'$b = \\sqrt{c b_1} = \\sqrt{100} = 10$' }, + { q:'$h = 12$, $a_1 = 9$. Найти $b_1$.', ans:16, tol:0.1, hint:'$b_1 = h^2/a_1 = 144/9 = 16$' }, + { q:'$a = 6$, $c = 9$. Найти $a_1$.', ans:4, tol:0.05, hint:'$a_1 = a^2/c = 36/9 = 4$' }, + { q:'Среднее геометрическое чисел $4$ и $25$.', ans:10, tol:0.05, hint:'$\\sqrt{4 \\cdot 25} = \\sqrt{100} = 10$' }, + { q:'$c = 10$, $a_1 = 2$. Найти $a^2$.', ans:20, tol:0.1, hint:'$a^2 = c \\cdot a_1 = 10 \\cdot 2 = 20$' }, + ]; + let i = 0, score = 0; + function show(){ + if(i >= Q.length){ + document.getElementById('p6-iv4-q').innerHTML = 'Готово! Результат: ' + score + ' / ' + Q.length; + if(score === Q.length){ addXp(15,'p6-iv4'); bumpProgress('p6', 25); } + else if(score >= 4){ addXp(8,'p6-iv4'); bumpProgress('p6', 15); } + return; + } + document.getElementById('p6-iv4-i').textContent = (i+1); + document.getElementById('p6-iv4-s').textContent = score; + document.getElementById('p6-iv4-q').innerHTML = Q[i].q; + document.getElementById('p6-iv4-ans').value = ''; + renderMath(document.getElementById('p6-iv4-q')); + document.getElementById('p6-iv4-fb').style.display = 'none'; + } + function go(){ + if(i >= Q.length) return; + const fb = document.getElementById('p6-iv4-fb'); + const ans = parseFloat(document.getElementById('p6-iv4-ans').value); + if(isNaN(ans)){ feedback(fb, false, '✗ Введи число.'); return; } + if(Math.abs(ans - Q[i].ans) <= Q[i].tol){ score++; feedback(fb, true, '✓ Верно! '+Q[i].hint+'. Дальше ▶'); } + else feedback(fb, false, '✗ Неверно. Ответ: '+Q[i].ans+' ('+Q[i].hint+'). Дальше ▶'); + document.getElementById('p6-iv4-s').textContent = score; + i++; + setTimeout(show, 1400); + } + document.getElementById('p6-iv4-go').addEventListener('click', go); + document.getElementById('p6-iv4-ans').addEventListener('keydown', e=>{ if(e.key==='Enter') go(); }); + document.getElementById('p6-iv4-start').addEventListener('click', ()=>{ i=0; score=0; show(); }); + show(); + })(); + + wireReadBtn('p6'); +} function buildFinal1(){ const body = document.getElementById('final1-body');