fix(geom8 ch4): §4 — маркеры прямого угла к центру O во всех SVG

Тот же системный фикс что и в §3: маркер прямого угла в точке
касания T должен быть ВНУТРИ треугольника OTA (между T→O и T→A).
Раньше использовалось +u_radius (наружу от центра) — теперь
-u_radius (к центру O).

Затронуты:
- §4 Card 4.1 (задача построения): 2 маркера в T₁, T₂
- §4 Card 4.3 (длина касательной): 1 маркер в T
- §4 Интерактив 1 (пошаговое построение, шаги 4-5): 2 маркера

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Maxim Dolgolyov
2026-05-28 18:52:56 +03:00
parent ca6b93fb57
commit 892024f6a3
+15 -13
View File
@@ -1690,10 +1690,13 @@ function buildP4(){
<circle cx="165" cy="100" r="3" fill="#f59e0b"/>
<circle cx="107" cy="53" r="4" fill="#10b981"/>
<circle cx="107" cy="147" r="4" fill="#10b981"/>
<!-- right-angle at T₂=(107,53): u_r=(0.34,-0.94) u_t_CCW=(0.94,0.34) toward A s=8 -->
<polyline points="109.7,45.5 117.2,48.2 114.5,55.7" fill="none" stroke="#1d4ed8" stroke-width="1.6"/>
<!-- right-angle at T₁=(107,147): u_r=(0.34,0.94) u_t_CW=(0.94,-0.34) toward A s=8 -->
<polyline points="109.7,154.5 117.2,151.8 114.5,144.3" fill="none" stroke="#1d4ed8" stroke-width="1.6"/>
<!-- right-angle at T₂=(107,53): arms toward O and toward A (INSIDE △OT₂A) -->
<!-- toO=(-0.34,0.94); u_t=(0.94,0.34); s=8 -->
<!-- p1=T₂+8·toO=(104.3,60.5) corner=(111.8,63.2) p2=T₂+8·u_t=(114.5,55.7) -->
<polyline points="104.3,60.5 111.8,63.2 114.5,55.7" fill="none" stroke="#1d4ed8" stroke-width="1.8"/>
<!-- right-angle at T₁=(107,147): toO=(-0.34,-0.94); u_t=(0.94,-0.34); s=8 -->
<!-- p1=T₁+8·toO=(104.3,139.5) corner=(111.8,136.8) p2=T₁+8·u_t=(114.5,144.3) -->
<polyline points="104.3,139.5 111.8,136.8 114.5,144.3" fill="none" stroke="#1d4ed8" stroke-width="1.8"/>
<!-- labels -->
<text x="74" y="97" font-size="11" font-weight="700" fill="#1d4ed8">O</text>
<text x="244" y="97" font-size="11" font-weight="700" fill="#1d4ed8">A</text>
@@ -1735,8 +1738,9 @@ function buildP4(){
<line x1="89" y1="59" x2="205" y2="105" stroke="#10b981" stroke-width="2.2"/>
<!-- OA base line -->
<line x1="70" y1="105" x2="205" y2="105" stroke="#64748b" stroke-width="1.5" stroke-dasharray="4,3"/>
<!-- right-angle at T=(89,59): u_r=(0.38,-0.92) u_t=(0.92,0.38) s=8 -->
<polyline points="92.0,51.6 99.4,54.6 96.4,62.0" fill="none" stroke="#1d4ed8" stroke-width="1.6"/>
<!-- right-angle at T=(89,59): toO=(-0.38,0.92) u_t toward A=(0.92,0.38) s=8 -->
<!-- p1=T+8·toO=(85.96,66.36) corner=(93.36,69.4) p2=T+8·u_t=(96.36,62.04) -->
<polyline points="85.96,66.36 93.36,69.4 96.36,62.04" fill="none" stroke="#1d4ed8" stroke-width="1.8"/>
<!-- labels off their respective lines -->
<text x="54" y="102" font-size="11" font-weight="700" fill="#1d4ed8">O</text>
<text x="209" y="109" font-size="11" font-weight="700" fill="#1d4ed8">A</text>
@@ -1869,14 +1873,12 @@ function buildP4(){
const ur2x=(T2X-OX)/R, ur2y=(T2Y-OY)/R;
extras+=`<text x="${(T1X+ur1x*15-5).toFixed(1)}" y="${(T1Y+ur1y*15+4).toFixed(1)}" font-size="11" font-weight="700" fill="#065f46">T₁</text>`;
extras+=`<text x="${(T2X+ur2x*15-5).toFixed(1)}" y="${(T2Y+ur2y*15+10).toFixed(1)}" font-size="11" font-weight="700" fill="#065f46">T₂</text>`;
/* right-angle markers: ut must point TOWARD A from each tangent point */
/* T1 is upper (ur1y<0): CCW perp = down-right = toward A */
const ut1x=-ur1y, ut1y=ur1x;
/* right-angle markers: arms toward O (INSIDE △OTA) and toward A */
const ut1x=-ur1y, ut1y=ur1x; // CCW perp = toward A for upper T1
const s=8;
const rm1=`${(T1X+ur1x*s).toFixed(1)},${(T1Y+ur1y*s).toFixed(1)} ${(T1X+ur1x*s+ut1x*s).toFixed(1)},${(T1Y+ur1y*s+ut1y*s).toFixed(1)} ${(T1X+ut1x*s).toFixed(1)},${(T1Y+ut1y*s).toFixed(1)}`;
/* T2 is lower (ur2y>0): CW perp = up-right = toward A ✓ */
const ut2x=ur2y, ut2y=-ur2x;
const rm2=`${(T2X+ur2x*s).toFixed(1)},${(T2Y+ur2y*s).toFixed(1)} ${(T2X+ur2x*s+ut2x*s).toFixed(1)},${(T2Y+ur2y*s+ut2y*s).toFixed(1)} ${(T2X+ut2x*s).toFixed(1)},${(T2Y+ut2y*s).toFixed(1)}`;
const rm1=`${(T1X-ur1x*s).toFixed(1)},${(T1Y-ur1y*s).toFixed(1)} ${(T1X-ur1x*s+ut1x*s).toFixed(1)},${(T1Y-ur1y*s+ut1y*s).toFixed(1)} ${(T1X+ut1x*s).toFixed(1)},${(T1Y+ut1y*s).toFixed(1)}`;
const ut2x=ur2y, ut2y=-ur2x; // CW perp = toward A for lower T2
const rm2=`${(T2X-ur2x*s).toFixed(1)},${(T2Y-ur2y*s).toFixed(1)} ${(T2X-ur2x*s+ut2x*s).toFixed(1)},${(T2Y-ur2y*s+ut2y*s).toFixed(1)} ${(T2X+ut2x*s).toFixed(1)},${(T2Y+ut2y*s).toFixed(1)}`;
extras+=`<polyline points="${rm1}" fill="none" stroke="#1d4ed8" stroke-width="1.6"/>`;
extras+=`<polyline points="${rm2}" fill="none" stroke="#1d4ed8" stroke-width="1.6"/>`;
}