fix(alg10 ch1 §11): SVG двойного угла — подписи без LaTeX-скобок + 30°/60°

Проблемы старого рисунка:
- Метки 'P_α' и 'P_{2α}' рисовались как SVG <text>, а KaTeX
  не обрабатывает SVG — фигурные скобки '{2α}' показывались как
  литерал, выглядело как «P_{2α}»
- Угол 2α = 70° был слишком близко к оси y, метка P_{2α}
  наезжала на цифру '1' оси y
- Подзаголовок 'α = 35°, 2α = 70°' тоже перекрывался

Что переделано:
- Углы изменены на textbook-стандарт: α = 30°, 2α = 60°.
  Это даёт хорошо видимое разделение и удобные значения для
  вспоминания формул
- Размер канваса увеличен до 380x360, радиус R=130 — больше
  пространства для подписей
- Точки и подписи рисуются вручную (без c.point auto-label),
  потому что нужно тонкое позиционирование чтобы не пересечь
  '1' на оси y
- Подписи изменены на 'P(α)' и 'P(2α)' — скобки решают проблему
  визуально (math-нотация) и не используют braces которые SVG
  рисует литералом
- Подписи углов 'α' и '2α' расположены на биссектрисах секторов
  (через формулу 48*cos(ang/2), 48*sin(ang/2)) — посередине
  внутри своего сектора
- Усилены: размер шрифта 13, font-family Unbounded для контраста
  с Inter в остальном тексте
