diff --git a/frontend/textbooks/geometry_7_ch5.html b/frontend/textbooks/geometry_7_ch5.html
index 52bf3ad..1478ee9 100644
--- a/frontend/textbooks/geometry_7_ch5.html
+++ b/frontend/textbooks/geometry_7_ch5.html
@@ -317,8 +317,8 @@ function achievement(id,text){
const PARAS = [
{ id:'p27', num:'§ 27', name:'Простейшие построения', sub:'циркуль + линейка' },
{ id:'p28', num:'§ 28', name:'Треугольник по 3 сторонам', sub:'отрезок + 2 окружн.' },
- { id:'p29', num:'§ 29', name:'Биссектриса угла', sub:'3 дуги + точка $M$' },
- { id:'p30', num:'§ 30', name:'Середина и $\\perp$', sub:'2 окружн. → 2 точки' },
+ { id:'p29', num:'§ 29', name:'Биссектриса угла', sub:'3 дуги + точка M' },
+ { id:'p30', num:'§ 30', name:'Середина и ⊥', sub:'2 окружн. → 2 точки' },
{ id:'p31', num:'§ 31', name:'Метод ГМТ', sub:'2 ГМТ → пересечение' },
{ id:'final5', num:'★', name:'Финал главы', sub:'Итоги \xB7 5 боссов', final:true },
];
@@ -333,6 +333,7 @@ function buildParaSelector(){
card.addEventListener('click', ()=>goTo(p.id));
g.appendChild(card);
});
+ if(window.renderMathInElement) try{ renderMath(g); }catch(e){}
}
const BUILT=new Set();
@@ -540,23 +541,47 @@ function buildP27(){
let svgTools='';
if(G){
- const b=G.svgBox(320,160,{id:'p27-tools',cell:20});
- svgTools = b.open
- /* Линейка слева */
- + ''
- + 'ЛИНЕЙКА'
- + '↑ прямая через 2 точки'
- + G.point(30,120,'',{r:3,color:'#1e293b'})
- + G.point(130,128,'',{r:3,color:'#1e293b'})
- + G.segment({x:30,y:120},{x:130,y:128},{color:'#0891b2',width:2})
- /* Циркуль справа: схематично */
- + ''
- + ''
- + ''
- + 'ЦИРКУЛЬ'
- + G.circle({x:250,y:108},32,{color:'#0891b2',width:1.5,dash:'3 2'})
- + '↑ окружность'
+ /* Две панели: ЛИНЕЙКА слева, ЦИРКУЛЬ справа.
+ В каждой панели: инструмент сверху → стрелка ↓ → результат снизу. */
+ const b=G.svgBox(340,210,{id:'p27-tools',cell:0,grid:false,bg:'#fff'});
+ /* Вертикальный разделитель */
+ let s=b.open
+ + ''
+ /* ===== ЛЕВАЯ ПАНЕЛЬ — ЛИНЕЙКА ===== */
+ + 'ЛИНЕЙКА'
+ /* Корпус линейки */
+ + '';
+ /* Маленькие штрихи на верхнем крае линейки (без чисел) */
+ for(let i=0;i<=9;i++){ const x=22+i*14; s+=''; }
+ s += '(без делений)'
+ /* Стрелка ↓ */
+ + ''
+ /* Результат: 2 точки и прямая через них */
+ + ''
+ + G.point(30,148,'A',{color:'#1e293b',dx:-12,dy:-2,fontSize:11,r:3.5})
+ + G.point(140,158,'B',{color:'#1e293b',dx:6,dy:-2,fontSize:11,r:3.5})
+ + 'прямая через 2 точки'
+ /* ===== ПРАВАЯ ПАНЕЛЬ — ЦИРКУЛЬ ===== */
+ + 'ЦИРКУЛЬ'
+ /* Две ноги от шарнира вниз */
+ + ''
+ + ''
+ /* Шарнир */
+ + ''
+ /* Игла (треугольник) на левой ноге */
+ + ''
+ /* Грифель на правой ноге */
+ + ''
+ /* Стрелка ↓ */
+ + ''
+ /* Результат: окружность с центром O и пунктирным радиусом */
+ + ''
+ + ''
+ + 'r'
+ + G.point(255,148,'O',{color:'#1e293b',dx:-10,dy:-2,fontSize:11,r:3})
+ + 'окружность (O, r)'
+ b.close;
+ svgTools = s;
}
html += makeCard('theory', 'Что такое задача на построение?', '27.1', `
@@ -1044,34 +1069,51 @@ function buildP31(){
let svgGMT='';
if(G){
- const b=G.svgBox(300,200,{id:'p31-gmt',cell:20});
- const O={x:50,y:120};
- const ang=25*Math.PI/180;
- const len=240;
+ /* Чистый рисунок: угол ∠AOB слева, биссектриса (ГМТ 1, красная)
+ и окружность (ГМТ 2, синяя) пересекаются в двух точках K₁, K₂. */
+ const b=G.svgBox(320,230,{id:'p31-gmt',cell:20});
+ const O={x:50,y:135};
+ const ang=20*Math.PI/180; /* половина раствора угла */
+ const len=220;
const Aend={x:O.x+len*Math.cos(-ang), y:O.y+len*Math.sin(-ang)};
const Bend={x:O.x+len*Math.cos(ang), y:O.y+len*Math.sin(ang)};
- /* Биссектриса — ось x от O */
- /* Окружность с центром (170,80) радиуса 50.
- Пересечение биссектрисы (y=120) с этой окружностью:
- (x-170)² + (120-80)² = 2500 → (x-170)² = 900 → x = 140 или 200 */
- const Cc={x:170,y:80}, R=50;
- const K1={x:140,y:120}, K2={x:200,y:120};
+ /* Окружность (ГМТ 2): центр Cc, радиус R.
+ Биссектриса — горизонталь y=O.y от O.
+ Пересечение: (x-Cc.x)² + (O.y-Cc.y)² = R² → x = Cc.x ± √(R² - dy²) */
+ const Cc={x:180,y:90}, R=55;
+ const dy = O.y - Cc.y;
+ const dx = Math.sqrt(R*R - dy*dy);
+ const K1={x:Cc.x-dx, y:O.y}, K2={x:Cc.x+dx, y:O.y};
+ /* Конец биссектрисы — заходит чуть за K2 */
+ const Bs={x:O.x+len,y:O.y};
svgGMT = b.open
/* Стороны угла */
+ G.segment(O,Aend,{color:'#7c3aed',width:2.5})
+ G.segment(O,Bend,{color:'#7c3aed',width:2.5})
- /* ГМТ 1: биссектриса */
- + G.segment(O,{x:O.x+len,y:O.y},{color:'#dc2626',width:2,dash:'6 3'})
- /* ГМТ 2: окружность */
- + G.circle(Cc,R,{color:'#0891b2',width:1.8,dash:'4 3'})
- /* Точки пересечения */
- + G.point(K1.x,K1.y,'K₁',{color:'#059669',dx:-14,dy:-8,fontSize:12,r:4})
- + G.point(K2.x,K2.y,'K₂',{color:'#059669',dx:6,dy:-8,fontSize:12,r:4})
- + G.point(O.x,O.y,'O',{color:'#1e293b',dx:-14,dy:5,fontSize:12})
- + G.point(Cc.x,Cc.y,'C',{color:'#0891b2',dx:6,dy:-6,fontSize:12,r:3})
- + 'ГМТ 1: бис.'
- + 'ГМТ 2: окружн.'
- + 'K₁, K₂ = ГМТ 1 ∩ ГМТ 2'
+ + G.point(O.x,O.y,'O',{color:'#1e293b',dx:-14,dy:5,fontSize:13})
+ + 'A'
+ + 'B'
+ /* Маленькие дуги показывают, что биссектриса делит угол пополам */
+ + G.arc(O,18,-ang,0,{color:'#dc2626',width:1.4})
+ + G.arc(O,18,0,ang,{color:'#dc2626',width:1.4})
+ /* ГМТ 1 — биссектриса (красная пунктирная) */
+ + G.segment(O,Bs,{color:'#dc2626',width:2.2,dash:'7 4'})
+ /* ГМТ 2 — окружность (синяя пунктирная) */
+ + G.circle(Cc,R,{color:'#0891b2',width:2,dash:'5 3'})
+ + G.point(Cc.x,Cc.y,'C',{color:'#0891b2',dx:6,dy:-6,fontSize:11,r:3})
+ /* Точки пересечения K₁, K₂ — крупные зелёные с обводкой */
+ + ''
+ + ''
+ + 'K₁'
+ + 'K₂'
+ /* Подпись ГМТ 1 (плашка справа от биссектрисы, за K₂) */
+ + ''
+ + 'ГМТ 1: бис.'
+ /* Подпись ГМТ 2 (плашка сверху над окружностью) */
+ + ''
+ + 'ГМТ 2: окружн.'
+ /* Итог снизу */
+ + 'K₁, K₂ = ГМТ 1 ∩ ГМТ 2'
+ b.close;
}
@@ -1203,7 +1245,7 @@ const BOSSES = [
]
},
{
- n:3, title:'Босс \xA729-30 — Биссектриса, середина, $\\perp$', color:'#7c3aed',
+ n:3, title:'Босс \xA729-30 — Биссектриса, середина, ⊥', color:'#7c3aed',
steps:[
{ q:'По какому признаку доказываем равенство $\\triangle OXM = \\triangle OYM$ в построении бис.? «ССС», «СУС», «УСУ»', verify:(v)=>String(v).trim().toUpperCase().startsWith('ССС'), hint:'ССС — три стороны.' },
{ q:'Сколько окружностей в построении серединного $\\perp$?', verify:(v)=>+v===2, hint:'Из $A$ и $B$.' },
@@ -1288,6 +1330,7 @@ function buildFinal5(){
+'
'
+'';
}).join('');
+ if(window.renderMathInElement) try{ renderMath(cont); }catch(e){}
BOSSES.forEach((b,idx)=>{
function show(){