From e22405516ba88c55b60672770ae12b57112c47f9 Mon Sep 17 00:00:00 2001 From: Maxim Dolgolyov Date: Thu, 28 May 2026 08:56:35 +0300 Subject: [PATCH] =?UTF-8?q?fix(geom8):=20=C2=A73=20=D0=B2=D0=BD=D0=B5?= =?UTF-8?q?=D1=88=D0=BD=D0=B8=D0=B5=20=D1=83=D0=B3=D0=BB=D1=8B=20=E2=80=94?= =?UTF-8?q?=20=D0=BA=D0=BE=D1=80=D1=80=D0=B5=D0=BA=D1=82=D0=BD=D0=B0=D1=8F?= =?UTF-8?q?=20=D0=B3=D0=B5=D0=BE=D0=BC=D0=B5=D1=82=D1=80=D0=B8=D1=8F=20?= =?UTF-8?q?=D0=B2=D0=B8=D0=B7=D1=83=D0=B0=D0=BB=D0=B8=D0=B7=D0=B0=D1=86?= =?UTF-8?q?=D0=B8=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Было: продолжение рисовалось от next-vertex назад через v, дуга центрировалась у next-vertex с углом из произвольного направления — углы отображались неправильно (не у тех вершин, не в тех направлениях). Стало: для каждой вершины v вычисляются prev/next, направления u=(v-prev)/|·| (входящая сторона), w=(next-v)/|·| (исходящая). Продолжение u рисуется от v дальше. Дуга — сектор у v от u-направления до w-направления, sweep определяется через знак векторного произведения (u×w). Подпись угла — по биссектрисе дуги на радиусе Rlabel. Co-Authored-By: Claude Opus 4.7 (1M context) --- frontend/textbooks/geometry_8_ch1.html | 33 ++++++++++++++------------ 1 file changed, 18 insertions(+), 15 deletions(-) diff --git a/frontend/textbooks/geometry_8_ch1.html b/frontend/textbooks/geometry_8_ch1.html index d2b085f..48baddf 100644 --- a/frontend/textbooks/geometry_8_ch1.html +++ b/frontend/textbooks/geometry_8_ch1.html @@ -1433,26 +1433,29 @@ function buildP3(){ function pts(nv){ const v=[];for(let i=0;i'; s+=''; vs.forEach((v,i)=>{ - const nxt=vs[(i+1)%n]; - const ext=40; - const dx=v.x-nxt.x,dy=v.y-nxt.y; - const len=Math.hypot(dx,dy); - const ex=v.x+ext*dx/len,ey=v.y+ext*dy/len; - s+=''; + const prev=vs[(i-1+n)%n], next=vs[(i+1)%n]; + const ux=v.x-prev.x, uy=v.y-prev.y, ul=Math.hypot(ux,uy); + const wx=next.x-v.x, wy=next.y-v.y, wl=Math.hypot(wx,wy); + const u={x:ux/ul, y:uy/ul}, w={x:wx/wl, y:wy/wl}; + const ex=v.x+extLen*u.x, ey=v.y+extLen*u.y; + s+=''; + const sx=v.x+Rarc*u.x, sy=v.y+Rarc*u.y; + const tx=v.x+Rarc*w.x, ty=v.y+Rarc*w.y; + const cross=u.x*w.y - u.y*w.x; + const sweep=cross>0?1:0; const extAngle=360/n; - const startAng=Math.atan2(v.y-nxt.y,v.x-nxt.x)*180/Math.PI; - const endAng=startAng-extAngle; - const ra=Rext,sa=startAng*(Math.PI/180),ea=endAng*(Math.PI/180); - const x1=nxt.x+ra*Math.cos(sa),y1=nxt.y+ra*Math.sin(sa); - const x2=nxt.x+ra*Math.cos(ea),y2=nxt.y+ra*Math.sin(ea); - const large=extAngle>180?1:0; - s+=''; - s+=''+(extAngle.toFixed(1))+'°'; + s+=''; + let aU=Math.atan2(u.y,u.x), aW=Math.atan2(w.y,w.x); + if(sweep===1){ if(aWaU) aW-=2*Math.PI; } + const mid=(aU+aW)/2; + const lx=v.x+Rlabel*Math.cos(mid), ly=v.y+Rlabel*Math.sin(mid); + s+=''+extAngle.toFixed(1).replace(/\.0$/,'')+'°'; }); - vs.forEach((v,i)=>{ + vs.forEach(v=>{ s+=''; }); s+='';