diff --git a/frontend/textbooks/algebra_10_ch1.html b/frontend/textbooks/algebra_10_ch1.html
index c78f144..b8ded8a 100644
--- a/frontend/textbooks/algebra_10_ch1.html
+++ b/frontend/textbooks/algebra_10_ch1.html
@@ -252,6 +252,9 @@ const ACH_LABELS = {
p2_done:'sin α и cos α — на ладони!',
p3_done:'tg α и ctg α — понимаешь!',
p4_done:'Тождества — твои!',
+ p5_done:'Графики sin x и cos x — мастер!',
+ p6_done:'Графики tg x и ctg x — знаешь!',
+ p7_done:'Обратные тригонометрические — освоены!',
ch1_done:'Глава 1 — Тригонометрия пройдена!',
};
@@ -279,6 +282,9 @@ function bumpProgress(key, delta){
else if(key==='p2') achievement('p2_done');
else if(key==='p3') achievement('p3_done');
else if(key==='p4') achievement('p4_done');
+ else if(key==='p5') achievement('p5_done');
+ else if(key==='p6') achievement('p6_done');
+ else if(key==='p7') achievement('p7_done');
else if(key==='final1') achievement('ch1_done');
}
}
@@ -355,9 +361,7 @@ function buildParaSelector(){
const BUILT=new Set();
const BUILDERS = { p1:()=>buildP1(), p2:()=>buildP2(), p3:()=>buildP3(), p4:()=>buildP4(),
- p5:()=>buildStub('p5','§5 — Графики функций sin x и cos x'),
- p6:()=>buildStub('p6','§6 — Графики функций tg x и ctg x'),
- p7:()=>buildStub('p7','§7 — Арксинус, арккосинус, арктангенс, арккотангенс'),
+ p5:()=>buildP5(), p6:()=>buildP6(), p7:()=>buildP7(),
p8:()=>buildStub('p8','§8 — Тригонометрические уравнения'),
p9:()=>buildStub('p9','§9 — Формулы приведения'),
p10:()=>buildStub('p10','§10 — Синус, косинус, тангенс суммы и разности'),
@@ -411,6 +415,36 @@ const SIDEBARS = {
['Связь','$\\tg\\alpha \\cdot \\ctg\\alpha = 1$'],
['Знать одно','найти все 4'],
]},
+ p5:{title:'Шпаргалка §5',rows:[
+ ['Период','$T = 2\\pi$'],
+ ['$D(\\sin)$','$\\mathbb{R}$'],
+ ['$E(\\sin)$','$[-1;\\,1]$'],
+ ['sin — нечётная','$\\sin(-x) = -\\sin x$'],
+ ['cos — чётная','$\\cos(-x) = \\cos x$'],
+ ['Нули sin','$x = \\pi n$'],
+ ['Нули cos','$x = \\frac{\\pi}{2} + \\pi n$'],
+ ['Связь','$\\cos x = \\sin(x + \\frac{\\pi}{2})$'],
+ ]},
+ p6:{title:'Шпаргалка §6',rows:[
+ ['Период tg / ctg','$T = \\pi$'],
+ ['$D(\\tg)$','$x \\ne \\frac{\\pi}{2} + \\pi n$'],
+ ['$D(\\ctg)$','$x \\ne \\pi n$'],
+ ['$E(\\tg) = E(\\ctg)$','$\\mathbb{R}$'],
+ ['Асимптоты tg','$x = \\frac{\\pi}{2} + \\pi n$'],
+ ['Асимптоты ctg','$x = \\pi n$'],
+ ['tg — нечётная','$\\tg(-x) = -\\tg x$'],
+ ['ctg — нечётная','$\\ctg(-x) = -\\ctg x$'],
+ ]},
+ p7:{title:'Шпаргалка §7',rows:[
+ ['$\\arcsin a$','$\\in [-\\frac{\\pi}{2};\\,\\frac{\\pi}{2}]$, $a \\in [-1;1]$'],
+ ['$\\arccos a$','$\\in [0;\\,\\pi]$, $a \\in [-1;1]$'],
+ ['$\\arctg a$','$\\in (-\\frac{\\pi}{2};\\,\\frac{\\pi}{2})$, $a \\in \\mathbb{R}$'],
+ ['$\\arcctg a$','$\\in (0;\\,\\pi)$, $a \\in \\mathbb{R}$'],
+ ['Связь','$\\arcsin a + \\arccos a = \\frac{\\pi}{2}$'],
+ ['','$\\arctg a + \\arcctg a = \\frac{\\pi}{2}$'],
+ ['Нечётные','$\\arcsin(-a) = -\\arcsin a$, $\\arctg$'],
+ ['Не нечётные','$\\arccos(-a) = \\pi - \\arccos a$'],
+ ]},
};
const TIPS=[
@@ -418,6 +452,9 @@ const TIPS=[
{sec:'p2',html:'Запомни: sin = ордината (y) , cos = абсцисса (x) . Точка $P_\\alpha$ — это и есть пара $(\\cos\\alpha;\\,\\sin\\alpha)$.'},
{sec:'p3',html:'Ось тангенсов — касательная к окружности при $x=1$. Продолжение радиуса $OP_\\alpha$ упирается в эту ось — там и сидит значение tg α.'},
{sec:'p4',html:'Алгоритм «знаю одну → найду все»: 1) основное тождество даёт пару sin/cos; 2) знак выбираем по четверти; 3) tg = sin/cos; 4) ctg = 1/tg.'},
+ {sec:'p5',html:'$\\cos x$ — это $\\sin x$, сдвинутый влево на $\\frac{\\pi}{2}$ . Графики выглядят одинаково, но смещены: где у sin ноль — у cos максимум, и наоборот.'},
+ {sec:'p6',html:'tg x имеет вертикальные асимптоты в $\\frac{\\pi}{2} + \\pi n$ (там, где $\\cos x = 0$). ctg x — в $\\pi n$ (там, где $\\sin x = 0$). Период $\\pi$ , а не $2\\pi$ — это короче, чем у sin/cos.'},
+ {sec:'p7',html:'Главные значения: $\\arcsin$ и $\\arctg$ — от $-\\frac{\\pi}{2}$ до $\\frac{\\pi}{2}$ ; $\\arccos$ и $\\arcctg$ — от $0$ до $\\pi$ . Это всегда!'},
];
function buildSidebar(id){
@@ -1338,6 +1375,560 @@ function buildP4(){
wireReadBtn('p4');
}
+/* ============================================================
+ § 5 — Функции y = sin x и y = cos x. Свойства и графики
+ ============================================================ */
+function buildP5(){
+ const box = document.getElementById('p5-body');
+ const A = window.ALG10;
+ let html = '';
+
+ /* === SVG 1: график y = sin x на [-2π; 2π] === */
+ let svgSin = '';
+ if(A){
+ const f = A.func.canvas({id:'p5-sin', W:640, H:240, xRange:[-2*Math.PI, 2*Math.PI], yRange:[-1.6, 1.6], bg:'#fff'});
+ let s = f.open
+ + f.grid({xStep:Math.PI/2, yStep:0.5, color:'#f1f5f9'})
+ + f.axes({color:'#475569',
+ xTicks:[
+ {val:-2*Math.PI, label:'-2π'},{val:-3*Math.PI/2, label:'-3π/2'},
+ {val:-Math.PI, label:'-π'},{val:-Math.PI/2, label:'-π/2'},
+ {val:Math.PI/2, label:'π/2'},{val:Math.PI, label:'π'},
+ {val:3*Math.PI/2, label:'3π/2'},{val:2*Math.PI, label:'2π'}
+ ],
+ yTicks:[{val:-1, label:'-1'}, {val:1, label:'1'}]
+ })
+ /* Полупрозрачные горизонтальные полоски области значений */
+ + ' '
+ + ' '
+ + f.plot(x => Math.sin(x), {color:'#0d9488', width:2.8})
+ /* Точки максимума и минимума */
+ + f.pointXY(Math.PI/2, 1, {color:'#dc2626', r:3.5, label:'max', dx:6, dy:-8, fontSize:10})
+ + f.pointXY(-Math.PI/2, -1, {color:'#dc2626', r:3.5, label:'min', dx:6, dy:14, fontSize:10})
+ + f.pointXY(3*Math.PI/2, -1, {color:'#dc2626', r:3.5})
+ + f.pointXY(-3*Math.PI/2, 1, {color:'#dc2626', r:3.5})
+ + f.close;
+ svgSin = s;
+ }
+
+ /* === SVG 2: график y = cos x === */
+ let svgCos = '';
+ if(A){
+ const f = A.func.canvas({id:'p5-cos', W:640, H:240, xRange:[-2*Math.PI, 2*Math.PI], yRange:[-1.6, 1.6], bg:'#fff'});
+ let s = f.open
+ + f.grid({xStep:Math.PI/2, yStep:0.5, color:'#f1f5f9'})
+ + f.axes({color:'#475569',
+ xTicks:[
+ {val:-2*Math.PI, label:'-2π'},{val:-Math.PI, label:'-π'},
+ {val:Math.PI, label:'π'},{val:2*Math.PI, label:'2π'}
+ ],
+ yTicks:[{val:-1, label:'-1'}, {val:1, label:'1'}]
+ })
+ + ' '
+ + ' '
+ + f.plot(x => Math.cos(x), {color:'#0891b2', width:2.8})
+ + f.pointXY(0, 1, {color:'#dc2626', r:3.5, label:'max', dx:6, dy:-8, fontSize:10})
+ + f.pointXY(Math.PI, -1, {color:'#dc2626', r:3.5, label:'min', dx:6, dy:14, fontSize:10})
+ + f.pointXY(-Math.PI, -1, {color:'#dc2626', r:3.5})
+ + f.pointXY(2*Math.PI, 1, {color:'#dc2626', r:3.5})
+ + f.pointXY(-2*Math.PI, 1, {color:'#dc2626', r:3.5})
+ + f.close;
+ svgCos = s;
+ }
+
+ /* === SVG 3: совмещённые sin и cos === */
+ let svgBoth = '';
+ if(A){
+ const f = A.func.canvas({id:'p5-both', W:640, H:240, xRange:[-2*Math.PI, 2*Math.PI], yRange:[-1.6, 1.6], bg:'#fff'});
+ let s = f.open
+ + f.grid({xStep:Math.PI/2, yStep:0.5, color:'#f1f5f9'})
+ + f.axes({color:'#475569',
+ xTicks:[{val:-Math.PI, label:'-π'},{val:Math.PI, label:'π'},{val:2*Math.PI, label:'2π'}],
+ yTicks:[{val:-1, label:'-1'}, {val:1, label:'1'}]
+ })
+ + f.plot(x => Math.sin(x), {color:'#0d9488', width:2.5})
+ + f.plot(x => Math.cos(x), {color:'#0891b2', width:2.5, dash:'5 4'})
+ /* Точка пересечения при x = π/4: sin = cos = √2/2 */
+ + f.pointXY(Math.PI/4, Math.sqrt(2)/2, {color:'#dc2626', r:4, label:'π/4', dx:6, dy:-6, fontSize:10})
+ /* Легенда */
+ + ' '
+ + ' '
+ + 'sin x '
+ + ' '
+ + 'cos x '
+ + f.close;
+ svgBoth = s;
+ }
+
+ html += makeCard('rule', 'Свойства функции y = sin x', '5.1', `
+
На каждом числе $x$ значение $\\sin x$ — это ордината точки $P_x$ единичной окружности.
+
+ Свойство Значение
+ Область определения $D(\\sin) = \\mathbb{R}$
+ Область значений $E(\\sin) = [-1;\\,1]$
+ Период $T = 2\\pi$
+ Чётность Нечётная: $\\sin(-x) = -\\sin x$
+ Нули $x = \\pi n$, $n \\in \\mathbb{Z}$
+ Возрастает на $\\left[-\\frac{\\pi}{2} + 2\\pi n;\\,\\frac{\\pi}{2} + 2\\pi n\\right]$
+ max $1$ при $x = \\frac{\\pi}{2} + 2\\pi n$
+ min $-1$ при $x = -\\frac{\\pi}{2} + 2\\pi n$
+
`);
+
+ html += makeCard('rule', 'График y = sin x', '5.2', `
+ График — синусоида . Повторяется каждые $2\\pi$.
+ ${svgSin}
+ Красные точки — экстремумы. Кривая всегда лежит между $y = -1$ и $y = 1$.
`);
+
+ html += makeCard('rule', 'Свойства y = cos x', '5.3', `
+ Свойства аналогичны синусу, но с двумя ключевыми отличиями:
+
+ Свойство Значение
+ Область определения $D(\\cos) = \\mathbb{R}$
+ Область значений $E(\\cos) = [-1;\\,1]$
+ Период $T = 2\\pi$
+ Чётность Чётная: $\\cos(-x) = \\cos x$
+ Нули $x = \\frac{\\pi}{2} + \\pi n$
+ max $1$ при $x = 2\\pi n$
+ min $-1$ при $x = \\pi + 2\\pi n$
+
`);
+
+ html += makeCard('rule', 'График y = cos x', '5.4', `
+ График $y = \\cos x$ — та же синусоида, но сдвинутая на $\\dfrac{\\pi}{2}$ влево .
+ ${svgCos}
+ Это значит: $\\cos x = \\sin\\left(x + \\dfrac{\\pi}{2}\\right)$.
+ ${svgBoth}
+ На совмещённом графике видно: где у $\\sin x$ нули — у $\\cos x$ экстремумы, и наоборот.
`);
+
+ html += makeCard('algo', 'Преобразования графиков', '5.5', `
+ Общий вид: $y = A \\sin(\\omega x + \\varphi) + b$, где:
+
+ $A$ — амплитуда : растяжение по оси $y$. $E = [-|A| + b;\\,|A| + b]$.
+ $\\omega$ — частота : новый период $T = \\dfrac{2\\pi}{|\\omega|}$.
+ $\\varphi$ — начальная фаза : сдвиг по оси $x$ на $-\\dfrac{\\varphi}{\\omega}$.
+ $b$ — сдвиг по оси $y$ (вверх или вниз).
+
+ Поэкспериментируй с параметрами на следующем интерактиве!
`);
+
+ /* === ИНТЕРАКТИВ 1: Slider-эксперимент === */
+ html += ''
+ +''
+ +'
Двигай ползунки и смотри, как меняется график синусоиды.
'
+ +'
A (амплитуда): 1.0
'
+ +'
ω (частота): 1.00
'
+ +'
φ (фаза): 0.00
'
+ +'
b (сдвиг): 0.0
'
+ +'
'
+ +'
'
+ +'
';
+
+ /* === ИНТЕРАКТИВ 2: Найди свойство === */
+ html += ''
+ +''
+ +'
Ответы — числа (период в виде «2pi», «pi/2» и т.д.), названия («чётная»/«нечётная»), или градусы.
'
+ +trainerHTML('p5-iv2', 7, 'ответ')
+ +'
';
+
+ /* === БОСС === */
+ html += 'Босс §5 — Графики sin и cos ';
+ html += makeBoss('p5', {
+ color:'#0d9488',
+ title:'Босс §5 — Графики sin и cos',
+ steps:[
+ { q:'Период функции $y = \\sin 2x$ — введи как pi/n или 2pi/n.', verify:(v)=>{const s=String(v).replace(/\\s/g,'').toLowerCase(); return s==='pi'||s==='π';}, hint:'$T = 2\\pi / \\omega = 2\\pi / 2 = \\pi$.' },
+ { q:'$y = \\cos x$ — чётная или нечётная? Введи слово.', verify:(v)=>String(v).trim().toLowerCase().startsWith('чёт')||String(v).trim().toLowerCase().startsWith('чет'), hint:'$\\cos(-x) = \\cos x$.' },
+ { q:'На каком из промежутков $[0;\\,2\\pi]$ функция $\\sin x$ возрастает ? Введи правую границу как градусы: $\\pi/2$ → 90.', verify:(v)=>+v===90, hint:'$\\sin x$ возрастает на $[0; \\pi/2]$.' },
+ { q:'Чему равно $\\sin\\left(\\dfrac{\\pi}{2} + 4\\pi\\right)$? (используй период)', verify:(v)=>+v===1, hint:'$4\\pi = 2 \\cdot 2\\pi$ — два полных периода. Эквивалентно $\\sin\\frac{\\pi}{2} = 1$.' },
+ { q:'Сколько корней у уравнения $\\sin x = 0$ на $[0;\\,2\\pi]$?', verify:(v)=>+v===3, hint:'$x = 0, \\pi, 2\\pi$.' },
+ ]
+ });
+
+ html += secNav('p4', 'p6') + readButton('p5');
+ box.innerHTML = html; renderMath(box);
+
+ /* IV1: slider experiment */
+ (function(){
+ const A_in = document.getElementById('p5-A');
+ const w_in = document.getElementById('p5-w');
+ const ph_in = document.getElementById('p5-ph');
+ const b_in = document.getElementById('p5-b');
+ const Av = document.getElementById('p5-Av');
+ const wv = document.getElementById('p5-wv');
+ const phv = document.getElementById('p5-phv');
+ const bv = document.getElementById('p5-bv');
+ const formula = document.getElementById('p5-formula');
+ const svgHost = document.getElementById('p5-iv1-svg');
+ function redraw(){
+ if(!A) return;
+ const Av0 = parseFloat(A_in.value);
+ const wv0 = parseFloat(w_in.value);
+ const phv0 = parseFloat(ph_in.value);
+ const bv0 = parseFloat(b_in.value);
+ Av.textContent = Av0.toFixed(1);
+ wv.textContent = wv0.toFixed(2);
+ phv.textContent = phv0.toFixed(2);
+ bv.textContent = bv0.toFixed(1);
+ formula.textContent = 'y = ' + Av0.toFixed(1) + ' · sin(' + wv0.toFixed(2) + 'x + ' + phv0.toFixed(2) + ') + ' + bv0.toFixed(1);
+ const f = A.func.canvas({id:'p5-iv1-c', W:640, H:240, xRange:[-2*Math.PI, 2*Math.PI], yRange:[-4.5, 4.5], bg:'#fff'});
+ let svg = f.open
+ + f.grid({xStep:Math.PI/2, yStep:1, color:'#f1f5f9'})
+ + f.axes({color:'#475569',
+ xTicks:[{val:-Math.PI, label:'-π'},{val:Math.PI, label:'π'},{val:2*Math.PI, label:'2π'}],
+ yTicks:[{val:-3, label:'-3'},{val:-1, label:'-1'},{val:1, label:'1'},{val:3, label:'3'}]
+ })
+ /* Базовый sin x пунктиром */
+ + f.plot(x => Math.sin(x), {color:'#cbd5e1', width:1.5, dash:'4 3'})
+ /* Преобразованный график */
+ + f.plot(x => Av0 * Math.sin(wv0 * x + phv0) + bv0, {color:'#0d9488', width:2.8})
+ + f.close;
+ svgHost.innerHTML = svg;
+ }
+ [A_in, w_in, ph_in, b_in].forEach(el => el.addEventListener('input', redraw));
+ redraw();
+ })();
+
+ /* IV2: properties */
+ makeTrainer({
+ idPrefix:'p5-iv2',
+ parser:(v)=>v,
+ questions:[
+ { q:'Чему равен период функции $y = \\sin x$? (введи как 2pi)', a:(v)=>{const s=String(v).replace(/\\s/g,'').toLowerCase(); return s==='2pi'||s==='2π';}, show:'$2\\pi$' },
+ { q:'Период функции $y = \\cos 3x$? (введи как 2pi/n)', a:(v)=>{const s=String(v).replace(/\\s/g,'').toLowerCase(); return s==='2pi/3'||s==='2π/3';}, show:'$2\\pi/3$' },
+ { q:'$y = \\sin x$ — чётная или нечётная? Введи слово.', a:(v)=>String(v).trim().toLowerCase().startsWith('нечёт')||String(v).trim().toLowerCase().startsWith('нечет'), show:'нечётная' },
+ { q:'$y = \\cos x$ — чётная или нечётная? Введи слово.', a:(v)=>String(v).trim().toLowerCase().startsWith('чёт')||String(v).trim().toLowerCase().startsWith('чет'), show:'чётная' },
+ { q:'Сколько нулей у $\\sin x$ на $[0;\\,2\\pi]$?', a:(v)=>+v===3, show:'3 (это $0, \\pi, 2\\pi$)' },
+ { q:'Сколько нулей у $\\cos x$ на $[0;\\,2\\pi]$?', a:(v)=>+v===2, show:'2 (это $\\pi/2, 3\\pi/2$)' },
+ { q:'Наибольшее значение $y = 3\\sin x + 1$? ', a:(v)=>+v===4, show:'4 (при sin = 1)' },
+ ],
+ onComplete:(s,n)=>{ if(s===n){addXp(20,'p5-iv2');bumpProgress('p5',35);} else if(s>=4){addXp(10,'p5-iv2');bumpProgress('p5',16);} }
+ });
+
+ wireReadBtn('p5');
+}
+
+/* ============================================================
+ § 6 — Функции y = tg x и y = ctg x
+ ============================================================ */
+function buildP6(){
+ const box = document.getElementById('p6-body');
+ const A = window.ALG10;
+ let html = '';
+
+ /* === SVG 1: график y = tg x === */
+ let svgTg = '';
+ if(A){
+ const f = A.func.canvas({id:'p6-tg', W:640, H:280, xRange:[-2*Math.PI, 2*Math.PI], yRange:[-5, 5], bg:'#fff'});
+ let s = f.open
+ + f.grid({xStep:Math.PI/2, yStep:1, color:'#f1f5f9'})
+ /* Асимптоты */
+ + f.asymptoteV(-3*Math.PI/2, {color:'#dc2626'})
+ + f.asymptoteV(-Math.PI/2, {color:'#dc2626'})
+ + f.asymptoteV(Math.PI/2, {color:'#dc2626'})
+ + f.asymptoteV(3*Math.PI/2, {color:'#dc2626'})
+ + f.axes({color:'#475569',
+ xTicks:[
+ {val:-3*Math.PI/2, label:'-3π/2'},
+ {val:-Math.PI, label:'-π'},
+ {val:-Math.PI/2, label:'-π/2'},
+ {val:Math.PI/2, label:'π/2'},
+ {val:Math.PI, label:'π'},
+ {val:3*Math.PI/2, label:'3π/2'}
+ ],
+ yTicks:[{val:-3, label:'-3'},{val:-1, label:'-1'},{val:1, label:'1'},{val:3, label:'3'}]
+ })
+ /* Tg x с авто-разрывами */
+ + f.plot(x => {
+ /* Избегаем точек слишком близко к асимптотам */
+ const t = Math.tan(x);
+ if (Math.abs(t) > 12) return NaN;
+ return t;
+ }, {color:'#16a34a', width:2.8})
+ + f.close;
+ svgTg = s;
+ }
+
+ /* === SVG 2: график y = ctg x === */
+ let svgCtg = '';
+ if(A){
+ const f = A.func.canvas({id:'p6-ctg', W:640, H:280, xRange:[-2*Math.PI, 2*Math.PI], yRange:[-5, 5], bg:'#fff'});
+ let s = f.open
+ + f.grid({xStep:Math.PI/2, yStep:1, color:'#f1f5f9'})
+ + f.asymptoteV(-2*Math.PI, {color:'#dc2626'})
+ + f.asymptoteV(-Math.PI, {color:'#dc2626'})
+ + f.asymptoteV(0, {color:'#dc2626'})
+ + f.asymptoteV(Math.PI, {color:'#dc2626'})
+ + f.asymptoteV(2*Math.PI, {color:'#dc2626'})
+ + f.axes({color:'#475569',
+ xTicks:[
+ {val:-3*Math.PI/2, label:'-3π/2'},
+ {val:-Math.PI/2, label:'-π/2'},
+ {val:Math.PI/2, label:'π/2'},
+ {val:3*Math.PI/2, label:'3π/2'}
+ ],
+ yTicks:[{val:-3, label:'-3'},{val:-1, label:'-1'},{val:1, label:'1'},{val:3, label:'3'}]
+ })
+ + f.plot(x => {
+ const c = 1 / Math.tan(x);
+ if (Math.abs(c) > 12) return NaN;
+ return c;
+ }, {color:'#7c3aed', width:2.8})
+ + f.close;
+ svgCtg = s;
+ }
+
+ html += makeCard('rule', 'Свойства y = tg x', '6.1', `
+
+ Свойство Значение
+ $D(\\tg)$ $x \\ne \\dfrac{\\pi}{2} + \\pi n$
+ $E(\\tg)$ $\\mathbb{R}$ — все действительные числа
+ Период $T = \\pi$ (вдвое короче, чем у sin/cos!)
+ Чётность Нечётная: $\\tg(-x) = -\\tg x$
+ Нули $x = \\pi n$
+ Асимптоты $x = \\dfrac{\\pi}{2} + \\pi n$ (вертикальные)
+ Монотонность Возрастает на $\\left(-\\dfrac{\\pi}{2} + \\pi n;\\,\\dfrac{\\pi}{2} + \\pi n\\right)$
+
`);
+
+ html += makeCard('rule', 'График y = tg x', '6.2', `
+ Тангенс не похож на синусоиду — это «ветви» , разорванные вертикальными асимптотами.
+ ${svgTg}
+ Красные пунктирные линии — асимптоты. На каждом промежутке между ними функция возрастает от $-\\infty$ до $+\\infty$.
`);
+
+ html += makeCard('rule', 'Свойства y = ctg x', '6.3', `
+
+ Свойство Значение
+ $D(\\ctg)$ $x \\ne \\pi n$
+ $E(\\ctg)$ $\\mathbb{R}$
+ Период $T = \\pi$
+ Чётность Нечётная
+ Нули $x = \\dfrac{\\pi}{2} + \\pi n$
+ Асимптоты $x = \\pi n$
+ Монотонность Убывает на $(\\pi n;\\,\\pi + \\pi n)$
+
`);
+
+ html += makeCard('rule', 'График y = ctg x', '6.4', `
+ Котангенс — «зеркало» тангенса: те же ветви, но убывающие , и сдвинуты на $\\frac{\\pi}{2}$.
+ ${svgCtg}
+ Связь: $\\ctg x = \\tg\\left(\\dfrac{\\pi}{2} - x\\right)$.
`);
+
+ /* === ИНТЕРАКТИВ === */
+ html += ''
+ +''
+ +'
Период обоих $= \\pi$. Асимптоты — там, где знаменатель = 0.
'
+ +trainerHTML('p6-iv1', 6, 'ответ')
+ +'
';
+
+ html += ''
+ +''
+ +'
Используй монотонность: $\\tg$ возрастает , $\\ctg$ убывает на главном промежутке.
'
+ +'
Задача 1 / 5 Очки: 0 / 5
'
+ +'
'
+ +'
< = >
'
+ +'
';
+
+ /* === БОСС === */
+ html += 'Босс §6 — Графики tg и ctg ';
+ html += makeBoss('p6', {
+ color:'#16a34a',
+ title:'Босс §6 — Графики tg и ctg',
+ steps:[
+ { q:'Период функции $y = \\tg x$ — введи как pi/n или просто pi.', verify:(v)=>{const s=String(v).replace(/\\s/g,'').toLowerCase(); return s==='pi'||s==='π';}, hint:'$T = \\pi$.' },
+ { q:'Период функции $y = \\tg 2x$? (введи pi/n)', verify:(v)=>{const s=String(v).replace(/\\s/g,'').toLowerCase(); return s==='pi/2'||s==='π/2';}, hint:'$T = \\pi / 2$.' },
+ { q:'Где у $\\tg x$ вертикальные асимптоты? Введи общую формулу в виде «pi/2+pi*n» (без пробелов).', verify:(v)=>{const s=String(v).replace(/\\s/g,'').toLowerCase(); return s==='pi/2+pi*n'||s==='pi/2+pin'||s==='π/2+πn'||s==='π/2+π*n';}, hint:'Там, где $\\cos x = 0$.' },
+ { q:'$\\tg x$ — возрастает или убывает на главном промежутке? Введи слово.', verify:(v)=>String(v).trim().toLowerCase().startsWith('возр'), hint:'От $-\\infty$ до $+\\infty$.' },
+ { q:'$\\ctg x$ — возрастает или убывает? Введи слово.', verify:(v)=>String(v).trim().toLowerCase().startsWith('убыв'), hint:'От $+\\infty$ до $-\\infty$.' },
+ ]
+ });
+
+ html += secNav('p5', 'p7') + readButton('p6');
+ box.innerHTML = html; renderMath(box);
+
+ /* IV1 */
+ makeTrainer({
+ idPrefix:'p6-iv1',
+ parser:(v)=>v,
+ questions:[
+ { q:'Период $y = \\tg x$? (введи pi)', a:(v)=>{const s=String(v).replace(/\\s/g,'').toLowerCase(); return s==='pi'||s==='π';}, show:'$\\pi$' },
+ { q:'Период $y = \\ctg 3x$? (введи pi/n)', a:(v)=>{const s=String(v).replace(/\\s/g,'').toLowerCase(); return s==='pi/3'||s==='π/3';}, show:'$\\pi/3$' },
+ { q:'$\\tg x$ — чётная или нечётная? Введи слово.', a:(v)=>String(v).trim().toLowerCase().startsWith('нечёт')||String(v).trim().toLowerCase().startsWith('нечет'), show:'нечётная' },
+ { q:'Сколько нулей у $\\tg x$ на $[0;\\,2\\pi]$?', a:(v)=>+v===3, show:'3 (0, π, 2π)' },
+ { q:'Сколько вертикальных асимптот у $\\tg x$ на $(0;\\,2\\pi)$?', a:(v)=>+v===2, show:'2 (π/2 и 3π/2)' },
+ { q:'$\\tg 0 = ?$', a:(v)=>+v===0, show:'0' },
+ ],
+ onComplete:(s,n)=>{ if(s===n){addXp(15,'p6-iv1');bumpProgress('p6',30);} else if(s>=4){addXp(8,'p6-iv1');bumpProgress('p6',14);} }
+ });
+
+ /* IV2: compare */
+ (function(){
+ const Q=[
+ { e:'Сравни $\\tg 30°$ и $\\tg 45°$', ans:'lt' },
+ { e:'Сравни $\\tg 60°$ и $\\tg 80°$', ans:'lt' },
+ { e:'Сравни $\\ctg 30°$ и $\\ctg 60°$', ans:'gt' },
+ { e:'Сравни $\\tg(-30°)$ и $\\tg 30°$', ans:'lt' },
+ { e:'Сравни $\\tg 45°$ и $\\ctg 45°$', ans:'eq' },
+ ];
+ let i=0,score=0;
+ function show(){
+ if(i>=Q.length){ document.getElementById('p6-iv2-q').innerHTML='Готово! '+score+' / '+Q.length; if(score===Q.length){addXp(15,'p6-iv2');bumpProgress('p6',25);} else if(score>=3){addXp(8,'p6-iv2');bumpProgress('p6',12);} return; }
+ document.getElementById('p6-iv2-i').textContent=(i+1);
+ document.getElementById('p6-iv2-s').textContent=score;
+ document.getElementById('p6-iv2-q').innerHTML=Q[i].e;
+ renderMath(document.getElementById('p6-iv2-q'));
+ document.getElementById('p6-iv2-fb').style.display='none';
+ }
+ function ans(a){
+ if(i>=Q.length) return;
+ const fb=document.getElementById('p6-iv2-fb');
+ if(a===Q[i].ans){ score++; feedback(fb,true,'✓ Верно!'); }
+ else{ const lab={lt:'<',eq:'=',gt:'>'}; feedback(fb,false,'✗ Правильно: '+lab[Q[i].ans]+' '); }
+ document.getElementById('p6-iv2-s').textContent=score;
+ i++; setTimeout(show,1200);
+ }
+ document.getElementById('p6-iv2-lt').addEventListener('click',()=>ans('lt'));
+ document.getElementById('p6-iv2-eq').addEventListener('click',()=>ans('eq'));
+ document.getElementById('p6-iv2-gt').addEventListener('click',()=>ans('gt'));
+ show();
+ })();
+
+ wireReadBtn('p6');
+}
+
+/* ============================================================
+ § 7 — Арксинус, арккосинус, арктангенс, арккотангенс
+ ============================================================ */
+function buildP7(){
+ const box = document.getElementById('p7-body');
+ const A = window.ALG10;
+ let html = '';
+
+ /* === SVG: 4 графика обратных функций === */
+ function plotInverse(id, fn, xRange, yRange, color, title){
+ if(!A) return '';
+ const f = A.func.canvas({id, W:280, H:240, xRange, yRange, bg:'#fff'});
+ let s = f.open
+ + f.grid({xStep:1, yStep:0.5, color:'#f1f5f9'})
+ + f.axes({color:'#475569',
+ xTicks:[{val:-1, label:'-1'},{val:1, label:'1'}],
+ yTicks:[
+ {val:-Math.PI/2, label:'-π/2'},
+ {val:0, label:'0'},
+ {val:Math.PI/2, label:'π/2'},
+ {val:Math.PI, label:'π'}
+ ].filter(t => t.val >= yRange[0] && t.val <= yRange[1])
+ })
+ + f.plot(fn, {color, width:2.5, step:(xRange[1]-xRange[0])/200})
+ + ''+title+' '
+ + f.close;
+ return s;
+ }
+ const svgAsin = plotInverse('p7-asin', Math.asin, [-1.05, 1.05], [-Math.PI/2 - 0.2, Math.PI/2 + 0.2], '#0d9488', 'y = arcsin x');
+ const svgAcos = plotInverse('p7-acos', Math.acos, [-1.05, 1.05], [-0.2, Math.PI + 0.2], '#0891b2', 'y = arccos x');
+ const svgAtg = plotInverse('p7-atg', Math.atan, [-4, 4], [-Math.PI/2 - 0.2, Math.PI/2 + 0.2], '#16a34a', 'y = arctg x');
+ const svgActg = plotInverse('p7-actg', x => Math.PI/2 - Math.atan(x), [-4, 4], [-0.2, Math.PI + 0.2], '#7c3aed', 'y = arcctg x');
+
+ html += makeCard('theory', 'Зачем обратные функции', '7.1', `
+ Уравнение $\\sin x = \\dfrac{1}{2}$ имеет бесконечно много решений ($x = \\dfrac{\\pi}{6} + 2\\pi n$ и $x = \\pi - \\dfrac{\\pi}{6} + 2\\pi n$).
+ Если хочется записать одно «опорное» решение, мы выбираем главное значение — это и есть $\\arcsin\\dfrac{1}{2}$.
`);
+
+ html += makeCard('rule', 'arcsin a', '7.2', `
+ Определение. $\\arcsin a$ — это такое число $\\alpha \\in \\left[-\\dfrac{\\pi}{2};\\,\\dfrac{\\pi}{2}\\right]$, что $\\sin\\alpha = a$.
+ Существует только при $a \\in [-1;\\,1]$. Главные значения:
+
+ $a$ $0$ $\\frac{1}{2}$ $\\frac{\\sqrt{2}}{2}$ $\\frac{\\sqrt{3}}{2}$ $1$
+ $\\arcsin a$ $0$ $\\frac{\\pi}{6}$ $\\frac{\\pi}{4}$ $\\frac{\\pi}{3}$ $\\frac{\\pi}{2}$
+
+ $\\arcsin$ — нечётная : $\\arcsin(-a) = -\\arcsin a$.
+ ${svgAsin}
`);
+
+ html += makeCard('rule', 'arccos a', '7.3', `
+ Определение. $\\arccos a$ — это такое число $\\alpha \\in [0;\\,\\pi]$, что $\\cos\\alpha = a$.
+ Существует только при $a \\in [-1;\\,1]$. Главные значения:
+
+ $a$ $1$ $\\frac{\\sqrt{3}}{2}$ $\\frac{\\sqrt{2}}{2}$ $\\frac{1}{2}$ $0$ $-1$
+ $\\arccos a$ $0$ $\\frac{\\pi}{6}$ $\\frac{\\pi}{4}$ $\\frac{\\pi}{3}$ $\\frac{\\pi}{2}$ $\\pi$
+
+ Важно: $\\arccos$ не является нечётной ! $\\arccos(-a) = \\pi - \\arccos a$.
+ ${svgAcos}
`);
+
+ html += makeCard('rule', 'arctg a и arcctg a', '7.4', `
+ Определение.
+
+ $\\arctg a$ — такое $\\alpha \\in \\left(-\\dfrac{\\pi}{2};\\,\\dfrac{\\pi}{2}\\right)$, что $\\tg\\alpha = a$. Определено для всех $a \\in \\mathbb{R}$.
+ $\\arcctg a$ — такое $\\alpha \\in (0;\\,\\pi)$, что $\\ctg\\alpha = a$. Определено для всех $a \\in \\mathbb{R}$.
+
+ Главные значения: $\\arctg 0 = 0$, $\\arctg 1 = \\dfrac{\\pi}{4}$, $\\arctg\\sqrt{3} = \\dfrac{\\pi}{3}$, $\\arctg\\dfrac{1}{\\sqrt{3}} = \\dfrac{\\pi}{6}$.
+ $\\arctg$ — нечётная : $\\arctg(-a) = -\\arctg a$. $\\arcctg$ — нет: $\\arcctg(-a) = \\pi - \\arcctg a$.
+ ${svgAtg}${svgActg}
`);
+
+ html += makeCard('rule', 'Полезные связки', '7.5', `
+ Эти две формулы стоит запомнить:
+ $\\arcsin a + \\arccos a = \\dfrac{\\pi}{2}$
+ $\\arctg a + \\arcctg a = \\dfrac{\\pi}{2}$
+ Например, $\\arccos\\dfrac{1}{2} = \\dfrac{\\pi}{2} - \\arcsin\\dfrac{1}{2} = \\dfrac{\\pi}{2} - \\dfrac{\\pi}{6} = \\dfrac{\\pi}{3}$.
`);
+
+ /* === ИНТЕРАКТИВ 1: Главные значения === */
+ html += ''
+ +''
+ +'
Ответ — в виде дроби: pi/6 , pi/3 , -pi/4 , или просто число (для нуля).
'
+ +trainerHTML('p7-iv1', 8, 'значение')
+ +'
';
+
+ /* === ИНТЕРАКТИВ 2: arc(sin(α)) vs α === */
+ html += ''
+ +''
+ +'
$\\sin(\\arcsin a) = a$ всегда. Но $\\arcsin(\\sin\\alpha) = \\alpha$ только если $\\alpha \\in [-\\pi/2;\\,\\pi/2]$. Иначе нужно привести!
'
+ +trainerHTML('p7-iv2', 5, 'ответ')
+ +'
';
+
+ /* === БОСС === */
+ html += 'Босс §7 — Обратные функции ';
+ html += makeBoss('p7', {
+ color:'#7c3aed',
+ title:'Босс §7 — Обратные функции',
+ steps:[
+ { q:'Чему равен $\\arcsin 0$?', verify:(v)=>+v===0, hint:'$\\sin 0 = 0$.' },
+ { q:'$\\arcsin\\dfrac{1}{2} = ?$ (введи как pi/n)', verify:(v)=>{const s=String(v).replace(/\\s/g,'').toLowerCase(); return s==='pi/6'||s==='π/6';}, hint:'$\\sin(\\pi/6) = 1/2$.' },
+ { q:'$\\arccos(-1) = ?$ (введи как pi или 0)', verify:(v)=>{const s=String(v).replace(/\\s/g,'').toLowerCase(); return s==='pi'||s==='π';}, hint:'$\\cos\\pi = -1$.' },
+ { q:'$\\arcsin\\dfrac{\\sqrt{3}}{2} + \\arccos\\dfrac{\\sqrt{3}}{2} = ?$ (введи pi/n)', verify:(v)=>{const s=String(v).replace(/\\s/g,'').toLowerCase(); return s==='pi/2'||s==='π/2';}, hint:'Сумма всегда $= \\pi/2$.' },
+ { q:'$\\arcsin\\left(\\sin\\dfrac{5\\pi}{6}\\right) = ?$ (внимание, $5\\pi/6$ вне $[-\\pi/2;\\,\\pi/2]$! Введи pi/n.)', verify:(v)=>{const s=String(v).replace(/\\s/g,'').toLowerCase(); return s==='pi/6'||s==='π/6';}, hint:'$\\sin(5\\pi/6) = \\sin(\\pi - \\pi/6) = \\sin(\\pi/6) = 1/2$. arcsin(1/2) = $\\pi/6$.' },
+ ]
+ });
+
+ html += secNav('p6', 'p8') + readButton('p7');
+ box.innerHTML = html; renderMath(box);
+
+ /* IV1: главные значения */
+ makeTrainer({
+ idPrefix:'p7-iv1',
+ parser:(v)=>v,
+ questions:[
+ { q:'$\\arcsin 1 = ?$ (введи pi/n)', a:(v)=>{const s=String(v).replace(/\\s/g,'').toLowerCase(); return s==='pi/2'||s==='π/2';}, show:'$\\pi/2$' },
+ { q:'$\\arcsin(-1) = ?$ (введи -pi/n)', a:(v)=>{const s=String(v).replace(/\\s/g,'').toLowerCase(); return s==='-pi/2'||s==='-π/2';}, show:'$-\\pi/2$' },
+ { q:'$\\arccos 1 = ?$', a:(v)=>+v===0, show:'$0$' },
+ { q:'$\\arccos 0 = ?$ (введи pi/n)', a:(v)=>{const s=String(v).replace(/\\s/g,'').toLowerCase(); return s==='pi/2'||s==='π/2';}, show:'$\\pi/2$' },
+ { q:'$\\arctg 1 = ?$ (введи pi/n)', a:(v)=>{const s=String(v).replace(/\\s/g,'').toLowerCase(); return s==='pi/4'||s==='π/4';}, show:'$\\pi/4$' },
+ { q:'$\\arctg(-1) = ?$ (введи -pi/n)', a:(v)=>{const s=String(v).replace(/\\s/g,'').toLowerCase(); return s==='-pi/4'||s==='-π/4';}, show:'$-\\pi/4$' },
+ { q:'$\\arccos\\dfrac{1}{2} = ?$ (введи pi/n)', a:(v)=>{const s=String(v).replace(/\\s/g,'').toLowerCase(); return s==='pi/3'||s==='π/3';}, show:'$\\pi/3$' },
+ { q:'$\\arccos\\left(-\\dfrac{1}{2}\\right) = ?$ (введи 2pi/3)', a:(v)=>{const s=String(v).replace(/\\s/g,'').toLowerCase(); return s==='2pi/3'||s==='2π/3';}, show:'$2\\pi/3$ ($\\pi - \\pi/3$)' },
+ ],
+ onComplete:(s,n)=>{ if(s===n){addXp(20,'p7-iv1');bumpProgress('p7',32);} else if(s>=5){addXp(10,'p7-iv1');bumpProgress('p7',15);} }
+ });
+
+ /* IV2: arcsin(sin α) */
+ makeTrainer({
+ idPrefix:'p7-iv2',
+ parser:(v)=>v,
+ questions:[
+ { q:'$\\sin(\\arcsin 0{,}5) = ?$', a:(v)=>+v===0.5, show:'$0{,}5$' },
+ { q:'$\\arcsin\\left(\\sin\\dfrac{\\pi}{4}\\right) = ?$ (введи pi/n)', a:(v)=>{const s=String(v).replace(/\\s/g,'').toLowerCase(); return s==='pi/4'||s==='π/4';}, show:'$\\pi/4$ — внутри $[-\\pi/2;\\pi/2]$' },
+ { q:'$\\arcsin\\left(\\sin\\dfrac{3\\pi}{4}\\right) = ?$ (введи pi/n)', a:(v)=>{const s=String(v).replace(/\\s/g,'').toLowerCase(); return s==='pi/4'||s==='π/4';}, show:'$\\pi/4$ ($\\sin(3\\pi/4) = \\sin(\\pi/4)$)' },
+ { q:'$\\cos(\\arccos(-0{,}3)) = ?$', a:(v)=>+v===-0.3, show:'$-0{,}3$' },
+ { q:'$\\arccos\\left(\\cos\\dfrac{5\\pi}{4}\\right) = ?$ (введи как 3pi/4)', a:(v)=>{const s=String(v).replace(/\\s/g,'').toLowerCase(); return s==='3pi/4'||s==='3π/4';}, show:'$3\\pi/4$ ($\\cos(5\\pi/4) = -\\frac{\\sqrt{2}}{2}$, $\\arccos = 3\\pi/4$)' },
+ ],
+ onComplete:(s,n)=>{ if(s===n){addXp(18,'p7-iv2');bumpProgress('p7',28);} else if(s>=3){addXp(9,'p7-iv2');bumpProgress('p7',14);} }
+ });
+
+ wireReadBtn('p7');
+}
+