feat(geom9 ch1 wave2): §3 «Тригонометрические формулы» + §4 «Тупой угол + единичная окружность»
This commit is contained in:
@@ -1175,8 +1175,640 @@ function buildP2(){
|
||||
|
||||
wireReadBtn('p2');
|
||||
}
|
||||
function buildP3(){ _stubBuilder('p3', '§3', 'Тригонометрические формулы', 'p2', 'p4'); }
|
||||
function buildP4(){ _stubBuilder('p4', '§4', 'sin, cos, tg, ctg тупого угла', 'p3', 'p5'); }
|
||||
/* ===== §3 Тригонометрические формулы ===== */
|
||||
function buildP3(){
|
||||
const box = document.getElementById('p3-body');
|
||||
let html = '';
|
||||
|
||||
html += makeCard('theory', 'Основное тригонометрическое тождество', '3.1', `
|
||||
<p>Возьмём прямоугольный треугольник с острым углом $\\alpha$, противолежащим катетом $a$, прилежащим катетом $b$ и гипотенузой $c$. По определению $\\sin \\alpha = a/c$, $\\cos \\alpha = b/c$.</p>
|
||||
<p>По теореме Пифагора $a^2 + b^2 = c^2$. Поделим обе части на $c^2$:</p>
|
||||
<p style="text-align:center">$\\dfrac{a^2}{c^2} + \\dfrac{b^2}{c^2} = 1 \\;\\Rightarrow\\; \\left(\\dfrac{a}{c}\\right)^2 + \\left(\\dfrac{b}{c}\\right)^2 = 1.$</p>
|
||||
<p style="text-align:center;font-size:1.1rem"><b>$\\sin^2 \\alpha + \\cos^2 \\alpha = 1$</b></p>
|
||||
<p><b>Следствия</b> (для острого $\\alpha$):</p>
|
||||
<ul style="padding-left:22px;line-height:1.95">
|
||||
<li>$\\sin \\alpha = \\sqrt{1 - \\cos^2 \\alpha}$</li>
|
||||
<li>$\\cos \\alpha = \\sqrt{1 - \\sin^2 \\alpha}$</li>
|
||||
</ul>
|
||||
<details class="spoiler"><summary>Зачем это нужно?</summary><div class="spoiler-body">
|
||||
Если известно одно из значений ($\\sin \\alpha$ или $\\cos \\alpha$), второе мгновенно вычисляется без чертежа треугольника. Это первое настоящее тригонометрическое <b>тождество</b> — равенство, верное для любого допустимого угла.
|
||||
</div></details>`);
|
||||
|
||||
html += makeCard('rule', 'Связь tg и ctg с sin и cos', '3.2', `
|
||||
<p>Из определений $\\tan \\alpha = \\dfrac{a}{b}$ и $\\sin \\alpha / \\cos \\alpha = \\dfrac{a/c}{b/c} = \\dfrac{a}{b}$ получаем:</p>
|
||||
<ul style="padding-left:22px;line-height:1.95">
|
||||
<li>$\\tan \\alpha = \\dfrac{\\sin \\alpha}{\\cos \\alpha}$</li>
|
||||
<li>$\\cot \\alpha = \\dfrac{\\cos \\alpha}{\\sin \\alpha}$</li>
|
||||
<li>$\\tan \\alpha \\cdot \\cot \\alpha = 1$ (значит, $\\cot \\alpha = 1/\\tan \\alpha$)</li>
|
||||
</ul>
|
||||
<p>Поделим основное тождество $\\sin^2 \\alpha + \\cos^2 \\alpha = 1$ на $\\cos^2 \\alpha$:</p>
|
||||
<p style="text-align:center">$\\dfrac{\\sin^2 \\alpha}{\\cos^2 \\alpha} + 1 = \\dfrac{1}{\\cos^2 \\alpha} \\;\\Rightarrow\\; \\boxed{\\,1 + \\tan^2 \\alpha = \\dfrac{1}{\\cos^2 \\alpha}\\,}$</p>
|
||||
<p>Аналогично, поделив на $\\sin^2 \\alpha$:</p>
|
||||
<p style="text-align:center">$\\boxed{\\,1 + \\cot^2 \\alpha = \\dfrac{1}{\\sin^2 \\alpha}\\,}$</p>`);
|
||||
|
||||
html += makeCard('example', 'Откуда берутся 30°, 45°, 60°', '3.3', `
|
||||
<p><b>1) Треугольник 45°-45°-90°</b> — равнобедренный прямоугольный. Возьмём оба катета равными $1$. Тогда гипотенуза $\\sqrt{1^2 + 1^2} = \\sqrt{2}$. Значит:</p>
|
||||
<p style="text-align:center">$\\sin 45^\\circ = \\cos 45^\\circ = \\dfrac{1}{\\sqrt{2}} = \\dfrac{\\sqrt{2}}{2},\\quad \\tan 45^\\circ = \\cot 45^\\circ = 1.$</p>
|
||||
<p><b>2) Треугольник 30°-60°-90°</b> — половина равностороннего. У равностороннего треугольника со стороной $2$ все углы $60^\\circ$. Высота делит его на два прямоугольных треугольника с катетами $1$ (половина основания) и $\\sqrt{2^2 - 1^2} = \\sqrt{3}$, гипотенузой $2$. Углы: $30^\\circ$ (при вершине) и $60^\\circ$ (у основания). Получаем:</p>
|
||||
<p style="text-align:center">$\\sin 30^\\circ = \\dfrac{1}{2},\\; \\cos 30^\\circ = \\dfrac{\\sqrt{3}}{2},\\; \\tan 30^\\circ = \\dfrac{1}{\\sqrt{3}}.$</p>
|
||||
<p style="text-align:center">$\\sin 60^\\circ = \\dfrac{\\sqrt{3}}{2},\\; \\cos 60^\\circ = \\dfrac{1}{2},\\; \\tan 60^\\circ = \\sqrt{3}.$</p>
|
||||
<div style="overflow-x:auto;margin:10px 0">
|
||||
<table style="width:100%;border-collapse:collapse;font-size:.95rem;background:var(--card);border:1.5px solid var(--border);border-radius:9px;overflow:hidden">
|
||||
<thead><tr style="background:var(--pri-soft)">
|
||||
<th style="padding:8px;border-bottom:1px solid var(--border);text-align:left">Угол</th>
|
||||
<th style="padding:8px;border-bottom:1px solid var(--border)">$\\sin$</th>
|
||||
<th style="padding:8px;border-bottom:1px solid var(--border)">$\\cos$</th>
|
||||
<th style="padding:8px;border-bottom:1px solid var(--border)">$\\tan$</th>
|
||||
<th style="padding:8px;border-bottom:1px solid var(--border)">$\\cot$</th>
|
||||
</tr></thead>
|
||||
<tbody>
|
||||
<tr><td style="padding:8px;border-bottom:1px solid var(--border)"><b>30°</b></td><td style="padding:8px;border-bottom:1px solid var(--border);text-align:center">$\\tfrac{1}{2}$</td><td style="padding:8px;border-bottom:1px solid var(--border);text-align:center">$\\tfrac{\\sqrt{3}}{2}$</td><td style="padding:8px;border-bottom:1px solid var(--border);text-align:center">$\\tfrac{1}{\\sqrt{3}}$</td><td style="padding:8px;border-bottom:1px solid var(--border);text-align:center">$\\sqrt{3}$</td></tr>
|
||||
<tr><td style="padding:8px;border-bottom:1px solid var(--border)"><b>45°</b></td><td style="padding:8px;border-bottom:1px solid var(--border);text-align:center">$\\tfrac{\\sqrt{2}}{2}$</td><td style="padding:8px;border-bottom:1px solid var(--border);text-align:center">$\\tfrac{\\sqrt{2}}{2}$</td><td style="padding:8px;border-bottom:1px solid var(--border);text-align:center">$1$</td><td style="padding:8px;border-bottom:1px solid var(--border);text-align:center">$1$</td></tr>
|
||||
<tr><td style="padding:8px"><b>60°</b></td><td style="padding:8px;text-align:center">$\\tfrac{\\sqrt{3}}{2}$</td><td style="padding:8px;text-align:center">$\\tfrac{1}{2}$</td><td style="padding:8px;text-align:center">$\\sqrt{3}$</td><td style="padding:8px;text-align:center">$\\tfrac{1}{\\sqrt{3}}$</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>`);
|
||||
|
||||
/* IV1 — Три эталонных треугольника */
|
||||
html += `<div class="wg" id="p3-iv1">
|
||||
<div class="wg-header"><span class="wg-badge">ИНТЕРАКТИВ 1</span><div class="wg-title">Три эталонных треугольника</div></div>
|
||||
<div class="wg-help">Слева — треугольник $30^\\circ\\text{-}60^\\circ\\text{-}90^\\circ$ (катеты $1$ и $\\sqrt{3}$, гипотенуза $2$). Справа — равнобедренный $45^\\circ\\text{-}45^\\circ\\text{-}90^\\circ$ (катеты $1$, гипотенуза $\\sqrt{2}$).</div>
|
||||
<div style="background:var(--card);border-radius:10px;padding:10px;overflow-x:auto">
|
||||
<svg id="p3-iv1-svg" viewBox="0 0 600 220" style="width:100%;min-width:420px;height:auto;display:block"></svg>
|
||||
</div>
|
||||
<div style="overflow-x:auto;margin-top:10px">
|
||||
<table style="width:100%;border-collapse:collapse;font-size:.92rem;background:var(--card);border:1.5px solid var(--border);border-radius:9px;overflow:hidden">
|
||||
<thead><tr style="background:var(--pri-soft)">
|
||||
<th style="padding:6px;border-bottom:1px solid var(--border)">Угол</th>
|
||||
<th style="padding:6px;border-bottom:1px solid var(--border)">$\\sin$</th>
|
||||
<th style="padding:6px;border-bottom:1px solid var(--border)">$\\cos$</th>
|
||||
<th style="padding:6px;border-bottom:1px solid var(--border)">$\\tan$</th>
|
||||
<th style="padding:6px;border-bottom:1px solid var(--border)">$\\cot$</th>
|
||||
</tr></thead>
|
||||
<tbody>
|
||||
<tr><td style="padding:6px;border-bottom:1px solid var(--border);text-align:center"><b>30°</b></td><td style="padding:6px;border-bottom:1px solid var(--border);text-align:center">$\\tfrac{1}{2}$</td><td style="padding:6px;border-bottom:1px solid var(--border);text-align:center">$\\tfrac{\\sqrt{3}}{2}$</td><td style="padding:6px;border-bottom:1px solid var(--border);text-align:center">$\\tfrac{1}{\\sqrt{3}}$</td><td style="padding:6px;border-bottom:1px solid var(--border);text-align:center">$\\sqrt{3}$</td></tr>
|
||||
<tr><td style="padding:6px;border-bottom:1px solid var(--border);text-align:center"><b>45°</b></td><td style="padding:6px;border-bottom:1px solid var(--border);text-align:center">$\\tfrac{\\sqrt{2}}{2}$</td><td style="padding:6px;border-bottom:1px solid var(--border);text-align:center">$\\tfrac{\\sqrt{2}}{2}$</td><td style="padding:6px;border-bottom:1px solid var(--border);text-align:center">$1$</td><td style="padding:6px;border-bottom:1px solid var(--border);text-align:center">$1$</td></tr>
|
||||
<tr><td style="padding:6px;text-align:center"><b>60°</b></td><td style="padding:6px;text-align:center">$\\tfrac{\\sqrt{3}}{2}$</td><td style="padding:6px;text-align:center">$\\tfrac{1}{2}$</td><td style="padding:6px;text-align:center">$\\sqrt{3}$</td><td style="padding:6px;text-align:center">$\\tfrac{1}{\\sqrt{3}}$</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>`;
|
||||
|
||||
/* IV2 — Калькулятор тождеств */
|
||||
html += `<div class="wg" id="p3-iv2">
|
||||
<div class="wg-header"><span class="wg-badge">ИНТЕРАКТИВ 2</span><div class="wg-title">Калькулятор тождеств</div></div>
|
||||
<div class="wg-help">Введи $\\sin \\alpha$ (значение от $0{,}01$ до $0{,}99$). Получишь $\\cos \\alpha$, $\\tan \\alpha$, $\\cot \\alpha$ и сам угол $\\alpha$ в градусах.</div>
|
||||
<div style="display:flex;gap:10px;align-items:center;flex-wrap:wrap;justify-content:center;margin-bottom:10px">
|
||||
<span style="font-family:'JetBrains Mono',monospace">$\\sin \\alpha$ =</span>
|
||||
<input type="range" id="p3-iv2-s" min="0.01" max="0.99" step="0.01" value="0.6" style="width:200px;accent-color:var(--pri)">
|
||||
<input type="number" id="p3-iv2-sn" class="tinp" style="width:90px;text-align:center" value="0.6" min="0.01" max="0.99" step="0.01">
|
||||
<button class="btn primary" id="p3-iv2-go">Вычислить</button>
|
||||
</div>
|
||||
<div id="p3-iv2-out" style="padding:12px 14px;background:var(--card);border-radius:9px;text-align:center;font-size:1rem;line-height:1.85;min-height:50px"></div>
|
||||
<div class="feedback" id="p3-iv2-fb"></div>
|
||||
</div>`;
|
||||
|
||||
/* IV3 — Quickfire «Какое значение?» */
|
||||
html += `<div class="wg" id="p3-iv3">
|
||||
<div class="wg-header"><span class="wg-badge">ИНТЕРАКТИВ 3</span><div class="wg-title">Какое значение?</div></div>
|
||||
<div class="wg-help">Дано тригонометрическое выражение — выбери его точное значение из 4 вариантов.</div>
|
||||
<div class="score-display"><span>Задача <b id="p3-iv3-i">1</b> / 8</span><span>Очки: <b id="p3-iv3-s">0</b> / 8</span></div>
|
||||
<div id="p3-iv3-q" style="padding:14px;background:var(--pri-soft);border-radius:10px;font-size:1.2rem;text-align:center;margin-bottom:10px"></div>
|
||||
<div style="display:grid;grid-template-columns:repeat(auto-fit,minmax(110px,1fr));gap:8px">
|
||||
<button class="btn primary" data-ans="half" id="p3-iv3-half">$\\tfrac{1}{2}$</button>
|
||||
<button class="btn primary" data-ans="s2" id="p3-iv3-s2">$\\tfrac{\\sqrt{2}}{2}$</button>
|
||||
<button class="btn primary" data-ans="s3" id="p3-iv3-s3">$\\tfrac{\\sqrt{3}}{2}$</button>
|
||||
<button class="btn primary" data-ans="one" id="p3-iv3-one">$1$</button>
|
||||
</div>
|
||||
<div class="feedback" id="p3-iv3-fb"></div>
|
||||
</div>`;
|
||||
|
||||
/* IV4 — Применение тождеств */
|
||||
html += `<div class="wg" id="p3-iv4">
|
||||
<div class="wg-header"><span class="wg-badge">ИНТЕРАКТИВ 4</span><div class="wg-title">Применение тождеств</div></div>
|
||||
<div class="wg-help">Реши задачу и введи число (целое или десятичную дробь до 3 знаков).</div>
|
||||
<div class="score-display"><span>Задача <b id="p3-iv4-i">1</b> / 6</span><span>Очки: <b id="p3-iv4-s">0</b> / 6</span></div>
|
||||
<div id="p3-iv4-q" style="padding:14px;background:var(--pri-soft);border-radius:10px;font-size:1.05rem;margin-bottom:10px;text-align:center"></div>
|
||||
<div style="display:flex;gap:10px;align-items:center;flex-wrap:wrap;justify-content:center">
|
||||
<span style="font-family:'JetBrains Mono',monospace">ответ =</span>
|
||||
<input type="number" id="p3-iv4-ans" class="tinp" style="width:110px;text-align:center" step="0.001">
|
||||
<button class="btn primary" id="p3-iv4-go">Проверить</button>
|
||||
<button class="btn" id="p3-iv4-start">Заново</button>
|
||||
</div>
|
||||
<div class="feedback" id="p3-iv4-fb"></div>
|
||||
</div>`;
|
||||
|
||||
html += secNav('p2', 'p4');
|
||||
html += readButton('p3');
|
||||
|
||||
box.innerHTML = html;
|
||||
renderMath(box);
|
||||
|
||||
/* IV1 — рисуем три эталонных треугольника */
|
||||
(function(){
|
||||
const svg = document.getElementById('p3-iv1-svg');
|
||||
if(!svg) return;
|
||||
let s = '';
|
||||
// Треугольник 30-60-90: катеты 1 и sqrt(3), гипотенуза 2. Используем масштаб 60 px = 1 ед.
|
||||
// Левый: BC = sqrt(3) (горизонт., прилежащий 30°), AB = 1 (вертикальный, противолежащий 30°)
|
||||
// Вершины: A слева внизу, B слева вверху (прямой угол), C справа внизу.
|
||||
// Угол 30° при C, угол 60° при A.
|
||||
(function(){
|
||||
const u = 60;
|
||||
const Ax = 40, Ay = 180;
|
||||
const A = {x: Ax, y: Ay};
|
||||
const B = {x: Ax, y: Ay - u}; // катет AB = 1
|
||||
const C = {x: Ax + Math.sqrt(3)*u, y: Ay}; // катет BC = sqrt(3)
|
||||
const uBA = unitVec(B, A);
|
||||
const uBC = unitVec(B, C);
|
||||
const uCA = unitVec(C, A);
|
||||
const uCB = unitVec(C, B);
|
||||
const uAB = unitVec(A, B);
|
||||
const uAC = unitVec(A, C);
|
||||
s += '<polygon points="'+A.x+','+A.y+' '+B.x+','+B.y+' '+C.x+','+C.y+'" fill="rgba(217,119,6,.08)" stroke="#b45309" stroke-width="2" stroke-linejoin="round"/>';
|
||||
s += '<polyline points="'+rightAngleMark(B, uBA, uBC, 10)+'" fill="none" stroke="#0f172a" stroke-width="1.6"/>';
|
||||
s += '<path d="'+angleArcAuto(C, uCA, uCB, 26)+'" fill="none" stroke="#dc2626" stroke-width="2"/>';
|
||||
s += '<path d="'+angleArcAuto(A, uAB, uAC, 22)+'" fill="none" stroke="#0ea5e9" stroke-width="2"/>';
|
||||
// подписи углов
|
||||
s += '<text x="'+(C.x-30)+'" y="'+(C.y-8)+'" text-anchor="middle" font-family="Inter,sans-serif" font-size="13" font-weight="700" fill="#dc2626">30°</text>';
|
||||
s += '<text x="'+(A.x+18)+'" y="'+(A.y-8)+'" text-anchor="middle" font-family="Inter,sans-serif" font-size="13" font-weight="700" fill="#0ea5e9">60°</text>';
|
||||
// вершины и подписи
|
||||
['A','B','C'].forEach((nm,i)=>{ const P=[A,B,C][i]; s+='<circle cx="'+P.x+'" cy="'+P.y+'" r="3.5" fill="#0f172a"/>'; });
|
||||
s += '<text x="'+(A.x-10)+'" y="'+(A.y+15)+'" text-anchor="end" font-family="Inter,sans-serif" font-size="14" font-weight="700">A</text>';
|
||||
s += '<text x="'+(B.x-10)+'" y="'+(B.y-4)+'" text-anchor="end" font-family="Inter,sans-serif" font-size="14" font-weight="700">B</text>';
|
||||
s += '<text x="'+(C.x+10)+'" y="'+(C.y+15)+'" text-anchor="start" font-family="Inter,sans-serif" font-size="14" font-weight="700">C</text>';
|
||||
// длины сторон
|
||||
s += '<text x="'+(B.x-22)+'" y="'+((A.y+B.y)/2+4)+'" text-anchor="middle" font-family="JetBrains Mono,monospace" font-size="12" fill="#b45309">1</text>';
|
||||
s += '<text x="'+((B.x+C.x)/2)+'" y="'+(A.y+22)+'" text-anchor="middle" font-family="JetBrains Mono,monospace" font-size="12" fill="#b45309">√3</text>';
|
||||
const midAC={x:(A.x+C.x)/2, y:(A.y+C.y)/2};
|
||||
const nAC={x:-(C.y-A.y), y:(C.x-A.x)};
|
||||
const nL=Math.sqrt(nAC.x*nAC.x+nAC.y*nAC.y)||1;
|
||||
const labP={x: midAC.x + 16*nAC.x/nL, y: midAC.y + 16*nAC.y/nL};
|
||||
s += '<text x="'+labP.x+'" y="'+labP.y+'" text-anchor="middle" font-family="JetBrains Mono,monospace" font-size="12" fill="#b45309">2</text>';
|
||||
// заголовок
|
||||
s += '<text x="'+((A.x+C.x)/2)+'" y="22" text-anchor="middle" font-family="Unbounded,sans-serif" font-size="13" font-weight="800" fill="#92400e">30\xb0-60\xb0-90\xb0</text>';
|
||||
})();
|
||||
// Треугольник 45-45-90: оба катета 1, гипотенуза sqrt(2). Масштаб тот же.
|
||||
(function(){
|
||||
const u = 90; // покрупнее
|
||||
const Ax = 360, Ay = 180;
|
||||
const A = {x: Ax, y: Ay};
|
||||
const B = {x: Ax, y: Ay - u};
|
||||
const C = {x: Ax + u, y: Ay};
|
||||
const uBA = unitVec(B, A);
|
||||
const uBC = unitVec(B, C);
|
||||
const uCA = unitVec(C, A);
|
||||
const uCB = unitVec(C, B);
|
||||
const uAB = unitVec(A, B);
|
||||
const uAC = unitVec(A, C);
|
||||
s += '<polygon points="'+A.x+','+A.y+' '+B.x+','+B.y+' '+C.x+','+C.y+'" fill="rgba(217,119,6,.08)" stroke="#b45309" stroke-width="2" stroke-linejoin="round"/>';
|
||||
s += '<polyline points="'+rightAngleMark(B, uBA, uBC, 10)+'" fill="none" stroke="#0f172a" stroke-width="1.6"/>';
|
||||
s += '<path d="'+angleArcAuto(C, uCA, uCB, 28)+'" fill="none" stroke="#dc2626" stroke-width="2"/>';
|
||||
s += '<path d="'+angleArcAuto(A, uAB, uAC, 26)+'" fill="none" stroke="#0ea5e9" stroke-width="2"/>';
|
||||
s += '<text x="'+(C.x-30)+'" y="'+(C.y-8)+'" text-anchor="middle" font-family="Inter,sans-serif" font-size="13" font-weight="700" fill="#dc2626">45°</text>';
|
||||
s += '<text x="'+(A.x+22)+'" y="'+(A.y-8)+'" text-anchor="middle" font-family="Inter,sans-serif" font-size="13" font-weight="700" fill="#0ea5e9">45°</text>';
|
||||
['A','B','C'].forEach((nm,i)=>{ const P=[A,B,C][i]; s+='<circle cx="'+P.x+'" cy="'+P.y+'" r="3.5" fill="#0f172a"/>'; });
|
||||
s += '<text x="'+(A.x-10)+'" y="'+(A.y+15)+'" text-anchor="end" font-family="Inter,sans-serif" font-size="14" font-weight="700">A</text>';
|
||||
s += '<text x="'+(B.x-10)+'" y="'+(B.y-4)+'" text-anchor="end" font-family="Inter,sans-serif" font-size="14" font-weight="700">B</text>';
|
||||
s += '<text x="'+(C.x+10)+'" y="'+(C.y+15)+'" text-anchor="start" font-family="Inter,sans-serif" font-size="14" font-weight="700">C</text>';
|
||||
s += '<text x="'+(B.x-22)+'" y="'+((A.y+B.y)/2+4)+'" text-anchor="middle" font-family="JetBrains Mono,monospace" font-size="12" fill="#b45309">1</text>';
|
||||
s += '<text x="'+((B.x+C.x)/2)+'" y="'+(A.y+22)+'" text-anchor="middle" font-family="JetBrains Mono,monospace" font-size="12" fill="#b45309">1</text>';
|
||||
const midAC={x:(A.x+C.x)/2, y:(A.y+C.y)/2};
|
||||
const nAC={x:-(C.y-A.y), y:(C.x-A.x)};
|
||||
const nL=Math.sqrt(nAC.x*nAC.x+nAC.y*nAC.y)||1;
|
||||
const labP={x: midAC.x + 16*nAC.x/nL, y: midAC.y + 16*nAC.y/nL};
|
||||
s += '<text x="'+labP.x+'" y="'+labP.y+'" text-anchor="middle" font-family="JetBrains Mono,monospace" font-size="12" fill="#b45309">√2</text>';
|
||||
s += '<text x="'+((A.x+C.x)/2)+'" y="22" text-anchor="middle" font-family="Unbounded,sans-serif" font-size="13" font-weight="800" fill="#92400e">45\xb0-45\xb0-90\xb0</text>';
|
||||
})();
|
||||
svg.innerHTML = s;
|
||||
addXp(10,'p3-iv1'); bumpProgress('p3', 15);
|
||||
})();
|
||||
|
||||
/* IV2 — Калькулятор тождеств */
|
||||
(function(){
|
||||
const sl = document.getElementById('p3-iv2-s');
|
||||
const inp = document.getElementById('p3-iv2-sn');
|
||||
const go = document.getElementById('p3-iv2-go');
|
||||
const out = document.getElementById('p3-iv2-out');
|
||||
const fb = document.getElementById('p3-iv2-fb');
|
||||
let solved = 0;
|
||||
function sync(from){
|
||||
if(from==='range') inp.value = sl.value;
|
||||
else { const v = Math.max(0.01, Math.min(0.99, parseFloat(inp.value)||0.5)); sl.value = v; inp.value = v; }
|
||||
}
|
||||
function calc(){
|
||||
const sn = parseFloat(sl.value);
|
||||
if(isNaN(sn) || sn<=0 || sn>=1){ feedback(fb, false, '✗ $\\sin \\alpha$ должен быть в (0; 1).'); return; }
|
||||
const cs = Math.sqrt(1 - sn*sn);
|
||||
const tn = sn / cs;
|
||||
const ct = cs / sn;
|
||||
const aDeg = Math.asin(sn) * 180 / Math.PI;
|
||||
out.innerHTML = '$\\sin \\alpha = '+sn.toFixed(3)+'$ · <b>$\\cos \\alpha = \\sqrt{1 - \\sin^2 \\alpha} \\approx '+cs.toFixed(3)+'$</b><br>'
|
||||
+ '$\\tan \\alpha \\approx '+tn.toFixed(3)+'$ · $\\cot \\alpha \\approx '+ct.toFixed(3)+'$<br>'
|
||||
+ '<span style="color:var(--pri2);font-weight:700">$\\alpha \\approx '+aDeg.toFixed(2)+'^\\circ$</span>';
|
||||
renderMath(out);
|
||||
feedback(fb, true, '✓ Все значения вычислены через основное тождество.');
|
||||
solved++;
|
||||
if(solved === 1){ addXp(10,'p3-iv2'); bumpProgress('p3', 15); }
|
||||
}
|
||||
sl.addEventListener('input', ()=>{ sync('range'); calc(); });
|
||||
inp.addEventListener('input', ()=>{ sync('input'); });
|
||||
go.addEventListener('click', calc);
|
||||
calc();
|
||||
})();
|
||||
|
||||
/* IV3 — Какое значение? */
|
||||
(function(){
|
||||
const Q = [
|
||||
{ expr:'$\\sin 30^\\circ$', ans:'half', why:'эталон: $\\sin 30^\\circ = 1/2$' },
|
||||
{ expr:'$\\cos 60^\\circ$', ans:'half', why:'эталон: $\\cos 60^\\circ = 1/2$' },
|
||||
{ expr:'$\\sin 45^\\circ$', ans:'s2', why:'эталон: $\\sin 45^\\circ = \\sqrt{2}/2$' },
|
||||
{ expr:'$\\cos 45^\\circ$', ans:'s2', why:'эталон: $\\cos 45^\\circ = \\sqrt{2}/2$' },
|
||||
{ expr:'$\\sin 60^\\circ$', ans:'s3', why:'эталон: $\\sin 60^\\circ = \\sqrt{3}/2$' },
|
||||
{ expr:'$\\cos 30^\\circ$', ans:'s3', why:'эталон: $\\cos 30^\\circ = \\sqrt{3}/2$' },
|
||||
{ expr:'$\\sin^2 30^\\circ + \\cos^2 30^\\circ$', ans:'one', why:'основное тождество: $\\sin^2 + \\cos^2 = 1$' },
|
||||
{ expr:'$\\tan 45^\\circ$', ans:'one', why:'эталон: $\\tan 45^\\circ = 1$' },
|
||||
];
|
||||
let i = 0, score = 0;
|
||||
function show(){
|
||||
if(i >= Q.length){
|
||||
document.getElementById('p3-iv3-q').innerHTML = '<b>Готово!</b> Результат: ' + score + ' / ' + Q.length;
|
||||
if(score === Q.length){ addXp(15,'p3-iv3'); bumpProgress('p3', 25); }
|
||||
else if(score >= Q.length - 2){ addXp(8,'p3-iv3'); bumpProgress('p3', 15); }
|
||||
return;
|
||||
}
|
||||
document.getElementById('p3-iv3-i').textContent = (i+1);
|
||||
document.getElementById('p3-iv3-s').textContent = score;
|
||||
document.getElementById('p3-iv3-q').innerHTML = Q[i].expr;
|
||||
renderMath(document.getElementById('p3-iv3-q'));
|
||||
document.getElementById('p3-iv3-fb').style.display = 'none';
|
||||
}
|
||||
function answer(a){
|
||||
if(i >= Q.length) return;
|
||||
const fb = document.getElementById('p3-iv3-fb');
|
||||
if(a === Q[i].ans){ score++; feedback(fb, true, '✓ Верно! '+Q[i].why+'. Дальше ▶'); }
|
||||
else feedback(fb, false, '✗ Нет. '+Q[i].why+'. Дальше ▶');
|
||||
document.getElementById('p3-iv3-s').textContent = score;
|
||||
i++;
|
||||
setTimeout(show, 1100);
|
||||
}
|
||||
['half','s2','s3','one'].forEach(k=>{
|
||||
const b = document.getElementById('p3-iv3-'+k); if(b) b.addEventListener('click', ()=>answer(k));
|
||||
});
|
||||
show();
|
||||
})();
|
||||
|
||||
/* IV4 — Применение тождеств */
|
||||
(function(){
|
||||
const Q = [
|
||||
{ q:'Если $\\sin \\alpha = 0{,}6$ и $\\alpha$ — острый, найди $\\cos \\alpha$.', ans:0.8, tol:0.02, hint:'$\\cos \\alpha = \\sqrt{1 - 0{,}36} = \\sqrt{0{,}64} = 0{,}8$' },
|
||||
{ q:'$\\sin^2 70^\\circ + \\cos^2 70^\\circ = ?$', ans:1, tol:0.01, hint:'основное тождество' },
|
||||
{ q:'Если $\\cos \\alpha = 0{,}5$ и $\\alpha$ — острый, найди $\\sin \\alpha$.', ans:0.866, tol:0.01, hint:'$\\sin \\alpha = \\sqrt{1 - 0{,}25} = \\sqrt{0{,}75} = \\sqrt{3}/2 \\approx 0{,}866$' },
|
||||
{ q:'$\\tan 60^\\circ \\cdot \\cot 60^\\circ = ?$', ans:1, tol:0.01, hint:'$\\tan \\alpha \\cdot \\cot \\alpha = 1$' },
|
||||
{ q:'Если $\\tan \\alpha = 1$, то $\\alpha = ?$ (в градусах).', ans:45, tol:0.5, hint:'$\\tan 45^\\circ = 1$' },
|
||||
{ q:'$\\sin 30^\\circ + \\cos 60^\\circ = ?$', ans:1, tol:0.01, hint:'$\\tfrac{1}{2} + \\tfrac{1}{2} = 1$' },
|
||||
];
|
||||
let i = 0, score = 0;
|
||||
function show(){
|
||||
if(i >= Q.length){
|
||||
document.getElementById('p3-iv4-q').innerHTML = '<b>Готово!</b> Результат: ' + score + ' / ' + Q.length;
|
||||
if(score === Q.length){ addXp(15,'p3-iv4'); bumpProgress('p3', 25); }
|
||||
else if(score >= 4){ addXp(8,'p3-iv4'); bumpProgress('p3', 15); }
|
||||
return;
|
||||
}
|
||||
document.getElementById('p3-iv4-i').textContent = (i+1);
|
||||
document.getElementById('p3-iv4-s').textContent = score;
|
||||
document.getElementById('p3-iv4-q').innerHTML = Q[i].q;
|
||||
document.getElementById('p3-iv4-ans').value = '';
|
||||
renderMath(document.getElementById('p3-iv4-q'));
|
||||
document.getElementById('p3-iv4-fb').style.display = 'none';
|
||||
}
|
||||
function go(){
|
||||
if(i >= Q.length) return;
|
||||
const fb = document.getElementById('p3-iv4-fb');
|
||||
const ans = parseFloat(document.getElementById('p3-iv4-ans').value);
|
||||
if(isNaN(ans)){ feedback(fb, false, '✗ Введи число.'); return; }
|
||||
if(Math.abs(ans - Q[i].ans) <= Q[i].tol){ score++; feedback(fb, true, '✓ Верно! '+Q[i].hint+'. Дальше ▶'); }
|
||||
else feedback(fb, false, '✗ Неверно. Ответ: '+Q[i].ans+' ('+Q[i].hint+'). Дальше ▶');
|
||||
document.getElementById('p3-iv4-s').textContent = score;
|
||||
i++;
|
||||
setTimeout(show, 1400);
|
||||
}
|
||||
document.getElementById('p3-iv4-go').addEventListener('click', go);
|
||||
document.getElementById('p3-iv4-ans').addEventListener('keydown', e=>{ if(e.key==='Enter') go(); });
|
||||
document.getElementById('p3-iv4-start').addEventListener('click', ()=>{ i=0; score=0; show(); });
|
||||
show();
|
||||
})();
|
||||
|
||||
wireReadBtn('p3');
|
||||
}
|
||||
|
||||
/* ===== §4 sin, cos, tg, ctg тупого угла ===== */
|
||||
function buildP4(){
|
||||
const box = document.getElementById('p4-body');
|
||||
let html = '';
|
||||
|
||||
html += makeCard('theory', 'Единичная окружность', '4.1', `
|
||||
<p>Введём координатную плоскость. <b>Единичная окружность</b> — окружность радиуса $1$ с центром в начале координат $O$.</p>
|
||||
<p>Для острого угла $\\alpha$ отложим его от положительного направления оси $Ox$ <b>против часовой стрелки</b>. Точку пересечения подвижного луча с единичной окружностью обозначим $P$. Тогда:</p>
|
||||
<ul style="padding-left:22px;line-height:1.95">
|
||||
<li>$\\cos \\alpha$ — это $x$-координата точки $P$</li>
|
||||
<li>$\\sin \\alpha$ — это $y$-координата точки $P$</li>
|
||||
</ul>
|
||||
<p>Это <b>обобщение</b> старых определений: для острых углов оно совпадает с привычным «отношение катета к гипотенузе» (можно построить прямоугольный треугольник с гипотенузой $OP = 1$). Но теперь определение работает для <b>любого</b> угла от $0^\\circ$ до $180^\\circ$ — даже когда привычного прямоугольного треугольника нет.</p>
|
||||
<details class="spoiler"><summary>Почему именно так?</summary><div class="spoiler-body">
|
||||
Если $OP = 1$, то $\\cos \\alpha = \\dfrac{\\text{прилежащий катет}}{\\text{гипотенуза}} = \\dfrac{x_P}{1} = x_P$. Аналогично для синуса. Единичная окружность позволяет «продолжить» функции на углы $> 90^\\circ$.
|
||||
</div></details>`);
|
||||
|
||||
html += makeCard('rule', 'Тупой угол: знаки и формулы приведения', '4.2', `
|
||||
<p>Для тупого угла $\\alpha$ (где $90^\\circ < \\alpha < 180^\\circ$) точка $P$ оказывается во <b>второй четверти</b>: выше оси $Ox$ и левее оси $Oy$. Значит:</p>
|
||||
<ul style="padding-left:22px;line-height:1.95">
|
||||
<li>$\\sin \\alpha = y_P > 0$ — синус <b>положителен</b></li>
|
||||
<li>$\\cos \\alpha = x_P < 0$ — косинус <b>отрицателен</b></li>
|
||||
<li>$\\tan \\alpha = \\dfrac{\\sin \\alpha}{\\cos \\alpha} < 0$ — тангенс <b>отрицателен</b></li>
|
||||
<li>$\\cot \\alpha < 0$ — котангенс <b>отрицателен</b></li>
|
||||
</ul>
|
||||
<p><b>Формулы приведения</b> (главные для этого параграфа):</p>
|
||||
<p style="text-align:center;font-size:1.05rem">$\\boxed{\\,\\sin(180^\\circ - \\alpha) = \\sin \\alpha,\\qquad \\cos(180^\\circ - \\alpha) = -\\cos \\alpha\\,}$</p>
|
||||
<p>Здесь $\\alpha$ — острый угол, а $180^\\circ - \\alpha$ — соответствующий ему тупой. Идея проста: точки $P(\\alpha)$ и $P(180^\\circ - \\alpha)$ симметричны относительно оси $Oy$ — у них одинаковая $y$-координата (синус), но противоположные $x$-координаты (косинус).</p>`);
|
||||
|
||||
html += makeCard('example', 'Эталонные тупые углы', '4.3', `
|
||||
<p>Считаем через формулы приведения, сводя всё к острым углам $30^\\circ$, $45^\\circ$, $60^\\circ$:</p>
|
||||
<ul style="padding-left:22px;line-height:1.95">
|
||||
<li>$\\sin 120^\\circ = \\sin(180^\\circ - 60^\\circ) = \\sin 60^\\circ = \\dfrac{\\sqrt{3}}{2}$</li>
|
||||
<li>$\\cos 120^\\circ = -\\cos 60^\\circ = -\\dfrac{1}{2}$</li>
|
||||
<li>$\\sin 135^\\circ = \\sin 45^\\circ = \\dfrac{\\sqrt{2}}{2}$</li>
|
||||
<li>$\\cos 135^\\circ = -\\cos 45^\\circ = -\\dfrac{\\sqrt{2}}{2}$</li>
|
||||
<li>$\\sin 150^\\circ = \\sin 30^\\circ = \\dfrac{1}{2}$</li>
|
||||
<li>$\\cos 150^\\circ = -\\cos 30^\\circ = -\\dfrac{\\sqrt{3}}{2}$</li>
|
||||
</ul>
|
||||
<p><b>Граничные случаи:</b></p>
|
||||
<ul style="padding-left:22px;line-height:1.95">
|
||||
<li>$\\sin 90^\\circ = 1$, $\\cos 90^\\circ = 0$ (точка $P = (0, 1)$)</li>
|
||||
<li>$\\sin 180^\\circ = 0$, $\\cos 180^\\circ = -1$ (точка $P = (-1, 0)$)</li>
|
||||
<li>$\\sin 0^\\circ = 0$, $\\cos 0^\\circ = 1$ (точка $P = (1, 0)$)</li>
|
||||
</ul>`);
|
||||
|
||||
/* IV1 — Единичная окружность */
|
||||
html += `<div class="wg" id="p4-iv1">
|
||||
<div class="wg-header"><span class="wg-badge">ИНТЕРАКТИВ 1</span><div class="wg-title">Единичная окружность</div></div>
|
||||
<div class="wg-help">Двигай ползунок угла $\\alpha$ от $0^\\circ$ до $180^\\circ$. Смотри, как точка $P$ движется по окружности и как меняются $\\sin \\alpha$ (по $y$) и $\\cos \\alpha$ (по $x$). При $\\alpha > 90^\\circ$ — тупой угол, $\\cos \\alpha < 0$.</div>
|
||||
<div class="sliders">
|
||||
<label>Угол $\\alpha$, °<b id="p4-iv1-aval">60</b><input type="range" id="p4-iv1-a" min="0" max="180" step="1" value="60"></label>
|
||||
</div>
|
||||
<div style="background:var(--card);border-radius:10px;padding:10px;overflow-x:auto">
|
||||
<svg id="p4-iv1-svg" viewBox="0 0 400 400" style="width:100%;max-width:420px;min-width:300px;height:auto;display:block;margin:0 auto"></svg>
|
||||
</div>
|
||||
<div id="p4-iv1-out" style="margin-top:10px;padding:12px 14px;background:var(--pri-soft);border-radius:9px;font-size:.98rem;text-align:center;line-height:1.95"></div>
|
||||
<div id="p4-iv1-tag" style="margin-top:6px;text-align:center;font-weight:700"></div>
|
||||
</div>`;
|
||||
|
||||
/* IV2 — Формула приведения */
|
||||
html += `<div class="wg" id="p4-iv2">
|
||||
<div class="wg-header"><span class="wg-badge">ИНТЕРАКТИВ 2</span><div class="wg-title">Формула приведения</div></div>
|
||||
<div class="wg-help">Выбери тупой угол $\\alpha$ — увидишь, как формула приведения сводит $\\sin \\alpha$ и $\\cos \\alpha$ к острому углу $180^\\circ - \\alpha$.</div>
|
||||
<div style="display:flex;gap:10px;align-items:center;flex-wrap:wrap;justify-content:center;margin-bottom:10px">
|
||||
<span style="font-family:'JetBrains Mono',monospace">$\\alpha$ =</span>
|
||||
<select id="p4-iv2-a" class="tinp" style="width:110px;text-align:center">
|
||||
<option value="100">100°</option>
|
||||
<option value="120" selected>120°</option>
|
||||
<option value="135">135°</option>
|
||||
<option value="150">150°</option>
|
||||
<option value="170">170°</option>
|
||||
</select>
|
||||
<button class="btn primary" id="p4-iv2-go">Применить формулу</button>
|
||||
</div>
|
||||
<div id="p4-iv2-out" style="padding:12px 14px;background:var(--card);border-radius:9px;font-size:1rem;line-height:1.85;min-height:50px"></div>
|
||||
<div class="feedback" id="p4-iv2-fb"></div>
|
||||
</div>`;
|
||||
|
||||
/* IV3 — Знак значения */
|
||||
html += `<div class="wg" id="p4-iv3">
|
||||
<div class="wg-header"><span class="wg-badge">ИНТЕРАКТИВ 3</span><div class="wg-title">Знак значения</div></div>
|
||||
<div class="wg-help">Каким будет знак данного тригонометрического значения: положительным, отрицательным или равным нулю?</div>
|
||||
<div class="score-display"><span>Задача <b id="p4-iv3-i">1</b> / 8</span><span>Очки: <b id="p4-iv3-s">0</b> / 8</span></div>
|
||||
<div id="p4-iv3-q" style="padding:14px;background:var(--pri-soft);border-radius:10px;font-size:1.2rem;text-align:center;margin-bottom:10px"></div>
|
||||
<div style="display:grid;grid-template-columns:repeat(auto-fit,minmax(140px,1fr));gap:8px">
|
||||
<button class="btn primary" data-ans="pos" id="p4-iv3-pos">положит. (+)</button>
|
||||
<button class="btn primary" data-ans="neg" id="p4-iv3-neg">отрицат. (−)</button>
|
||||
<button class="btn primary" data-ans="zero" id="p4-iv3-zero">равно $0$</button>
|
||||
</div>
|
||||
<div class="feedback" id="p4-iv3-fb"></div>
|
||||
</div>`;
|
||||
|
||||
/* IV4 — Тренажёр тупого угла */
|
||||
html += `<div class="wg" id="p4-iv4">
|
||||
<div class="wg-header"><span class="wg-badge">ИНТЕРАКТИВ 4</span><div class="wg-title">Тренажёр тупого угла</div></div>
|
||||
<div class="wg-help">Реши задачу и введи число (целое или десятичная дробь до 3 знаков; не забудь знак для отрицательных значений).</div>
|
||||
<div class="score-display"><span>Задача <b id="p4-iv4-i">1</b> / 6</span><span>Очки: <b id="p4-iv4-s">0</b> / 6</span></div>
|
||||
<div id="p4-iv4-q" style="padding:14px;background:var(--pri-soft);border-radius:10px;font-size:1.05rem;margin-bottom:10px;text-align:center"></div>
|
||||
<div style="display:flex;gap:10px;align-items:center;flex-wrap:wrap;justify-content:center">
|
||||
<span style="font-family:'JetBrains Mono',monospace">ответ =</span>
|
||||
<input type="number" id="p4-iv4-ans" class="tinp" style="width:120px;text-align:center" step="0.001">
|
||||
<button class="btn primary" id="p4-iv4-go">Проверить</button>
|
||||
<button class="btn" id="p4-iv4-start">Заново</button>
|
||||
</div>
|
||||
<div class="feedback" id="p4-iv4-fb"></div>
|
||||
</div>`;
|
||||
|
||||
html += secNav('p3', 'p5');
|
||||
html += readButton('p4');
|
||||
|
||||
box.innerHTML = html;
|
||||
renderMath(box);
|
||||
|
||||
/* IV1 — Единичная окружность */
|
||||
(function(){
|
||||
const sl = document.getElementById('p4-iv1-a');
|
||||
const lab = document.getElementById('p4-iv1-aval');
|
||||
const svg = document.getElementById('p4-iv1-svg');
|
||||
const out = document.getElementById('p4-iv1-out');
|
||||
const tag = document.getElementById('p4-iv1-tag');
|
||||
const seen = new Set();
|
||||
const cx = 200, cy = 200, R = 150;
|
||||
function draw(){
|
||||
const aDeg = +sl.value;
|
||||
lab.textContent = aDeg;
|
||||
const aRad = deg2rad(aDeg);
|
||||
const Px = cx + R*Math.cos(aRad);
|
||||
const Py = cy - R*Math.sin(aRad); // y инвертирован
|
||||
let s = '';
|
||||
// Сетка
|
||||
s += '<rect x="0" y="0" width="400" height="400" fill="none"/>';
|
||||
// Координатные оси
|
||||
s += '<line x1="20" y1="'+cy+'" x2="380" y2="'+cy+'" stroke="#94a3b8" stroke-width="1"/>';
|
||||
s += '<line x1="'+cx+'" y1="20" x2="'+cx+'" y2="380" stroke="#94a3b8" stroke-width="1"/>';
|
||||
// Стрелки на осях
|
||||
s += '<polyline points="370,'+(cy-5)+' 380,'+cy+' 370,'+(cy+5)+'" fill="none" stroke="#94a3b8" stroke-width="1"/>';
|
||||
s += '<polyline points="'+(cx-5)+',30 '+cx+',20 '+(cx+5)+',30" fill="none" stroke="#94a3b8" stroke-width="1"/>';
|
||||
s += '<text x="384" y="'+(cy+14)+'" font-family="Inter,sans-serif" font-size="13" font-weight="700" fill="#64748b">x</text>';
|
||||
s += '<text x="'+(cx+8)+'" y="22" font-family="Inter,sans-serif" font-size="13" font-weight="700" fill="#64748b">y</text>';
|
||||
// Единичная окружность
|
||||
s += '<circle cx="'+cx+'" cy="'+cy+'" r="'+R+'" fill="none" stroke="#b45309" stroke-width="2"/>';
|
||||
// Отметки 1, -1
|
||||
s += '<line x1="'+(cx+R)+'" y1="'+(cy-3)+'" x2="'+(cx+R)+'" y2="'+(cy+3)+'" stroke="#64748b" stroke-width="1.5"/>';
|
||||
s += '<text x="'+(cx+R)+'" y="'+(cy+16)+'" text-anchor="middle" font-family="JetBrains Mono,monospace" font-size="11" fill="#64748b">1</text>';
|
||||
s += '<line x1="'+(cx-R)+'" y1="'+(cy-3)+'" x2="'+(cx-R)+'" y2="'+(cy+3)+'" stroke="#64748b" stroke-width="1.5"/>';
|
||||
s += '<text x="'+(cx-R)+'" y="'+(cy+16)+'" text-anchor="middle" font-family="JetBrains Mono,monospace" font-size="11" fill="#64748b">−1</text>';
|
||||
s += '<line x1="'+(cx-3)+'" y1="'+(cy-R)+'" x2="'+(cx+3)+'" y2="'+(cy-R)+'" stroke="#64748b" stroke-width="1.5"/>';
|
||||
s += '<text x="'+(cx-10)+'" y="'+(cy-R+4)+'" text-anchor="end" font-family="JetBrains Mono,monospace" font-size="11" fill="#64748b">1</text>';
|
||||
// Проекции — пунктиром
|
||||
s += '<line x1="'+Px+'" y1="'+Py+'" x2="'+Px+'" y2="'+cy+'" stroke="#10b981" stroke-width="2" stroke-dasharray="4 3"/>';
|
||||
s += '<line x1="'+Px+'" y1="'+Py+'" x2="'+cx+'" y2="'+Py+'" stroke="#0ea5e9" stroke-width="2" stroke-dasharray="4 3"/>';
|
||||
// Радиус OP
|
||||
s += '<line x1="'+cx+'" y1="'+cy+'" x2="'+Px+'" y2="'+Py+'" stroke="#2563eb" stroke-width="2.5"/>';
|
||||
// Дуга угла alpha
|
||||
if(aDeg > 0){
|
||||
const uOx = {x:1, y:0};
|
||||
const uOP = {x: Math.cos(aRad), y: -Math.sin(aRad)};
|
||||
s += '<path d="'+angleArcAuto({x:cx,y:cy}, uOx, uOP, 36)+'" fill="none" stroke="#dc2626" stroke-width="2.2"/>';
|
||||
// Подпись α
|
||||
const aHalf = aRad/2;
|
||||
const tx = cx + 54*Math.cos(aHalf);
|
||||
const ty = cy - 54*Math.sin(aHalf);
|
||||
s += '<text x="'+tx+'" y="'+ty+'" text-anchor="middle" dominant-baseline="middle" font-family="Inter,sans-serif" font-size="14" font-weight="700" fill="#dc2626">α</text>';
|
||||
}
|
||||
// Точка P
|
||||
s += '<circle cx="'+Px+'" cy="'+Py+'" r="5.5" fill="#dc2626" stroke="#fff" stroke-width="2"/>';
|
||||
s += '<text x="'+(Px + (Math.cos(aRad)>=0?10:-10))+'" y="'+(Py - 10)+'" text-anchor="'+(Math.cos(aRad)>=0?'start':'end')+'" font-family="Inter,sans-serif" font-size="14" font-weight="800" fill="#dc2626">P</text>';
|
||||
// Подписи проекций
|
||||
s += '<text x="'+Px+'" y="'+(cy + (Math.sin(aRad)>=0?22:-12))+'" text-anchor="middle" font-family="JetBrains Mono,monospace" font-size="11" font-weight="700" fill="#0ea5e9">cos α</text>';
|
||||
s += '<text x="'+(cx + (Math.cos(aRad)>=0?-14:14))+'" y="'+Py+'" text-anchor="'+(Math.cos(aRad)>=0?'end':'start')+'" dominant-baseline="middle" font-family="JetBrains Mono,monospace" font-size="11" font-weight="700" fill="#10b981">sin α</text>';
|
||||
// Подпись радиуса
|
||||
s += '<text x="'+(cx + R*0.55*Math.cos(aRad) + (Math.sin(aRad)>=0?-12:12))+'" y="'+(cy - R*0.55*Math.sin(aRad) - 6)+'" text-anchor="middle" font-family="Inter,sans-serif" font-size="11" font-weight="700" fill="#2563eb">r=1</text>';
|
||||
svg.innerHTML = s;
|
||||
const sn = Math.sin(aRad), cs = Math.cos(aRad);
|
||||
const tn = (Math.abs(cs) < 1e-9) ? null : sn/cs;
|
||||
out.innerHTML = '$\\sin '+aDeg+'^\\circ \\approx '+sn.toFixed(3)+'$ · $\\cos '+aDeg+'^\\circ \\approx '+cs.toFixed(3)+'$<br>'
|
||||
+ (tn===null ? '$\\tan '+aDeg+'^\\circ$ — не определён' : '$\\tan '+aDeg+'^\\circ \\approx '+tn.toFixed(3)+'$');
|
||||
renderMath(out);
|
||||
if(aDeg > 90 && aDeg < 180){
|
||||
tag.innerHTML = '<span style="color:var(--pri2);background:var(--pri-soft);padding:5px 12px;border-radius:8px">⚠ Тупой угол! $\\cos \\alpha < 0$.</span>';
|
||||
renderMath(tag);
|
||||
} else if(aDeg === 90){
|
||||
tag.innerHTML = '<span style="color:#065f46;background:var(--ok-bg);padding:5px 12px;border-radius:8px">Прямой угол.</span>';
|
||||
} else if(aDeg === 180 || aDeg === 0){
|
||||
tag.innerHTML = '<span style="color:#7f1d1d;background:var(--fail-bg);padding:5px 12px;border-radius:8px">Развёрнутый/нулевой угол.</span>';
|
||||
} else {
|
||||
tag.innerHTML = '<span style="color:#065f46;background:var(--ok-bg);padding:5px 12px;border-radius:8px">Острый угол. Обе функции положительны.</span>';
|
||||
}
|
||||
seen.add(aDeg);
|
||||
if(seen.size >= 6 && !seen.has('done')){ addXp(10,'p4-iv1'); bumpProgress('p4', 15); seen.add('done'); }
|
||||
}
|
||||
sl.addEventListener('input', draw);
|
||||
draw();
|
||||
})();
|
||||
|
||||
/* IV2 — Формула приведения */
|
||||
(function(){
|
||||
const sel = document.getElementById('p4-iv2-a');
|
||||
const go = document.getElementById('p4-iv2-go');
|
||||
const out = document.getElementById('p4-iv2-out');
|
||||
const fb = document.getElementById('p4-iv2-fb');
|
||||
let solved = 0;
|
||||
function apply(){
|
||||
const aDeg = parseInt(sel.value, 10);
|
||||
const beta = 180 - aDeg;
|
||||
const r = deg2rad(aDeg);
|
||||
const sn = Math.sin(r), cs = Math.cos(r);
|
||||
out.innerHTML = '<b>Формула приведения для $\\alpha = '+aDeg+'^\\circ$:</b><br>'
|
||||
+ '$\\sin '+aDeg+'^\\circ = \\sin(180^\\circ - '+aDeg+'^\\circ) = \\sin '+beta+'^\\circ \\approx '+sn.toFixed(3)+'$<br>'
|
||||
+ '$\\cos '+aDeg+'^\\circ = -\\cos(180^\\circ - '+aDeg+'^\\circ) = -\\cos '+beta+'^\\circ \\approx '+cs.toFixed(3)+'$<br>'
|
||||
+ '<span style="color:var(--muted);font-size:.9rem">Заметь: синус сохранил знак, косинус — поменял.</span>';
|
||||
renderMath(out);
|
||||
feedback(fb, true, '✓ Сведено к острому углу '+beta+'°.');
|
||||
solved++;
|
||||
if(solved === 1){ addXp(10,'p4-iv2'); bumpProgress('p4', 15); }
|
||||
}
|
||||
go.addEventListener('click', apply);
|
||||
apply();
|
||||
})();
|
||||
|
||||
/* IV3 — Знак значения */
|
||||
(function(){
|
||||
const Q = [
|
||||
{ expr:'$\\sin 120^\\circ$', ans:'pos', why:'тупой угол: $\\sin > 0$' },
|
||||
{ expr:'$\\cos 120^\\circ$', ans:'neg', why:'тупой угол: $\\cos < 0$' },
|
||||
{ expr:'$\\sin 90^\\circ$', ans:'pos', why:'$\\sin 90^\\circ = 1 > 0$' },
|
||||
{ expr:'$\\cos 90^\\circ$', ans:'zero', why:'$\\cos 90^\\circ = 0$' },
|
||||
{ expr:'$\\sin 180^\\circ$', ans:'zero', why:'$\\sin 180^\\circ = 0$' },
|
||||
{ expr:'$\\cos 180^\\circ$', ans:'neg', why:'$\\cos 180^\\circ = -1 < 0$' },
|
||||
{ expr:'$\\sin 60^\\circ$', ans:'pos', why:'острый угол: $\\sin > 0$' },
|
||||
{ expr:'$\\cos 150^\\circ$', ans:'neg', why:'тупой угол: $\\cos < 0$' },
|
||||
];
|
||||
let i = 0, score = 0;
|
||||
function show(){
|
||||
if(i >= Q.length){
|
||||
document.getElementById('p4-iv3-q').innerHTML = '<b>Готово!</b> Результат: ' + score + ' / ' + Q.length;
|
||||
if(score === Q.length){ addXp(15,'p4-iv3'); bumpProgress('p4', 25); }
|
||||
else if(score >= Q.length - 2){ addXp(8,'p4-iv3'); bumpProgress('p4', 15); }
|
||||
return;
|
||||
}
|
||||
document.getElementById('p4-iv3-i').textContent = (i+1);
|
||||
document.getElementById('p4-iv3-s').textContent = score;
|
||||
document.getElementById('p4-iv3-q').innerHTML = Q[i].expr;
|
||||
renderMath(document.getElementById('p4-iv3-q'));
|
||||
document.getElementById('p4-iv3-fb').style.display = 'none';
|
||||
}
|
||||
function answer(a){
|
||||
if(i >= Q.length) return;
|
||||
const fb = document.getElementById('p4-iv3-fb');
|
||||
if(a === Q[i].ans){ score++; feedback(fb, true, '✓ Верно! '+Q[i].why+'. Дальше ▶'); }
|
||||
else feedback(fb, false, '✗ Нет. '+Q[i].why+'. Дальше ▶');
|
||||
document.getElementById('p4-iv3-s').textContent = score;
|
||||
i++;
|
||||
setTimeout(show, 1100);
|
||||
}
|
||||
['pos','neg','zero'].forEach(k=>{
|
||||
const b = document.getElementById('p4-iv3-'+k); if(b) b.addEventListener('click', ()=>answer(k));
|
||||
});
|
||||
show();
|
||||
})();
|
||||
|
||||
/* IV4 — Тренажёр тупого угла */
|
||||
(function(){
|
||||
const Q = [
|
||||
{ q:'$\\sin 120^\\circ = ?$', ans:0.866, tol:0.01, hint:'$\\sin 120^\\circ = \\sin 60^\\circ = \\sqrt{3}/2 \\approx 0{,}866$' },
|
||||
{ q:'$\\cos 120^\\circ = ?$', ans:-0.5, tol:0.02, hint:'$\\cos 120^\\circ = -\\cos 60^\\circ = -1/2$' },
|
||||
{ q:'$\\sin 150^\\circ = ?$', ans:0.5, tol:0.02, hint:'$\\sin 150^\\circ = \\sin 30^\\circ = 1/2$' },
|
||||
{ q:'$\\cos 150^\\circ = ?$', ans:-0.866, tol:0.01, hint:'$\\cos 150^\\circ = -\\cos 30^\\circ = -\\sqrt{3}/2$' },
|
||||
{ q:'$\\cos 90^\\circ = ?$', ans:0, tol:0.01, hint:'$\\cos 90^\\circ = 0$' },
|
||||
{ q:'$\\sin 180^\\circ + \\cos 180^\\circ = ?$', ans:-1, tol:0.02, hint:'$0 + (-1) = -1$' },
|
||||
];
|
||||
let i = 0, score = 0;
|
||||
function show(){
|
||||
if(i >= Q.length){
|
||||
document.getElementById('p4-iv4-q').innerHTML = '<b>Готово!</b> Результат: ' + score + ' / ' + Q.length;
|
||||
if(score === Q.length){ addXp(15,'p4-iv4'); bumpProgress('p4', 25); }
|
||||
else if(score >= 4){ addXp(8,'p4-iv4'); bumpProgress('p4', 15); }
|
||||
return;
|
||||
}
|
||||
document.getElementById('p4-iv4-i').textContent = (i+1);
|
||||
document.getElementById('p4-iv4-s').textContent = score;
|
||||
document.getElementById('p4-iv4-q').innerHTML = Q[i].q;
|
||||
document.getElementById('p4-iv4-ans').value = '';
|
||||
renderMath(document.getElementById('p4-iv4-q'));
|
||||
document.getElementById('p4-iv4-fb').style.display = 'none';
|
||||
}
|
||||
function go(){
|
||||
if(i >= Q.length) return;
|
||||
const fb = document.getElementById('p4-iv4-fb');
|
||||
const ans = parseFloat(document.getElementById('p4-iv4-ans').value);
|
||||
if(isNaN(ans)){ feedback(fb, false, '✗ Введи число.'); return; }
|
||||
if(Math.abs(ans - Q[i].ans) <= Q[i].tol){ score++; feedback(fb, true, '✓ Верно! '+Q[i].hint+'. Дальше ▶'); }
|
||||
else feedback(fb, false, '✗ Неверно. Ответ: '+Q[i].ans+' ('+Q[i].hint+'). Дальше ▶');
|
||||
document.getElementById('p4-iv4-s').textContent = score;
|
||||
i++;
|
||||
setTimeout(show, 1400);
|
||||
}
|
||||
document.getElementById('p4-iv4-go').addEventListener('click', go);
|
||||
document.getElementById('p4-iv4-ans').addEventListener('keydown', e=>{ if(e.key==='Enter') go(); });
|
||||
document.getElementById('p4-iv4-start').addEventListener('click', ()=>{ i=0; score=0; show(); });
|
||||
show();
|
||||
})();
|
||||
|
||||
wireReadBtn('p4');
|
||||
}
|
||||
function buildP5(){ _stubBuilder('p5', '§5', 'Формулы площади', 'p4', 'p6'); }
|
||||
function buildP6(){ _stubBuilder('p6', '§6', 'Среднее геометрическое', 'p5', 'final1'); }
|
||||
|
||||
|
||||
Reference in New Issue
Block a user