diff --git a/frontend/textbooks/geometry_9_ch1.html b/frontend/textbooks/geometry_9_ch1.html
index 9d51763..1797a27 100644
--- a/frontend/textbooks/geometry_9_ch1.html
+++ b/frontend/textbooks/geometry_9_ch1.html
@@ -1175,8 +1175,640 @@ function buildP2(){
wireReadBtn('p2');
}
-function buildP3(){ _stubBuilder('p3', '§3', 'Тригонометрические формулы', 'p2', 'p4'); }
-function buildP4(){ _stubBuilder('p4', '§4', 'sin, cos, tg, ctg тупого угла', 'p3', 'p5'); }
+/* ===== §3 Тригонометрические формулы ===== */
+function buildP3(){
+ const box = document.getElementById('p3-body');
+ let html = '';
+
+ html += makeCard('theory', 'Основное тригонометрическое тождество', '3.1', `
+
Возьмём прямоугольный треугольник с острым углом $\\alpha$, противолежащим катетом $a$, прилежащим катетом $b$ и гипотенузой $c$. По определению $\\sin \\alpha = a/c$, $\\cos \\alpha = b/c$.
+ По теореме Пифагора $a^2 + b^2 = c^2$. Поделим обе части на $c^2$:
+ $\\dfrac{a^2}{c^2} + \\dfrac{b^2}{c^2} = 1 \\;\\Rightarrow\\; \\left(\\dfrac{a}{c}\\right)^2 + \\left(\\dfrac{b}{c}\\right)^2 = 1.$
+ $\\sin^2 \\alpha + \\cos^2 \\alpha = 1$
+ Следствия (для острого $\\alpha$):
+
+ $\\sin \\alpha = \\sqrt{1 - \\cos^2 \\alpha}$
+ $\\cos \\alpha = \\sqrt{1 - \\sin^2 \\alpha}$
+
+ Зачем это нужно?
+ Если известно одно из значений ($\\sin \\alpha$ или $\\cos \\alpha$), второе мгновенно вычисляется без чертежа треугольника. Это первое настоящее тригонометрическое тождество — равенство, верное для любого допустимого угла.
+
`);
+
+ html += makeCard('rule', 'Связь tg и ctg с sin и cos', '3.2', `
+ Из определений $\\tan \\alpha = \\dfrac{a}{b}$ и $\\sin \\alpha / \\cos \\alpha = \\dfrac{a/c}{b/c} = \\dfrac{a}{b}$ получаем:
+
+ $\\tan \\alpha = \\dfrac{\\sin \\alpha}{\\cos \\alpha}$
+ $\\cot \\alpha = \\dfrac{\\cos \\alpha}{\\sin \\alpha}$
+ $\\tan \\alpha \\cdot \\cot \\alpha = 1$ (значит, $\\cot \\alpha = 1/\\tan \\alpha$)
+
+ Поделим основное тождество $\\sin^2 \\alpha + \\cos^2 \\alpha = 1$ на $\\cos^2 \\alpha$:
+ $\\dfrac{\\sin^2 \\alpha}{\\cos^2 \\alpha} + 1 = \\dfrac{1}{\\cos^2 \\alpha} \\;\\Rightarrow\\; \\boxed{\\,1 + \\tan^2 \\alpha = \\dfrac{1}{\\cos^2 \\alpha}\\,}$
+ Аналогично, поделив на $\\sin^2 \\alpha$:
+ $\\boxed{\\,1 + \\cot^2 \\alpha = \\dfrac{1}{\\sin^2 \\alpha}\\,}$
`);
+
+ html += makeCard('example', 'Откуда берутся 30°, 45°, 60°', '3.3', `
+ 1) Треугольник 45°-45°-90° — равнобедренный прямоугольный. Возьмём оба катета равными $1$. Тогда гипотенуза $\\sqrt{1^2 + 1^2} = \\sqrt{2}$. Значит:
+ $\\sin 45^\\circ = \\cos 45^\\circ = \\dfrac{1}{\\sqrt{2}} = \\dfrac{\\sqrt{2}}{2},\\quad \\tan 45^\\circ = \\cot 45^\\circ = 1.$
+ 2) Треугольник 30°-60°-90° — половина равностороннего. У равностороннего треугольника со стороной $2$ все углы $60^\\circ$. Высота делит его на два прямоугольных треугольника с катетами $1$ (половина основания) и $\\sqrt{2^2 - 1^2} = \\sqrt{3}$, гипотенузой $2$. Углы: $30^\\circ$ (при вершине) и $60^\\circ$ (у основания). Получаем:
+ $\\sin 30^\\circ = \\dfrac{1}{2},\\; \\cos 30^\\circ = \\dfrac{\\sqrt{3}}{2},\\; \\tan 30^\\circ = \\dfrac{1}{\\sqrt{3}}.$
+ $\\sin 60^\\circ = \\dfrac{\\sqrt{3}}{2},\\; \\cos 60^\\circ = \\dfrac{1}{2},\\; \\tan 60^\\circ = \\sqrt{3}.$
+
+
+
+ Угол
+ $\\sin$
+ $\\cos$
+ $\\tan$
+ $\\cot$
+
+
+ 30° $\\tfrac{1}{2}$ $\\tfrac{\\sqrt{3}}{2}$ $\\tfrac{1}{\\sqrt{3}}$ $\\sqrt{3}$
+ 45° $\\tfrac{\\sqrt{2}}{2}$ $\\tfrac{\\sqrt{2}}{2}$ $1$ $1$
+ 60° $\\tfrac{\\sqrt{3}}{2}$ $\\tfrac{1}{2}$ $\\sqrt{3}$ $\\tfrac{1}{\\sqrt{3}}$
+
+
+
`);
+
+ /* IV1 — Три эталонных треугольника */
+ html += `
+
+
Слева — треугольник $30^\\circ\\text{-}60^\\circ\\text{-}90^\\circ$ (катеты $1$ и $\\sqrt{3}$, гипотенуза $2$). Справа — равнобедренный $45^\\circ\\text{-}45^\\circ\\text{-}90^\\circ$ (катеты $1$, гипотенуза $\\sqrt{2}$).
+
+
+
+
+
+
+ Угол
+ $\\sin$
+ $\\cos$
+ $\\tan$
+ $\\cot$
+
+
+ 30° $\\tfrac{1}{2}$ $\\tfrac{\\sqrt{3}}{2}$ $\\tfrac{1}{\\sqrt{3}}$ $\\sqrt{3}$
+ 45° $\\tfrac{\\sqrt{2}}{2}$ $\\tfrac{\\sqrt{2}}{2}$ $1$ $1$
+ 60° $\\tfrac{\\sqrt{3}}{2}$ $\\tfrac{1}{2}$ $\\sqrt{3}$ $\\tfrac{1}{\\sqrt{3}}$
+
+
+
+
`;
+
+ /* IV2 — Калькулятор тождеств */
+ html += `
+
+
Введи $\\sin \\alpha$ (значение от $0{,}01$ до $0{,}99$). Получишь $\\cos \\alpha$, $\\tan \\alpha$, $\\cot \\alpha$ и сам угол $\\alpha$ в градусах.
+
+ $\\sin \\alpha$ =
+
+
+ Вычислить
+
+
+
+
`;
+
+ /* IV3 — Quickfire «Какое значение?» */
+ html += `
+
+
Дано тригонометрическое выражение — выбери его точное значение из 4 вариантов.
+
Задача 1 / 8 Очки: 0 / 8
+
+
+ $\\tfrac{1}{2}$
+ $\\tfrac{\\sqrt{2}}{2}$
+ $\\tfrac{\\sqrt{3}}{2}$
+ $1$
+
+
+
`;
+
+ /* IV4 — Применение тождеств */
+ html += `
+
+
Реши задачу и введи число (целое или десятичную дробь до 3 знаков).
+
Задача 1 / 6 Очки: 0 / 6
+
+
+ ответ =
+
+ Проверить
+ Заново
+
+
+
`;
+
+ html += secNav('p2', 'p4');
+ html += readButton('p3');
+
+ box.innerHTML = html;
+ renderMath(box);
+
+ /* IV1 — рисуем три эталонных треугольника */
+ (function(){
+ const svg = document.getElementById('p3-iv1-svg');
+ if(!svg) return;
+ let s = '';
+ // Треугольник 30-60-90: катеты 1 и sqrt(3), гипотенуза 2. Используем масштаб 60 px = 1 ед.
+ // Левый: BC = sqrt(3) (горизонт., прилежащий 30°), AB = 1 (вертикальный, противолежащий 30°)
+ // Вершины: A слева внизу, B слева вверху (прямой угол), C справа внизу.
+ // Угол 30° при C, угол 60° при A.
+ (function(){
+ const u = 60;
+ const Ax = 40, Ay = 180;
+ const A = {x: Ax, y: Ay};
+ const B = {x: Ax, y: Ay - u}; // катет AB = 1
+ const C = {x: Ax + Math.sqrt(3)*u, y: Ay}; // катет BC = sqrt(3)
+ const uBA = unitVec(B, A);
+ const uBC = unitVec(B, C);
+ const uCA = unitVec(C, A);
+ const uCB = unitVec(C, B);
+ const uAB = unitVec(A, B);
+ const uAC = unitVec(A, C);
+ s += ' ';
+ s += ' ';
+ s += ' ';
+ s += ' ';
+ // подписи углов
+ s += '30° ';
+ s += '60° ';
+ // вершины и подписи
+ ['A','B','C'].forEach((nm,i)=>{ const P=[A,B,C][i]; s+=' '; });
+ s += 'A ';
+ s += 'B ';
+ s += 'C ';
+ // длины сторон
+ s += '1 ';
+ s += '√3 ';
+ const midAC={x:(A.x+C.x)/2, y:(A.y+C.y)/2};
+ 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;
+ const labP={x: midAC.x + 16*nAC.x/nL, y: midAC.y + 16*nAC.y/nL};
+ s += '2 ';
+ // заголовок
+ s += '30\xb0-60\xb0-90\xb0 ';
+ })();
+ // Треугольник 45-45-90: оба катета 1, гипотенуза sqrt(2). Масштаб тот же.
+ (function(){
+ const u = 90; // покрупнее
+ const Ax = 360, Ay = 180;
+ const A = {x: Ax, y: Ay};
+ const B = {x: Ax, y: Ay - u};
+ const C = {x: Ax + u, y: Ay};
+ const uBA = unitVec(B, A);
+ const uBC = unitVec(B, C);
+ const uCA = unitVec(C, A);
+ const uCB = unitVec(C, B);
+ const uAB = unitVec(A, B);
+ const uAC = unitVec(A, C);
+ s += ' ';
+ s += ' ';
+ s += ' ';
+ s += ' ';
+ s += '45° ';
+ s += '45° ';
+ ['A','B','C'].forEach((nm,i)=>{ const P=[A,B,C][i]; s+=' '; });
+ s += 'A ';
+ s += 'B ';
+ s += 'C ';
+ s += '1 ';
+ s += '1 ';
+ const midAC={x:(A.x+C.x)/2, y:(A.y+C.y)/2};
+ 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;
+ const labP={x: midAC.x + 16*nAC.x/nL, y: midAC.y + 16*nAC.y/nL};
+ s += '√2 ';
+ s += '45\xb0-45\xb0-90\xb0 ';
+ })();
+ svg.innerHTML = s;
+ addXp(10,'p3-iv1'); bumpProgress('p3', 15);
+ })();
+
+ /* IV2 — Калькулятор тождеств */
+ (function(){
+ const sl = document.getElementById('p3-iv2-s');
+ const inp = document.getElementById('p3-iv2-sn');
+ const go = document.getElementById('p3-iv2-go');
+ const out = document.getElementById('p3-iv2-out');
+ const fb = document.getElementById('p3-iv2-fb');
+ let solved = 0;
+ function sync(from){
+ if(from==='range') inp.value = sl.value;
+ else { const v = Math.max(0.01, Math.min(0.99, parseFloat(inp.value)||0.5)); sl.value = v; inp.value = v; }
+ }
+ function calc(){
+ const sn = parseFloat(sl.value);
+ if(isNaN(sn) || sn<=0 || sn>=1){ feedback(fb, false, '✗ $\\sin \\alpha$ должен быть в (0; 1).'); return; }
+ const cs = Math.sqrt(1 - sn*sn);
+ const tn = sn / cs;
+ const ct = cs / sn;
+ const aDeg = Math.asin(sn) * 180 / Math.PI;
+ out.innerHTML = '$\\sin \\alpha = '+sn.toFixed(3)+'$ · $\\cos \\alpha = \\sqrt{1 - \\sin^2 \\alpha} \\approx '+cs.toFixed(3)+'$ '
+ + '$\\tan \\alpha \\approx '+tn.toFixed(3)+'$ · $\\cot \\alpha \\approx '+ct.toFixed(3)+'$ '
+ + '$\\alpha \\approx '+aDeg.toFixed(2)+'^\\circ$ ';
+ renderMath(out);
+ feedback(fb, true, '✓ Все значения вычислены через основное тождество.');
+ solved++;
+ if(solved === 1){ addXp(10,'p3-iv2'); bumpProgress('p3', 15); }
+ }
+ sl.addEventListener('input', ()=>{ sync('range'); calc(); });
+ inp.addEventListener('input', ()=>{ sync('input'); });
+ go.addEventListener('click', calc);
+ calc();
+ })();
+
+ /* IV3 — Какое значение? */
+ (function(){
+ const Q = [
+ { expr:'$\\sin 30^\\circ$', ans:'half', why:'эталон: $\\sin 30^\\circ = 1/2$' },
+ { expr:'$\\cos 60^\\circ$', ans:'half', why:'эталон: $\\cos 60^\\circ = 1/2$' },
+ { expr:'$\\sin 45^\\circ$', ans:'s2', why:'эталон: $\\sin 45^\\circ = \\sqrt{2}/2$' },
+ { expr:'$\\cos 45^\\circ$', ans:'s2', why:'эталон: $\\cos 45^\\circ = \\sqrt{2}/2$' },
+ { expr:'$\\sin 60^\\circ$', ans:'s3', why:'эталон: $\\sin 60^\\circ = \\sqrt{3}/2$' },
+ { expr:'$\\cos 30^\\circ$', ans:'s3', why:'эталон: $\\cos 30^\\circ = \\sqrt{3}/2$' },
+ { expr:'$\\sin^2 30^\\circ + \\cos^2 30^\\circ$', ans:'one', why:'основное тождество: $\\sin^2 + \\cos^2 = 1$' },
+ { expr:'$\\tan 45^\\circ$', ans:'one', why:'эталон: $\\tan 45^\\circ = 1$' },
+ ];
+ let i = 0, score = 0;
+ function show(){
+ if(i >= Q.length){
+ document.getElementById('p3-iv3-q').innerHTML = 'Готово! Результат: ' + score + ' / ' + Q.length;
+ if(score === Q.length){ addXp(15,'p3-iv3'); bumpProgress('p3', 25); }
+ else if(score >= Q.length - 2){ addXp(8,'p3-iv3'); bumpProgress('p3', 15); }
+ return;
+ }
+ document.getElementById('p3-iv3-i').textContent = (i+1);
+ document.getElementById('p3-iv3-s').textContent = score;
+ document.getElementById('p3-iv3-q').innerHTML = Q[i].expr;
+ renderMath(document.getElementById('p3-iv3-q'));
+ document.getElementById('p3-iv3-fb').style.display = 'none';
+ }
+ function answer(a){
+ if(i >= Q.length) return;
+ const fb = document.getElementById('p3-iv3-fb');
+ if(a === Q[i].ans){ score++; feedback(fb, true, '✓ Верно! '+Q[i].why+'. Дальше ▶'); }
+ else feedback(fb, false, '✗ Нет. '+Q[i].why+'. Дальше ▶');
+ document.getElementById('p3-iv3-s').textContent = score;
+ i++;
+ setTimeout(show, 1100);
+ }
+ ['half','s2','s3','one'].forEach(k=>{
+ const b = document.getElementById('p3-iv3-'+k); if(b) b.addEventListener('click', ()=>answer(k));
+ });
+ show();
+ })();
+
+ /* IV4 — Применение тождеств */
+ (function(){
+ const Q = [
+ { q:'Если $\\sin \\alpha = 0{,}6$ и $\\alpha$ — острый, найди $\\cos \\alpha$.', ans:0.8, tol:0.02, hint:'$\\cos \\alpha = \\sqrt{1 - 0{,}36} = \\sqrt{0{,}64} = 0{,}8$' },
+ { q:'$\\sin^2 70^\\circ + \\cos^2 70^\\circ = ?$', ans:1, tol:0.01, hint:'основное тождество' },
+ { q:'Если $\\cos \\alpha = 0{,}5$ и $\\alpha$ — острый, найди $\\sin \\alpha$.', ans:0.866, tol:0.01, hint:'$\\sin \\alpha = \\sqrt{1 - 0{,}25} = \\sqrt{0{,}75} = \\sqrt{3}/2 \\approx 0{,}866$' },
+ { q:'$\\tan 60^\\circ \\cdot \\cot 60^\\circ = ?$', ans:1, tol:0.01, hint:'$\\tan \\alpha \\cdot \\cot \\alpha = 1$' },
+ { q:'Если $\\tan \\alpha = 1$, то $\\alpha = ?$ (в градусах).', ans:45, tol:0.5, hint:'$\\tan 45^\\circ = 1$' },
+ { q:'$\\sin 30^\\circ + \\cos 60^\\circ = ?$', ans:1, tol:0.01, hint:'$\\tfrac{1}{2} + \\tfrac{1}{2} = 1$' },
+ ];
+ let i = 0, score = 0;
+ function show(){
+ if(i >= Q.length){
+ document.getElementById('p3-iv4-q').innerHTML = 'Готово! Результат: ' + score + ' / ' + Q.length;
+ if(score === Q.length){ addXp(15,'p3-iv4'); bumpProgress('p3', 25); }
+ else if(score >= 4){ addXp(8,'p3-iv4'); bumpProgress('p3', 15); }
+ return;
+ }
+ document.getElementById('p3-iv4-i').textContent = (i+1);
+ document.getElementById('p3-iv4-s').textContent = score;
+ document.getElementById('p3-iv4-q').innerHTML = Q[i].q;
+ document.getElementById('p3-iv4-ans').value = '';
+ renderMath(document.getElementById('p3-iv4-q'));
+ document.getElementById('p3-iv4-fb').style.display = 'none';
+ }
+ function go(){
+ if(i >= Q.length) return;
+ const fb = document.getElementById('p3-iv4-fb');
+ const ans = parseFloat(document.getElementById('p3-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('p3-iv4-s').textContent = score;
+ i++;
+ setTimeout(show, 1400);
+ }
+ document.getElementById('p3-iv4-go').addEventListener('click', go);
+ document.getElementById('p3-iv4-ans').addEventListener('keydown', e=>{ if(e.key==='Enter') go(); });
+ document.getElementById('p3-iv4-start').addEventListener('click', ()=>{ i=0; score=0; show(); });
+ show();
+ })();
+
+ wireReadBtn('p3');
+}
+
+/* ===== §4 sin, cos, tg, ctg тупого угла ===== */
+function buildP4(){
+ const box = document.getElementById('p4-body');
+ let html = '';
+
+ html += makeCard('theory', 'Единичная окружность', '4.1', `
+ Введём координатную плоскость. Единичная окружность — окружность радиуса $1$ с центром в начале координат $O$.
+ Для острого угла $\\alpha$ отложим его от положительного направления оси $Ox$ против часовой стрелки . Точку пересечения подвижного луча с единичной окружностью обозначим $P$. Тогда:
+
+ $\\cos \\alpha$ — это $x$-координата точки $P$
+ $\\sin \\alpha$ — это $y$-координата точки $P$
+
+ Это обобщение старых определений: для острых углов оно совпадает с привычным «отношение катета к гипотенузе» (можно построить прямоугольный треугольник с гипотенузой $OP = 1$). Но теперь определение работает для любого угла от $0^\\circ$ до $180^\\circ$ — даже когда привычного прямоугольного треугольника нет.
+ Почему именно так?
+ Если $OP = 1$, то $\\cos \\alpha = \\dfrac{\\text{прилежащий катет}}{\\text{гипотенуза}} = \\dfrac{x_P}{1} = x_P$. Аналогично для синуса. Единичная окружность позволяет «продолжить» функции на углы $> 90^\\circ$.
+
`);
+
+ html += makeCard('rule', 'Тупой угол: знаки и формулы приведения', '4.2', `
+ Для тупого угла $\\alpha$ (где $90^\\circ < \\alpha < 180^\\circ$) точка $P$ оказывается во второй четверти : выше оси $Ox$ и левее оси $Oy$. Значит:
+
+ $\\sin \\alpha = y_P > 0$ — синус положителен
+ $\\cos \\alpha = x_P < 0$ — косинус отрицателен
+ $\\tan \\alpha = \\dfrac{\\sin \\alpha}{\\cos \\alpha} < 0$ — тангенс отрицателен
+ $\\cot \\alpha < 0$ — котангенс отрицателен
+
+ Формулы приведения (главные для этого параграфа):
+ $\\boxed{\\,\\sin(180^\\circ - \\alpha) = \\sin \\alpha,\\qquad \\cos(180^\\circ - \\alpha) = -\\cos \\alpha\\,}$
+ Здесь $\\alpha$ — острый угол, а $180^\\circ - \\alpha$ — соответствующий ему тупой. Идея проста: точки $P(\\alpha)$ и $P(180^\\circ - \\alpha)$ симметричны относительно оси $Oy$ — у них одинаковая $y$-координата (синус), но противоположные $x$-координаты (косинус).
`);
+
+ html += makeCard('example', 'Эталонные тупые углы', '4.3', `
+ Считаем через формулы приведения, сводя всё к острым углам $30^\\circ$, $45^\\circ$, $60^\\circ$:
+
+ $\\sin 120^\\circ = \\sin(180^\\circ - 60^\\circ) = \\sin 60^\\circ = \\dfrac{\\sqrt{3}}{2}$
+ $\\cos 120^\\circ = -\\cos 60^\\circ = -\\dfrac{1}{2}$
+ $\\sin 135^\\circ = \\sin 45^\\circ = \\dfrac{\\sqrt{2}}{2}$
+ $\\cos 135^\\circ = -\\cos 45^\\circ = -\\dfrac{\\sqrt{2}}{2}$
+ $\\sin 150^\\circ = \\sin 30^\\circ = \\dfrac{1}{2}$
+ $\\cos 150^\\circ = -\\cos 30^\\circ = -\\dfrac{\\sqrt{3}}{2}$
+
+ Граничные случаи:
+
+ $\\sin 90^\\circ = 1$, $\\cos 90^\\circ = 0$ (точка $P = (0, 1)$)
+ $\\sin 180^\\circ = 0$, $\\cos 180^\\circ = -1$ (точка $P = (-1, 0)$)
+ $\\sin 0^\\circ = 0$, $\\cos 0^\\circ = 1$ (точка $P = (1, 0)$)
+ `);
+
+ /* IV1 — Единичная окружность */
+ html += `
+
+
Двигай ползунок угла $\\alpha$ от $0^\\circ$ до $180^\\circ$. Смотри, как точка $P$ движется по окружности и как меняются $\\sin \\alpha$ (по $y$) и $\\cos \\alpha$ (по $x$). При $\\alpha > 90^\\circ$ — тупой угол, $\\cos \\alpha < 0$.
+
+ Угол $\\alpha$, °60
+
+
+
+
+
+
+
`;
+
+ /* IV2 — Формула приведения */
+ html += `
+
+
Выбери тупой угол $\\alpha$ — увидишь, как формула приведения сводит $\\sin \\alpha$ и $\\cos \\alpha$ к острому углу $180^\\circ - \\alpha$.
+
+ $\\alpha$ =
+
+ 100°
+ 120°
+ 135°
+ 150°
+ 170°
+
+ Применить формулу
+
+
+
+
`;
+
+ /* IV3 — Знак значения */
+ html += `
+
+
Каким будет знак данного тригонометрического значения: положительным, отрицательным или равным нулю?
+
Задача 1 / 8 Очки: 0 / 8
+
+
+ положит. (+)
+ отрицат. (−)
+ равно $0$
+
+
+
`;
+
+ /* IV4 — Тренажёр тупого угла */
+ html += `
+
+
Реши задачу и введи число (целое или десятичная дробь до 3 знаков; не забудь знак для отрицательных значений).
+
Задача 1 / 6 Очки: 0 / 6
+
+
+ ответ =
+
+ Проверить
+ Заново
+
+
+
`;
+
+ html += secNav('p3', 'p5');
+ html += readButton('p4');
+
+ box.innerHTML = html;
+ renderMath(box);
+
+ /* IV1 — Единичная окружность */
+ (function(){
+ const sl = document.getElementById('p4-iv1-a');
+ const lab = document.getElementById('p4-iv1-aval');
+ const svg = document.getElementById('p4-iv1-svg');
+ const out = document.getElementById('p4-iv1-out');
+ const tag = document.getElementById('p4-iv1-tag');
+ const seen = new Set();
+ const cx = 200, cy = 200, R = 150;
+ function draw(){
+ const aDeg = +sl.value;
+ lab.textContent = aDeg;
+ const aRad = deg2rad(aDeg);
+ const Px = cx + R*Math.cos(aRad);
+ const Py = cy - R*Math.sin(aRad); // y инвертирован
+ let s = '';
+ // Сетка
+ s += ' ';
+ // Координатные оси
+ s += ' ';
+ s += ' ';
+ // Стрелки на осях
+ s += ' ';
+ s += ' ';
+ s += 'x ';
+ s += 'y ';
+ // Единичная окружность
+ s += ' ';
+ // Отметки 1, -1
+ s += ' ';
+ s += '1 ';
+ s += ' ';
+ s += '−1 ';
+ s += ' ';
+ s += '1 ';
+ // Проекции — пунктиром
+ s += ' ';
+ s += ' ';
+ // Радиус OP
+ s += ' ';
+ // Дуга угла alpha
+ if(aDeg > 0){
+ const uOx = {x:1, y:0};
+ const uOP = {x: Math.cos(aRad), y: -Math.sin(aRad)};
+ s += ' ';
+ // Подпись α
+ const aHalf = aRad/2;
+ const tx = cx + 54*Math.cos(aHalf);
+ const ty = cy - 54*Math.sin(aHalf);
+ s += 'α ';
+ }
+ // Точка P
+ s += ' ';
+ s += 'P ';
+ // Подписи проекций
+ s += 'cos α ';
+ s += 'sin α ';
+ // Подпись радиуса
+ s += 'r=1 ';
+ svg.innerHTML = s;
+ const sn = Math.sin(aRad), cs = Math.cos(aRad);
+ const tn = (Math.abs(cs) < 1e-9) ? null : sn/cs;
+ out.innerHTML = '$\\sin '+aDeg+'^\\circ \\approx '+sn.toFixed(3)+'$ · $\\cos '+aDeg+'^\\circ \\approx '+cs.toFixed(3)+'$ '
+ + (tn===null ? '$\\tan '+aDeg+'^\\circ$ — не определён' : '$\\tan '+aDeg+'^\\circ \\approx '+tn.toFixed(3)+'$');
+ renderMath(out);
+ if(aDeg > 90 && aDeg < 180){
+ tag.innerHTML = '⚠ Тупой угол! $\\cos \\alpha < 0$. ';
+ renderMath(tag);
+ } else if(aDeg === 90){
+ tag.innerHTML = 'Прямой угол. ';
+ } else if(aDeg === 180 || aDeg === 0){
+ tag.innerHTML = 'Развёрнутый/нулевой угол. ';
+ } else {
+ tag.innerHTML = 'Острый угол. Обе функции положительны. ';
+ }
+ seen.add(aDeg);
+ if(seen.size >= 6 && !seen.has('done')){ addXp(10,'p4-iv1'); bumpProgress('p4', 15); seen.add('done'); }
+ }
+ sl.addEventListener('input', draw);
+ draw();
+ })();
+
+ /* IV2 — Формула приведения */
+ (function(){
+ const sel = document.getElementById('p4-iv2-a');
+ const go = document.getElementById('p4-iv2-go');
+ const out = document.getElementById('p4-iv2-out');
+ const fb = document.getElementById('p4-iv2-fb');
+ let solved = 0;
+ function apply(){
+ const aDeg = parseInt(sel.value, 10);
+ const beta = 180 - aDeg;
+ const r = deg2rad(aDeg);
+ const sn = Math.sin(r), cs = Math.cos(r);
+ out.innerHTML = 'Формула приведения для $\\alpha = '+aDeg+'^\\circ$: '
+ + '$\\sin '+aDeg+'^\\circ = \\sin(180^\\circ - '+aDeg+'^\\circ) = \\sin '+beta+'^\\circ \\approx '+sn.toFixed(3)+'$ '
+ + '$\\cos '+aDeg+'^\\circ = -\\cos(180^\\circ - '+aDeg+'^\\circ) = -\\cos '+beta+'^\\circ \\approx '+cs.toFixed(3)+'$ '
+ + 'Заметь: синус сохранил знак, косинус — поменял. ';
+ renderMath(out);
+ feedback(fb, true, '✓ Сведено к острому углу '+beta+'°.');
+ solved++;
+ if(solved === 1){ addXp(10,'p4-iv2'); bumpProgress('p4', 15); }
+ }
+ go.addEventListener('click', apply);
+ apply();
+ })();
+
+ /* IV3 — Знак значения */
+ (function(){
+ const Q = [
+ { expr:'$\\sin 120^\\circ$', ans:'pos', why:'тупой угол: $\\sin > 0$' },
+ { expr:'$\\cos 120^\\circ$', ans:'neg', why:'тупой угол: $\\cos < 0$' },
+ { expr:'$\\sin 90^\\circ$', ans:'pos', why:'$\\sin 90^\\circ = 1 > 0$' },
+ { expr:'$\\cos 90^\\circ$', ans:'zero', why:'$\\cos 90^\\circ = 0$' },
+ { expr:'$\\sin 180^\\circ$', ans:'zero', why:'$\\sin 180^\\circ = 0$' },
+ { expr:'$\\cos 180^\\circ$', ans:'neg', why:'$\\cos 180^\\circ = -1 < 0$' },
+ { expr:'$\\sin 60^\\circ$', ans:'pos', why:'острый угол: $\\sin > 0$' },
+ { expr:'$\\cos 150^\\circ$', ans:'neg', why:'тупой угол: $\\cos < 0$' },
+ ];
+ let i = 0, score = 0;
+ function show(){
+ if(i >= Q.length){
+ document.getElementById('p4-iv3-q').innerHTML = 'Готово! Результат: ' + score + ' / ' + Q.length;
+ if(score === Q.length){ addXp(15,'p4-iv3'); bumpProgress('p4', 25); }
+ else if(score >= Q.length - 2){ addXp(8,'p4-iv3'); bumpProgress('p4', 15); }
+ return;
+ }
+ document.getElementById('p4-iv3-i').textContent = (i+1);
+ document.getElementById('p4-iv3-s').textContent = score;
+ document.getElementById('p4-iv3-q').innerHTML = Q[i].expr;
+ renderMath(document.getElementById('p4-iv3-q'));
+ document.getElementById('p4-iv3-fb').style.display = 'none';
+ }
+ function answer(a){
+ if(i >= Q.length) return;
+ const fb = document.getElementById('p4-iv3-fb');
+ if(a === Q[i].ans){ score++; feedback(fb, true, '✓ Верно! '+Q[i].why+'. Дальше ▶'); }
+ else feedback(fb, false, '✗ Нет. '+Q[i].why+'. Дальше ▶');
+ document.getElementById('p4-iv3-s').textContent = score;
+ i++;
+ setTimeout(show, 1100);
+ }
+ ['pos','neg','zero'].forEach(k=>{
+ const b = document.getElementById('p4-iv3-'+k); if(b) b.addEventListener('click', ()=>answer(k));
+ });
+ show();
+ })();
+
+ /* IV4 — Тренажёр тупого угла */
+ (function(){
+ const Q = [
+ { q:'$\\sin 120^\\circ = ?$', ans:0.866, tol:0.01, hint:'$\\sin 120^\\circ = \\sin 60^\\circ = \\sqrt{3}/2 \\approx 0{,}866$' },
+ { q:'$\\cos 120^\\circ = ?$', ans:-0.5, tol:0.02, hint:'$\\cos 120^\\circ = -\\cos 60^\\circ = -1/2$' },
+ { q:'$\\sin 150^\\circ = ?$', ans:0.5, tol:0.02, hint:'$\\sin 150^\\circ = \\sin 30^\\circ = 1/2$' },
+ { q:'$\\cos 150^\\circ = ?$', ans:-0.866, tol:0.01, hint:'$\\cos 150^\\circ = -\\cos 30^\\circ = -\\sqrt{3}/2$' },
+ { q:'$\\cos 90^\\circ = ?$', ans:0, tol:0.01, hint:'$\\cos 90^\\circ = 0$' },
+ { q:'$\\sin 180^\\circ + \\cos 180^\\circ = ?$', ans:-1, tol:0.02, hint:'$0 + (-1) = -1$' },
+ ];
+ let i = 0, score = 0;
+ function show(){
+ if(i >= Q.length){
+ document.getElementById('p4-iv4-q').innerHTML = 'Готово! Результат: ' + score + ' / ' + Q.length;
+ if(score === Q.length){ addXp(15,'p4-iv4'); bumpProgress('p4', 25); }
+ else if(score >= 4){ addXp(8,'p4-iv4'); bumpProgress('p4', 15); }
+ return;
+ }
+ document.getElementById('p4-iv4-i').textContent = (i+1);
+ document.getElementById('p4-iv4-s').textContent = score;
+ document.getElementById('p4-iv4-q').innerHTML = Q[i].q;
+ document.getElementById('p4-iv4-ans').value = '';
+ renderMath(document.getElementById('p4-iv4-q'));
+ document.getElementById('p4-iv4-fb').style.display = 'none';
+ }
+ function go(){
+ if(i >= Q.length) return;
+ const fb = document.getElementById('p4-iv4-fb');
+ const ans = parseFloat(document.getElementById('p4-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('p4-iv4-s').textContent = score;
+ i++;
+ setTimeout(show, 1400);
+ }
+ document.getElementById('p4-iv4-go').addEventListener('click', go);
+ document.getElementById('p4-iv4-ans').addEventListener('keydown', e=>{ if(e.key==='Enter') go(); });
+ document.getElementById('p4-iv4-start').addEventListener('click', ()=>{ i=0; score=0; show(); });
+ show();
+ })();
+
+ wireReadBtn('p4');
+}
function buildP5(){ _stubBuilder('p5', '§5', 'Формулы площади', 'p4', 'p6'); }
function buildP6(){ _stubBuilder('p6', '§6', 'Среднее геометрическое', 'p5', 'final1'); }