diff --git a/frontend/textbooks/algebra_11_ch3.html b/frontend/textbooks/algebra_11_ch3.html index f45bc7b..2e018fa 100644 --- a/frontend/textbooks/algebra_11_ch3.html +++ b/frontend/textbooks/algebra_11_ch3.html @@ -1059,15 +1059,459 @@ function buildP7(){ function buildP8(){ const box = document.getElementById('p8-body'); let html = ''; - html += makeCard('theory', 'В разработке', '8.0', ` -

Содержание параграфа Логарифмическая функция будет добавлено в Phase 1+.

-

Раздел Phase 0 — skeleton. Здесь появятся теория, примеры и интерактивы.

-

Ключевая формула: $y = \log_a x$

- `); + + /* === ТЕОРИЯ === */ + + html += makeCard('theory', 'Определение и графики', '8.1', ` +

Функция вида $y = \\log_a x$, где $a > 0$, $a \\ne 1$, $x > 0$, называется логарифмической.

+

Логарифмическая функция — обратная к показательной $y = a^x$ (см. §4). Это значит, что:

+ +

Графики $y = \\log_a x$ и $y = a^x$ симметричны относительно прямой $y = x$ — это общее свойство любой пары взаимно обратных функций.

+

Примеры логарифмических функций:

+ +

График логарифмической функции:

+ +

Все графики $y = \\log_a x$ проходят через точку $(1; 0)$ — ведь $\\log_a 1 = 0$ при любом $a > 0$, $a \\ne 1$. Также через $(a; 1)$, потому что $\\log_a a = 1$.

`); + + html += makeCard('rule', 'Свойства логарифмической функции', '8.2', ` +

Сведём все ключевые свойства функции $y = \\log_a x$ в одну таблицу — отдельно для двух случаев $a > 1$ и $0 < a < 1$:

+
+ + + + + + + + + + + + + + + + + + + + +
Свойство$a > 1$$0 < a < 1$
$D(y)$ — область определения$(0; +\\infty)$ — только положительные $x$
$E(y)$ — область значений$\\mathbb{R}$ — вся числовая прямая
Нули функции$x = 1$ (так как $\\log_a 1 = 0$)
$y > 0$ при$x > 1$$0 < x < 1$
$y < 0$ при$0 < x < 1$$x > 1$
Монотонностьвозрастает на $(0; +\\infty)$убывает на $(0; +\\infty)$
Контрольные точки$(1; 0)$ и $(a; 1)$
Асимптота$x = 0$ (ось ординат)
При $x \\to +\\infty$$y \\to +\\infty$$y \\to -\\infty$
При $x \\to 0^+$$y \\to -\\infty$$y \\to +\\infty$
+
+

Ключевая идея: два графика $y = \\log_a x$ и $y = \\log_{1/a} x$ симметричны относительно оси $Ox$, потому что $\\log_{1/a} x = -\\log_a x$.

`); + + html += makeCard('example', 'Обратная функция и применение', '8.3', ` +

Логарифм и показательная — обратные функции. Это означает, что они «отменяют» друг друга:

+

$a^{\\log_a x} = x$ (при $x > 0$),$\\quad \\log_a a^x = x$ (при любом $x$).

+

Графически: график $y = \\log_a x$ получается из графика $y = a^x$ зеркальным отражением относительно прямой $y = x$. Каждая точка $(p; q)$ на показательной кривой переходит в точку $(q; p)$ на логарифмической.

+

Например, для $a = 2$: точка $(3; 8)$ лежит на $y = 2^x$, а симметричная ей $(8; 3)$ — на $y = \\log_2 x$.

+

Применение логарифмической функции в реальной жизни — там, где величина изменяется в очень широких пределах и удобно «сжать» шкалу:

+ +

Логарифмическая шкала идеально подходит для природы: наше ухо, глаз и нервная система воспринимают раздражители логарифмически.

`); + + /* === ИНТЕРАКТИВЫ === */ + + /* IV1 — двухпанельный визуализатор y = log_a x */ + html += `
+
ИНТЕРАКТИВ 1
Двухпанельный визуализатор $y = \\log_a x$
+
Меняй основание $a$ ползунком — наблюдай, как меняется характер логарифмической функции. Левая панель для $a > 1$ (возрастающая, синий), правая — для $0 < a < 1$ (убывающая, оранжевый). Snap-точки: $a \\in \\{0{,}1;\\ 0{,}25;\\ 0{,}5;\\ 1;\\ 2;\\ e;\\ 3;\\ 10\\}$. Точка $(1; 0)$ — всегда на графике, ось $Oy$ — вертикальная асимптота.
+
+ +
+
+
+
`; + + /* IV2 — сравнение y = a^x и y = log_a x (симметрия) */ + html += `
+
ИНТЕРАКТИВ 2
Сравнение $y = a^x$ и $y = \\log_a x$
+
Ползунок меняет основание $a > 1$. На одних осях рисуются обе функции — показательная (синий) и логарифмическая (оранжевый), а серым пунктиром — ось симметрии $y = x$. Нажми «Показать симметрию», чтобы увидеть пары симметричных точек.
+
+ +
+
+
+ + +
+
+
`; + + /* IV3 — квикфайр «Возрастает или убывает?» */ + html += `
+
ИНТЕРАКТИВ 3
Возрастает или убывает?
+
Для каждой логарифмической функции определи характер монотонности. 8 заданий.
+
Задача 1 / 8Очки: 0 / 8
+
+
+
+
+
`; + + /* IV4 — тренажёр значений логарифмической функции */ + html += `
+
ИНТЕРАКТИВ 4
Тренажёр свойств
+
Вычисли значение логарифмической функции. Введи число (целое или десятичное до 2 знаков, допуск $\\pm 0{,}05$). 6 задач.
+
Задача 1 / 6Очки: 0 / 6
+
+
+ ответ = + + + +
+
+
`; + html += secNavFor('p8'); html += readButton('p8'); + box.innerHTML = html; renderMath(box); + + /* === IV1 — двухпанельный визуализатор y = log_a x === */ + (function(){ + const sa = document.getElementById('p8-iv1-sa'); + const aL = document.getElementById('p8-iv1-a'); + const svg = document.getElementById('p8-iv1-svg'); + const desc = document.getElementById('p8-iv1-desc'); + const E = Math.E; + const SNAP = [0.1, 0.25, 0.5, 1, 2, E, 3, 10]; + const seen = new Set(); + let _done = false; + + const COL_GROW = '#2563eb'; + const COL_DECAY = '#ea580c'; + const COL_NEUTRAL = '#94a3b8'; + const COL_POINT10 = '#10b981'; + const COL_POINTA1 = '#dc2626'; + + function aLabel(a){ + if(Math.abs(a - E) < 0.03) return 'e \\approx 2{,}72'; + if(Math.abs(a - Math.round(a)) < 0.005) return String(Math.round(a)); + if(Math.abs(a - 0.5) < 0.005) return '\\tfrac{1}{2}'; + if(Math.abs(a - 0.25) < 0.005) return '\\tfrac{1}{4}'; + if(Math.abs(a - 0.1) < 0.005) return '\\tfrac{1}{10}'; + return (+a.toFixed(2)).toString(); + } + function aPlain(a){ + if(Math.abs(a - E) < 0.03) return 'e'; + return (+a.toFixed(2)).toString(); + } + function drawPanel(active, isGrow, a, ox){ + const W = 360, H = 360, pad = 28; + const xmin = -0.5, xmax = 8, ymin = -4, ymax = 4; + const ax = axes2D(W, H, pad, xmin, xmax, ymin, ymax); + let g = ''; + g += ax.content; + const col = isGrow ? COL_GROW : COL_DECAY; + // заголовок панели + g += '' + + (isGrow ? 'a > 1 — возрастающая' : '0 < a < 1 — убывающая') + + ''; + + if(!active){ + g += ''; + g += ''; + g += isGrow ? 'выбери a > 1' : 'выбери 0 < a < 1'; + g += ''; + g += ''; + return g; + } + + // вертикальная асимптота x = 0 + g += asymptote('v', 0, ax.toX, ax.toY, xmin, xmax, ymin, ymax, '#94a3b8'); + + // график y = log_a x — только при x > 0 + const lnA = Math.log(a); + g += plotFunc(x => (x > 0 ? Math.log(x) / lnA : NaN), 0.001, xmax, ax.toX, ax.toY, col, 300); + + // точка (1; 0) — зелёная + g += pointWithDrop(1, 0, ax.toX, ax.toY, COL_POINT10, '(1; 0)'); + // точка (a; 1) — красная (если a в пределах xmax) + if(a > 0 && a <= xmax){ + g += pointWithDrop(a, 1, ax.toX, ax.toY, COL_POINTA1, '('+aPlain(a)+'; 1)'); + } + g += ''; + return g; + } + function drawConstPanel(){ + // обе панели — серые заглушки для a = 1 + const W = 720, H = 360, pad = 28; + const xmin = -0.5, xmax = 8, ymin = -4, ymax = 4; + let out = ''; + // левая + { + const ax = axes2D(360, H, pad, xmin, xmax, ymin, ymax); + let g = '' + ax.content; + g += 'a = 1: $\\log_1 x$ не определён'; + g += asymptote('v', 0, ax.toX, ax.toY, xmin, xmax, ymin, ymax, '#cbd5e1'); + g += ''; + out += g; + } + // правая + { + const ax = axes2D(360, H, pad, xmin, xmax, ymin, ymax); + let g = '' + ax.content; + g += 'a = 1 — не логарифмическая'; + g += asymptote('v', 0, ax.toX, ax.toY, xmin, xmax, ymin, ymax, '#cbd5e1'); + g += ''; + out += g; + } + return out; + } + + function describe(a){ + if(Math.abs(a - 1) < 0.01){ + return '$a = 1$: функция $y = \\log_1 x$ не определена — основание логарифма не должно равняться $1$.'; + } + if(a > 1){ + const aTxt = aLabel(a); + return '$a = '+aTxt+' > 1$ — функция возрастает.
' + + '$D = (0; +\\infty)$, $E = \\mathbb{R}$. Проходит через $(1; 0)$ и $('+aPlain(a)+'; 1)$.
' + + 'При $x \\to +\\infty$: $y \\to +\\infty$. При $x \\to 0^+$: $y \\to -\\infty$ (асимптота $x = 0$).
' + + '$y > 0$ при $x > 1$; $y < 0$ при $0 < x < 1$.'; + } + // 0 < a < 1 + const aTxt = aLabel(a); + return '$a = '+aTxt+'$, $0 < a < 1$ — функция убывает.
' + + '$D = (0; +\\infty)$, $E = \\mathbb{R}$. Проходит через $(1; 0)$ и $('+aPlain(a)+'; 1)$.
' + + 'При $x \\to +\\infty$: $y \\to -\\infty$. При $x \\to 0^+$: $y \\to +\\infty$ (асимптота $x = 0$).
' + + '$y > 0$ при $0 < x < 1$; $y < 0$ при $x > 1$.'; + } + + function draw(){ + let a = +sa.value; + a = snapToValue(a, SNAP, 0.06); + aL.textContent = aLabel(a); + + let svgContent = ''; + if(Math.abs(a - 1) < 0.01){ + svgContent = drawConstPanel(); + } else if(a > 1){ + svgContent += drawPanel(true, true, a, 0); + svgContent += drawPanel(false, false, a, 360); + } else { + svgContent += drawPanel(false, true, a, 0); + svgContent += drawPanel(true, false, a, 360); + } + // разделитель + svgContent += ''; + + svg.innerHTML = svgContent; + desc.innerHTML = describe(a); + renderMath(desc); + + const key = (+a.toFixed(2)).toString(); + seen.add(key); + if(!_done && seen.size >= 6){ _done = true; addXp(10, 'p8-iv1'); bumpProgress('p8', 15); } + } + sa.addEventListener('input', draw); + draw(); + })(); + + /* === IV2 — сравнение y = a^x и y = log_a x === */ + (function(){ + const sa = document.getElementById('p8-iv2-sa'); + const aL = document.getElementById('p8-iv2-a'); + const svg = document.getElementById('p8-iv2-svg'); + const desc = document.getElementById('p8-iv2-desc'); + const symBtn = document.getElementById('p8-iv2-sym'); + const hideBtn = document.getElementById('p8-iv2-hide'); + const seen = new Set(); + let _done = false; + let showSym = false; + + const COL_EXP = '#2563eb'; + const COL_LOG = '#ea580c'; + const COL_AXIS = '#94a3b8'; + + function aPlain(a){ return (+a.toFixed(2)).toString(); } + + function draw(){ + const a = +sa.value; + aL.textContent = aPlain(a); + + const W = 480, H = 420, pad = 32; + const xmin = -3, xmax = 6, ymin = -3, ymax = 6; + const ax = axes2D(W, H, pad, xmin, xmax, ymin, ymax); + let g = ax.content; + + // ось симметрии y = x — серый пунктир + g += ''; + g += 'y = x'; + + // показательная y = a^x + const lnA = Math.log(a); + g += plotFunc(x => Math.pow(a, x), xmin, xmax, ax.toX, ax.toY, COL_EXP, 240); + // логарифмическая y = log_a x + g += plotFunc(x => (x > 0 ? Math.log(x) / lnA : NaN), 0.001, xmax, ax.toX, ax.toY, COL_LOG, 240); + + // подписи кривых + g += 'y = a^x'; + const xLogLabel = Math.min(5, Math.pow(a, 1.4)); + g += 'y = log_a x'; + + // ключевые точки + g += pointWithDrop(0, 1, ax.toX, ax.toY, COL_EXP, ''); // (0;1) на y=a^x + g += pointWithDrop(1, 0, ax.toX, ax.toY, COL_LOG, ''); // (1;0) на y=log_a x + // (1; a) на показательной и (a; 1) на логарифмической + if(a <= ymax) g += pointWithDrop(1, a, ax.toX, ax.toY, COL_EXP, ''); + if(a <= xmax) g += pointWithDrop(a, 1, ax.toX, ax.toY, COL_LOG, ''); + + if(showSym){ + // линии симметрии: (0;1) ↔ (1;0) и (1;a) ↔ (a;1) + g += ''; + if(a <= ymax && a <= xmax){ + g += ''; + } + // дополнительная пара (2; a^2) ↔ (a^2; 2), если в пределах + const a2 = Math.pow(a, 2); + if(a2 <= ymax && a2 <= xmax){ + g += pointWithDrop(2, a2, ax.toX, ax.toY, COL_EXP, ''); + g += pointWithDrop(a2, 2, ax.toX, ax.toY, COL_LOG, ''); + g += ''; + } + } + + svg.innerHTML = g; + + desc.innerHTML = '$y = '+aPlain(a)+'^x$ (синий) и $y = \\log_{'+aPlain(a)+'} x$ (оранжевый) симметричны относительно прямой $y = x$ — это обратные функции.
' + + 'Точка $(0; 1)$ на показательной соответствует точке $(1; 0)$ на логарифмической; точка $(1; '+aPlain(a)+')$ — точке $('+aPlain(a)+'; 1)$.'; + renderMath(desc); + + const key = (+a.toFixed(1)).toString(); + seen.add(key); + if(!_done && seen.size >= 4){ _done = true; addXp(10, 'p8-iv2'); bumpProgress('p8', 15); } + } + sa.addEventListener('input', draw); + symBtn.addEventListener('click', () => { showSym = true; draw(); }); + hideBtn.addEventListener('click', () => { showSym = false; draw(); }); + draw(); + })(); + + /* === IV3 — квикфайр «Возрастает или убывает?» === */ + (function(){ + const Q = [ + { q:'$y = \\log_2 x$', ans:0 }, + { q:'$y = \\log_{1/2} x$', ans:1 }, + { q:'$y = \\lg x$', ans:0 }, + { q:'$y = \\log_{0{,}1} x$', ans:1 }, + { q:'$y = \\ln x$', ans:0 }, + { q:'$y = \\log_{1/3} x$', ans:1 }, + { q:'$y = \\log_5 x$', ans:0 }, + { q:'$y = \\log_{0{,}5} x$', ans:1 }, + ]; + const OPTS = ['Возрастает', 'Убывает']; + let i = 0, score = 0; + const qEl = document.getElementById('p8-iv3-q'); + const oEl = document.getElementById('p8-iv3-opts'); + const fb = document.getElementById('p8-iv3-fb'); + const iEl = document.getElementById('p8-iv3-i'); + const sEl = document.getElementById('p8-iv3-s'); + + function show(){ + if(i >= Q.length){ + qEl.innerHTML = 'Готово! Результат: '+score+' / '+Q.length; + oEl.innerHTML = ''; + if(score === Q.length){ addXp(15, 'p8-iv3'); bumpProgress('p8', 25); } + else if(score >= 5){ addXp(8, 'p8-iv3'); bumpProgress('p8', 15); } + return; + } + iEl.textContent = (i+1); + sEl.textContent = score; + const item = Q[i]; + qEl.innerHTML = 'Какая монотонность у функции ' + item.q + ' ?'; + oEl.innerHTML = OPTS.map((o, k) => '').join(''); + fb.style.display = 'none'; + renderMath(qEl); + oEl.querySelectorAll('button').forEach(b => { + b.addEventListener('click', () => { + const k = +b.dataset.k; + if(k === item.ans){ score++; feedback(fb, true, '✓ Верно! Дальше ▶'); } + else feedback(fb, false, '✗ Неверно. Правильно: '+OPTS[item.ans]+'. Дальше ▶'); + sEl.textContent = score; + oEl.querySelectorAll('button').forEach(x => x.disabled = true); + i++; + setTimeout(show, 1100); + }); + }); + } + document.getElementById('p8-iv3-restart').addEventListener('click', () => { i = 0; score = 0; show(); }); + show(); + })(); + + /* === IV4 — тренажёр свойств === */ + (function(){ + const Q = [ + { q:'$\\log_3 9 = \\,?$', ans:2, hint:'$3^2 = 9$, поэтому $\\log_3 9 = 2$.' }, + { q:'$\\log_{1/2} 4 = \\,?$', ans:-2, hint:'$(1/2)^{-2} = 4$, поэтому $\\log_{1/2} 4 = -2$.' }, + { q:'$\\lg 100 = \\,?$', ans:2, hint:'$10^2 = 100$, поэтому $\\lg 100 = 2$.' }, + { q:'$\\log_5 1 = \\,?$', ans:0, hint:'$\\log_a 1 = 0$ при любом $a$.' }, + { q:'$\\log_2 \\sqrt{8} = \\,?$', ans:1.5, hint:'$\\sqrt{8} = 2^{3/2}$, поэтому $\\log_2 \\sqrt{8} = \\dfrac{3}{2} = 1{,}5$.' }, + { q:'$\\log_{0{,}1} 100 = \\,?$', ans:-2, hint:'$0{,}1 = 10^{-1}$ и $100 = 10^2$, значит $\\log_{0{,}1} 100 = -2$.' }, + ]; + let i = 0, score = 0; + function show(){ + const qEl = document.getElementById('p8-iv4-q'); + const iEl = document.getElementById('p8-iv4-i'); + const sEl = document.getElementById('p8-iv4-s'); + const fb = document.getElementById('p8-iv4-fb'); + const ansI = document.getElementById('p8-iv4-ans'); + if(i >= Q.length){ + qEl.innerHTML = 'Готово! Результат: '+score+' / '+Q.length; + if(score === Q.length){ addXp(15, 'p8-iv4'); bumpProgress('p8', 25); } + else if(score >= 4){ addXp(8, 'p8-iv4'); bumpProgress('p8', 15); } + return; + } + iEl.textContent = (i+1); + sEl.textContent = score; + qEl.innerHTML = Q[i].q; + ansI.value = ''; + renderMath(qEl); + fb.style.display = 'none'; + setTimeout(() => ansI.focus(), 30); + } + function go(){ + if(i >= Q.length) return; + const fb = document.getElementById('p8-iv4-fb'); + const raw = document.getElementById('p8-iv4-ans').value.replace(',', '.'); + const ans = parseFloat(raw); + if(isNaN(ans)){ feedback(fb, false, '✗ Введи число.'); return; } + if(Math.abs(ans - Q[i].ans) < 0.05){ + score++; + feedback(fb, true, '✓ Верно! '+Q[i].hint+' Дальше ▶'); + } else { + feedback(fb, false, '✗ Неверно. Ответ $= '+Q[i].ans+'$. '+Q[i].hint+' Дальше ▶'); + } + document.getElementById('p8-iv4-s').textContent = score; + i++; + setTimeout(show, 1500); + } + document.getElementById('p8-iv4-go').addEventListener('click', go); + document.getElementById('p8-iv4-ans').addEventListener('keydown', e => { if(e.key === 'Enter') go(); }); + document.getElementById('p8-iv4-start').addEventListener('click', () => { i = 0; score = 0; show(); }); + show(); + })(); + wireReadBtn('p8'); }