feat(geom11 ch4 wave1): §8 «Планиметрия» + §9 «Площади и объёмы» (повторение)
This commit is contained in:
@@ -400,7 +400,7 @@ function buildParaSelector(){
|
||||
}
|
||||
|
||||
const BUILT=new Set();
|
||||
const BUILDERS = { p8:()=>buildStub('p8'), p9:()=>buildStub('p9'), p10:()=>buildStub('p10'), p11:()=>buildStub('p11'), final4:()=>buildStub('final4') };
|
||||
const BUILDERS = { p8:()=>buildP8(), p9:()=>buildP9(), p10:()=>buildStub('p10'), p11:()=>buildStub('p11'), final4:()=>buildStub('final4') };
|
||||
function ensureBuilt(id){ if(BUILT.has(id)) return; const fn=BUILDERS[id]; if(fn){ fn(); BUILT.add(id); } }
|
||||
function goTo(id){
|
||||
STATE.current=id; ensureBuilt(id);
|
||||
@@ -415,16 +415,16 @@ function goTo(id){
|
||||
}
|
||||
|
||||
const SIDEBARS = {
|
||||
p8:{title:"Шпаргалка § 8", rows:[["Тема", "Геометрические фигуры и их свойства"],["Формула","планиметрия"]]},
|
||||
p9:{title:"Шпаргалка § 9", rows:[["Тема", "Геометрические величины"],["Формула","площади, объёмы"]]},
|
||||
p8:{title:"Шпаргалка § 8", rows:[["Сумма углов $\\triangle$","$180°$"],["Пифагор","$a^2+b^2=c^2$"],["Синусов","$\\dfrac{a}{\\sin A}=2R$"],["Косинусов","$c^2=a^2+b^2-2ab\\cos C$"],["Длина окр.","$C=2\\pi R$"],["$S$ круга","$\\pi R^2$"]]},
|
||||
p9:{title:"Шпаргалка § 9", rows:[["$S_\\triangle$","$\\frac{1}{2}ab\\sin C$"],["Герон","$\\sqrt{p(p-a)(p-b)(p-c)}$"],["$S$ трап.","$\\frac{a+b}{2}h$"],["$V$ призмы","$S_{осн}h$"],["$V$ пир.","$\\frac{1}{3}S_{осн}h$"],["$V$ шара","$\\frac{4}{3}\\pi R^3$"]]},
|
||||
p10:{title:"Шпаргалка § 10", rows:[["Тема", "Координаты и векторы"],["Формула","3D: $\\\\vec{a}=(x;y;z)$"]]},
|
||||
p11:{title:"Шпаргалка § 11", rows:[["Тема", "Геометрические построения"],["Формула","циркуль и линейка"]]},
|
||||
final4:{title:"Финал раздела 4", rows:[["§ 8–§ 11","теория раздела 4"],["Награда","+50 XP"]]}
|
||||
};
|
||||
|
||||
const TIPS=[
|
||||
{sec:'p8',html:"§ 8 «Геометрические фигуры и их свойства» — содержание в разработке. планиметрия"},
|
||||
{sec:'p9',html:"§ 9 «Геометрические величины» — содержание в разработке. площади, объёмы"},
|
||||
{sec:'p8',html:"§ 8: обзор планиметрии. Теоремы Пифагора, синусов, косинусов; виды треугольников и четырёхугольников; окружность."},
|
||||
{sec:'p9',html:"§ 9: площади плоских фигур и объёмы тел. Формулы Герона, $S=\\frac{1}{2}ab\\sin C$, $V=\\frac{1}{3}S_{осн}h$, шар."},
|
||||
{sec:'p10',html:"§ 10 «Координаты и векторы» — содержание в разработке. 3D: $\\\\\\\\vec{a}=(x;y;z)$"},
|
||||
{sec:'p11',html:"§ 11 «Геометрические построения» — содержание в разработке. циркуль и линейка"},
|
||||
{sec:'final4',html:"Финал раздела 4 — интегрированные задачи по разделу."}
|
||||
@@ -708,6 +708,489 @@ function buildStub(id){
|
||||
wireReadBtn(id);
|
||||
}
|
||||
|
||||
/* ===== §8 «Геометрические фигуры и их свойства» (повторение планиметрии) ===== */
|
||||
|
||||
function buildP8(){
|
||||
const box = document.getElementById('p8-body');
|
||||
if(!box) return;
|
||||
let html = '';
|
||||
|
||||
/* === ТЕОРИЯ === */
|
||||
|
||||
html += makeCard('theory', 'Треугольники и четырёхугольники', '§ 8.1',
|
||||
'<p><b>Треугольник.</b> Сумма углов любого треугольника равна $180°$. Виды по углам: <i>остроугольный, прямоугольный, тупоугольный</i>. По сторонам: <i>разносторонний, равнобедренный, равносторонний</i>.</p>'
|
||||
+ '<p><b>Замечательные точки треугольника:</b> центроид $G$ (точка пересечения медиан, делит каждую медиану $2{:}1$ от вершины), ортоцентр $H$ (пересечение высот), центр описанной окружности $O$ (пересечение серединных перпендикуляров), центр вписанной окружности $I$ (пересечение биссектрис).</p>'
|
||||
+ '<p><b>Прямоугольный треугольник:</b> теорема Пифагора $a^2 + b^2 = c^2$. Тригонометрия острого угла $A$:</p>'
|
||||
+ '<p style="text-align:center;margin:6px 0">$\\sin A = \\dfrac{a}{c},\\quad \\cos A = \\dfrac{b}{c},\\quad \\tan A = \\dfrac{a}{b}$</p>'
|
||||
+ '<p><b>Теорема синусов</b> (для любого треугольника):</p>'
|
||||
+ '<p style="text-align:center;margin:6px 0">$\\dfrac{a}{\\sin A} = \\dfrac{b}{\\sin B} = \\dfrac{c}{\\sin C} = 2R$</p>'
|
||||
+ '<p><b>Теорема косинусов:</b></p>'
|
||||
+ '<p style="text-align:center;margin:6px 0">$c^2 = a^2 + b^2 - 2ab\\cos C$</p>'
|
||||
+ '<p><b>Четырёхугольники.</b> Сумма углов выпуклого четырёхугольника равна $360°$. Иерархия: <b>параллелограмм</b> $\\supset$ <b>прямоугольник</b>, <b>ромб</b> $\\supset$ <b>квадрат</b>. У параллелограмма противоположные стороны равны и параллельны, диагонали точкой пересечения делятся пополам.</p>'
|
||||
+ '<p><b>Трапеция:</b> две параллельные стороны (основания) разной длины. Средняя линия $m = \\dfrac{a+b}{2}$.</p>');
|
||||
|
||||
html += makeCard('example', 'Окружность и её свойства', '§ 8.2',
|
||||
'<p><b>Окружность.</b> Длина окружности: $C = 2\\pi R$. Длина дуги в $\\alpha$ градусов: $\\ell = \\dfrac{\\pi R \\alpha}{180°}$.</p>'
|
||||
+ '<p><b>Круг:</b> площадь $S = \\pi R^2$. Площадь сектора с центральным углом $\\alpha$: $S_{сект} = \\dfrac{\\pi R^2 \\alpha}{360°}$.</p>'
|
||||
+ '<p><b>Вписанный угол.</b> Угол, вершина которого лежит на окружности, а стороны — хорды, равен <i>половине</i> центрального угла, опирающегося на ту же дугу. Все вписанные углы, опирающиеся на один диаметр, прямые (теорема Фалеса).</p>'
|
||||
+ '<p><b>Касательная.</b> Прямая, имеющая с окружностью ровно одну общую точку. <i>Касательная перпендикулярна радиусу, проведённому в точку касания.</i> Отрезки касательных из одной внешней точки равны.</p>'
|
||||
+ '<p><b>Вписанная и описанная окружности треугольника:</b></p>'
|
||||
+ '<p style="text-align:center;margin:6px 0">$r = \\dfrac{S}{p},\\qquad R = \\dfrac{abc}{4S}$</p>'
|
||||
+ '<p>где $p = \\dfrac{a+b+c}{2}$ — полупериметр, $S$ — площадь треугольника.</p>'
|
||||
+ '<details class="spoiler"><summary>Пример: треугольник $a=3$, $b=4$, $c=5$</summary><div class="spoiler-body">'
|
||||
+ '<p>Прямоугольный (так как $3^2+4^2=5^2$). $S = \\frac{1}{2}\\cdot 3 \\cdot 4 = 6$. $p = 6$.</p>'
|
||||
+ '<p>$r = S/p = 6/6 = 1$. $R = (3\\cdot 4\\cdot 5)/(4\\cdot 6) = 60/24 = 2{,}5$ (= $c/2$ — гипотенуза диаметр).</p>'
|
||||
+ '</div></details>');
|
||||
|
||||
/* === ИНТЕРАКТИВ 1 — Квикфайр === */
|
||||
html += '<div class="wg" id="p8-iv1">'
|
||||
+ '<div class="wg-header"><span class="wg-badge">квикфайр · 8 вопросов</span><div class="wg-title">Какая теорема нужна?</div></div>'
|
||||
+ '<div class="wg-help">Для каждой ситуации выбери теорему: Пифагор, синусов или косинусов. После 8 верных — +10 XP.</div>'
|
||||
+ '<div id="p8-iv1-area"></div>'
|
||||
+ '<div class="score-display" style="margin-top:10px">Верно: <b id="p8-iv1-score">0</b> / 8</div>'
|
||||
+ '</div>';
|
||||
|
||||
/* === ИНТЕРАКТИВ 2 — DnD сортер === */
|
||||
html += '<div class="wg" id="p8-iv2">'
|
||||
+ '<div class="wg-header"><span class="wg-badge">сортер</span><div class="wg-title">Тип четырёхугольника</div></div>'
|
||||
+ '<div class="wg-help">Перетащи описание в нужный ящик. После всех верных — +15 XP.</div>'
|
||||
+ '<div class="dnd-hint"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="10"/><path d="M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3"/></svg>6 описаний → 4 типа</div>'
|
||||
+ '<div id="p8-iv2-pool" class="dnd-pool"></div>'
|
||||
+ '<div style="display:grid;grid-template-columns:repeat(auto-fit,minmax(150px,1fr));gap:10px">'
|
||||
+ '<div class="drop-box"><h5>Квадрат</h5><div class="drop-items" data-cat="square"></div></div>'
|
||||
+ '<div class="drop-box"><h5>Ромб</h5><div class="drop-items" data-cat="rhomb"></div></div>'
|
||||
+ '<div class="drop-box"><h5>Прям-к / Парал-м</h5><div class="drop-items" data-cat="rect"></div></div>'
|
||||
+ '<div class="drop-box"><h5>Трапеция</h5><div class="drop-items" data-cat="trap"></div></div>'
|
||||
+ '</div>'
|
||||
+ '<div class="actions"><button class="btn primary" id="p8-iv2-check">Проверить</button><button class="btn" id="p8-iv2-reset">Сброс</button></div>'
|
||||
+ '<div class="feedback" id="p8-iv2-fb"></div>'
|
||||
+ '</div>';
|
||||
|
||||
/* === ИНТЕРАКТИВ 3 — Тренажёр повторения === */
|
||||
html += '<div class="wg" id="p8-iv3">'
|
||||
+ '<div class="wg-header"><span class="wg-badge">тренажёр · 5 задач</span><div class="wg-title">Повторение планиметрии</div></div>'
|
||||
+ '<div class="wg-help">Введи числовой ответ. Допуск $\\pm 0{,}05$. Для $\\pi$ используй $3{,}14$.</div>'
|
||||
+ '<div id="p8-iv3-list"></div>'
|
||||
+ '<div class="score-display" style="margin-top:10px">Решено: <b id="p8-iv3-score">0</b> / 5</div>'
|
||||
+ '</div>';
|
||||
|
||||
html += secNavFor('p8');
|
||||
html += readButton('p8');
|
||||
|
||||
box.innerHTML = html;
|
||||
renderMath(box);
|
||||
|
||||
/* IV1 — Квикфайр */
|
||||
(function(){
|
||||
const tasks = [
|
||||
{ q:'В прямоугольном треугольнике даны <b>оба катета</b>. Найти гипотенузу.', a:'pyth' },
|
||||
{ q:'В произвольном треугольнике даны <b>две стороны и угол между ними</b>. Найти третью сторону.', a:'cos' },
|
||||
{ q:'Дана сторона и <b>противолежащий ей угол</b>. Найти радиус описанной окружности.', a:'sin' },
|
||||
{ q:'В треугольнике даны <b>все три стороны</b>. Найти один из углов.', a:'cos' },
|
||||
{ q:'Даны <b>два угла и сторона</b>. Найти другую сторону.', a:'sin' },
|
||||
{ q:'В прямоугольном треугольнике даны <b>катет и гипотенуза</b>. Найти второй катет.', a:'pyth' },
|
||||
{ q:'Даны <b>две стороны и угол между ними</b>. Найти третью сторону.', a:'cos' },
|
||||
{ q:'Сторона и противолежащий угол в произвольном треугольнике. Найти радиус $R$.', a:'sin' }
|
||||
];
|
||||
const LABELS = {pyth:'Пифагор', sin:'Синусов', cos:'Косинусов'};
|
||||
const area = document.getElementById('p8-iv1-area');
|
||||
const scoreEl = document.getElementById('p8-iv1-score');
|
||||
const solved = new Set();
|
||||
let xpGiven = false;
|
||||
|
||||
area.innerHTML = tasks.map(function(t, i){
|
||||
return '<div style="background:var(--card);border:1px solid var(--border);border-radius:9px;padding:10px 12px;margin-bottom:8px" id="p8-iv1-q-'+i+'">'
|
||||
+ '<div style="margin-bottom:6px"><b>Вопрос '+(i+1)+'.</b> '+t.q+'</div>'
|
||||
+ '<div style="display:flex;gap:6px;flex-wrap:wrap">'
|
||||
+ '<button class="btn" data-i="'+i+'" data-v="pyth">Пифагор</button>'
|
||||
+ '<button class="btn" data-i="'+i+'" data-v="sin">Синусов</button>'
|
||||
+ '<button class="btn" data-i="'+i+'" data-v="cos">Косинусов</button>'
|
||||
+ '</div>'
|
||||
+ '<div class="feedback" id="p8-iv1-fb-'+i+'"></div>'
|
||||
+ '</div>';
|
||||
}).join('');
|
||||
renderMath(area);
|
||||
|
||||
area.querySelectorAll('button[data-i]').forEach(function(b){
|
||||
b.addEventListener('click', function(){
|
||||
const i = +b.dataset.i, v = b.dataset.v, t = tasks[i];
|
||||
const fb = document.getElementById('p8-iv1-fb-'+i);
|
||||
if(v === t.a){
|
||||
feedback(fb, true, '✓ Верно — теорема '+LABELS[t.a]+'!');
|
||||
if(!solved.has(i)){
|
||||
solved.add(i);
|
||||
scoreEl.textContent = solved.size;
|
||||
if(solved.size === tasks.length && !xpGiven){
|
||||
xpGiven = true;
|
||||
addXp(10, 'p8-iv1');
|
||||
bumpProgress('p8', 20);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
feedback(fb, false, '✗ Неверно. Подумай: что дано — прямоуг. $\\triangle$? Угол между двумя сторонами? Сторона + противолежащий угол?');
|
||||
}
|
||||
});
|
||||
});
|
||||
})();
|
||||
|
||||
/* IV2 — DnD сортер */
|
||||
(function(){
|
||||
const items = [
|
||||
{ id:'q1', html:'4 стороны равны, все углы прямые', cat:'square' },
|
||||
{ id:'q2', html:'4 стороны равны, углы не обязательно прямые', cat:'rhomb' },
|
||||
{ id:'q3', html:'Противоположные стороны равны и параллельны', cat:'rect' },
|
||||
{ id:'q4', html:'2 параллельные стороны (основания) разной длины', cat:'trap' },
|
||||
{ id:'q5', html:'4 угла по $90°$, противоположные стороны равны', cat:'rect' },
|
||||
{ id:'q6', html:'Все 4 угла $90°$ и все стороны равны', cat:'square' }
|
||||
];
|
||||
const sorter = setupSorter({
|
||||
poolId:'p8-iv2-pool',
|
||||
scopeSelector:'#p8-iv2',
|
||||
items: items,
|
||||
cats: ['square','rhomb','rect','trap']
|
||||
});
|
||||
let xpGiven = false;
|
||||
document.getElementById('p8-iv2-check').addEventListener('click', function(){
|
||||
const fb = document.getElementById('p8-iv2-fb');
|
||||
let correct = 0;
|
||||
items.forEach(function(it){ if(sorter.placed[it.id] === it.cat) correct++; });
|
||||
if(correct === items.length){
|
||||
feedback(fb, true, '✓ Все 6 правильно! +15 XP');
|
||||
if(!xpGiven){
|
||||
xpGiven = true;
|
||||
addXp(15, 'p8-iv2');
|
||||
bumpProgress('p8', 30);
|
||||
}
|
||||
} else {
|
||||
feedback(fb, false, '✗ Правильно: '+correct+' из '+items.length+'. Попробуй ещё раз.');
|
||||
}
|
||||
});
|
||||
document.getElementById('p8-iv2-reset').addEventListener('click', function(){
|
||||
sorter.reset();
|
||||
const fb = document.getElementById('p8-iv2-fb'); fb.style.display = 'none';
|
||||
});
|
||||
})();
|
||||
|
||||
/* IV3 — Тренажёр повторения */
|
||||
(function(){
|
||||
const tasks = [
|
||||
{ q:'Треугольник со сторонами 3, 4, 5. Какой угол (в градусах) лежит против стороны 5?', a:90, tol:0.05 },
|
||||
{ q:'В прямоугольном треугольнике катеты 6 и 8. Найди гипотенузу.', a:10, tol:0.05 },
|
||||
{ q:'Чему равна сумма углов выпуклого 5-угольника (в градусах)?', a:540, tol:0.05 },
|
||||
{ q:'В круге $R=6$. Длина окружности ($\\pi\\approx 3{,}14$)?', a:37.68, tol:0.05 },
|
||||
{ q:'Треугольник со сторонами 7, 8, 9. Найди площадь по формуле Герона (точность 0,01).', a:26.83, tol:0.05 }
|
||||
];
|
||||
const list = document.getElementById('p8-iv3-list');
|
||||
const scoreEl = document.getElementById('p8-iv3-score');
|
||||
const solved = new Set();
|
||||
let xpGiven = false;
|
||||
|
||||
list.innerHTML = tasks.map(function(t, i){
|
||||
return '<div style="background:var(--card);border:1px solid var(--border);border-radius:9px;padding:10px 12px;margin-bottom:8px">'
|
||||
+ '<div style="margin-bottom:6px"><b>Задача '+(i+1)+'.</b> '+t.q+'</div>'
|
||||
+ '<div style="display:flex;gap:6px;flex-wrap:wrap;align-items:center">'
|
||||
+ '<input type="text" class="tinp" id="p8-iv3-inp-'+i+'" placeholder="число" style="width:140px">'
|
||||
+ '<button class="btn primary" data-i="'+i+'">Проверить</button>'
|
||||
+ '</div>'
|
||||
+ '<div class="feedback" id="p8-iv3-fb-'+i+'"></div>'
|
||||
+ '</div>';
|
||||
}).join('');
|
||||
renderMath(list);
|
||||
|
||||
list.querySelectorAll('button[data-i]').forEach(function(b){
|
||||
b.addEventListener('click', function(){
|
||||
const i = +b.dataset.i, t = tasks[i];
|
||||
const inp = document.getElementById('p8-iv3-inp-'+i);
|
||||
const fb = document.getElementById('p8-iv3-fb-'+i);
|
||||
const raw = (inp.value || '').replace(',', '.').trim();
|
||||
const val = parseFloat(raw);
|
||||
if(!isFinite(val)){ feedback(fb, false, '✗ Введи число'); return; }
|
||||
if(Math.abs(val - t.a) <= t.tol){
|
||||
feedback(fb, true, '✓ Верно!');
|
||||
if(!solved.has(i)){
|
||||
solved.add(i);
|
||||
scoreEl.textContent = solved.size;
|
||||
if(solved.size === tasks.length && !xpGiven){
|
||||
xpGiven = true;
|
||||
addXp(15, 'p8-iv3');
|
||||
bumpProgress('p8', 30);
|
||||
setTimeout(function(){ achievement('p8_done'); }, 400);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
feedback(fb, false, '✗ Не точно. Пересчитай аккуратно.');
|
||||
}
|
||||
});
|
||||
});
|
||||
})();
|
||||
|
||||
wireReadBtn('p8');
|
||||
}
|
||||
|
||||
/* ===== §9 «Геометрические величины» (площади + объёмы — обзор) ===== */
|
||||
|
||||
function buildP9(){
|
||||
const box = document.getElementById('p9-body');
|
||||
if(!box) return;
|
||||
let html = '';
|
||||
|
||||
/* === ТЕОРИЯ === */
|
||||
|
||||
html += makeCard('theory', 'Площади плоских фигур', '§ 9.1',
|
||||
'<p><b>Треугольник.</b> Несколько эквивалентных формул:</p>'
|
||||
+ '<p style="text-align:center;margin:6px 0">$S = \\dfrac{1}{2} a h_a = \\dfrac{1}{2} a b \\sin C = \\sqrt{p(p-a)(p-b)(p-c)} = \\dfrac{abc}{4R} = p r$</p>'
|
||||
+ '<p>где $p = \\dfrac{a+b+c}{2}$, $R$ — описанная, $r$ — вписанная окружности.</p>'
|
||||
+ '<p><b>Четырёхугольники:</b></p>'
|
||||
+ '<ul style="margin:6px 0 10px 22px;line-height:1.7">'
|
||||
+ '<li>Прямоугольник: $S = a b$.</li>'
|
||||
+ '<li>Параллелограмм: $S = a h = a b \\sin\\alpha$.</li>'
|
||||
+ '<li>Ромб: $S = \\dfrac{1}{2} d_1 d_2 = a^2 \\sin\\alpha$.</li>'
|
||||
+ '<li>Трапеция: $S = \\dfrac{a + b}{2} \\cdot h$ (где $a$, $b$ — основания).</li>'
|
||||
+ '</ul>'
|
||||
+ '<p><b>Круг и сектор:</b></p>'
|
||||
+ '<p style="text-align:center;margin:6px 0">$S_{круг} = \\pi R^2,\\qquad S_{сект} = \\dfrac{\\pi R^2 \\alpha}{360°}$</p>');
|
||||
|
||||
html += makeCard('example', 'Объёмы тел в пространстве', '§ 9.2',
|
||||
'<p>Сводная таблица формул объёмов (повторение §§ 1–6):</p>'
|
||||
+ '<ul style="margin:6px 0 10px 22px;line-height:1.7">'
|
||||
+ '<li><b>Куб</b> со стороной $a$: $V = a^3$.</li>'
|
||||
+ '<li><b>Прямоугольный параллелепипед</b> $a \\times b \\times c$: $V = a b c$.</li>'
|
||||
+ '<li><b>Призма</b>: $V = S_{осн} \\cdot h$.</li>'
|
||||
+ '<li><b>Цилиндр</b>: $V = \\pi R^2 h$.</li>'
|
||||
+ '<li><b>Пирамида</b>: $V = \\dfrac{1}{3} S_{осн} \\cdot h$.</li>'
|
||||
+ '<li><b>Конус</b>: $V = \\dfrac{1}{3} \\pi R^2 h$.</li>'
|
||||
+ '<li><b>Шар</b>: $V = \\dfrac{4}{3} \\pi R^3$, $S_{пов} = 4\\pi R^2$.</li>'
|
||||
+ '</ul>'
|
||||
+ '<p><b>Ключевая идея.</b> Объёмы «остроконечных» тел (пирамида, конус) в <b>3 раза меньше</b> объёма «призменных» аналогов с той же основой и высотой: $V_{пир} = \\frac{1}{3} V_{призмы}$, $V_{конус} = \\frac{1}{3} V_{цил}$.</p>'
|
||||
+ '<details class="spoiler"><summary>Пример сравнения: $R=3$, $h=4$</summary><div class="spoiler-body">'
|
||||
+ '<ul style="margin:6px 0 0 22px;line-height:1.7">'
|
||||
+ '<li>Цилиндр: $V = \\pi \\cdot 9 \\cdot 4 = 36\\pi \\approx 113{,}0$.</li>'
|
||||
+ '<li>Конус с теми же $R$, $h$: $V = \\frac{1}{3}\\cdot 36\\pi = 12\\pi \\approx 37{,}7$ — ровно треть.</li>'
|
||||
+ '<li>Шар $R=3$: $V = \\frac{4}{3}\\pi \\cdot 27 = 36\\pi \\approx 113{,}0$ — столько же, сколько у цилиндра $R=3$, $h=4$!</li>'
|
||||
+ '</ul>'
|
||||
+ '</div></details>');
|
||||
|
||||
/* === ИНТЕРАКТИВ 1 — Универсальный калькулятор === */
|
||||
html += '<div class="wg" id="p9-iv1">'
|
||||
+ '<div class="wg-header"><span class="wg-badge">калькулятор</span><div class="wg-title">$S$ и $V$ — универсальный</div></div>'
|
||||
+ '<div class="wg-help">Выбери фигуру, введи параметры. После <b>5 разных фигур</b> — +10 XP.</div>'
|
||||
+ '<div class="sliders">'
|
||||
+ '<label>Фигура:<select id="p9-iv1-fig" style="margin-left:8px;padding:5px 8px;border-radius:7px;border:1px solid var(--border);background:var(--card);color:var(--text)">'
|
||||
+ '<option value="rect">Прямоугольник ($a,b$)</option>'
|
||||
+ '<option value="tri">Треугольник ($a,b,C°$)</option>'
|
||||
+ '<option value="par">Параллелограмм ($a,b,\\alpha°$)</option>'
|
||||
+ '<option value="rhomb">Ромб ($d_1,d_2$)</option>'
|
||||
+ '<option value="trap">Трапеция ($a,b,h$)</option>'
|
||||
+ '<option value="circ">Круг ($R$)</option>'
|
||||
+ '<option value="prism">Призма ($S_{осн},h$)</option>'
|
||||
+ '<option value="cyl">Цилиндр ($R,h$)</option>'
|
||||
+ '<option value="pyr">Пирамида ($S_{осн},h$)</option>'
|
||||
+ '<option value="cone">Конус ($R,h$)</option>'
|
||||
+ '<option value="sph">Шар ($R$)</option>'
|
||||
+ '</select></label>'
|
||||
+ '</div>'
|
||||
+ '<div id="p9-iv1-fields" style="display:flex;gap:10px;flex-wrap:wrap;margin-top:8px;align-items:center"></div>'
|
||||
+ '<div style="margin-top:10px"><button class="btn primary" id="p9-iv1-calc">Вычислить</button></div>'
|
||||
+ '<div id="p9-iv1-out" style="margin-top:10px;padding:10px 14px;background:var(--card);border:1px solid var(--border);border-radius:9px;font-size:.92rem;line-height:1.7;min-height:40px">Выбери фигуру и параметры, затем нажми «Вычислить».</div>'
|
||||
+ '<div style="font-size:.78rem;color:var(--muted);margin-top:6px">Фигур изучено: <b id="p9-iv1-cnt">0</b> / 5</div>'
|
||||
+ '</div>';
|
||||
|
||||
/* === ИНТЕРАКТИВ 2 — Тренажёр площадей === */
|
||||
html += '<div class="wg" id="p9-iv2">'
|
||||
+ '<div class="wg-header"><span class="wg-badge">тренажёр площадей · 6 задач</span><div class="wg-title">Найди площадь $S$</div></div>'
|
||||
+ '<div class="wg-help">Введи числовой ответ. Допуск $\\pm 0{,}05$. Для $\\pi$ используй $3{,}14$.</div>'
|
||||
+ '<div id="p9-iv2-list"></div>'
|
||||
+ '<div class="score-display" style="margin-top:10px">Решено: <b id="p9-iv2-score">0</b> / 6</div>'
|
||||
+ '</div>';
|
||||
|
||||
/* === ИНТЕРАКТИВ 3 — Тренажёр объёмов === */
|
||||
html += '<div class="wg" id="p9-iv3">'
|
||||
+ '<div class="wg-header"><span class="wg-badge">тренажёр объёмов · 6 задач</span><div class="wg-title">Найди объём $V$</div></div>'
|
||||
+ '<div class="wg-help">Введи числовой ответ. Допуск $\\pm 0{,}05$. Для $\\pi$ используй $3{,}14$.</div>'
|
||||
+ '<div id="p9-iv3-list"></div>'
|
||||
+ '<div class="score-display" style="margin-top:10px">Решено: <b id="p9-iv3-score">0</b> / 6</div>'
|
||||
+ '</div>';
|
||||
|
||||
html += secNavFor('p9');
|
||||
html += readButton('p9');
|
||||
|
||||
box.innerHTML = html;
|
||||
renderMath(box);
|
||||
|
||||
/* IV1 — Универсальный калькулятор */
|
||||
(function(){
|
||||
const PI = 3.14;
|
||||
/* Спецификация полей: { key, label, defValue } */
|
||||
const SPEC = {
|
||||
rect: { name:'Прямоугольник', fields:[['a','$a$',5],['b','$b$',8]], calc:p=>({fx:'S = a\\cdot b = '+p.a+'\\cdot '+p.b+' = '+(p.a*p.b).toFixed(2), val:p.a*p.b, unit:'S'}) },
|
||||
tri: { name:'Треугольник', fields:[['a','$a$',5],['b','$b$',8],['C','$C°$',30]], calc:p=>{const v=0.5*p.a*p.b*Math.sin(p.C*Math.PI/180); return {fx:'S = \\tfrac{1}{2}ab\\sin C = \\tfrac{1}{2}\\cdot '+p.a+'\\cdot '+p.b+'\\cdot \\sin '+p.C+'° = '+v.toFixed(2), val:v, unit:'S'};} },
|
||||
par: { name:'Параллелограмм', fields:[['a','$a$',6],['b','$b$',10],['A','$\\alpha°$',30]], calc:p=>{const v=p.a*p.b*Math.sin(p.A*Math.PI/180); return {fx:'S = ab\\sin\\alpha = '+p.a+'\\cdot '+p.b+'\\cdot \\sin '+p.A+'° = '+v.toFixed(2), val:v, unit:'S'};} },
|
||||
rhomb: { name:'Ромб', fields:[['d1','$d_1$',6],['d2','$d_2$',8]], calc:p=>({fx:'S = \\tfrac{1}{2}d_1 d_2 = \\tfrac{1}{2}\\cdot '+p.d1+'\\cdot '+p.d2+' = '+(0.5*p.d1*p.d2).toFixed(2), val:0.5*p.d1*p.d2, unit:'S'}) },
|
||||
trap: { name:'Трапеция', fields:[['a','$a$',4],['b','$b$',8],['h','$h$',5]], calc:p=>({fx:'S = \\tfrac{a+b}{2}\\cdot h = \\tfrac{'+p.a+'+'+p.b+'}{2}\\cdot '+p.h+' = '+(0.5*(p.a+p.b)*p.h).toFixed(2), val:0.5*(p.a+p.b)*p.h, unit:'S'}) },
|
||||
circ: { name:'Круг', fields:[['R','$R$',4]], calc:p=>({fx:'S = \\pi R^2 \\approx 3{,}14\\cdot '+p.R+'^2 = '+(PI*p.R*p.R).toFixed(2), val:PI*p.R*p.R, unit:'S'}) },
|
||||
prism: { name:'Призма', fields:[['So','$S_{осн}$',12],['h','$h$',5]], calc:p=>({fx:'V = S_{осн}\\cdot h = '+p.So+'\\cdot '+p.h+' = '+(p.So*p.h).toFixed(2), val:p.So*p.h, unit:'V'}) },
|
||||
cyl: { name:'Цилиндр', fields:[['R','$R$',3],['h','$h$',5]], calc:p=>({fx:'V = \\pi R^2 h \\approx 3{,}14\\cdot '+p.R+'^2\\cdot '+p.h+' = '+(PI*p.R*p.R*p.h).toFixed(2), val:PI*p.R*p.R*p.h, unit:'V'}) },
|
||||
pyr: { name:'Пирамида', fields:[['So','$S_{осн}$',24],['h','$h$',5]], calc:p=>({fx:'V = \\tfrac{1}{3}S_{осн}h = \\tfrac{1}{3}\\cdot '+p.So+'\\cdot '+p.h+' = '+(p.So*p.h/3).toFixed(2), val:p.So*p.h/3, unit:'V'}) },
|
||||
cone: { name:'Конус', fields:[['R','$R$',6],['h','$h$',5]], calc:p=>({fx:'V = \\tfrac{1}{3}\\pi R^2 h \\approx \\tfrac{1}{3}\\cdot 3{,}14\\cdot '+p.R+'^2\\cdot '+p.h+' = '+(PI*p.R*p.R*p.h/3).toFixed(2), val:PI*p.R*p.R*p.h/3, unit:'V'}) },
|
||||
sph: { name:'Шар', fields:[['R','$R$',3]], calc:p=>({fx:'V = \\tfrac{4}{3}\\pi R^3 \\approx \\tfrac{4}{3}\\cdot 3{,}14\\cdot '+p.R+'^3 = '+(4*PI*p.R*p.R*p.R/3).toFixed(2), val:4*PI*p.R*p.R*p.R/3, unit:'V'}) }
|
||||
};
|
||||
const sel = document.getElementById('p9-iv1-fig');
|
||||
const fields = document.getElementById('p9-iv1-fields');
|
||||
const out = document.getElementById('p9-iv1-out');
|
||||
const oCnt = document.getElementById('p9-iv1-cnt');
|
||||
const seen = new Set();
|
||||
let xpGiven = false;
|
||||
|
||||
function renderFields(){
|
||||
const sp = SPEC[sel.value];
|
||||
fields.innerHTML = sp.fields.map(function(f){
|
||||
return '<label style="font-size:.88rem;display:flex;align-items:center;gap:6px">'
|
||||
+ '<span class="kx">'+f[1]+'</span> = <input type="text" class="tinp" id="p9-iv1-f-'+f[0]+'" value="'+f[2]+'" style="width:80px">'
|
||||
+ '</label>';
|
||||
}).join('');
|
||||
renderMath(fields);
|
||||
}
|
||||
sel.addEventListener('change', function(){ renderFields(); out.innerHTML = 'Параметры обновлены. Нажми «Вычислить».'; });
|
||||
renderFields();
|
||||
|
||||
document.getElementById('p9-iv1-calc').addEventListener('click', function(){
|
||||
const key = sel.value;
|
||||
const sp = SPEC[key];
|
||||
const p = {};
|
||||
let bad = false;
|
||||
sp.fields.forEach(function(f){
|
||||
const el = document.getElementById('p9-iv1-f-'+f[0]);
|
||||
const raw = (el.value || '').replace(',', '.').trim();
|
||||
const v = parseFloat(raw);
|
||||
if(!isFinite(v) || v <= 0){ bad = true; }
|
||||
p[f[0]] = v;
|
||||
});
|
||||
if(bad){ out.innerHTML = '<span style="color:var(--bad,#ef4444)">Введи положительные числа во все поля.</span>'; return; }
|
||||
const r = sp.calc(p);
|
||||
out.innerHTML = '<p><b>'+sp.name+'</b></p>'
|
||||
+ '<p>$$ '+r.fx+' $$</p>'
|
||||
+ '<p><b>Ответ:</b> $'+r.unit+' \\approx '+r.val.toFixed(2)+'$</p>';
|
||||
renderMath(out);
|
||||
seen.add(key);
|
||||
oCnt.textContent = seen.size;
|
||||
if(seen.size >= 5 && !xpGiven){
|
||||
xpGiven = true;
|
||||
addXp(10, 'p9-iv1');
|
||||
bumpProgress('p9', 20);
|
||||
}
|
||||
});
|
||||
})();
|
||||
|
||||
/* IV2 — Тренажёр площадей */
|
||||
(function(){
|
||||
const tasks = [
|
||||
{ q:'Прямоугольник $5 \\times 8$. Найди площадь.', a:40, tol:0.05 },
|
||||
{ q:'Круг $R=4$. Найди площадь ($\\pi\\approx 3{,}14$).', a:50.24, tol:0.05 },
|
||||
{ q:'Треугольник со сторонами 5, 12, 13. Найди площадь.', a:30, tol:0.05 },
|
||||
{ q:'Трапеция: основания 4 и 8, высота 5. Найди площадь.', a:30, tol:0.05 },
|
||||
{ q:'Параллелограмм со сторонами 6 и 10, угол $30°$. Площадь?', a:30, tol:0.05 },
|
||||
{ q:'Ромб с диагоналями 6 и 8. Площадь?', a:24, tol:0.05 }
|
||||
];
|
||||
const list = document.getElementById('p9-iv2-list');
|
||||
const scoreEl = document.getElementById('p9-iv2-score');
|
||||
const solved = new Set();
|
||||
let xpGiven = false;
|
||||
|
||||
list.innerHTML = tasks.map(function(t, i){
|
||||
return '<div style="background:var(--card);border:1px solid var(--border);border-radius:9px;padding:10px 12px;margin-bottom:8px">'
|
||||
+ '<div style="margin-bottom:6px"><b>Задача '+(i+1)+'.</b> '+t.q+'</div>'
|
||||
+ '<div style="display:flex;gap:6px;flex-wrap:wrap;align-items:center">'
|
||||
+ '<input type="text" class="tinp" id="p9-iv2-inp-'+i+'" placeholder="число" style="width:140px">'
|
||||
+ '<button class="btn primary" data-i="'+i+'">Проверить</button>'
|
||||
+ '</div>'
|
||||
+ '<div class="feedback" id="p9-iv2-fb-'+i+'"></div>'
|
||||
+ '</div>';
|
||||
}).join('');
|
||||
renderMath(list);
|
||||
|
||||
list.querySelectorAll('button[data-i]').forEach(function(b){
|
||||
b.addEventListener('click', function(){
|
||||
const i = +b.dataset.i, t = tasks[i];
|
||||
const inp = document.getElementById('p9-iv2-inp-'+i);
|
||||
const fb = document.getElementById('p9-iv2-fb-'+i);
|
||||
const raw = (inp.value || '').replace(',', '.').trim();
|
||||
const val = parseFloat(raw);
|
||||
if(!isFinite(val)){ feedback(fb, false, '✗ Введи число'); return; }
|
||||
if(Math.abs(val - t.a) <= t.tol){
|
||||
feedback(fb, true, '✓ Верно!');
|
||||
if(!solved.has(i)){
|
||||
solved.add(i);
|
||||
scoreEl.textContent = solved.size;
|
||||
if(solved.size === tasks.length && !xpGiven){
|
||||
xpGiven = true;
|
||||
addXp(15, 'p9-iv2');
|
||||
bumpProgress('p9', 30);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
feedback(fb, false, '✗ Не точно. Пересчитай аккуратно.');
|
||||
}
|
||||
});
|
||||
});
|
||||
})();
|
||||
|
||||
/* IV3 — Тренажёр объёмов */
|
||||
(function(){
|
||||
const tasks = [
|
||||
{ q:'Куб со стороной 4. Найди $V$.', a:64, tol:0.05 },
|
||||
{ q:'Прямоугольный параллелепипед $3\\times 4\\times 5$. Найди $V$.', a:60, tol:0.05 },
|
||||
{ q:'Цилиндр $R=3$, $h=5$. Найди $V$ ($\\pi\\approx 3{,}14$).', a:141.3, tol:0.05 },
|
||||
{ q:'Пирамида: $S_{осн}=24$, $h=5$. Найди $V$.', a:40, tol:0.05 },
|
||||
{ q:'Конус $R=6$, $h=5$. Найди $V$ ($\\pi\\approx 3{,}14$).', a:188.4, tol:0.05 },
|
||||
{ q:'Шар $R=3$. Найди $V$ ($\\pi\\approx 3{,}14$).', a:113.04, tol:0.05 }
|
||||
];
|
||||
const list = document.getElementById('p9-iv3-list');
|
||||
const scoreEl = document.getElementById('p9-iv3-score');
|
||||
const solved = new Set();
|
||||
let xpGiven = false;
|
||||
|
||||
list.innerHTML = tasks.map(function(t, i){
|
||||
return '<div style="background:var(--card);border:1px solid var(--border);border-radius:9px;padding:10px 12px;margin-bottom:8px">'
|
||||
+ '<div style="margin-bottom:6px"><b>Задача '+(i+1)+'.</b> '+t.q+'</div>'
|
||||
+ '<div style="display:flex;gap:6px;flex-wrap:wrap;align-items:center">'
|
||||
+ '<input type="text" class="tinp" id="p9-iv3-inp-'+i+'" placeholder="число" style="width:140px">'
|
||||
+ '<button class="btn primary" data-i="'+i+'">Проверить</button>'
|
||||
+ '</div>'
|
||||
+ '<div class="feedback" id="p9-iv3-fb-'+i+'"></div>'
|
||||
+ '</div>';
|
||||
}).join('');
|
||||
renderMath(list);
|
||||
|
||||
list.querySelectorAll('button[data-i]').forEach(function(b){
|
||||
b.addEventListener('click', function(){
|
||||
const i = +b.dataset.i, t = tasks[i];
|
||||
const inp = document.getElementById('p9-iv3-inp-'+i);
|
||||
const fb = document.getElementById('p9-iv3-fb-'+i);
|
||||
const raw = (inp.value || '').replace(',', '.').trim();
|
||||
const val = parseFloat(raw);
|
||||
if(!isFinite(val)){ feedback(fb, false, '✗ Введи число'); return; }
|
||||
if(Math.abs(val - t.a) <= t.tol){
|
||||
feedback(fb, true, '✓ Верно!');
|
||||
if(!solved.has(i)){
|
||||
solved.add(i);
|
||||
scoreEl.textContent = solved.size;
|
||||
if(solved.size === tasks.length && !xpGiven){
|
||||
xpGiven = true;
|
||||
addXp(15, 'p9-iv3');
|
||||
bumpProgress('p9', 30);
|
||||
setTimeout(function(){ achievement('p9_done'); }, 400);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
feedback(fb, false, '✗ Не точно. Пересчитай аккуратно.');
|
||||
}
|
||||
});
|
||||
});
|
||||
})();
|
||||
|
||||
wireReadBtn('p9');
|
||||
}
|
||||
|
||||
/* ===== Search ===== */
|
||||
const SEARCH_INDEX = (function(){
|
||||
const arr=[];
|
||||
|
||||
Reference in New Issue
Block a user