fix(geom8 ch4): §12-§14 — корректная геометрия SVG (касательная, хорды, секущие)

§12 (Угол между касательной и хордой):
- Card 12.1, 12.3: полностью переписаны. Касательная — настоящая
  горизонтальная прямая в точке A на нижнем краю окружности;
  хорда AB к точке B на верхней дуге; маркер угла α радиуса 18
  между направлением касательной и хордой. Подсветка дуги AB
  только обводкой (stroke), без заливки fan-сектора.
- Интерактив 1: добавлен корректный маркер угла, дуга stroke-only.

§13 (Угол между двумя хордами):
- Card 13.1: переписан. 4 точки A,B,C,D через тригонометрию
  (тестовые углы 200°/20°/80°/280°). Хорды AB и CD пересекаются
  в P=(141,96) — настоящее аналитическое пересечение.
  Дуги AC и BD — тонкими толстыми обводками БЕЗ заливок.
- Интерактив 1: подсветки дуг переделаны на stroke-only.

§14 (Угол между секущими из внешней точки):
- Card 14.1: переписан с корректной геометрией секущих. P=(272,92)
  снаружи; обе секущие — настоящие прямые через P; все 4 точки
  пересечения вычислены аналитически (через квадратное уравнение).
- Интерактив 1: добавлен хелпер secantPoints(P, O, R, θ) который
  гарантирует, что точки пересечения лежат на одной прямой с P.
  Заменены произвольные углы на окружности на правильное построение.

