fix(geom8 ch4): аудит §12-§16 — корректные точки на окружности и пересечения хорд

Найдено 6 геометрических SVG-фиксов (LaTeX везде чист):

§13 Card 13.1 (две хорды): точки A,B,C,D были смещены от окружности,
точка P не лежала на обеих хордах. Пересчитаны через
(cx+R·cos θ, cy+R·sin θ) с r=65; P=(126,74) — настоящее пересечение
хорд AB и CD.

§13 Proof: углы 210°/290°/350°/70° давали хорды AC и BD которые
НЕ пересекались внутри окружности. Изменены на 220°/10°/130°/300° —
P=(119,71) внутри.

§14 Card 14.1: точки секущих не лежали на окружности и линии от P
не проходили через обе точки пересечения. Пересчитаны как реальные
пересечения секущих с окружностью при углах ±20°/-10°.

§14 Proof: A,B,C,D построены как окружностные точки без проверки
коллинеарности с P. Заменены на построение через хелпер _sec()
с углами ±15° от P.

§15 Card 15.1: P=(116,87) но хорды пересекались в (114.7,88.1) —
2px разница. P сдвинут на (114,88); концы хорд пересчитаны
точно на окружность r=65.

§16 Card 16.1: T не была настоящей точкой касания (OT⊥PT нарушено).
T пересчитана как настоящая касательная из P через asin(R/|OP|);
добавлен маркер прямого угла; A,B заменены на реальные пересечения
секущей.

