fix(geom8 ch2): §5 высота/доказательство + §8 прямые углы
§5 Draggable трапеция: - Высота теперь рисуется как вертикальная пунктирная линия В СЕРЕДИНЕ трапеции от верхнего основания до нижнего (с прямым углом у основания), а не уходит вертикально вверх от вершины A вне фигуры - Жёлтый drag-handle для h перенесён в вершину D (верх-лево) — тащишь её вертикально и высота меняется. Синий drag-handle для b остался в C. - Добавлены подписи всех вершин ABCD точками и Unbounded-буквами - Подсказки в углу SVG что какой цвет означает §5 Пошаговое доказательство: - Полностью переписана геометрия с КОРРЕКТНЫМ поворотом на 180° вокруг середины M боковой стороны BC (формула P'=2M-P) - Раньше копия трапеции уходила за пределы viewBox (y=-20) - Теперь 4 шага: трапеция → поворот вокруг M → параллелограмм ABD'A' → половина = трапеция, формула S=½(a+b)h §8 Прямые углы: - Card 8.1: треугольник A(20,150) B(220,150) C(92,54) — НАСТОЯЩИЙ прямоугольный 3-4-5 с h_c=ab/c (раньше координаты не давали 90° в C) - Card 8.2: оба треугольника теперь корректные прямоугольные с прямыми углами на правильных вершинах - Card 8.3: треугольник 6-8-10, маркер прямого угла в H пересчитан через единичные векторы H→C и H→A (раньше показывал не то направление) Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -2201,50 +2201,48 @@ function buildP5(){
|
||||
|
||||
/* == INIT: Draggable трапеция == */
|
||||
(function(){
|
||||
const W=400, H=260;
|
||||
const AX=40, AY=200, BW=220;
|
||||
let topB=100, topOff=40, trapH=110;
|
||||
const W=420, H=280;
|
||||
const AX=50, AY=220, BW=300;
|
||||
let topB=140, topOff=80, trapH=130;
|
||||
function draw(){
|
||||
const ax=AX, ay=AY, bx=ax+BW, by=ay;
|
||||
const dx=ax+topOff, dy=ay-trapH, cx=dx+topB, cy=dy;
|
||||
const midX=(dx+cx)/2, midY=dy;
|
||||
const Sval=Math.round((BW+topB)/2*trapH);
|
||||
let s='<svg id="p5-trap-svg" viewBox="0 0 '+W+' '+H+'" style="width:100%;max-width:420px;background:var(--card);border:1px solid var(--border);border-radius:14px;touch-action:none">';
|
||||
// height dashes
|
||||
s+='<line x1="'+ax+'" y1="'+ay+'" x2="'+ax+'" y2="'+dy+'" stroke="#f59e0b" stroke-width="1.5" stroke-dasharray="5 3"/>';
|
||||
s+='<text x="'+(ax-14)+'" y="'+((ay+dy)/2)+'" text-anchor="middle" dominant-baseline="middle" font-size="12" font-weight="700" fill="#b45309" font-family="JetBrains Mono,monospace">h</text>';
|
||||
// right angle
|
||||
s+='<polyline points="'+(ax+8)+','+ay+' '+(ax+8)+','+(ay-8)+' '+ax+','+(ay-8)+'" fill="none" stroke="#f59e0b" stroke-width="1.5"/>';
|
||||
// trapezoid fill
|
||||
const footX=Math.round((dx+cx)/2);
|
||||
const Sval=Math.round((BW+topB)/2*trapH/10);
|
||||
let s='<svg id="p5-trap-svg" viewBox="0 0 '+W+' '+H+'" style="width:100%;max-width:440px;background:var(--card);border:1px solid var(--border);border-radius:14px;touch-action:none">';
|
||||
s+='<polygon points="'+ax+','+ay+' '+bx+','+by+' '+cx+','+cy+' '+dx+','+dy+'" fill="rgba(2,132,199,.13)" stroke="#0284c7" stroke-width="2.5" stroke-linejoin="round"/>';
|
||||
// base a label
|
||||
s+='<text x="'+((ax+bx)/2)+'" y="'+(ay+18)+'" text-anchor="middle" font-size="12" font-weight="700" fill="#0369a1" font-family="JetBrains Mono,monospace">a='+BW+'</text>';
|
||||
// top b label
|
||||
s+='<text x="'+midX+'" y="'+(cy-8)+'" text-anchor="middle" font-size="12" font-weight="700" fill="#0369a1" font-family="JetBrains Mono,monospace">b='+topB+'</text>';
|
||||
// S label
|
||||
const cxLabel=Math.round((ax+bx+cx+dx)/4), cyLabel=Math.round((ay+ay+cy+dy)/4);
|
||||
s+='<text x="'+cxLabel+'" y="'+cyLabel+'" text-anchor="middle" dominant-baseline="middle" font-size="13" font-weight="700" fill="#0369a1" font-family="Unbounded,sans-serif">S='+Sval+'</text>';
|
||||
// drag handles
|
||||
const hTop=cx, hTopY=cy;
|
||||
s+='<circle cx="'+hTop+'" cy="'+hTopY+'" r="12" fill="rgba(2,132,199,.18)"/>';
|
||||
s+='<circle cx="'+hTop+'" cy="'+hTopY+'" r="7" fill="#0284c7" stroke="#fff" stroke-width="2" id="p5-drag-top" style="cursor:ew-resize"/>';
|
||||
const hH=ax, hHY=Math.round(ay-trapH/2);
|
||||
s+='<circle cx="'+hH+'" cy="'+hHY+'" r="12" fill="rgba(245,158,11,.18)"/>';
|
||||
s+='<circle cx="'+hH+'" cy="'+hHY+'" r="7" fill="#f59e0b" stroke="#fff" stroke-width="2" id="p5-drag-h" style="cursor:ns-resize"/>';
|
||||
s+='<line x1="'+footX+'" y1="'+dy+'" x2="'+footX+'" y2="'+ay+'" stroke="#dc2626" stroke-width="2" stroke-dasharray="5 3"/>';
|
||||
s+='<polyline points="'+(footX+9)+','+ay+' '+(footX+9)+','+(ay-9)+' '+footX+','+(ay-9)+'" fill="none" stroke="#dc2626" stroke-width="1.5"/>';
|
||||
s+='<circle cx="'+footX+'" cy="'+ay+'" r="2.5" fill="#dc2626"/>';
|
||||
['A','B','C','D'].forEach((lbl,i)=>{
|
||||
const pt=[[ax,ay],[bx,by],[cx,cy],[dx,dy]][i];
|
||||
s+='<circle cx="'+pt[0]+'" cy="'+pt[1]+'" r="3" fill="#0284c7"/>';
|
||||
const off=[[ -10,14],[10,14],[10,-6],[-10,-6]][i];
|
||||
s+='<text x="'+(pt[0]+off[0])+'" y="'+(pt[1]+off[1])+'" font-size="12" font-weight="800" fill="#0369a1" font-family="Unbounded,sans-serif">'+lbl+'</text>';
|
||||
});
|
||||
s+='<text x="'+((ax+bx)/2)+'" y="'+(ay+28)+'" text-anchor="middle" font-size="13" font-weight="700" fill="#047857" font-family="JetBrains Mono,monospace">a = '+BW+'</text>';
|
||||
s+='<text x="'+((dx+cx)/2)+'" y="'+(dy-16)+'" text-anchor="middle" font-size="13" font-weight="700" fill="#047857" font-family="JetBrains Mono,monospace">b = '+topB+'</text>';
|
||||
s+='<text x="'+(footX+12)+'" y="'+((ay+dy)/2)+'" dominant-baseline="middle" font-size="14" font-weight="800" fill="#b91c1c" font-family="JetBrains Mono,monospace">h = '+trapH+'</text>';
|
||||
s+='<text x="'+(W-12)+'" y="22" text-anchor="end" font-size="14" font-weight="800" fill="#0369a1" font-family="Unbounded,sans-serif">S = '+Sval+' усл.</text>';
|
||||
s+='<circle cx="'+cx+'" cy="'+cy+'" r="13" fill="rgba(2,132,199,.18)"/>';
|
||||
s+='<circle cx="'+cx+'" cy="'+cy+'" r="8" fill="#0284c7" stroke="#fff" stroke-width="2" id="p5-drag-top" style="cursor:ew-resize"/>';
|
||||
s+='<circle cx="'+dx+'" cy="'+dy+'" r="13" fill="rgba(245,158,11,.18)"/>';
|
||||
s+='<circle cx="'+dx+'" cy="'+dy+'" r="8" fill="#f59e0b" stroke="#fff" stroke-width="2" id="p5-drag-h" style="cursor:ns-resize"/>';
|
||||
s+='<text x="14" y="22" font-size="11" font-weight="700" fill="#0284c7" font-family="Inter,sans-serif">синий: тащи b</text>';
|
||||
s+='<text x="14" y="38" font-size="11" font-weight="700" fill="#f59e0b" font-family="Inter,sans-serif">жёлтый: тащи h</text>';
|
||||
s+='</svg>';
|
||||
document.getElementById('p5-trap-svg-wrap').innerHTML=s;
|
||||
document.getElementById('p5-trap-info').innerHTML=`
|
||||
<div style="padding:8px 12px;background:var(--card);border-radius:8px;border:1px solid var(--border);font-size:.88rem"><div style="color:var(--muted);font-size:.72rem;font-weight:700;text-transform:uppercase;margin-bottom:4px">Основание a</div><b>${BW}</b></div>
|
||||
<div style="padding:8px 12px;background:var(--card);border-radius:8px;border:1px solid var(--border);font-size:.88rem"><div style="color:var(--muted);font-size:.72rem;font-weight:700;text-transform:uppercase;margin-bottom:4px">Основание b</div><b>${topB}</b></div>
|
||||
<div style="padding:8px 12px;background:var(--card);border-radius:8px;border:1px solid var(--border);font-size:.88rem"><div style="color:var(--muted);font-size:.72rem;font-weight:700;text-transform:uppercase;margin-bottom:4px">Высота h</div><b>${trapH}</b></div>
|
||||
<div style="padding:8px 12px;background:var(--card);border-radius:8px;border:1px solid var(--border);font-size:.88rem"><div style="color:var(--muted);font-size:.72rem;font-weight:700;text-transform:uppercase;margin-bottom:4px">S = (a+b)/2·h</div><b style="color:#0369a1">${Sval}</b></div>`;
|
||||
<div style="padding:8px 12px;background:var(--card);border-radius:8px;border:1px solid var(--border);font-size:.88rem"><div style="color:var(--muted);font-size:.72rem;font-weight:700;text-transform:uppercase;margin-bottom:4px">S = (a+b)·h/2</div><b style="color:#0369a1">${Sval}</b></div>`;
|
||||
const handleTop=document.getElementById('p5-drag-top');
|
||||
if(handleTop){
|
||||
handleTop.addEventListener('pointerdown',ev=>{
|
||||
const startX=ev.clientX, startB=topB;
|
||||
function onMove(e){
|
||||
const svgEl=document.getElementById('p5-trap-svg');
|
||||
if(!svgEl) return;
|
||||
const svgEl=document.getElementById('p5-trap-svg'); if(!svgEl) return;
|
||||
const rect=svgEl.getBoundingClientRect();
|
||||
const scale=W/rect.width;
|
||||
const delta=Math.round((e.clientX-startX)*scale);
|
||||
@@ -2262,12 +2260,11 @@ function buildP5(){
|
||||
handleH.addEventListener('pointerdown',ev=>{
|
||||
const startY=ev.clientY, startH=trapH;
|
||||
function onMove(e){
|
||||
const svgEl=document.getElementById('p5-trap-svg');
|
||||
if(!svgEl) return;
|
||||
const svgEl=document.getElementById('p5-trap-svg'); if(!svgEl) return;
|
||||
const rect=svgEl.getBoundingClientRect();
|
||||
const scale=H/rect.height;
|
||||
const delta=Math.round((startY-e.clientY)*scale);
|
||||
trapH=Math.max(40,Math.min(160,startH+delta));
|
||||
trapH=Math.max(50,Math.min(180,startH+delta));
|
||||
draw();
|
||||
}
|
||||
function onUp(){window.removeEventListener('pointermove',onMove);window.removeEventListener('pointerup',onUp);window.removeEventListener('pointercancel',onUp);}
|
||||
@@ -2283,51 +2280,84 @@ function buildP5(){
|
||||
/* == INIT: Доказательство пошаговое == */
|
||||
(function(){
|
||||
let step=0;
|
||||
const W=400, H=220;
|
||||
const ax=30, ay=180, bw=200, h=100, off=50;
|
||||
const W=460, H=240;
|
||||
/* Trapezoid ABCD: A,B bottom; C,D top. a=AB (bottom), b=DC (top).
|
||||
Origin trapezoid: A(50,200), B(50+a,200), C(50+ofL+b,200-h), D(50+ofL,200-h). */
|
||||
const a=170, b=110, h=110, ofL=40, ofR=20;
|
||||
const Ax=50, Ay=200;
|
||||
const Bx=Ax+a, By=Ay;
|
||||
const Dx=Ax+ofL, Dy=Ay-h;
|
||||
const Cx=Dx+b, Cy=Dy;
|
||||
/* Mid of right slanted side BC */
|
||||
const Mx=(Bx+Cx)/2, My=(By+Cy)/2;
|
||||
/* Rotate 180° around M: P -> (2M-P) */
|
||||
const r=(p)=>({x:2*Mx-p.x, y:2*My-p.y});
|
||||
/* Rotated copy: A'=r(A), B'=r(B)=C, C'=r(C)=B, D'=r(D) */
|
||||
const Ap=r({x:Ax,y:Ay}), Dp=r({x:Dx,y:Dy});
|
||||
/* The combined parallelogram: A B D' A' D (going around).
|
||||
Actually after rotation:
|
||||
original sides: A→B→C→D→A
|
||||
rotated copy sides: B→D'→A'→C(=B')→B
|
||||
The union has outer boundary: A→B→D'→A'→D→A
|
||||
which is a parallelogram with sides AB+BD'=(a+b) on bottom, A'D+DA on slants. */
|
||||
const heightFootX=Math.round((Dx+Cx)/2);
|
||||
function vertexDots(pts){
|
||||
return pts.map(p=>`<circle cx="${p.x}" cy="${p.y}" r="3.2" fill="#0284c7"/>`).join('');
|
||||
}
|
||||
function vertexLabels(items){
|
||||
return items.map(([lbl,p,dx,dy,col])=>`<text x="${p.x+dx}" y="${p.y+dy}" font-size="12" font-weight="800" fill="${col||'#0369a1'}" font-family="Unbounded,sans-serif">${lbl}</text>`).join('');
|
||||
}
|
||||
const steps=[
|
||||
{desc:'Исходная трапеция ABCD. Основания: $a=AB$ (нижнее) и $b=CD$ (верхнее), высота $h$.',
|
||||
{desc:'Исходная трапеция $ABCD$: основания $a=AB$ (нижнее) и $b=DC$ (верхнее), высота $h$ — расстояние между основаниями.',
|
||||
draw(){
|
||||
const bx=ax+bw, dx=ax+off, cx=dx+Math.round(bw*0.55);
|
||||
const dy=ay-h, cy=dy;
|
||||
return '<polygon points="'+ax+','+ay+' '+bx+','+ay+' '+cx+','+cy+' '+dx+','+dy+'" fill="rgba(2,132,199,.15)" stroke="#0284c7" stroke-width="2.2"/>'
|
||||
+'<line x1="'+ax+'" y1="'+ay+'" x2="'+ax+'" y2="'+dy+'" stroke="#f59e0b" stroke-width="1.5" stroke-dasharray="4 3"/>'
|
||||
+'<text x="'+((ax+bx)/2)+'" y="'+(ay+16)+'" text-anchor="middle" font-size="12" font-weight="700" fill="#0369a1" font-family="JetBrains Mono,monospace">a</text>'
|
||||
+'<text x="'+((dx+cx)/2)+'" y="'+(dy-6)+'" text-anchor="middle" font-size="12" font-weight="700" fill="#0369a1" font-family="JetBrains Mono,monospace">b</text>'
|
||||
+'<text x="'+(ax-14)+'" y="'+((ay+dy)/2)+'" text-anchor="middle" font-size="12" font-weight="700" fill="#b45309" font-family="JetBrains Mono,monospace">h</text>'
|
||||
+'<text x="'+ax+'" y="'+(ay+14)+'" font-size="11" fill="#0369a1" font-weight="700">A</text>'
|
||||
+'<text x="'+bx+'" y="'+(ay+14)+'" font-size="11" fill="#0369a1" font-weight="700">B</text>'
|
||||
+'<text x="'+(cx+4)+'" y="'+(cy-4)+'" font-size="11" fill="#0369a1" font-weight="700">C</text>'
|
||||
+'<text x="'+(dx-14)+'" y="'+(dy-4)+'" font-size="11" fill="#0369a1" font-weight="700">D</text>';
|
||||
let s='';
|
||||
s+=`<polygon points="${Ax},${Ay} ${Bx},${By} ${Cx},${Cy} ${Dx},${Dy}" fill="rgba(2,132,199,.16)" stroke="#0284c7" stroke-width="2.2"/>`;
|
||||
s+=`<line x1="${heightFootX}" y1="${Dy}" x2="${heightFootX}" y2="${Ay}" stroke="#dc2626" stroke-width="1.8" stroke-dasharray="5 3"/>`;
|
||||
s+=`<polyline points="${heightFootX+8},${Ay} ${heightFootX+8},${Ay-8} ${heightFootX},${Ay-8}" fill="none" stroke="#dc2626" stroke-width="1.4"/>`;
|
||||
s+=`<text x="${heightFootX+11}" y="${(Ay+Dy)/2}" dominant-baseline="middle" font-size="13" font-weight="800" fill="#b91c1c" font-family="JetBrains Mono,monospace">h</text>`;
|
||||
s+=`<text x="${(Ax+Bx)/2}" y="${Ay+22}" text-anchor="middle" font-size="13" font-weight="700" fill="#047857" font-family="JetBrains Mono,monospace">a</text>`;
|
||||
s+=`<text x="${(Dx+Cx)/2}" y="${Dy-9}" text-anchor="middle" font-size="13" font-weight="700" fill="#047857" font-family="JetBrains Mono,monospace">b</text>`;
|
||||
s+=vertexDots([{x:Ax,y:Ay},{x:Bx,y:By},{x:Cx,y:Cy},{x:Dx,y:Dy}]);
|
||||
s+=vertexLabels([['A',{x:Ax,y:Ay},-12,14],['B',{x:Bx,y:By},6,14],['C',{x:Cx,y:Cy},6,-4],['D',{x:Dx,y:Dy},-12,-4]]);
|
||||
return s;
|
||||
}},
|
||||
{desc:'Повернём копию трапеции на 180° и приложим сверху-справа так, чтобы стороны CD совпали.',
|
||||
{desc:'Найдём середину $M$ боковой стороны $BC$. Повернём трапецию $ABCD$ на $180°$ вокруг точки $M$ — получим копию $A\'BCD\'$ (фиолетовая).',
|
||||
draw(){
|
||||
const bx=ax+bw, dx=ax+off, cx=dx+Math.round(bw*0.55);
|
||||
const dy=ay-h, cy=dy;
|
||||
const bw2=Math.round(bw*0.55);
|
||||
const ax2=cx, ay2=cy, bx2=cx+bw, by2=cy, cx2=cx+bw-off, cy2=cy-h, dx2=cx, dy2=cy-h;
|
||||
return '<polygon points="'+ax+','+ay+' '+bx+','+ay+' '+cx+','+cy+' '+dx+','+dy+'" fill="rgba(2,132,199,.18)" stroke="#0284c7" stroke-width="2"/>'
|
||||
+'<polygon points="'+ax2+','+ay2+' '+bx2+','+by2+' '+cx2+','+cy2+' '+dx2+','+dy2+'" fill="rgba(124,58,237,.18)" stroke="#7c3aed" stroke-width="2" stroke-dasharray="6 3"/>'
|
||||
+'<text x="'+((ax+bx)/2)+'" y="'+(ay+16)+'" text-anchor="middle" font-size="11" fill="#0369a1" font-weight="700">a</text>'
|
||||
+'<text x="'+((ax2+bx2)/2)+'" y="'+(ay2+14)+'" text-anchor="middle" font-size="11" fill="#6d28d9" font-weight="700">копия (перевёрнута)</text>';
|
||||
let s='';
|
||||
s+=`<polygon points="${Ax},${Ay} ${Bx},${By} ${Cx},${Cy} ${Dx},${Dy}" fill="rgba(2,132,199,.18)" stroke="#0284c7" stroke-width="2"/>`;
|
||||
s+=`<polygon points="${Ap.x},${Ap.y} ${Cx},${Cy} ${Bx},${By} ${Dp.x},${Dp.y}" fill="rgba(124,58,237,.16)" stroke="#7c3aed" stroke-width="2" stroke-dasharray="5 3"/>`;
|
||||
s+=`<circle cx="${Mx}" cy="${My}" r="5" fill="#f59e0b" stroke="#fff" stroke-width="1.5"/>`;
|
||||
s+=`<text x="${Mx+10}" y="${My-6}" font-size="13" font-weight="800" fill="#b45309" font-family="Unbounded,sans-serif">M</text>`;
|
||||
s+=vertexDots([{x:Ax,y:Ay},{x:Bx,y:By},{x:Cx,y:Cy},{x:Dx,y:Dy},Ap,Dp]);
|
||||
s+=vertexLabels([
|
||||
['A',{x:Ax,y:Ay},-12,14],['B',{x:Bx,y:By},4,14],
|
||||
['C',{x:Cx,y:Cy},-8,16],['D',{x:Dx,y:Dy},-12,-4],
|
||||
["D'",Dp,4,16,'#6d28d9'],["A'",Ap,6,-4,'#6d28d9']
|
||||
]);
|
||||
return s;
|
||||
}},
|
||||
{desc:'Две трапеции образуют параллелограмм! Его основание $a+b$, высота $h$.',
|
||||
{desc:'Объединение двух трапеций — параллелограмм $ABD\'A\'$ со сторонами $AB+BD\' = a+b$ (внизу) и высотой $h$.',
|
||||
draw(){
|
||||
const bx=ax+bw, dx=ax+off, cx=dx+Math.round(bw*0.55);
|
||||
const dy=ay-h, cy=dy;
|
||||
const fullW=bw+Math.round(bw*0.55);
|
||||
return '<polygon points="'+ax+','+ay+' '+(ax+fullW)+','+ay+' '+(ax+fullW-off)+','+(ay-h)+' '+(ax+off)+','+(ay-h)+'" fill="rgba(5,150,105,.18)" stroke="#059669" stroke-width="2.5"/>'
|
||||
+'<text x="'+((ax+ax+fullW)/2)+'" y="'+(ay+16)+'" text-anchor="middle" font-size="12" font-weight="700" fill="#047857" font-family="JetBrains Mono,monospace">a+b</text>'
|
||||
+'<text x="'+(ax-14)+'" y="'+((ay+ay-h)/2)+'" text-anchor="middle" font-size="12" font-weight="700" fill="#b45309" font-family="JetBrains Mono,monospace">h</text>'
|
||||
+'<text x="'+((ax*2+fullW)/2)+'" y="'+((ay+ay-h)/2)+'" text-anchor="middle" dominant-baseline="middle" font-size="13" font-weight="700" fill="#047857" font-family="Unbounded,sans-serif">паралл.</text>';
|
||||
let s='';
|
||||
s+=`<polygon points="${Ax},${Ay} ${Bx},${By} ${Dp.x},${Dp.y} ${Ap.x},${Ap.y}" fill="rgba(5,150,105,.22)" stroke="#059669" stroke-width="2.5"/>`;
|
||||
s+=`<line x1="${Bx}" y1="${By}" x2="${Cx}" y2="${Cy}" stroke="#0284c7" stroke-width="1.5" stroke-dasharray="4 3" opacity=".6"/>`;
|
||||
s+=`<line x1="${heightFootX}" y1="${Dy}" x2="${heightFootX}" y2="${Ay}" stroke="#dc2626" stroke-width="1.8" stroke-dasharray="5 3"/>`;
|
||||
s+=`<polyline points="${heightFootX+8},${Ay} ${heightFootX+8},${Ay-8} ${heightFootX},${Ay-8}" fill="none" stroke="#dc2626" stroke-width="1.4"/>`;
|
||||
s+=`<text x="${heightFootX+11}" y="${(Ay+Dy)/2}" dominant-baseline="middle" font-size="13" font-weight="800" fill="#b91c1c" font-family="JetBrains Mono,monospace">h</text>`;
|
||||
s+=`<text x="${(Ax+Dp.x)/2}" y="${Ay+22}" text-anchor="middle" font-size="14" font-weight="800" fill="#047857" font-family="JetBrains Mono,monospace">a + b</text>`;
|
||||
s+=vertexDots([{x:Ax,y:Ay},{x:Bx,y:By},Dp,Ap]);
|
||||
s+=vertexLabels([['A',{x:Ax,y:Ay},-12,14],['B',{x:Bx,y:By},-4,16],["D'",Dp,4,16,'#047857'],["A'",Ap,6,-4,'#047857']]);
|
||||
return s;
|
||||
}},
|
||||
{desc:'Площадь параллелограмма $S_{\\text{пар}}=(a+b)\\cdot h$. Трапеция — его <b>половина</b>, значит $S=\\dfrac{(a+b)}{2}\\cdot h$.',
|
||||
{desc:'$S_{\\text{пар}} = (a+b)\\cdot h$. Трапеция — ровно <b>половина</b> параллелограмма, поэтому $S_{\\text{трап}} = \\dfrac{a+b}{2}\\cdot h$.',
|
||||
draw(){
|
||||
const fullW=bw+Math.round(bw*0.55);
|
||||
return '<polygon points="'+ax+','+ay+' '+(ax+fullW)+','+ay+' '+(ax+fullW-off)+','+(ay-h)+' '+(ax+off)+','+(ay-h)+'" fill="rgba(5,150,105,.12)" stroke="#059669" stroke-width="2"/>'
|
||||
+'<polygon points="'+ax+','+ay+' '+(ax+bw)+','+ay+' '+(ax+Math.round(bw*0.55)+off)+','+(ay-h)+' '+(ax+off)+','+(ay-h)+'" fill="rgba(2,132,199,.28)" stroke="#0284c7" stroke-width="2.5"/>'
|
||||
+'<line x1="'+(ax+bw)+'" y1="'+ay+'" x2="'+(ax+Math.round(bw*0.55)+off)+'" y2="'+(ay-h)+'" stroke="#0284c7" stroke-width="2" stroke-dasharray="5 3"/>'
|
||||
+'<text x="'+((ax*2+bw)/2)+'" y="'+((ay+ay-h)/2)+'" text-anchor="middle" dominant-baseline="middle" font-size="13" font-weight="800" fill="#0369a1" font-family="Unbounded,sans-serif">S=½(a+b)h</text>';
|
||||
let s='';
|
||||
s+=`<polygon points="${Ax},${Ay} ${Bx},${By} ${Dp.x},${Dp.y} ${Ap.x},${Ap.y}" fill="rgba(5,150,105,.10)" stroke="#059669" stroke-width="1.5" stroke-dasharray="6 4"/>`;
|
||||
s+=`<polygon points="${Ax},${Ay} ${Bx},${By} ${Cx},${Cy} ${Dx},${Dy}" fill="rgba(2,132,199,.32)" stroke="#0284c7" stroke-width="2.5"/>`;
|
||||
s+=`<line x1="${Bx}" y1="${By}" x2="${Cx}" y2="${Cy}" stroke="#7c3aed" stroke-width="2"/>`;
|
||||
s+=`<text x="${(Ax+Dp.x)/2}" y="${(Ay+Dy)/2}" text-anchor="middle" dominant-baseline="middle" font-size="15" font-weight="800" fill="#0369a1" font-family="Unbounded,sans-serif">S = ½(a+b)·h</text>`;
|
||||
s+=vertexDots([{x:Ax,y:Ay},{x:Bx,y:By},{x:Cx,y:Cy},{x:Dx,y:Dy}]);
|
||||
return s;
|
||||
}},
|
||||
];
|
||||
function render(){
|
||||
@@ -3425,30 +3455,34 @@ function buildP8(){
|
||||
</ul>
|
||||
<div style="display:flex;justify-content:center;margin-top:14px">
|
||||
<svg viewBox="0 0 280 170" style="max-width:300px;background:#fafafa;border:1px solid var(--border);border-radius:10px">
|
||||
<!-- main right triangle A(20,150) B(260,150) C(80,40) -->
|
||||
<polygon points="20,150 260,150 80,40" fill="rgba(5,150,105,.12)" stroke="#059669" stroke-width="2.5"/>
|
||||
<!-- right angle at C -->
|
||||
<polyline points="90,40 90,50 80,50" fill="none" stroke="#059669" stroke-width="1.5"/>
|
||||
<!-- foot of altitude H on AB: project C onto AB -->
|
||||
<!-- AB horizontal y=150, foot is (80,150) -->
|
||||
<line x1="80" y1="40" x2="80" y2="150" stroke="#f59e0b" stroke-width="2" stroke-dasharray="5 3"/>
|
||||
<!-- right angle at H -->
|
||||
<polyline points="80,140 90,140 90,150" fill="none" stroke="#f59e0b" stroke-width="1.5"/>
|
||||
<!-- sub-triangle 1: A,H,C -->
|
||||
<polygon points="20,150 80,150 80,40" fill="rgba(2,132,199,.18)" stroke="#0284c7" stroke-width="1.2"/>
|
||||
<!-- sub-triangle 2: H,B,C -->
|
||||
<polygon points="80,150 260,150 80,40" fill="rgba(124,58,237,.18)" stroke="#7c3aed" stroke-width="1.2"/>
|
||||
<!-- Right triangle 3-4-5 scaled: A(20,150) B(220,150) C(92,54); legs 120 and 160; hyp 200; h_c=96; foot H(92,150) -->
|
||||
<polygon points="20,150 92,54 92,150" fill="rgba(2,132,199,.20)" stroke="#0284c7" stroke-width="1.5"/>
|
||||
<polygon points="92,150 220,150 92,54" fill="rgba(124,58,237,.20)" stroke="#7c3aed" stroke-width="1.5"/>
|
||||
<polygon points="20,150 220,150 92,54" fill="none" stroke="#059669" stroke-width="2.5"/>
|
||||
<!-- altitude C->H -->
|
||||
<line x1="92" y1="54" x2="92" y2="150" stroke="#dc2626" stroke-width="2" stroke-dasharray="5 3"/>
|
||||
<!-- right angle at C: between CA(down-left) and CB(down-right) -->
|
||||
<polyline points="83,62 88,69 96,63" fill="none" stroke="#059669" stroke-width="1.5"/>
|
||||
<!-- right angle at H (between altitude and hypotenuse, inside left sub-triangle) -->
|
||||
<polyline points="82,141 82,150 92,150" fill="none" stroke="#dc2626" stroke-width="1.5"/>
|
||||
<polyline points="82,141 92,141" fill="none" stroke="#dc2626" stroke-width="1.5"/>
|
||||
<!-- vertex dots -->
|
||||
<circle cx="20" cy="150" r="3.5" fill="#059669"/>
|
||||
<circle cx="220" cy="150" r="3.5" fill="#059669"/>
|
||||
<circle cx="92" cy="54" r="3.5" fill="#059669"/>
|
||||
<circle cx="92" cy="150" r="3" fill="#dc2626"/>
|
||||
<!-- labels -->
|
||||
<text x="14" y="162" font-size="11" font-weight="700" fill="#047857">A</text>
|
||||
<text x="262" y="162" font-size="11" font-weight="700" fill="#047857">B</text>
|
||||
<text x="67" y="36" font-size="11" font-weight="700" fill="#047857">C</text>
|
||||
<text x="82" y="162" font-size="11" font-weight="700" fill="#b45309">H</text>
|
||||
<text x="44" y="100" font-size="10" fill="#0284c7" font-family="JetBrains Mono,monospace">b</text>
|
||||
<text x="185" y="100" font-size="10" fill="#7c3aed" font-family="JetBrains Mono,monospace">a</text>
|
||||
<text x="140" y="163" text-anchor="middle" font-size="10" fill="#047857" font-family="JetBrains Mono,monospace">c</text>
|
||||
<text x="88" y="100" font-size="10" fill="#b45309" font-family="JetBrains Mono,monospace">h_c</text>
|
||||
<text x="47" y="163" text-anchor="middle" font-size="9" fill="#0284c7" font-family="JetBrains Mono,monospace">a_c</text>
|
||||
<text x="170" y="163" text-anchor="middle" font-size="9" fill="#7c3aed" font-family="JetBrains Mono,monospace">b_c</text>
|
||||
<text x="10" y="164" font-size="13" font-weight="800" fill="#047857" font-family="Unbounded,sans-serif">A</text>
|
||||
<text x="222" y="164" font-size="13" font-weight="800" fill="#047857" font-family="Unbounded,sans-serif">B</text>
|
||||
<text x="84" y="46" font-size="13" font-weight="800" fill="#047857" font-family="Unbounded,sans-serif">C</text>
|
||||
<text x="86" y="165" font-size="12" font-weight="800" fill="#b91c1c" font-family="Unbounded,sans-serif">H</text>
|
||||
<!-- side labels -->
|
||||
<text x="48" y="100" font-size="12" font-weight="700" fill="#0369a1" font-family="JetBrains Mono,monospace">b</text>
|
||||
<text x="160" y="95" font-size="12" font-weight="700" fill="#6d28d9" font-family="JetBrains Mono,monospace">a</text>
|
||||
<text x="100" y="105" font-size="12" font-weight="800" fill="#b91c1c" font-family="JetBrains Mono,monospace">h_c</text>
|
||||
<text x="55" y="143" text-anchor="middle" font-size="11" font-weight="700" fill="#0369a1" font-family="JetBrains Mono,monospace">a_c</text>
|
||||
<text x="155" y="143" text-anchor="middle" font-size="11" font-weight="700" fill="#6d28d9" font-family="JetBrains Mono,monospace">b_c</text>
|
||||
<text x="20" y="22" font-size="10" fill="#047857" font-family="Inter,sans-serif">катеты: a, b · гипотенуза: c = a_c + b_c</text>
|
||||
</svg>
|
||||
</div>`);
|
||||
|
||||
@@ -3460,25 +3494,35 @@ function buildP8(){
|
||||
</ul>
|
||||
<p style="margin-top:8px">Приравниваем: $\\dfrac{1}{2} a b = \\dfrac{1}{2} c h_c$  ⇒  $h_c = \\dfrac{ab}{c}$. $\\square$</p>
|
||||
<div style="display:flex;justify-content:center;margin-top:14px">
|
||||
<svg viewBox="0 0 280 160" style="max-width:300px;background:#fafafa;border:1px solid var(--border);border-radius:10px">
|
||||
<!-- Triangle with both height visualizations side by side -->
|
||||
<!-- Left: via catheti a,b -->
|
||||
<polygon points="20,140 110,140 20,40" fill="rgba(5,150,105,.15)" stroke="#059669" stroke-width="2"/>
|
||||
<polyline points="32,140 32,128 20,128" fill="none" stroke="#059669" stroke-width="1.5"/>
|
||||
<text x="65" y="154" text-anchor="middle" font-size="10" font-weight="700" fill="#047857" font-family="JetBrains Mono,monospace">a</text>
|
||||
<text x="8" y="90" text-anchor="middle" dominant-baseline="middle" font-size="10" font-weight="700" fill="#047857" font-family="JetBrains Mono,monospace" transform="rotate(-90,8,90)">b</text>
|
||||
<text x="60" y="100" text-anchor="middle" font-size="11" font-weight="800" fill="#047857" font-family="Unbounded,sans-serif">S=ab/2</text>
|
||||
<text x="65" y="20" text-anchor="middle" font-size="9" fill="#047857">катеты a, b</text>
|
||||
<svg viewBox="0 0 320 180" style="max-width:340px;background:#fafafa;border:1px solid var(--border);border-radius:10px">
|
||||
<!-- LEFT: right triangle with catheti horizontal (a=80) and vertical (b=100), right angle at A -->
|
||||
<!-- A(20,150) B(100,150) C(20,50) -->
|
||||
<polygon points="20,150 100,150 20,50" fill="rgba(5,150,105,.18)" stroke="#059669" stroke-width="2"/>
|
||||
<polyline points="32,150 32,138 20,138" fill="none" stroke="#059669" stroke-width="1.5"/>
|
||||
<circle cx="20" cy="150" r="2.5" fill="#059669"/><circle cx="100" cy="150" r="2.5" fill="#059669"/><circle cx="20" cy="50" r="2.5" fill="#059669"/>
|
||||
<text x="60" y="166" text-anchor="middle" font-size="11" font-weight="800" fill="#047857" font-family="JetBrains Mono,monospace">a</text>
|
||||
<text x="11" y="103" text-anchor="middle" dominant-baseline="middle" font-size="11" font-weight="800" fill="#047857" font-family="JetBrains Mono,monospace">b</text>
|
||||
<text x="55" y="105" text-anchor="middle" font-size="12" font-weight="800" fill="#047857" font-family="Unbounded,sans-serif">S = ½ab</text>
|
||||
<text x="60" y="22" text-anchor="middle" font-size="10" font-weight="700" fill="#047857">через катеты</text>
|
||||
<!-- Equals sign -->
|
||||
<text x="135" y="100" text-anchor="middle" font-size="20" font-weight="900" fill="#059669">=</text>
|
||||
<!-- Right: via hypotenuse c and h_c -->
|
||||
<polygon points="160,140 260,140 200,40" fill="rgba(5,150,105,.15)" stroke="#059669" stroke-width="2"/>
|
||||
<line x1="200" y1="40" x2="200" y2="140" stroke="#f59e0b" stroke-width="2" stroke-dasharray="5 3"/>
|
||||
<polyline points="200,130 210,130 210,140" fill="none" stroke="#f59e0b" stroke-width="1.5"/>
|
||||
<text x="210" y="100" font-size="10" fill="#b45309" font-family="JetBrains Mono,monospace">h_c</text>
|
||||
<text x="210" y="154" text-anchor="middle" font-size="10" font-weight="700" fill="#047857" font-family="JetBrains Mono,monospace">c</text>
|
||||
<text x="210" y="20" text-anchor="middle" font-size="9" fill="#047857">гипотенуза c, h_c</text>
|
||||
<text x="174" y="100" text-anchor="middle" font-size="11" font-weight="800" fill="#047857" font-family="Unbounded,sans-serif">S=ch_c/2</text>
|
||||
<text x="160" y="105" text-anchor="middle" font-size="24" font-weight="900" fill="#059669">=</text>
|
||||
<!-- RIGHT: SAME right triangle, but with hypotenuse horizontal -->
|
||||
<!-- Catheti a=80 (horizontal) and b=100 (vertical) → hypotenuse c=sqrt(6400+10000)≈128.06. h_c=ab/c≈62.5
|
||||
Place hypotenuse from (190,150) to (190+128, 150)=(318,150) ← off; scale down: use a=60,b=80,c=100,h_c=48
|
||||
A'(200,150) B'(300,150) — hypotenuse length 100. Foot H' at b²/c from A = 6400/100 = 64. So H'=(264,150).
|
||||
h_c = 48. So C'=(264, 102). Verify: A'C'=sqrt(64²+48²)=sqrt(4096+2304)=sqrt(6400)=80=b ✓; B'C'=sqrt(36²+48²)=sqrt(1296+2304)=sqrt(3600)=60=a ✓ -->
|
||||
<polygon points="200,150 300,150 264,102" fill="rgba(5,150,105,.18)" stroke="#059669" stroke-width="2"/>
|
||||
<line x1="264" y1="102" x2="264" y2="150" stroke="#dc2626" stroke-width="2" stroke-dasharray="5 3"/>
|
||||
<!-- right angle at foot H' (inside right sub-triangle) -->
|
||||
<polyline points="264,141 273,141 273,150" fill="none" stroke="#dc2626" stroke-width="1.5"/>
|
||||
<!-- right angle at C' (between catheti) -->
|
||||
<polyline points="259,109 268,114 271,107" fill="none" stroke="#059669" stroke-width="1.3"/>
|
||||
<circle cx="200" cy="150" r="2.5" fill="#059669"/><circle cx="300" cy="150" r="2.5" fill="#059669"/><circle cx="264" cy="102" r="2.5" fill="#059669"/>
|
||||
<circle cx="264" cy="150" r="2" fill="#dc2626"/>
|
||||
<text x="250" y="166" text-anchor="middle" font-size="11" font-weight="800" fill="#047857" font-family="JetBrains Mono,monospace">c</text>
|
||||
<text x="273" y="129" font-size="12" font-weight="800" fill="#b91c1c" font-family="JetBrains Mono,monospace">h_c</text>
|
||||
<text x="217" y="125" font-size="11" font-weight="800" fill="#047857" font-family="Unbounded,sans-serif">S = ½ch_c</text>
|
||||
<text x="248" y="22" text-anchor="middle" font-size="10" font-weight="700" fill="#047857">через гипотенузу и h_c</text>
|
||||
</svg>
|
||||
</div>`);
|
||||
|
||||
@@ -3487,27 +3531,36 @@ function buildP8(){
|
||||
<p style="margin-top:8px"><b>Проекции катетов $a_c=4$, $b_c=9$. Найти $h_c$.</b><br>$h_c=\\sqrt{4 \\cdot 9}=\\sqrt{36}=6$.</p>
|
||||
<p style="margin-top:8px"><b>$h_c=12$, $a_c=9$. Найти $b_c$.</b><br>$b_c=\\dfrac{h_c^2}{a_c}=\\dfrac{144}{9}=16$.</p>
|
||||
<div style="display:flex;justify-content:center;margin-top:14px">
|
||||
<svg viewBox="0 0 260 160" style="max-width:280px;background:#fafafa;border:1px solid var(--border);border-radius:10px">
|
||||
<!-- CLEAN: right angle at C(30,140). B(30,44) vertical cathetus b=6. D(158,140) horizontal cathetus a=8. H≈(76,79) -->
|
||||
<!-- sub-triangles -->
|
||||
<polygon points="30,140 76,79 30,44" fill="rgba(2,132,199,.18)" stroke="#0284c7" stroke-width="1.2"/>
|
||||
<polygon points="30,140 76,79 158,140" fill="rgba(124,58,237,.18)" stroke="#7c3aed" stroke-width="1.2"/>
|
||||
<!-- main triangle -->
|
||||
<polygon points="30,44 158,140 30,140" fill="none" stroke="#059669" stroke-width="2.5"/>
|
||||
<!-- right angle at C(30,140) -->
|
||||
<polyline points="42,140 42,128 30,128" fill="none" stroke="#059669" stroke-width="1.5"/>
|
||||
<!-- altitude from C to hyp -->
|
||||
<line x1="30" y1="140" x2="76" y2="79" stroke="#f59e0b" stroke-width="2" stroke-dasharray="5 3"/>
|
||||
<polyline points="68,85 74,70 82,76" fill="none" stroke="#f59e0b" stroke-width="1.3"/>
|
||||
<svg viewBox="0 0 260 180" style="max-width:280px;background:#fafafa;border:1px solid var(--border);border-radius:10px">
|
||||
<!-- Triangle 6-8-10: C(30,150) right angle; A(30,30) above (b=120/20 → 6); B(190,150) right (a=160/20 → 8). Hypotenuse c=200 px (=10). h_c=ab/c=96 px (=4.8). Foot H projection on AB:
|
||||
AB from A(30,30) to B(190,150). |AB|=200. C=(30,150). H = A + ((C-A)·(B-A)/|AB|²)·(B-A).
|
||||
(C-A)=(0,120), (B-A)=(160,120). dot=0·160+120·120=14400. /200²=14400/40000=0.36. So H=A+0.36·(160,120)=(30+57.6, 30+43.2)=(87.6, 73.2)≈(88, 73). -->
|
||||
<polygon points="30,150 88,73 30,30" fill="rgba(2,132,199,.18)" stroke="#0284c7" stroke-width="1.4"/>
|
||||
<polygon points="30,150 88,73 190,150" fill="rgba(124,58,237,.18)" stroke="#7c3aed" stroke-width="1.4"/>
|
||||
<polygon points="30,30 190,150 30,150" fill="none" stroke="#059669" stroke-width="2.5"/>
|
||||
<!-- right angle at C(30,150): between CA(up) and CB(right) -->
|
||||
<polyline points="42,150 42,138 30,138" fill="none" stroke="#059669" stroke-width="1.5"/>
|
||||
<!-- altitude C->H -->
|
||||
<line x1="30" y1="150" x2="88" y2="73" stroke="#dc2626" stroke-width="2" stroke-dasharray="5 3"/>
|
||||
<!-- right angle at H: between altitude (towards C: down-left) and hypotenuse (towards A: up-left). Inside △AHC.
|
||||
u_HC = (30-88, 150-73)/sqrt(58²+77²) ≈ (-58,77)/96.4 ≈ (-0.601, 0.799). 10·u_HC=(82,81).
|
||||
u_HA = (30-88, 30-73)/sqrt(58²+43²) ≈ (-58,-43)/72.2 ≈ (-0.803, -0.595). 10·u_HA=(80,67).
|
||||
corner = H + 10·u_HC + 10·u_HA = (88-6-8, 73+8-6)=(74,75). -->
|
||||
<polyline points="82,81 74,75 80,67" fill="none" stroke="#dc2626" stroke-width="1.4"/>
|
||||
<!-- vertex dots -->
|
||||
<circle cx="30" cy="30" r="3" fill="#059669"/>
|
||||
<circle cx="190" cy="150" r="3" fill="#059669"/>
|
||||
<circle cx="30" cy="150" r="3" fill="#059669"/>
|
||||
<circle cx="88" cy="73" r="2.5" fill="#dc2626"/>
|
||||
<!-- labels -->
|
||||
<text x="18" y="144" font-size="11" font-weight="700" fill="#047857">C</text>
|
||||
<text x="160" y="152" font-size="11" font-weight="700" fill="#047857">B</text>
|
||||
<text x="18" y="40" font-size="11" font-weight="700" fill="#047857">A</text>
|
||||
<text x="79" y="76" font-size="11" font-weight="700" fill="#b45309">H</text>
|
||||
<text x="18" y="96" font-size="10" font-weight="700" fill="#047857" font-family="JetBrains Mono,monospace">b=6</text>
|
||||
<text x="92" y="152" text-anchor="middle" font-size="10" font-weight="700" fill="#047857" font-family="JetBrains Mono,monospace">a=8</text>
|
||||
<text x="106" y="98" font-size="9" fill="#047857" font-family="JetBrains Mono,monospace">c=10</text>
|
||||
<text x="42" y="108" font-size="9" fill="#b45309" font-family="JetBrains Mono,monospace">h_c=4,8</text>
|
||||
<text x="14" y="32" font-size="12" font-weight="800" fill="#047857" font-family="Unbounded,sans-serif">A</text>
|
||||
<text x="195" y="158" font-size="12" font-weight="800" fill="#047857" font-family="Unbounded,sans-serif">B</text>
|
||||
<text x="14" y="164" font-size="12" font-weight="800" fill="#047857" font-family="Unbounded,sans-serif">C</text>
|
||||
<text x="92" y="68" font-size="12" font-weight="800" fill="#b91c1c" font-family="Unbounded,sans-serif">H</text>
|
||||
<text x="11" y="93" font-size="11" font-weight="700" fill="#0369a1" font-family="JetBrains Mono,monospace">b=6</text>
|
||||
<text x="105" y="165" text-anchor="middle" font-size="11" font-weight="700" fill="#6d28d9" font-family="JetBrains Mono,monospace">a=8</text>
|
||||
<text x="115" y="92" font-size="11" font-weight="700" fill="#047857" font-family="JetBrains Mono,monospace">c=10</text>
|
||||
<text x="48" y="118" font-size="11" font-weight="800" fill="#b91c1c" font-family="JetBrains Mono,monospace">h_c=4,8</text>
|
||||
</svg>
|
||||
</div>`);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user