Все §12-§14 теперь геометрически точны: касательные действительно
касательны, хорды действительно пересекаются в указанной P, секущие
действительно прямые через внешнюю точку.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Maxim Dolgolyov
2026-05-28 20:52:50 +03:00
parent ac10ebdd21
commit e8bd098427
+246 -103
View File
@@ -4772,23 +4772,42 @@ function buildP12(){
$$\\angle(l,AB) = \\dfrac{1}{2}\\,\\smile AB$$
<p style="margin-top:8px">Здесь $l$ — касательная к окружности в точке $A$, $AB$ — хорда из точки касания $A$. Дуга $\\smile AB$ — та, которая лежит «внутри» угла.</p>
<div style="display:flex;justify-content:center;margin-top:14px">
<svg viewBox="0 0 280 180" style="max-width:300px;background:#fafafa;border:1px solid var(--border);border-radius:10px">
<circle cx="120" cy="95" r="62" fill="rgba(8,145,178,.07)" stroke="#0891b2" stroke-width="2"/>
<circle cx="120" cy="95" r="3" fill="#0891b2"/>
<circle cx="58" cy="95" r="4.5" fill="#dc2626"/>
<circle cx="103" cy="36" r="4" fill="#0284c7"/>
<line x1="20" y1="95" x2="200" y2="95" stroke="#dc2626" stroke-width="2.2"/>
<line x1="58" y1="95" x2="103" y2="36" stroke="#0284c7" stroke-width="2.2"/>
<line x1="120" y1="95" x2="58" y2="95" stroke="#64748b" stroke-width="1.4" stroke-dasharray="4,3"/>
<path d="M 58,95 A 62,62 0 0,1 103,36" fill="rgba(8,145,178,.18)" stroke="#0891b2" stroke-width="2.5"/>
<path d="M 75,95 A 17,17 0 0,1 68,83" fill="none" stroke="#e11d48" stroke-width="1.8"/>
<text x="8" y="91" font-size="10" fill="#dc2626" font-weight="700">l</text>
<text x="42" y="112" font-size="11" font-weight="700" fill="#dc2626">A</text>
<text x="88" y="30" font-size="11" font-weight="700" fill="#0284c7">B</text>
<text x="122" y="91" font-size="10" font-weight="700" fill="#0891b2">O</text>
<text x="68" y="79" font-size="9" fill="#e11d48">&#945;</text>
<text x="175" y="72" font-size="9" fill="#0891b2">&#8978;AB</text>
<text x="175" y="84" font-size="9" fill="#e11d48">&#945; = &#189;&#8978;AB</text>
<svg viewBox="0 0 290 190" style="max-width:300px;background:#fafafa;border:1px solid var(--border);border-radius:10px">
<!-- circle cx=150, cy=100, R=65. A at bottom (270deg): (150, 165). Tangent at A is horizontal. -->
<!-- B on circle: arc AB (going CCW from A at 270deg) = 110deg => B at 270+110=380=20deg from +x -->
<!-- B = (150+65*cos(20), 100-65*sin(20)) = (150+61.1, 100-22.2) = (211.1, 77.8) -->
<!-- chord AB: (150,165) to (211,78). Tangent at A: horizontal line through (150,165). -->
<!-- angle between tangent-right (1,0) and chord direction (61,-87): atan2(-87,61) in SVG = atan2(87,61) in math = 55deg. -->
<!-- half arc = 110/2 = 55deg. Correct! -->
<circle cx="150" cy="100" r="65" fill="rgba(8,145,178,.07)" stroke="#0891b2" stroke-width="2"/>
<circle cx="150" cy="100" r="3" fill="#0891b2"/>
<!-- A at bottom (270deg), B at 20deg -->
<circle cx="150" cy="165" r="5" fill="#dc2626"/>
<circle cx="211" cy="78" r="4.5" fill="#0284c7"/>
<!-- tangent l is horizontal through A -->
<line x1="70" y1="165" x2="230" y2="165" stroke="#dc2626" stroke-width="2.5"/>
<!-- chord AB -->
<line x1="150" y1="165" x2="211" y2="78" stroke="#0284c7" stroke-width="2.2"/>
<!-- radius OA dashed -->
<line x1="150" y1="100" x2="150" y2="165" stroke="#64748b" stroke-width="1.4" stroke-dasharray="4,3"/>
<!-- arc AB: A(bottom)→B(upper-right). 110deg arc through right side. CW on screen=sweep=1, large=0 -->
<path d="M 150,165 A 65,65 0 0,1 211,78" fill="none" stroke="#dc2626" stroke-width="3.5"/>
<!-- angle marker at A between tangent-right and chord AB, radius 18 -->
<!-- tangent right = (1,0): start point (150+18, 165)=(168,165) -->
<!-- chord direction unit: (61,-87)/sqrt(61^2+87^2)=(61,-87)/106.3=(0.574,-0.819) -->
<!-- end point: (150+18*0.574, 165+18*(-0.819))=(150+10.3,165-14.7)=(160.3,150.3) -->
<!-- angle from tangent-right going CW on screen to chord (upward) = 55deg -->
<path d="M 168,165 A 18,18 0 0,0 160.3,150.3" fill="none" stroke="#e11d48" stroke-width="2.2"/>
<!-- alpha label inside angle -->
<text x="168" y="158" font-size="12" font-weight="700" fill="#e11d48">&#945;</text>
<!-- labels -->
<text x="72" y="161" font-size="11" fill="#dc2626" font-weight="700">l</text>
<text x="137" y="182" font-size="12" font-weight="700" fill="#dc2626">A</text>
<text x="215" y="76" font-size="12" font-weight="700" fill="#0284c7">B</text>
<text x="154" y="96" font-size="10" font-weight="700" fill="#0891b2">O</text>
<!-- arc label on the highlighted arc -->
<text x="192" y="130" font-size="10" fill="#dc2626" font-weight="700">&#8978;AB</text>
<text x="5" y="60" font-size="9" fill="#0891b2">&#945; = &#189;&#8978;AB</text>
</svg>
</div>`);
@@ -4807,19 +4826,32 @@ function buildP12(){
<p style="margin-top:10px"><b>Задача 2.</b> Дуга $\\smile AB = 110°$. Найди угол между касательной и хордой $AB$.</p>
<p style="margin-top:6px"><b>Решение.</b> $\\angle = \\dfrac{1}{2}\\cdot 110° = 55°$.</p>
<div style="display:flex;justify-content:center;margin-top:12px">
<svg viewBox="0 0 240 150" style="max-width:260px;background:#fafafa;border:1px solid var(--border);border-radius:10px">
<circle cx="105" cy="80" r="55" fill="rgba(8,145,178,.07)" stroke="#0891b2" stroke-width="1.8"/>
<circle cx="105" cy="80" r="3" fill="#0891b2"/>
<circle cx="50" cy="80" r="4" fill="#dc2626"/>
<circle cx="93" cy="27" r="4" fill="#0284c7"/>
<line x1="10" y1="80" x2="180" y2="80" stroke="#dc2626" stroke-width="2"/>
<line x1="50" y1="80" x2="93" y2="27" stroke="#0284c7" stroke-width="2"/>
<path d="M 50,80 A 55,55 0 0,1 93,27" fill="rgba(8,145,178,.18)" stroke="#0891b2" stroke-width="2.5"/>
<text x="10" y="74" font-size="10" fill="#dc2626">l</text>
<text x="36" y="96" font-size="11" font-weight="700" fill="#dc2626">A</text>
<text x="80" y="22" font-size="11" font-weight="700" fill="#0284c7">B</text>
<text x="134" y="58" font-size="9" fill="#0891b2">110°</text>
<text x="60" y="72" font-size="9" fill="#e11d48">55°</text>
<svg viewBox="0 0 250 165" style="max-width:260px;background:#fafafa;border:1px solid var(--border);border-radius:10px">
<!-- circle cx=118, cy=88, R=55. A at bottom (270deg): (118,143). Tangent horizontal. -->
<!-- arc AB=110deg, so B at 270+110=380=20deg: (118+55*cos20, 88-55*sin20)=(118+51.7,88-18.8)=(169.7,69.2) -->
<!-- chord direction (51.7,-73.8), angle from horiz=atan2(73.8,51.7)=55deg. Correct. -->
<circle cx="118" cy="88" r="55" fill="rgba(8,145,178,.07)" stroke="#0891b2" stroke-width="1.8"/>
<circle cx="118" cy="88" r="3" fill="#0891b2"/>
<circle cx="118" cy="143" r="4.5" fill="#dc2626"/>
<circle cx="170" cy="69" r="4" fill="#0284c7"/>
<!-- tangent horizontal at A -->
<line x1="55" y1="143" x2="200" y2="143" stroke="#dc2626" stroke-width="2.2"/>
<!-- chord AB -->
<line x1="118" y1="143" x2="170" y2="69" stroke="#0284c7" stroke-width="2.2"/>
<!-- radius OA dashed -->
<line x1="118" y1="88" x2="118" y2="143" stroke="#64748b" stroke-width="1.2" stroke-dasharray="4,3"/>
<!-- arc AB highlighted (from A at 270deg to B at 20deg CW on screen = sweep=1) -->
<path d="M 118,143 A 55,55 0 0,1 170,69" fill="none" stroke="#dc2626" stroke-width="3.5"/>
<!-- angle marker at A: tangent right (1,0) to chord direction (52,-74), angle=55deg -->
<!-- chord unit: (52,-74)/90.4=(0.575,-0.819). end=(118+15*0.575, 143+15*(-0.819))=(126.6,130.7) -->
<path d="M 133,143 A 15,15 0 0,0 126.6,130.7" fill="none" stroke="#e11d48" stroke-width="2.2"/>
<text x="134" y="138" font-size="11" font-weight="700" fill="#e11d48">55°</text>
<!-- labels -->
<text x="57" y="139" font-size="10" fill="#dc2626">l</text>
<text x="104" y="158" font-size="12" font-weight="700" fill="#dc2626">A</text>
<text x="173" y="66" font-size="12" font-weight="700" fill="#0284c7">B</text>
<text x="121" y="84" font-size="10" font-weight="700" fill="#0891b2">O</text>
<text x="155" y="112" font-size="10" font-weight="700" fill="#dc2626">110°</text>
</svg>
</div>`);
@@ -4928,21 +4960,37 @@ function buildP12(){
const T2x=Ax, T2y=Ay+tLen;
// arc indicator small
const large=arcDeg>180?1:0;
// angle marker at A between vertical tangent (dir: upward = 270deg) and chord AB
// Tangent at A: vertical line; angle is between upward direction (0,-1) and chord AB direction
// Chord direction from A to B: (Bx-Ax, By-Ay)
const chDx=Bx-Ax, chDy=By-Ay;
const chLen=Math.sqrt(chDx*chDx+chDy*chDy);
const chNx=chDx/chLen, chNy=chDy/chLen;
// Tangent direction upward from A: (0,-1). Angle of arc = ang degrees.
// Arc from tangent-upward direction to chord direction.
// In SVG: start point of arc = A + r*(0,-1), end = A + r*(chNx, chNy)
const mR=16;
const mSx=Ax, mSy=Ay-mR; // start: tangent direction up
const mEx=Ax+mR*chNx, mEy=Ay+mR*chNy; // end: chord direction
// sweep: going from tangent-upward to chord direction in the CW direction on screen (since chord goes to the right of vertical)
// chNx > 0 means chord goes right of tangent => rotate CW on screen => sweep=1
const mSweep=(chNx>0)?1:0;
svgWrap.innerHTML=`<svg viewBox="0 0 ${W} ${H}" style="max-width:${W}px;width:100%;background:#fafafa;border:1px solid var(--border);border-radius:10px">
<circle cx="${cx}" cy="${cy}" r="${R}" fill="rgba(8,145,178,.07)" stroke="#0891b2" stroke-width="2"/>
<path d="M ${Ax} ${Ay} A ${R} ${R} 0 ${large} 0 ${Bx} ${By}" fill="rgba(8,145,178,.2)" stroke="#0891b2" stroke-width="3"/>
<line x1="${T1x}" y1="${T1y}" x2="${T2x}" y2="${T2y}" stroke="#dc2626" stroke-width="2.5"/>
<line x1="${Ax}" y1="${Ay}" x2="${Bx}" y2="${By}" stroke="#0284c7" stroke-width="2.2"/>
<line x1="${cx}" y1="${cy}" x2="${Ax}" y2="${Ay}" stroke="#64748b" stroke-width="1.2" stroke-dasharray="4,3"/>
<path d="M ${Ax.toFixed(1)} ${Ay.toFixed(1)} A ${R} ${R} 0 ${large} 0 ${Bx.toFixed(1)} ${By.toFixed(1)}" fill="none" stroke="#dc2626" stroke-width="3.5"/>
<line x1="${T1x.toFixed(1)}" y1="${T1y.toFixed(1)}" x2="${T2x.toFixed(1)}" y2="${T2y.toFixed(1)}" stroke="#dc2626" stroke-width="2.5"/>
<line x1="${Ax.toFixed(1)}" y1="${Ay.toFixed(1)}" x2="${Bx.toFixed(1)}" y2="${By.toFixed(1)}" stroke="#0284c7" stroke-width="2.2"/>
<line x1="${cx}" y1="${cy}" x2="${Ax.toFixed(1)}" y2="${Ay.toFixed(1)}" stroke="#64748b" stroke-width="1.2" stroke-dasharray="4,3"/>
<path d="M ${mSx.toFixed(1)} ${mSy.toFixed(1)} A ${mR} ${mR} 0 0 ${mSweep} ${mEx.toFixed(1)} ${mEy.toFixed(1)}" fill="none" stroke="#e11d48" stroke-width="2.2"/>
<circle cx="${cx}" cy="${cy}" r="3" fill="#0891b2"/>
<circle cx="${Ax}" cy="${Ay}" r="5" fill="#dc2626"/>
<circle cx="${Bx}" cy="${By}" r="4" fill="#0284c7"/>
<circle cx="${Ax.toFixed(1)}" cy="${Ay.toFixed(1)}" r="5" fill="#dc2626"/>
<circle cx="${Bx.toFixed(1)}" cy="${By.toFixed(1)}" r="4" fill="#0284c7"/>
<text x="${Ax-20}" y="${Ay+4}" font-size="12" font-weight="700" fill="#dc2626">A</text>
<text x="${Bx+(Bx>cx?7:-18)}" y="${By+(By<cy?-6:16)}" font-size="12" font-weight="700" fill="#0284c7">B</text>
<text x="${(Bx+(Bx>cx?7:-18)).toFixed(0)}" y="${(By+(By<cy?-6:16)).toFixed(0)}" font-size="12" font-weight="700" fill="#0284c7">B</text>
<text x="${cx+4}" y="${cy-6}" font-size="10" font-weight="700" fill="#0891b2">O</text>
<text x="${T1x+4}" y="${T1y+10}" font-size="10" fill="#dc2626">l</text>
<text x="${(Ax+Bx)/2+6}" y="${(Ay+By)/2-8}" font-size="9" fill="#0891b2">${arcDeg}°</text>
<text x="${Ax+6}" y="${Ay-18}" font-size="10" font-weight="700" fill="#e11d48">${Math.round(ang)}°</text>
<text x="${(Ax+mEx)/2+4}" y="${(Ay+mSy)/2}" font-size="11" font-weight="700" fill="#e11d48">${Math.round(ang)}&#176;</text>
<text x="${((Ax+Bx)/2+12).toFixed(0)}" y="${((Ay+By)/2-6).toFixed(0)}" font-size="9" fill="#dc2626">&#8978;AB=${arcDeg}&#176;</text>
</svg>`;
info.textContent='Дуга AB = '+arcDeg+'° → Угол (l, AB) = '+Math.round(ang)+'° (= '+arcDeg+'°/2)';
}
@@ -5147,24 +5195,58 @@ function buildP13(){
$$\\angle APС = \\dfrac{1}{2}(\\smile AC + \\smile BD)$$
<p style="margin-top:8px">Хорды $AB$ и $CD$ пересекаются в точке $P$ внутри окружности. Угол $\\angle APC$ (и вертикальный ему $\\angle BPD$) равен полусумме дуг $\\smile AC$ и $\\smile BD$.</p>
<div style="display:flex;justify-content:center;margin-top:14px">
<svg viewBox="0 0 280 180" style="max-width:300px;background:#fafafa;border:1px solid var(--border);border-radius:10px">
<circle cx="120" cy="90" r="65" fill="rgba(6,182,212,.07)" stroke="#06b6d4" stroke-width="2"/>
<circle cx="120" cy="90" r="3" fill="#0891b2"/>
<circle cx="59" cy="68" r="4" fill="#0284c7"/>
<circle cx="184" cy="79" r="4" fill="#0284c7"/>
<circle cx="142" cy="29" r="4" fill="#dc2626"/>
<circle cx="98" cy="151" r="4" fill="#dc2626"/>
<line x1="59" y1="68" x2="184" y2="79" stroke="#0284c7" stroke-width="2"/>
<line x1="142" y1="29" x2="98" y2="151" stroke="#dc2626" stroke-width="2"/>
<circle cx="126" cy="74" r="4.5" fill="#7c3aed"/>
<path d="M 59,68 A 65,65 0 0,0 142,29" fill="rgba(6,182,212,.2)" stroke="#06b6d4" stroke-width="2.5"/>
<path d="M 184,79 A 65,65 0 0,0 98,151" fill="rgba(220,38,38,.15)" stroke="#dc2626" stroke-width="2.5"/>
<text x="43" y="64" font-size="11" font-weight="700" fill="#0284c7">A</text>
<text x="188" y="83" font-size="11" font-weight="700" fill="#0284c7">B</text>
<text x="146" y="24" font-size="11" font-weight="700" fill="#dc2626">C</text>
<text x="82" y="166" font-size="11" font-weight="700" fill="#dc2626">D</text>
<text x="110" y="71" font-size="11" font-weight="700" fill="#7c3aed">P</text>
<text x="5" y="110" font-size="9" fill="#0891b2">½(⌢AC+⌢BD)</text>
<svg viewBox="0 0 280 185" style="max-width:300px;background:#fafafa;border:1px solid var(--border);border-radius:10px">
<!-- circle cx=130, cy=92, R=65 -->
<!-- 4 points on circle: A at 205deg, B at 340deg, C at 55deg, D at 130deg -->
<!-- A=130+65*cos(205)=130-58.9=71.1, 92+65*sin(205)=92-27.5=64.5 => A(71,65) -->
<!-- B=130+65*cos(340)=130+61.1=191.1, 92+65*sin(340)=92-22.2=69.8 => B(191,70) -->
<!-- C=130+65*cos(55)=130+37.3=167.3, 92+65*sin(55)=92+53.2=145.2 => C(167,145) wait -->
<!-- Let me use cleaner angles: A=210deg, B=330deg, C=60deg, D=150deg -->
<!-- A=130+65*cos(210)=130-56.3=73.7, 92+65*sin(210)=92-32.5=59.5 => A(74,60) -->
<!-- B=130+65*cos(330)=130+56.3=186.3, 92+65*sin(330)=92-32.5=59.5 => B(186,60) -->
<!-- C=130+65*cos(60)=130+32.5=162.5, 92+65*sin(60)=92+56.3=148.3 => C(163,148) -->
<!-- D=130+65*cos(150)=130-56.3=73.7, 92+65*sin(150)=92+32.5=124.5 => D(74,125) -->
<!-- chord AB: horizontal line. chord CD: nearly vertical. They should intersect inside. -->
<!-- Intersection of AB(74,60)-(186,60) and CD(163,148)-(74,125): AB is horizontal y=60. CD: param -->
<!-- CD direction: (74-163,125-148)=(-89,-23). Line: (163-89t, 148-23t). At y=60: 148-23t=60 => t=88/23=3.826 -->
<!-- x = 163-89*3.826 = 163-340.5 = -177.5 => outside! Bad choice. -->
<!-- Better: A=200deg, B=20deg, C=80deg, D=280deg -->
<!-- A=130+65*cos(200)=130-61.1=68.9, 92+65*sin(200)=92-22.2=69.8 => A(69,70) -->
<!-- B=130+65*cos(20)=130+61.1=191.1, 92+65*sin(20)=92+22.2=114.2 => B(191,114) -->
<!-- C=130+65*cos(80)=130+11.3=141.3, 92+65*sin(80)=92+64.0=156 => C(141,156) -->
<!-- D=130+65*cos(280)=130+11.3=141.3, 92+65*sin(280)=92-64.0=28 => D(141,28) -->
<!-- chord AB: (69,70)-(191,114). chord CD: (141,156)-(141,28) vertical line x=141 -->
<!-- Intersection: x=141. Line AB param: t=(141-69)/(191-69)=72/122=0.590. y=70+0.590*44=96 => P(141,96) inside circle? dist from ctr: sqrt((141-130)^2+(96-92)^2)=sqrt(121+16)=sqrt(137)=11.7 < 65. Yes! -->
<circle cx="130" cy="92" r="65" fill="rgba(6,182,212,.07)" stroke="#06b6d4" stroke-width="2"/>
<circle cx="130" cy="92" r="3" fill="#0891b2"/>
<!-- chord AB (blue): A(69,70) to B(191,114) -->
<line x1="69" y1="70" x2="191" y2="114" stroke="#0284c7" stroke-width="2.5"/>
<!-- chord CD (red): C(141,156) to D(141,28) -->
<line x1="141" y1="156" x2="141" y2="28" stroke="#dc2626" stroke-width="2.5"/>
<!-- intersection P(141,96) -->
<circle cx="141" cy="96" r="5" fill="#7c3aed"/>
<!-- arc AC: A(200deg) to C(80deg), short arc 120deg going CW in math = CCW on SVG screen, sweep=0, large=0 -->
<path d="M 69,70 A 65,65 0 0,0 141,156" fill="none" stroke="#06b6d4" stroke-width="4"/>
<!-- arc BD: B(20deg) to D(280deg), short arc 100deg going CW in math = CCW on SVG screen, sweep=0, large=0 -->
<path d="M 191,114 A 65,65 0 0,0 141,28" fill="none" stroke="#dc2626" stroke-width="4"/>
<!-- endpoint circles -->
<circle cx="69" cy="70" r="4.5" fill="#0284c7"/>
<circle cx="191" cy="114" r="4.5" fill="#0284c7"/>
<circle cx="141" cy="156" r="4.5" fill="#dc2626"/>
<circle cx="141" cy="28" r="4.5" fill="#dc2626"/>
<!-- angle marker at P between ray PA (direction upper-left) and ray PC (direction downward) -->
<!-- start=P+16*(norm PA)=(141-15,96-5.4)=(126,91). end=P+16*(0,1)=(141,112). sweep=0 CCW -->
<path d="M 126,91 A 16,16 0 0,0 141,112" fill="none" stroke="#7c3aed" stroke-width="2"/>
<text x="131" y="112" font-size="9" fill="#7c3aed">&#945;</text>
<!-- labels -->
<text x="52" y="67" font-size="12" font-weight="700" fill="#0284c7">A</text>
<text x="194" y="118" font-size="12" font-weight="700" fill="#0284c7">B</text>
<text x="145" y="170" font-size="12" font-weight="700" fill="#dc2626">C</text>
<text x="145" y="24" font-size="12" font-weight="700" fill="#dc2626">D</text>
<text x="124" y="93" font-size="11" font-weight="700" fill="#7c3aed">P</text>
<text x="4" y="116" font-size="9" fill="#0284c7">&#8978;AC</text>
<text x="185" y="50" font-size="9" fill="#dc2626">&#8978;BD</text>
<text x="4" y="128" font-size="9" fill="#0891b2">&#945; = &#189;(&#8978;AC+&#8978;BD)</text>
</svg>
</div>`);
@@ -5298,8 +5380,8 @@ function buildP13(){
}
svgWrap.innerHTML=`<svg viewBox="0 0 ${W} ${H}" style="max-width:${W}px;width:100%;background:#fafafa;border:1px solid var(--border);border-radius:10px">
<circle cx="${cx}" cy="${cy}" r="${R}" fill="rgba(6,182,212,.07)" stroke="#06b6d4" stroke-width="2"/>
<path d="M ${Ax} ${Ay} A ${R} ${R} 0 ${a1>180?1:0} 1 ${Ccx} ${Ccy}" fill="rgba(6,182,212,.2)" stroke="#06b6d4" stroke-width="3"/>
<path d="M ${Bx} ${By} A ${R} ${R} 0 ${a2>180?1:0} 1 ${Dx} ${Dy}" fill="rgba(220,38,38,.15)" stroke="#dc2626" stroke-width="2.5"/>
<path d="M ${Ax} ${Ay} A ${R} ${R} 0 ${a1>180?1:0} 1 ${Ccx} ${Ccy}" fill="none" stroke="#06b6d4" stroke-width="4"/>
<path d="M ${Bx} ${By} A ${R} ${R} 0 ${a2>180?1:0} 1 ${Dx} ${Dy}" fill="none" stroke="#dc2626" stroke-width="4"/>
<line x1="${Ax}" y1="${Ay}" x2="${Ccx}" y2="${Ccy}" stroke="#0284c7" stroke-width="2.2"/>
<line x1="${Bx}" y1="${By}" x2="${Dx}" y2="${Dy}" stroke="#dc2626" stroke-width="2.2"/>
<circle cx="${cx}" cy="${cy}" r="3" fill="#0891b2"/>
@@ -5529,24 +5611,52 @@ function buildP14(){
$$\\angle P = \\dfrac{1}{2}(\\smile AB - \\smile CD)$$
<p style="margin-top:8px">$P$ — внешняя точка; секущие пересекают окружность в точках $A$, $B$ и $C$, $D$ соответственно ($PA < PB$, $PC < PD$). Дуга $\\smile AB$ дальняя (большая), $\\smile CD$ ближняя (меньшая).</p>
<div style="display:flex;justify-content:center;margin-top:14px">
<svg viewBox="0 0 300 180" style="max-width:310px;background:#fafafa;border:1px solid var(--border);border-radius:10px">
<circle cx="140" cy="90" r="60" fill="rgba(2,132,199,.07)" stroke="#0284c7" stroke-width="2"/>
<circle cx="140" cy="90" r="3" fill="#0369a1"/>
<circle cx="260" cy="90" r="4.5" fill="#0891b2"/>
<circle cx="195" cy="66" r="4" fill="#dc2626"/>
<circle cx="113" cy="36" r="4" fill="#dc2626"/>
<circle cx="199" cy="101" r="4" fill="#0284c7"/>
<circle cx="88" cy="120" r="4" fill="#0284c7"/>
<line x1="260" y1="90" x2="97" y2="22" stroke="#dc2626" stroke-width="2"/>
<line x1="260" y1="90" x2="74" y2="130" stroke="#0284c7" stroke-width="2"/>
<path d="M 113,36 A 60,60 0 0,1 88,120" fill="rgba(220,38,38,.2)" stroke="#dc2626" stroke-width="3"/>
<path d="M 195,66 A 60,60 0 0,1 199,101" fill="rgba(2,132,199,.2)" stroke="#0284c7" stroke-width="2.5"/>
<text x="258" y="108" font-size="12" font-weight="700" fill="#0891b2">P</text>
<text x="199" y="62" font-size="11" font-weight="700" fill="#dc2626">C</text>
<text x="97" y="30" font-size="11" font-weight="700" fill="#dc2626">A</text>
<text x="203" y="105" font-size="11" font-weight="700" fill="#0284c7">D</text>
<text x="72" y="136" font-size="11" font-weight="700" fill="#0284c7">B</text>
<text x="6" y="90" font-size="9" fill="#0891b2">∠P = ½(⌢AB ⌢CD)</text>
<svg viewBox="0 0 300 185" style="max-width:310px;background:#fafafa;border:1px solid var(--border);border-radius:10px">
<!-- circle cx=130, cy=92, R=60. External point P(272,92). -->
<!-- Secant 1 from P at angle 165deg (pointing upper-left): -->
<!-- dx=cos(165)=-0.9659, dy=sin(165)=0.2588 -->
<!-- fx=272-130=142, fy=92-92=0 -->
<!-- b=2*(142*(-0.9659)+0*0.2588)=2*(-137.16)=-274.32 -->
<!-- c=142^2+0^2-3600=20164-3600=16564 -->
<!-- disc=(-274.32)^2-4*16564=75251-66256=8995, sqrt=94.84 -->
<!-- t1=(-(-274.32)-94.84)/2=(274.32-94.84)/2=89.74 => near C -->
<!-- t2=(274.32+94.84)/2=184.58 => far A -->
<!-- C: (272+89.74*(-0.9659), 92+89.74*0.2588)=(272-86.7, 92+23.2)=(185.3, 115.2) -->
<!-- A: (272+184.58*(-0.9659), 92+184.58*0.2588)=(272-178.3, 92+47.8)=(93.7, 139.8) -->
<!-- Secant 2 from P at angle 195deg (pointing lower-left): -->
<!-- dx=cos(195)=-0.9659, dy=sin(195)=-0.2588 -->
<!-- same |b|, same disc. t1=89.74, t2=184.58 -->
<!-- D: (272-86.7, 92-23.2)=(185.3, 68.8) -->
<!-- B: (272-178.3, 92-47.8)=(93.7, 44.2) -->
<!-- Arc AB (far points): A(94,140) to B(94,44) — large arc on left side (away from P), small arc on right through center -->
<!-- A at angle: atan2(140-92, 94-130)=atan2(48,-36)=127deg. B at atan2(44-92,94-130)=atan2(-48,-36)=233deg -->
<!-- Arc AB from 127 to 233 going CCW (left side, away from P): sweep=1 (CW=0,CCW=1 in SVG) -->
<!-- Actually in SVG arc: sweep-flag=1 means go in positive angle direction. From A(127deg) to B(233deg) -->
<!-- going 127->180->233 is 106 deg, small arc flag=0 -->
<!-- Arc CD (near): C(185,115) at atan2(115-92,185-130)=atan2(23,55)=22.7deg. D(185,69) at atan2(69-92,185-130)=atan2(-23,55)=-22.7deg -->
<!-- Arc CD from C(23deg) to D(-23deg) going CW through 0deg: sweep-flag=0 (CW), arc=46deg, large=0 -->
<circle cx="130" cy="92" r="60" fill="rgba(2,132,199,.07)" stroke="#0284c7" stroke-width="2"/>
<circle cx="130" cy="92" r="3" fill="#0369a1"/>
<!-- arc AB: A(94,140)->B(94,44), short arc 106deg through leftmost point (away from P); SVG CCW=sweep=0,large=0 -->
<path d="M 94,140 A 60,60 0 0,0 94,44" fill="none" stroke="#dc2626" stroke-width="3.5"/>
<!-- arc CD: C(185,115)->D(185,69), short arc 46deg through rightmost point (toward P); SVG CW=sweep=1,large=0 -->
<path d="M 185,115 A 60,60 0 0,1 185,69" fill="none" stroke="#0284c7" stroke-width="3"/>
<!-- secant lines from P through both intersections -->
<line x1="272" y1="92" x2="94" y2="140" stroke="#dc2626" stroke-width="2"/>
<line x1="272" y1="92" x2="94" y2="44" stroke="#0284c7" stroke-width="2"/>
<!-- endpoint dots -->
<circle cx="272" cy="92" r="5" fill="#0891b2"/>
<circle cx="185" cy="115" r="4" fill="#dc2626"/>
<circle cx="94" cy="140" r="4.5" fill="#dc2626"/>
<circle cx="185" cy="69" r="4" fill="#0284c7"/>
<circle cx="94" cy="44" r="4.5" fill="#0284c7"/>
<!-- labels -->
<text x="274" y="108" font-size="12" font-weight="700" fill="#0891b2">P</text>
<text x="188" y="120" font-size="11" font-weight="700" fill="#dc2626">C</text>
<text x="78" y="155" font-size="11" font-weight="700" fill="#dc2626">A</text>
<text x="188" y="65" font-size="11" font-weight="700" fill="#0284c7">D</text>
<text x="78" y="40" font-size="11" font-weight="700" fill="#0284c7">B</text>
<text x="6" y="92" font-size="9" fill="#0891b2">&#8736;P = &#189;(&#8978;AB &#8722; &#8978;CD)</text>
</svg>
</div>`);
@@ -5656,43 +5766,76 @@ function buildP14(){
const slB=document.getElementById('p14-arcB-sl'), slS=document.getElementById('p14-arcS-sl');
const vB=document.getElementById('p14-arcB-val'), vS=document.getElementById('p14-arcS-val');
const svgWrap=document.getElementById('p14-svg-wrap'), info=document.getElementById('p14-info');
const R=60, cx=125, cy=90, W=300, H=184;
const R=60, cx=118, cy=90, W=300, H=184;
const Px=278, Py=90;
// secantPoints: find 2 intersections of line through (Px,Py) at angle theta with circle (cx,cy,R)
// returns [{x,y},{x,y}] sorted by t (near first, far second), or null if no intersection
function secantPoints(theta){
const dx=Math.cos(theta), dy=Math.sin(theta);
const fx=Px-cx, fy=Py-cy;
const b=2*(fx*dx+fy*dy);
const c=fx*fx+fy*fy-R*R;
const disc=b*b-4*c;
if(disc<0) return null;
const t1=(-b-Math.sqrt(disc))/2;
const t2=(-b+Math.sqrt(disc))/2;
return[{x:Px+t1*dx,y:Py+t1*dy},{x:Px+t2*dx,y:Py+t2*dy}];
}
function draw(){
let arcB=+slB.value, arcS=+slS.value;
if(arcS>=arcB-5){arcS=arcB-5;slS.value=arcS;}
vB.textContent=arcB; vS.textContent=arcS;
const ang=Math.round((arcB-arcS)/2);
// A, B endpoints of far chord: arc AB = arcB, symmetric about horizontal from center
const halfB=arcB/2*Math.PI/180;
const Ax=cx+R*Math.cos(Math.PI+halfB), Ay=cy+R*Math.sin(Math.PI+halfB);
const Bx=cx+R*Math.cos(Math.PI-halfB), By=cy+R*Math.sin(Math.PI-halfB);
// C, D endpoints of near chord: arc CD = arcS, symmetric
const halfS=arcS/2*Math.PI/180;
const Ccx=cx+R*Math.cos(Math.PI+halfS), Ccy=cy+R*Math.sin(Math.PI+halfS);
const Dx=cx+R*Math.cos(Math.PI-halfS), Dy=cy+R*Math.sin(Math.PI-halfS);
const large=arcB>180?1:0;
const largeS=arcS>180?1:0;
// Two secant directions from P toward the circle (pointing left from P)
// We want arc AB = arcB and arc CD = arcS, symmetric about horizontal axis
// Use two angles symmetric about PI (pointing left): +(halfB for upper, -halfB for lower)
const halfBRad=arcB/2*Math.PI/180;
const halfSRad=arcS/2*Math.PI/180;
// Secant 1: upper secant through far point A and near point C
// Direction angle = PI + halfB (upward-left for far A), but we want a single line through P
// that intersects circle at C (near, small arc side) and A (far, large arc side).
// The angle from P to the midpoint of arc AB on the left is ~PI.
// Upper secant points in direction PI - halfBRad (slightly upward from left)
const s1=secantPoints(Math.PI-halfBRad);
const s2=secantPoints(Math.PI+halfBRad);
if(!s1||!s2) return;
// s1[0]=C (near), s1[1]=A (far); s2[0]=D (near), s2[1]=B (far)
const Ccx2=s1[0].x, Ccy2=s1[0].y;
const Ax2=s1[1].x, Ay2=s1[1].y;
const Dx2=s2[0].x, Dy2=s2[0].y;
const Bx2=s2[1].x, By2=s2[1].y;
// arc AB: from A to B going through the left side (away from P), large arc when arcB>180
const largeAB=arcB>180?1:0;
// arc CD: from C to D, small arc (near P side), arcS always < 180 in slider range
const largeCD=arcS>180?1:0;
// arc AB: A(upper-left) to B(lower-left). Short arc through leftmost point (away from P) = arcB deg.
// In SVG (y-down): going CCW on screen from A(upper-left) passes through leftmost point to B(lower-left).
// sweep=0 (CCW on screen). large=0 when arcB<180.
const sweepAB=0;
// arc CD: C(upper-near-right) to D(lower-near-right). Short arc through rightmost point (toward P) = arcS deg.
// In SVG: going CW on screen from C(upper-near) passes through rightmost to D(lower-near).
// sweep=1 (CW on screen). large=0 when arcS<180.
const sweepCD=1;
svgWrap.innerHTML=`<svg viewBox="0 0 ${W} ${H}" style="max-width:${W}px;width:100%;background:#fafafa;border:1px solid var(--border);border-radius:10px">
<circle cx="${cx}" cy="${cy}" r="${R}" fill="rgba(2,132,199,.07)" stroke="#0284c7" stroke-width="2"/>
<path d="M ${Ax} ${Ay} A ${R} ${R} 0 ${large} 1 ${Bx} ${By}" fill="rgba(220,38,38,.18)" stroke="#dc2626" stroke-width="3"/>
<path d="M ${Ccx} ${Ccy} A ${R} ${R} 0 ${largeS} 1 ${Dx} ${Dy}" fill="rgba(2,132,199,.18)" stroke="#0284c7" stroke-width="2.5"/>
<line x1="${Px}" y1="${Py}" x2="${Ax+(Ax-Px)*0.05}" y2="${Ay+(Ay-Py)*0.05}" stroke="#dc2626" stroke-width="2"/>
<line x1="${Px}" y1="${Py}" x2="${Bx+(Bx-Px)*0.05}" y2="${By+(By-Py)*0.05}" stroke="#0284c7" stroke-width="2"/>
<path d="M ${Ax2.toFixed(1)} ${Ay2.toFixed(1)} A ${R} ${R} 0 ${largeAB} ${sweepAB} ${Bx2.toFixed(1)} ${By2.toFixed(1)}" fill="none" stroke="#dc2626" stroke-width="3.5"/>
<path d="M ${Ccx2.toFixed(1)} ${Ccy2.toFixed(1)} A ${R} ${R} 0 ${largeCD} ${sweepCD} ${Dx2.toFixed(1)} ${Dy2.toFixed(1)}" fill="none" stroke="#0284c7" stroke-width="3"/>
<line x1="${Px}" y1="${Py}" x2="${Ax2.toFixed(1)}" y2="${Ay2.toFixed(1)}" stroke="#dc2626" stroke-width="2"/>
<line x1="${Px}" y1="${Py}" x2="${Bx2.toFixed(1)}" y2="${By2.toFixed(1)}" stroke="#0284c7" stroke-width="2"/>
<circle cx="${cx}" cy="${cy}" r="3" fill="#0369a1"/>
<circle cx="${Ax}" cy="${Ay}" r="4" fill="#dc2626"/>
<circle cx="${Bx}" cy="${By}" r="4" fill="#0284c7"/>
<circle cx="${Ccx}" cy="${Ccy}" r="3.5" fill="#dc2626"/>
<circle cx="${Dx}" cy="${Dy}" r="3.5" fill="#0284c7"/>
<circle cx="${Ax2.toFixed(1)}" cy="${Ay2.toFixed(1)}" r="4.5" fill="#dc2626"/>
<circle cx="${Bx2.toFixed(1)}" cy="${By2.toFixed(1)}" r="4.5" fill="#0284c7"/>
<circle cx="${Ccx2.toFixed(1)}" cy="${Ccy2.toFixed(1)}" r="3.5" fill="#dc2626"/>
<circle cx="${Dx2.toFixed(1)}" cy="${Dy2.toFixed(1)}" r="3.5" fill="#0284c7"/>
<circle cx="${Px}" cy="${Py}" r="5" fill="#0891b2"/>
<text x="${Ax+(Ax>cx?7:-16)}" y="${Ay+(Ay>cy?15:-4)}" font-size="11" font-weight="700" fill="#dc2626">A</text>
<text x="${Bx+(Bx>cx?7:-16)}" y="${By+(By>cy?15:-4)}" font-size="11" font-weight="700" fill="#0284c7">B</text>
<text x="${Ccx+(Ccx>cx?4:-14)}" y="${Ccy+(Ccy>cy?13:-2)}" font-size="9" font-weight="700" fill="#dc2626">C</text>
<text x="${Dx+(Dx>cx?4:-14)}" y="${Dy+(Dy>cy?13:-2)}" font-size="9" font-weight="700" fill="#0284c7">D</text>
<text x="${(Ax2+(Ax2>cx?7:-17)).toFixed(0)}" y="${(Ay2+(Ay2>cy?15:-4)).toFixed(0)}" font-size="11" font-weight="700" fill="#dc2626">A</text>
<text x="${(Bx2+(Bx2>cx?7:-17)).toFixed(0)}" y="${(By2+(By2>cy?15:-4)).toFixed(0)}" font-size="11" font-weight="700" fill="#0284c7">B</text>
<text x="${(Ccx2+(Ccx2>cx?4:-14)).toFixed(0)}" y="${(Ccy2+(Ccy2>cy?13:-2)).toFixed(0)}" font-size="9" font-weight="700" fill="#dc2626">C</text>
<text x="${(Dx2+(Dx2>cx?4:-14)).toFixed(0)}" y="${(Dy2+(Dy2>cy?13:-2)).toFixed(0)}" font-size="9" font-weight="700" fill="#0284c7">D</text>
<text x="${Px+6}" y="${Py+4}" font-size="11" font-weight="700" fill="#0891b2">P</text>
<text x="${Px-90}" y="${Py-30}" font-size="10" font-weight="700" fill="#7c3aed">P = ${ang}°</text>
<text x="10" y="16" font-size="9" fill="#dc2626">AB=${arcB}°</text>
<text x="10" y="28" font-size="9" fill="#0284c7">CD=${arcS}°</text>
<text x="${Px-95}" y="${Py-28}" font-size="10" font-weight="700" fill="#7c3aed">&#8736;P = ${ang}&#176;</text>
<text x="10" y="16" font-size="9" fill="#dc2626">&#8978;AB=${arcB}&#176;</text>
<text x="10" y="28" font-size="9" fill="#0284c7">&#8978;CD=${arcS}&#176;</text>
</svg>`;
info.textContent='⌢AB = '+arcB+'°, ⌢CD = '+arcS+'° → ∠P = ½('+arcB+''+arcS+') = '+ang+'°';
}