KaTeX-эскейпы в §12-§16 проверены — все \angle, \dfrac и т.п.
корректно удвоены. Математика в задачах проверена выборочно — без
ошибок.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Maxim Dolgolyov
2026-05-28 20:15:22 +03:00
parent b400366f06
commit 9b6a9adaf9
+61 -55
View File
@@ -5150,21 +5150,21 @@ function buildP13(){
<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="57" cy="75" r="4" fill="#0284c7"/>
<circle cx="170" cy="40" r="4" fill="#0284c7"/>
<circle cx="75" cy="148" r="4" fill="#dc2626"/>
<circle cx="177" cy="130" r="4" fill="#dc2626"/>
<line x1="57" y1="75" x2="177" y2="130" stroke="#0284c7" stroke-width="2"/>
<line x1="75" y1="148" x2="170" y2="40" stroke="#dc2626" stroke-width="2"/>
<circle cx="116" cy="100" r="4.5" fill="#7c3aed"/>
<path d="M 57,75 A 65,65 0 0,1 170,40" fill="rgba(6,182,212,.2)" stroke="#06b6d4" stroke-width="2.5"/>
<path d="M 75,148 A 65,65 0 0,1 177,130" fill="rgba(220,38,38,.15)" stroke="#dc2626" stroke-width="2.5"/>
<text x="40" y="70" font-size="11" font-weight="700" fill="#0284c7">A</text>
<text x="174" y="36" font-size="11" font-weight="700" fill="#0284c7">C</text>
<text x="60" y="163" font-size="11" font-weight="700" fill="#dc2626">B</text>
<text x="181" y="134" font-size="11" font-weight="700" fill="#dc2626">D</text>
<text x="100" y="98" font-size="11" font-weight="700" fill="#7c3aed">P</text>
<text x="198" y="80" font-size="9" fill="#0891b2">½(⌢AC+⌢BD)</text>
<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>
</div>`);
@@ -5326,8 +5326,8 @@ function buildP13(){
/* === INIT 2: пошаговое доказательство === */
(function(){
const R=55, cx=115, cy=85, W=250, H=175;
const aA=210*Math.PI/180, aC=290*Math.PI/180;
const aB=350*Math.PI/180, aD=70*Math.PI/180;
const aA=220*Math.PI/180, aC=10*Math.PI/180;
const aB=130*Math.PI/180, aD=300*Math.PI/180;
const Ax=cx+R*Math.cos(aA), Ay=cy+R*Math.sin(aA);
const Ccx=cx+R*Math.cos(aC), Ccy=cy+R*Math.sin(aC);
const Bx=cx+R*Math.cos(aB), By=cy+R*Math.sin(aB);
@@ -5533,19 +5533,19 @@ function buildP14(){
<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="91" cy="55" r="4" fill="#dc2626"/>
<circle cx="188" cy="50" r="4" fill="#dc2626"/>
<circle cx="100" cy="128" r="4" fill="#0284c7"/>
<circle cx="196" cy="133" r="4" fill="#0284c7"/>
<line x1="260" y1="90" x2="76" y2="47" stroke="#dc2626" stroke-width="2"/>
<line x1="260" y1="90" x2="86" y2="135" stroke="#0284c7" stroke-width="2"/>
<path d="M 91,55 A 60,60 0 0,1 188,50" fill="rgba(220,38,38,.2)" stroke="#dc2626" stroke-width="3"/>
<path d="M 100,128 A 60,60 0 0,0 196,133" fill="rgba(2,132,199,.2)" stroke="#0284c7" stroke-width="2.5"/>
<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="78" y="47" font-size="11" font-weight="700" fill="#dc2626">C</text>
<text x="190" y="44" font-size="11" font-weight="700" fill="#dc2626">A</text>
<text x="86" y="144" font-size="11" font-weight="700" fill="#0284c7">D</text>
<text x="198" y="148" font-size="11" font-weight="700" fill="#0284c7">B</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>
</div>`);
@@ -5704,10 +5704,15 @@ function buildP14(){
(function(){
const R=52, cx=105, cy=80, W=260, H=165;
const Px=242, Py=80;
const Ax=cx+R*Math.cos(Math.PI+60*Math.PI/180), Ay=cy+R*Math.sin(Math.PI+60*Math.PI/180);
const Bx=cx+R*Math.cos(Math.PI-60*Math.PI/180), By=cy+R*Math.sin(Math.PI-60*Math.PI/180);
const Ccx=cx+R*Math.cos(Math.PI+25*Math.PI/180), Ccy=cy+R*Math.sin(Math.PI+25*Math.PI/180);
const Dx=cx+R*Math.cos(Math.PI-25*Math.PI/180), Dy=cy+R*Math.sin(Math.PI-25*Math.PI/180);
// Secants from P: computed as actual intersections with the circle
const _base=Math.atan2(cy-Py,cx-Px);
function _sec(offDeg){const a=_base+offDeg*Math.PI/180,dx=Math.cos(a),dy=Math.sin(a),b=2*((Px-cx)*dx+(Py-cy)*dy),c=(Px-cx)**2+(Py-cy)**2-R*R,d=b*b-4*c,t1=(-b-Math.sqrt(d))/2,t2=(-b+Math.sqrt(d))/2;return[{x:Px+t1*dx,y:Py+t1*dy},{x:Px+t2*dx,y:Py+t2*dy}];}
const _s1=_sec(15), _s2=_sec(-15);
// s1: near=C, far=A; s2: near=D, far=B
const Ccx=_s1[0].x, Ccy=_s1[0].y;
const Ax=_s1[1].x, Ay=_s1[1].y;
const Dx=_s2[0].x, Dy=_s2[0].y;
const Bx=_s2[1].x, By=_s2[1].y;
const steps=[
{text:'<b>Дано:</b> Из точки $P$ вне окружности проведены две секущие. Одна пересекает в $C, A$ ($C$ ближе к $P$), другая — в $D, B$ ($D$ ближе к $P$). Доказать: $\\angle P = \\dfrac{1}{2}(\\smile AB - \\smile CD)$.'},
{text:'<b>Шаг 1.</b> Соединим точки $A$ и $D$. Рассмотрим треугольник $\\triangle PAD$.'},
@@ -5904,19 +5909,19 @@ function buildP15(){
<svg viewBox="0 0 270 180" style="max-width:290px;background:#fafafa;border:1px solid var(--border);border-radius:10px">
<circle cx="120" cy="90" r="65" fill="rgba(16,185,129,.07)" stroke="#10b981" stroke-width="2"/>
<circle cx="120" cy="90" r="3" fill="#059669"/>
<circle cx="58" cy="70" r="4" fill="#0284c7"/>
<circle cx="184" cy="107" r="4" fill="#0284c7"/>
<circle cx="73" cy="145" r="4" fill="#dc2626"/>
<circle cx="170" cy="44" r="4" fill="#dc2626"/>
<line x1="58" y1="70" x2="184" y2="107" stroke="#0284c7" stroke-width="2.2"/>
<line x1="73" y1="145" x2="170" y2="44" stroke="#dc2626" stroke-width="2.2"/>
<circle cx="116" cy="87" r="5" fill="#7c3aed"/>
<text x="41" y="66" font-size="11" font-weight="700" fill="#0284c7">A</text>
<text x="188" y="111" font-size="11" font-weight="700" fill="#0284c7">B</text>
<text x="57" y="159" font-size="11" font-weight="700" fill="#dc2626">C</text>
<text x="174" y="40" font-size="11" font-weight="700" fill="#dc2626">D</text>
<text x="100" y="84" font-size="11" font-weight="700" fill="#7c3aed">P</text>
<text x="186" y="65" font-size="9" fill="#059669">PA·PB = PC·PD</text>
<circle cx="59" cy="68" r="4" fill="#0284c7"/>
<circle cx="181" cy="112" r="4" fill="#0284c7"/>
<circle cx="78" cy="140" r="4" fill="#dc2626"/>
<circle cx="153" cy="34" r="4" fill="#dc2626"/>
<line x1="59" y1="68" x2="181" y2="112" stroke="#0284c7" stroke-width="2.2"/>
<line x1="78" y1="140" x2="153" y2="34" stroke="#dc2626" stroke-width="2.2"/>
<circle cx="114" cy="88" r="5" fill="#7c3aed"/>
<text x="43" y="64" font-size="11" font-weight="700" fill="#0284c7">A</text>
<text x="185" y="116" font-size="11" font-weight="700" fill="#0284c7">B</text>
<text x="62" y="154" font-size="11" font-weight="700" fill="#dc2626">C</text>
<text x="157" y="30" font-size="11" font-weight="700" fill="#dc2626">D</text>
<text x="98" y="85" font-size="11" font-weight="700" fill="#7c3aed">P</text>
<text x="183" y="65" font-size="9" fill="#059669">PA·PB = PC·PD</text>
</svg>
</div>`);
@@ -6306,16 +6311,17 @@ function buildP16(){
<circle cx="130" cy="95" r="65" fill="rgba(124,58,237,.07)" stroke="#7c3aed" stroke-width="2"/>
<circle cx="130" cy="95" r="3" fill="#5b21b6"/>
<circle cx="260" cy="95" r="5" fill="#0891b2"/>
<circle cx="76" cy="57" r="4.5" fill="#dc2626"/>
<circle cx="83" cy="142" r="4" fill="#0284c7"/>
<circle cx="193" cy="138" r="4" fill="#0284c7"/>
<line x1="260" y1="95" x2="60" y2="45" stroke="#dc2626" stroke-width="2.5"/>
<line x1="260" y1="95" x2="68" y2="149" stroke="#0284c7" stroke-width="2"/>
<line x1="130" y1="95" x2="76" y2="57" stroke="#5b21b6" stroke-width="1.4" stroke-dasharray="3,3"/>
<circle cx="163" cy="151" r="4.5" fill="#dc2626"/>
<circle cx="192" cy="77" r="4" fill="#0284c7"/>
<circle cx="85" cy="48" r="4" fill="#0284c7"/>
<line x1="260" y1="95" x2="153" y2="158" stroke="#dc2626" stroke-width="2.5"/>
<line x1="260" y1="95" x2="68" y2="42" stroke="#0284c7" stroke-width="2"/>
<line x1="130" y1="95" x2="163" y2="151" stroke="#5b21b6" stroke-width="1.4" stroke-dasharray="3,3"/>
<polyline points="159,144 152,148 156,155" fill="none" stroke="#5b21b6" stroke-width="1.6"/>
<text x="258" y="113" font-size="12" font-weight="700" fill="#0891b2">P</text>
<text x="64" y="50" font-size="11" font-weight="700" fill="#dc2626">T</text>
<text x="69" y="162" font-size="11" font-weight="700" fill="#0284c7">A</text>
<text x="197" y="153" font-size="11" font-weight="700" fill="#0284c7">B</text>
<text x="154" y="168" font-size="11" font-weight="700" fill="#dc2626">T</text>
<text x="196" y="73" font-size="11" font-weight="700" fill="#0284c7">A</text>
<text x="70" y="38" font-size="11" font-weight="700" fill="#0284c7">B</text>
<text x="128" y="91" font-size="9" font-weight="700" fill="#5b21b6">O</text>
<text x="10" y="72" font-size="9" fill="#dc2626">PT</text>
<text x="10" y="90" font-size="9" fill="#0284c7">PA · PB</text>