- Жирность fill-цвета увеличена (rgba .22 → .30 для α сектора)
This commit is contained in:
Maxim Dolgolyov
2026-05-29 11:33:23 +03:00
parent 5e37707b11
commit 4747229b09
+26 -15
View File
@@ -2632,25 +2632,36 @@ function buildP11(){
/* === SVG: α и 2α на единичной окружности (только геометрия) === */
let svgDouble = '';
if(A){
const c = A.tri.canvas({id:'p11-d', W:360, H:340, R:120});
const ang = 35 * Math.PI / 180; /* α = 35° */
const ang2 = 2 * ang; /* 2α = 70° */
const c = A.tri.canvas({id:'p11-d', W:380, H:360, R:130});
const ang = 30 * Math.PI / 180; /* α = 30° */
const ang2 = 60 * Math.PI / 180; /* 2α = 60° */
const p1 = c.pointPx(ang);
const p2 = c.pointPx(ang2);
let s = c.open
+ '<rect x="0" y="0" width="'+c.W+'" height="44" fill="rgba(13,148,136,.08)"/>'
/* === Заголовочная плашка === */
+ '<rect x="0" y="0" width="'+c.W+'" height="44" fill="rgba(13,148,136,.10)"/>'
+ '<text x="'+(c.W/2)+'" y="22" text-anchor="middle" font-size="13" font-family="Unbounded,Inter,sans-serif" font-weight="800" fill="#0d9488">УГОЛ α И ДВОЙНОЙ УГОЛ 2α</text>'
+ '<text x="'+(c.W/2)+'" y="38" text-anchor="middle" font-size="10" font-family="Inter,sans-serif" font-style="italic" fill="#64748b">Пример: α = 35°, 2α = 70°</text>'
+ '<text x="'+(c.W/2)+'" y="38" text-anchor="middle" font-size="10" font-family="Inter,sans-serif" font-style="italic" fill="#64748b">Пример: α = 30°, 2α = 60°</text>'
/* === Оси и окружность === */
+ c.axes()
+ c.circle({width:2.5})
/* Сектор α */
+ '<path d="M '+c.cx+' '+c.cy+' L '+(c.cx+34)+' '+c.cy+' A 34 34 0 0 0 '+(c.cx + 34*Math.cos(ang))+' '+(c.cy - 34*Math.sin(ang))+' Z" fill="rgba(13,148,136,.22)" stroke="#0d9488" stroke-width="1.5"/>'
+ '<text x="'+(c.cx+44)+'" y="'+(c.cy-8)+'" font-size="12" font-family="JetBrains Mono,monospace" font-weight="800" fill="#0f766e">α</text>'
/* Сектор 2α (поверх) */
+ '<path d="M '+c.cx+' '+c.cy+' L '+(c.cx+60)+' '+c.cy+' A 60 60 0 0 0 '+(c.cx + 60*Math.cos(ang2))+' '+(c.cy - 60*Math.sin(ang2))+' Z" fill="rgba(124,58,237,.12)" stroke="#7c3aed" stroke-width="1.5" stroke-dasharray="3 2"/>'
+ '<text x="'+(c.cx+72)+'" y="'+(c.cy-22)+'" font-size="12" font-family="JetBrains Mono,monospace" font-weight="800" fill="#6d28d9">2α</text>'
+ c.radius(ang, {color:'#0d9488', width:2.5})
+ c.radius(ang2, {color:'#7c3aed', width:2.5})
+ c.point(ang, {color:'#0d9488', label:'P_α', labelOffset:20, fontSize:12, labelColor:'#0f766e'})
+ c.point(ang2, {color:'#7c3aed', label:'P_{2α}', labelOffset:20, fontSize:12, labelColor:'#6d28d9'})
/* === Сектор 2α (фиолетовый пунктирный, под α) === */
+ '<path d="M '+c.cx+' '+c.cy+' L '+(c.cx+65)+' '+c.cy+' A 65 65 0 0 0 '+(c.cx + 65*Math.cos(ang2))+' '+(c.cy - 65*Math.sin(ang2))+' Z" fill="rgba(124,58,237,.14)" stroke="#7c3aed" stroke-width="1.5" stroke-dasharray="4 2"/>'
/* === Сектор α (бирюзовый, поверх) === */
+ '<path d="M '+c.cx+' '+c.cy+' L '+(c.cx+36)+' '+c.cy+' A 36 36 0 0 0 '+(c.cx + 36*Math.cos(ang))+' '+(c.cy - 36*Math.sin(ang))+' Z" fill="rgba(13,148,136,.30)" stroke="#0d9488" stroke-width="1.5"/>'
/* === Подписи углов внутри секторов === */
+ '<text x="'+(c.cx + 48*Math.cos(ang/2))+'" y="'+(c.cy - 48*Math.sin(ang/2) + 4)+'" text-anchor="middle" font-size="13" font-family="Unbounded,Inter,sans-serif" font-weight="800" fill="#0f766e">α</text>'
+ '<text x="'+(c.cx + 77*Math.cos(ang2/2))+'" y="'+(c.cy - 77*Math.sin(ang2/2) + 4)+'" text-anchor="middle" font-size="13" font-family="Unbounded,Inter,sans-serif" font-weight="800" fill="#6d28d9">2α</text>'
/* === Радиусы === */
+ c.radius(ang, {color:'#0d9488', width:2.8})
+ c.radius(ang2, {color:'#7c3aed', width:2.8})
/* === Точки P_α и P_{2α} (рисуем вручную, чтобы подписи не наезжали на оси) === */
+ '<circle cx="'+p1.px+'" cy="'+p1.py+'" r="5" fill="#0d9488" stroke="#fff" stroke-width="2"/>'
+ '<circle cx="'+p2.px+'" cy="'+p2.py+'" r="5" fill="#7c3aed" stroke="#fff" stroke-width="2"/>'
/* P_α — подпись справа-сверху от точки (она в правом нижнем углу I четверти) */
+ '<text x="'+(p1.px + 14)+'" y="'+(p1.py - 10)+'" font-size="13" font-family="Unbounded,Inter,sans-serif" font-weight="800" fill="#0f766e">P(α)</text>'
/* P_{2α} — подпись справа от точки (она ближе к верху), уводим вправо чтобы не пересечь "1" на оси y */
+ '<text x="'+(p2.px + 14)+'" y="'+(p2.py + 4)+'" font-size="13" font-family="Unbounded,Inter,sans-serif" font-weight="800" fill="#6d28d9">P(2α)</text>'
+ c.close;
svgDouble = s;
}