feat(geom11 ch3 wave1): §5 «Сфера» + 3D + уравнение + сечения
This commit is contained in:
@@ -396,7 +396,7 @@ function buildParaSelector(){
|
||||
}
|
||||
|
||||
const BUILT=new Set();
|
||||
const BUILDERS = { p5:()=>buildStub('p5'), p6:()=>buildStub('p6'), p7:()=>buildStub('p7'), final3:()=>buildStub('final3') };
|
||||
const BUILDERS = { p5:buildP5, p6:()=>buildStub('p6'), p7:()=>buildStub('p7'), final3:()=>buildStub('final3') };
|
||||
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);
|
||||
@@ -411,14 +411,24 @@ function goTo(id){
|
||||
}
|
||||
|
||||
const SIDEBARS = {
|
||||
p5:{title:"Шпаргалка § 5", rows:[["Тема", "Сфера"],["Формула","$(x-a)^2+(y-b)^2+(z-c)^2=R^2$"]]},
|
||||
p5:{title:"Шпаргалка § 5", rows:[
|
||||
["Тема", "Сфера"],
|
||||
["Сфера", "множество точек, $|OM|=R$"],
|
||||
["Шар", "множество точек, $|OM|\\\\le R$"],
|
||||
["Уравнение", "$(x-a)^2+(y-b)^2+(z-c)^2=R^2$"],
|
||||
["Касательная", "плоскость $\\\\perp$ радиусу $OM$"],
|
||||
["Сечение", "окружность $r=\\\\sqrt{R^2-d^2}$"],
|
||||
["Большой круг", "$d=0$, $r=R$"],
|
||||
["Площадь", "$S=4\\\\pi R^2$"],
|
||||
["Объём шара", "$V=\\\\tfrac{4}{3}\\\\pi R^3$"]
|
||||
]},
|
||||
p6:{title:"Шпаргалка § 6", rows:[["Тема", "Шар"],["Формула","$S=4\\\\pi R^2$, $V=\\\\frac{4}{3}\\\\pi R^3$"]]},
|
||||
p7:{title:"Шпаргалка § 7", rows:[["Тема", "Правильные многогранники"],["Формула","5 платоновых тел"]]},
|
||||
final3:{title:"Финал раздела 3", rows:[["§ 5–§ 7","теория раздела 3"],["Награда","+50 XP"]]}
|
||||
};
|
||||
|
||||
const TIPS=[
|
||||
{sec:'p5',html:"§ 5 «Сфера» — содержание в разработке. $(x-a)^2+(y-b)^2+(z-c)^2=R^2$"},
|
||||
{sec:'p5',html:"Сфера: $|OM|=R$. Уравнение $(x-a)^2+(y-b)^2+(z-c)^2=R^2$. Сечение плоскостью — окружность $r=\\\\sqrt{R^2-d^2}$."},
|
||||
{sec:'p6',html:"§ 6 «Шар» — содержание в разработке. $S=4\\\\\\\\pi R^2$, $V=\\\\\\\\frac{4}{3}\\\\\\\\pi R^3$"},
|
||||
{sec:'p7',html:"§ 7 «Правильные многогранники» — содержание в разработке. 5 платоновых тел"},
|
||||
{sec:'final3',html:"Финал раздела 3 — интегрированные задачи по разделу."}
|
||||
@@ -625,6 +635,357 @@ function wireReadBtn(paraId){
|
||||
});
|
||||
}
|
||||
|
||||
/* ===== § 5 «Сфера» — Wave 1 ===== */
|
||||
|
||||
function buildP5(){
|
||||
const box = document.getElementById('p5-body');
|
||||
if(!box) return;
|
||||
let html = '';
|
||||
|
||||
/* === ТЕОРИЯ === */
|
||||
|
||||
html += makeCard('theory', 'Определение и элементы', '§ 5.1',
|
||||
'<p><b>Сфера</b> — множество всех точек пространства, равноудалённых от заданной точки $O$ (<b>центра</b>).</p>'
|
||||
+ '<p><b>Шар</b> — множество точек, для которых $|OM|\\le R$, где $O$ — центр, $R$ — радиус. Шар ограничен сферой; сфера — поверхность шара.</p>'
|
||||
+ '<p><b>Элементы:</b></p>'
|
||||
+ '<ul style="margin:6px 0 10px 22px;line-height:1.7">'
|
||||
+ '<li><b>Центр</b> $O$ — точка, от которой все точки сферы равноудалены.</li>'
|
||||
+ '<li><b>Радиус</b> $R=|OM|$ для любой точки $M$ сферы.</li>'
|
||||
+ '<li><b>Диаметр</b> — отрезок через центр между двумя точками сферы. Длина $d=2R$.</li>'
|
||||
+ '<li><b>Хорда</b> — отрезок между двумя точками сферы (не обязательно через центр).</li>'
|
||||
+ '</ul>'
|
||||
+ '<p><b>Уравнение сферы</b> в декартовой системе координат. Для центра $C(a,b,c)$ и радиуса $R$:</p>'
|
||||
+ '<p style="text-align:center;margin:8px 0">$$(x-a)^2+(y-b)^2+(z-c)^2=R^2$$</p>'
|
||||
+ '<p>Если центр в начале координат:</p>'
|
||||
+ '<p style="text-align:center;margin:8px 0">$$x^2+y^2+z^2=R^2$$</p>'
|
||||
+ '<p>Уравнение выражает то, что квадрат расстояния от точки $(x,y,z)$ до центра $C$ равен $R^2$.</p>');
|
||||
|
||||
html += makeCard('rule', 'Касательная плоскость', '§ 5.2',
|
||||
'<p><b>Касательная плоскость к сфере</b> — плоскость, имеющая со сферой <b>ровно одну</b> общую точку. Эту точку называют <b>точкой касания</b>.</p>'
|
||||
+ '<p><b>Признак касания</b> (необходимый и достаточный):</p>'
|
||||
+ '<p style="background:var(--sec-acc-soft,var(--pri-soft));border-left:4px solid var(--sec-acc,var(--pri));padding:8px 12px;border-radius:6px;margin:8px 0">Плоскость касается сферы в точке $M$ тогда и только тогда, когда она <b>перпендикулярна радиусу $OM$</b>, проведённому в точку касания.</p>'
|
||||
+ '<p>Через каждую точку сферы можно провести <b>единственную</b> касательную плоскость.</p>'
|
||||
+ '<p>Расстояние от центра сферы до касательной плоскости равно радиусу $R$.</p>'
|
||||
+ '<details class="spoiler"><summary>Пример: касательная к сфере $x^2+y^2+z^2=25$ в точке $M(3;4;0)$</summary><div class="spoiler-body">'
|
||||
+ '<p>Центр $O(0;0;0)$, радиус-вектор $\\overrightarrow{OM}=(3;4;0)$ направлен из центра в точку касания.</p>'
|
||||
+ '<p>Значит нормаль касательной плоскости $\\vec{n}=(3;4;0)$. Уравнение плоскости в точке $M$:</p>'
|
||||
+ '<p>$3(x-3)+4(y-4)+0\\cdot(z-0)=0$, то есть $3x+4y=25$.</p>'
|
||||
+ '</div></details>');
|
||||
|
||||
html += makeCard('example', 'Сечения сферы и большой круг', '§ 5.3',
|
||||
'<p><b>Сечение сферы плоскостью</b>, пересекающей её — всегда <b>окружность</b>. Это следует из того, что точки сечения равноудалены от проекции центра сферы на эту плоскость.</p>'
|
||||
+ '<p>Связь радиуса сечения $r$, радиуса сферы $R$ и расстояния $d$ от центра сферы до секущей плоскости:</p>'
|
||||
+ '<p style="text-align:center;margin:8px 0">$$r=\\sqrt{R^2-d^2}$$</p>'
|
||||
+ '<p><b>Три случая:</b></p>'
|
||||
+ '<ul style="margin:6px 0 10px 22px;line-height:1.7">'
|
||||
+ '<li>$d<R$ — пересечение есть, сечение — окружность радиуса $r$.</li>'
|
||||
+ '<li>$d=R$ — плоскость касается сферы; «сечение» вырождается в точку.</li>'
|
||||
+ '<li>$d>R$ — общих точек нет.</li>'
|
||||
+ '</ul>'
|
||||
+ '<p><b>Большой круг</b> — сечение, проходящее через центр сферы ($d=0$). Радиус большого круга максимален и равен $R$.</p>'
|
||||
+ '<p>Любые два больших круга пересекаются по диаметру сферы.</p>'
|
||||
+ '<details class="spoiler"><summary>Пример: $R=5$, $d=3$</summary><div class="spoiler-body">'
|
||||
+ '<p>$r=\\sqrt{R^2-d^2}=\\sqrt{25-9}=\\sqrt{16}=4$.</p>'
|
||||
+ '<p>Сечение — окружность радиуса $4$ в секущей плоскости.</p>'
|
||||
+ '</div></details>');
|
||||
|
||||
/* === ИНТЕРАКТИВ 1 — 3D-визуализатор сферы === */
|
||||
html += '<div class="wg" id="p5-iv1">'
|
||||
+ '<div class="wg-header"><span class="wg-badge">3D · сфера</span><div class="wg-title">Визуализатор сферы (каркас)</div></div>'
|
||||
+ '<div class="wg-help">Меняй радиус $R$ ползунком, вращай мышью или выбирай вид. После <b>4 разных значений $R$</b> — +10 XP.</div>'
|
||||
+ '<div class="sliders">'
|
||||
+ '<label>$R$ (радиус):<b id="p5-iv1-R-v">2.0</b><input type="range" id="p5-iv1-R" min="1" max="4" step="0.1" value="2"></label>'
|
||||
+ '</div>'
|
||||
+ '<div class="g3d-tools">'
|
||||
+ '<button class="btn" data-view="iso">Изо</button>'
|
||||
+ '<button class="btn" data-view="front">Спереди</button>'
|
||||
+ '<button class="btn" data-view="top">Сверху</button>'
|
||||
+ '<button class="btn" data-view="side">Сбоку</button>'
|
||||
+ '</div>'
|
||||
+ '<div style="background:var(--card);border:1px solid var(--border);border-radius:9px;padding:8px;text-align:center"><svg id="p5-iv1-svg" viewBox="0 0 480 400" width="100%" style="max-width:480px;height:auto"></svg></div>'
|
||||
+ '<div class="score-display" style="margin-top:10px;flex-wrap:wrap">'
|
||||
+ '<span>$R=$<b id="p5-iv1-R-o">—</b></span>'
|
||||
+ '<span>$d=2R=$<b id="p5-iv1-d-o">—</b></span>'
|
||||
+ '<span>$S=4\\pi R^2\\approx$<b id="p5-iv1-S-o">—</b></span>'
|
||||
+ '<span>$V=\\tfrac{4}{3}\\pi R^3\\approx$<b id="p5-iv1-V-o">—</b></span>'
|
||||
+ '</div>'
|
||||
+ '<div style="font-size:.78rem;color:var(--muted);margin-top:6px">Разных $R$ изучено: <b id="p5-iv1-cnt">0</b> / 4</div>'
|
||||
+ '</div>';
|
||||
|
||||
/* === ИНТЕРАКТИВ 2 — Уравнение сферы и проверка точки === */
|
||||
html += '<div class="wg" id="p5-iv2">'
|
||||
+ '<div class="wg-header"><span class="wg-badge">уравнение</span><div class="wg-title">Уравнение сферы и проверка точки</div></div>'
|
||||
+ '<div class="wg-help">Введи центр $C(a;b;c)$ и радиус $R$ — получи уравнение. Затем введи точку $M(x_0;y_0;z_0)$ — узнай, лежит ли она на сфере, внутри шара или вне.</div>'
|
||||
+ '<div style="background:var(--card);border:1px solid var(--border);border-radius:9px;padding:10px 12px;margin-bottom:10px">'
|
||||
+ '<p style="font-weight:700;margin-bottom:6px">Параметры сферы</p>'
|
||||
+ '<div style="display:flex;gap:6px;flex-wrap:wrap;align-items:center;margin-bottom:8px">'
|
||||
+ '<span>$a=$</span><input type="text" class="tinp" id="p5-iv2-a" value="0" style="width:60px">'
|
||||
+ '<span>$b=$</span><input type="text" class="tinp" id="p5-iv2-b" value="0" style="width:60px">'
|
||||
+ '<span>$c=$</span><input type="text" class="tinp" id="p5-iv2-c" value="0" style="width:60px">'
|
||||
+ '<span>$R=$</span><input type="text" class="tinp" id="p5-iv2-R" value="5" style="width:60px">'
|
||||
+ '<button class="btn primary" id="p5-iv2-show">Показать уравнение</button>'
|
||||
+ '</div>'
|
||||
+ '<div id="p5-iv2-eq" style="font-size:1rem;line-height:1.7;margin-top:6px"></div>'
|
||||
+ '</div>'
|
||||
+ '<div style="background:var(--card);border:1px solid var(--border);border-radius:9px;padding:10px 12px">'
|
||||
+ '<p style="font-weight:700;margin-bottom:6px">Проверка точки $M(x_0;y_0;z_0)$</p>'
|
||||
+ '<div style="display:flex;gap:6px;flex-wrap:wrap;align-items:center;margin-bottom:8px">'
|
||||
+ '<span>$x_0=$</span><input type="text" class="tinp" id="p5-iv2-x0" value="3" style="width:60px">'
|
||||
+ '<span>$y_0=$</span><input type="text" class="tinp" id="p5-iv2-y0" value="4" style="width:60px">'
|
||||
+ '<span>$z_0=$</span><input type="text" class="tinp" id="p5-iv2-z0" value="0" style="width:60px">'
|
||||
+ '<button class="btn primary" id="p5-iv2-check">Проверить точку</button>'
|
||||
+ '</div>'
|
||||
+ '<div id="p5-iv2-pt" style="font-size:.94rem;line-height:1.65;margin-top:6px"></div>'
|
||||
+ '</div>'
|
||||
+ '</div>';
|
||||
|
||||
/* === ИНТЕРАКТИВ 3 — Сечение сферы (квикфайр 6) === */
|
||||
html += '<div class="wg" id="p5-iv3">'
|
||||
+ '<div class="wg-header"><span class="wg-badge">квикфайр · 6 заданий</span><div class="wg-title">Сечение сферы плоскостью</div></div>'
|
||||
+ '<div class="wg-help">Сравни $d$ и $R$. Выбери, что получится при пересечении: окружность, точка (касание) или ничего.</div>'
|
||||
+ '<div id="p5-iv3-list"></div>'
|
||||
+ '<div class="score-display" style="margin-top:10px">Верно: <b id="p5-iv3-score">0</b> / 6</div>'
|
||||
+ '</div>';
|
||||
|
||||
/* === ИНТЕРАКТИВ 4 — Тренажёр === */
|
||||
html += '<div class="wg" id="p5-iv4">'
|
||||
+ '<div class="wg-header"><span class="wg-badge">тренажёр · 6 задач</span><div class="wg-title">Сечения, расстояния и уравнения</div></div>'
|
||||
+ '<div class="wg-help">Введи числовой ответ. Допуск $\\pm 0{,}05$ для дробных значений.</div>'
|
||||
+ '<div id="p5-iv4-list"></div>'
|
||||
+ '<div class="score-display" style="margin-top:10px">Решено: <b id="p5-iv4-score">0</b> / 6</div>'
|
||||
+ '</div>';
|
||||
|
||||
html += secNav(null, 'p6');
|
||||
html += readButton('p5');
|
||||
|
||||
box.innerHTML = html;
|
||||
renderMath(box);
|
||||
|
||||
/* ====== JS-логика интерактивов ====== */
|
||||
|
||||
/* IV1 — 3D-визуализатор */
|
||||
(function(){
|
||||
if(!window.G3D) return;
|
||||
const svg = document.getElementById('p5-iv1-svg');
|
||||
const elR = document.getElementById('p5-iv1-R');
|
||||
const vR = document.getElementById('p5-iv1-R-v');
|
||||
const oR = document.getElementById('p5-iv1-R-o');
|
||||
const oD = document.getElementById('p5-iv1-d-o');
|
||||
const oS = document.getElementById('p5-iv1-S-o');
|
||||
const oV = document.getElementById('p5-iv1-V-o');
|
||||
const oCnt = document.getElementById('p5-iv1-cnt');
|
||||
if(!svg) return;
|
||||
const scene = G3D.createScene({W:480, H:400, scale:60, camDist:8, rotX:-0.35, rotY:0.7});
|
||||
const seen = new Set();
|
||||
let xpGiven = false;
|
||||
const PI = 3.14;
|
||||
|
||||
function draw(){
|
||||
const R = +elR.value;
|
||||
vR.textContent = R.toFixed(1);
|
||||
const sph = G3D.sphereWireframe(R, 6, 12);
|
||||
const M = G3D.buildRotMatrix(scene);
|
||||
svg.innerHTML = G3D.renderSphereWireframe(sph, M, scene);
|
||||
oR.textContent = R.toFixed(1);
|
||||
oD.textContent = (2*R).toFixed(1);
|
||||
oS.textContent = (4*PI*R*R).toFixed(2);
|
||||
oV.textContent = ((4/3)*PI*R*R*R).toFixed(2);
|
||||
const key = R.toFixed(1);
|
||||
seen.add(key);
|
||||
oCnt.textContent = Math.min(seen.size, 4);
|
||||
if(seen.size >= 4 && !xpGiven){
|
||||
xpGiven = true;
|
||||
addXp(10, 'p5-iv1');
|
||||
bumpProgress('p5', 15);
|
||||
const note = document.createElement('div');
|
||||
note.className = 'feedback ok';
|
||||
note.innerHTML = '✓ +10 XP за изучение 4 разных радиусов!';
|
||||
note.style.cssText = 'display:block;margin-top:8px';
|
||||
const host = document.getElementById('p5-iv1');
|
||||
if(host) host.appendChild(note);
|
||||
setTimeout(function(){ try{ note.remove(); }catch(e){} }, 3000);
|
||||
}
|
||||
}
|
||||
draw();
|
||||
G3D.attachOrbit(svg, scene, draw);
|
||||
elR.addEventListener('input', draw);
|
||||
document.querySelectorAll('#p5-iv1 .g3d-tools .btn').forEach(function(b){
|
||||
b.addEventListener('click', function(){ G3D.presetView(scene, b.dataset.view, draw); });
|
||||
});
|
||||
})();
|
||||
|
||||
/* IV2 — Уравнение сферы + проверка точки */
|
||||
(function(){
|
||||
let xpGiven = false, eqShown = false, ptChecked = false;
|
||||
function parseNum(id){ const v = (document.getElementById(id).value||'').replace(',', '.').trim(); const x = parseFloat(v); return isFinite(x) ? x : NaN; }
|
||||
function fmtSign(v, useVar){
|
||||
// возвращает строку для "(x - a)" с учётом знака
|
||||
if(v === 0) return useVar;
|
||||
if(v > 0) return '('+useVar+' - '+fmt(v)+')';
|
||||
return '('+useVar+' + '+fmt(-v)+')';
|
||||
}
|
||||
function maybeXp(){
|
||||
if(eqShown && ptChecked && !xpGiven){
|
||||
xpGiven = true;
|
||||
addXp(10, 'p5-iv2');
|
||||
bumpProgress('p5', 15);
|
||||
}
|
||||
}
|
||||
document.getElementById('p5-iv2-show').addEventListener('click', function(){
|
||||
const a = parseNum('p5-iv2-a'), b = parseNum('p5-iv2-b'), c = parseNum('p5-iv2-c'), R = parseNum('p5-iv2-R');
|
||||
const out = document.getElementById('p5-iv2-eq');
|
||||
if(!isFinite(a)||!isFinite(b)||!isFinite(c)||!isFinite(R)||R<=0){
|
||||
out.innerHTML = '<span style="color:var(--bad)">✗ Введи корректные числа ($R>0$).</span>';
|
||||
renderMath(out);
|
||||
return;
|
||||
}
|
||||
const fx = fmtSign(a, 'x');
|
||||
const fy = fmtSign(b, 'y');
|
||||
const fz = fmtSign(c, 'z');
|
||||
const R2 = R*R;
|
||||
const eq = '$$' + fx + '^2 + ' + fy + '^2 + ' + fz + '^2 = ' + fmt(R2) + '$$';
|
||||
out.innerHTML = '<p>Центр $C('+fmt(a)+';'+fmt(b)+';'+fmt(c)+')$, радиус $R='+fmt(R)+'$.</p>'
|
||||
+ '<p>Уравнение сферы:</p>' + eq;
|
||||
renderMath(out);
|
||||
eqShown = true;
|
||||
maybeXp();
|
||||
});
|
||||
document.getElementById('p5-iv2-check').addEventListener('click', function(){
|
||||
const a = parseNum('p5-iv2-a'), b = parseNum('p5-iv2-b'), c = parseNum('p5-iv2-c'), R = parseNum('p5-iv2-R');
|
||||
const x0 = parseNum('p5-iv2-x0'), y0 = parseNum('p5-iv2-y0'), z0 = parseNum('p5-iv2-z0');
|
||||
const out = document.getElementById('p5-iv2-pt');
|
||||
if(!isFinite(a)||!isFinite(b)||!isFinite(c)||!isFinite(R)||R<=0||!isFinite(x0)||!isFinite(y0)||!isFinite(z0)){
|
||||
out.innerHTML = '<span style="color:var(--bad)">✗ Введи корректные числа.</span>';
|
||||
renderMath(out);
|
||||
return;
|
||||
}
|
||||
const dx = x0 - a, dy = y0 - b, dz = z0 - c;
|
||||
const lhs = dx*dx + dy*dy + dz*dz;
|
||||
const R2 = R*R;
|
||||
const dist = Math.sqrt(lhs);
|
||||
let verdict = '', color = '';
|
||||
if(Math.abs(lhs - R2) < 1e-6){ verdict = 'лежит <b>на сфере</b>'; color = 'var(--ok)'; }
|
||||
else if(lhs < R2){ verdict = 'лежит <b>внутри шара</b>'; color = '#2563eb'; }
|
||||
else { verdict = 'лежит <b>вне шара</b>'; color = 'var(--warn)'; }
|
||||
out.innerHTML = '<p>Подставляем $M('+fmt(x0)+';'+fmt(y0)+';'+fmt(z0)+')$:</p>'
|
||||
+ '<p>$('+fmt(x0)+'-'+fmt(a)+')^2+('+fmt(y0)+'-'+fmt(b)+')^2+('+fmt(z0)+'-'+fmt(c)+')^2 = '
|
||||
+ fmt(dx*dx)+'+'+fmt(dy*dy)+'+'+fmt(dz*dz)+' = '+fmt(lhs)+'$</p>'
|
||||
+ '<p>Сравниваем с $R^2='+fmt(R2)+'$. Расстояние $|CM|='+fmt(+dist.toFixed(4))+'$.</p>'
|
||||
+ '<p style="color:'+color+';font-weight:700">✓ Точка $M$ '+verdict+'.</p>';
|
||||
renderMath(out);
|
||||
ptChecked = true;
|
||||
maybeXp();
|
||||
});
|
||||
})();
|
||||
|
||||
/* IV3 — Сечение сферы (квикфайр) */
|
||||
(function(){
|
||||
const tasks = [
|
||||
{ R:5, d:3, a:'circle' },
|
||||
{ R:5, d:5, a:'point' },
|
||||
{ R:5, d:6, a:'none' },
|
||||
{ R:10, d:0, a:'circle' },
|
||||
{ R:3, d:3.5, a:'none' },
|
||||
{ R:7, d:7, a:'point' }
|
||||
];
|
||||
const NAMES = {circle:'Окружность', point:'Точка', none:'Нет общих точек'};
|
||||
const HINTS = {
|
||||
circle: function(t){ const r = Math.sqrt(t.R*t.R - t.d*t.d); return '$d<R$, сечение — окружность радиуса $r=\\sqrt{'+t.R+'^2-'+t.d+'^2}='+fmt(+r.toFixed(4))+'$'+(t.d===0?' (большой круг)':'')+'.'; },
|
||||
point: function(t){ return '$d=R='+t.R+'$, плоскость касается сферы — общая точка одна.'; },
|
||||
none: function(t){ return '$d='+t.d+'>R='+t.R+'$, плоскость не пересекает сферу.'; }
|
||||
};
|
||||
const list = document.getElementById('p5-iv3-list');
|
||||
const scoreEl = document.getElementById('p5-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:8px"><b>Задание '+(i+1)+'.</b> Сфера $R='+t.R+'$, расстояние от центра до плоскости $d='+t.d+'$. Что получится?</div>'
|
||||
+ '<div style="display:flex;gap:6px;flex-wrap:wrap">'
|
||||
+ '<button class="btn" data-i="'+i+'" data-v="circle">Окружность</button>'
|
||||
+ '<button class="btn" data-i="'+i+'" data-v="point">Точка</button>'
|
||||
+ '<button class="btn" data-i="'+i+'" data-v="none">Нет общих точек</button>'
|
||||
+ '</div>'
|
||||
+ '<div class="feedback" id="p5-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, v = b.dataset.v, t = tasks[i];
|
||||
const fb = document.getElementById('p5-iv3-fb-'+i);
|
||||
if(solved.has(i)) return;
|
||||
if(v === t.a){
|
||||
feedback(fb, true, '✓ Верно — '+NAMES[t.a]+'. '+HINTS[t.a](t));
|
||||
solved.add(i);
|
||||
scoreEl.textContent = solved.size;
|
||||
if(solved.size === tasks.length && !xpGiven){
|
||||
xpGiven = true;
|
||||
addXp(15, 'p5-iv3');
|
||||
bumpProgress('p5', 25);
|
||||
}
|
||||
} else {
|
||||
feedback(fb, false, '✗ Не то. Сравни $d$ и $R$ внимательнее.');
|
||||
}
|
||||
});
|
||||
});
|
||||
})();
|
||||
|
||||
/* IV4 — Тренажёр */
|
||||
(function(){
|
||||
const tasks = [
|
||||
{ q:'Сфера $R=5$. Радиус сечения плоскостью на расстоянии $d=3$ от центра: $r=\\,?$', a:4, tol:0.05 },
|
||||
{ q:'Сфера с центром $C(2;3;-1)$, точка $M(5;7;3)$. Расстояние $|CM|=\\,?$ (точность 0,01)', a:6.40, tol:0.05 },
|
||||
{ q:'Сфера $R=13$. Сечение — окружность радиуса $12$. Найти $d$ (расстояние от центра до плоскости).', a:5, tol:0.05 },
|
||||
{ q:'К сфере $R=5$ построена касательная плоскость. Расстояние от центра до плоскости: $d=\\,?$', a:5, tol:0.05 },
|
||||
{ q:'Точка $A(3;4;0)$ принадлежит сфере с центром в начале координат. Найти $R$.', a:5, tol:0.05 },
|
||||
{ q:'Сфера $x^2+y^2+z^2=100$. Радиус большого круга: $R=\\,?$', a:10, tol:0.05 }
|
||||
];
|
||||
const list = document.getElementById('p5-iv4-list');
|
||||
const scoreEl = document.getElementById('p5-iv4-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="p5-iv4-inp-'+i+'" placeholder="число" style="width:140px">'
|
||||
+ '<button class="btn primary" data-i="'+i+'">Проверить</button>'
|
||||
+ '</div>'
|
||||
+ '<div class="feedback" id="p5-iv4-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('p5-iv4-inp-'+i);
|
||||
const fb = document.getElementById('p5-iv4-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, 'p5-iv4');
|
||||
bumpProgress('p5', 25);
|
||||
setTimeout(function(){ achievement('p5_done'); }, 400);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
feedback(fb, false, '✗ Не точно. Пересчитай аккуратно.');
|
||||
}
|
||||
});
|
||||
});
|
||||
})();
|
||||
|
||||
wireReadBtn('p5');
|
||||
}
|
||||
|
||||
/* ===== STUB BUILDER — единый для всех параграфов раздела (Phase 0) ===== */
|
||||
|
||||
function buildStub(id){
|
||||
@@ -706,6 +1067,10 @@ function buildStub(id){
|
||||
const SEARCH_INDEX = (function(){
|
||||
const arr=[];
|
||||
PARAS.forEach(p=>arr.push({kind:'Параграф',title:p.num+' '+p.name,desc:p.sub||'',sec:p.id}));
|
||||
arr.push({kind:'Теория',title:'Сфера и шар: определение',desc:'центр, радиус, диаметр, хорда',sec:'p5'});
|
||||
arr.push({kind:'Теория',title:'Уравнение сферы',desc:'(x-a)^2+(y-b)^2+(z-c)^2=R^2',sec:'p5'});
|
||||
arr.push({kind:'Теория',title:'Касательная плоскость к сфере',desc:'перпендикулярна радиусу в точке касания',sec:'p5'});
|
||||
arr.push({kind:'Теория',title:'Сечение сферы плоскостью',desc:'r = sqrt(R^2 - d^2), большой круг',sec:'p5'});
|
||||
return arr;
|
||||
})();
|
||||
function initSearch(){
|
||||
|
||||
Reference in New Issue
Block a user