ypv 2 недель назад
Родитель
Сommit
a23d0bed4a
2 измененных файлов с 110 добавлено и 49 удалено
  1. 97 48
      ПМ.03.01/3.1.400/001/index.html
  2. 13 1
      ПМ.03.01/3.1.400/001/specification.md

+ 97 - 48
ПМ.03.01/3.1.400/001/index.html

@@ -229,19 +229,30 @@
         background: var(--ink);
         color: #4af626;
         font-family: 'Roboto Mono', monospace;
-        font-size: 24px;
-        font-weight: 700;
         padding: 10px 16px;
-        text-align: right;
         border-radius: 3px;
         letter-spacing: 1px;
         text-shadow: 0 0 8px rgba(74,246,38,0.6);
         margin: 12px 0;
+        display: flex;
+        flex-direction: column;
+        gap: 6px;
+    }
+    .indicator .row {
         display: flex;
         justify-content: space-between;
         align-items: baseline;
     }
-    .indicator small { font-size: 11px; color: #8aa; letter-spacing: 1px; }
+    .indicator .main {
+        font-size: 24px;
+        font-weight: 700;
+    }
+    .indicator .secondary {
+        font-size: 16px;
+        opacity: 0.8;
+        font-weight: 700;
+    }
+    .indicator small { font-size: 11px; color: #8aa; letter-spacing: 1px; font-weight: 400; }
     .feedback {
         background: rgba(26,74,106,0.06);
         border-left: 3px solid var(--blue);
@@ -444,8 +455,10 @@
                 <div class="viz-caption">Линии магнитного поля: чем ближе магнит, тем гуще и ярче · гальванометр показывает ЭДС</div>
             </div>
             <div class="indicator">
-                <small>ЭДС = −dФ/dt</small>
-                <span><span id="emfValue">0.0</span> мВ</span>
+                <div class="row">
+                    <small>ЭДС = −dФ/dt</small>
+                    <span class="main"><span id="emfValue">0.0</span> мВ</span>
+                </div>
             </div>
             <div class="feedback" id="inductionFeedback">Зажмите магнит и двигайте его.</div>
             <div class="notebook">
@@ -542,7 +555,7 @@
             <p>Источник — провод с переменным током. Среда — магнитное поле. Приёмник — петля сигнального провода. Меняйте ток, частоту, расстояние и площадь петли. Провод можно перетаскивать мышью, углы петли — тянуть и менять площадь.</p>
             <div class="viz">
                 <canvas id="inductiveViz" width="800" height="440"></canvas>
-                <div class="viz-caption">Плотность линий = интенсивность поля · мерцание = частота · стрелка в петле = наведённая ЭДС</div>
+                <div class="viz-caption">Плотность линий = интенсивность поля · мерцание = частота · длина дуги в петле = амплитуда ЭДС</div>
             </div>
             <div class="two-col">
                 <div>
@@ -567,8 +580,14 @@
                 </div>
             </div>
             <div class="indicator">
-                <small>Мгновенная ЭДС = −dФ/dt</small>
-                <span><span id="indResult">0.0</span> мВ</span>
+                <div class="row">
+                    <small>Мгновенная ЭДС = −dФ/dt</small>
+                    <span class="main"><span id="indResult">0.0</span> мВ</span>
+                </div>
+                <div class="row">
+                    <small>Амплитуда (средняя)</small>
+                    <span class="secondary"><span id="indPeak">0.0</span> мВ</span>
+                </div>
             </div>
             <div class="feedback" id="indFeedback">Двигайте ползунки или перетаскивайте провод и углы петли.</div>
             <div class="notebook">
@@ -583,7 +602,7 @@
             <p>Источник — провод с переменным напряжением. Среда — электрическое поле. Приёмник — провод или плата. Меняйте напряжение, частоту, расстояние и площадь. Провод можно перетаскивать мышью, углы приёмника — тянуть и менять площадь.</p>
             <div class="viz">
                 <canvas id="capacitiveViz" width="800" height="440"></canvas>
-                <div class="viz-caption">Плотность линий = напряжённость поля E · мерцание = частота · стрелка на приёмнике = наведённый заряд</div>
+                <div class="viz-caption">Плотность линий = напряжённость поля E · мерцание = частота · длина стрелки = амплитуда наводки</div>
             </div>
             <div class="two-col">
                 <div>
@@ -608,8 +627,14 @@
                 </div>
             </div>
             <div class="indicator">
-                <small>Мгновенное наведённое напряжение</small>
-                <span><span id="capResult">0.0</span> мВ</span>
+                <div class="row">
+                    <small>Мгновенное наведённое напряжение</small>
+                    <span class="main"><span id="capResult">0.0</span> мВ</span>
+                </div>
+                <div class="row">
+                    <small>Амплитуда (средняя)</small>
+                    <span class="secondary"><span id="capPeak">0.0</span> мВ</span>
+                </div>
             </div>
             <div class="feedback" id="capFeedback">Двигайте ползунки или перетаскивайте провод и углы приёмника.</div>
             <div class="notebook">
@@ -645,8 +670,10 @@
                 </div>
             </div>
             <div class="indicator">
-                <small>Помеха в сигнальной цепи</small>
-                <span><span id="galResult">0.0</span> мВ</span>
+                <div class="row">
+                    <small>Помеха в сигнальной цепи</small>
+                    <span class="main"><span id="galResult">0.0</span> мВ</span>
+                </div>
             </div>
             <div class="feedback" id="galFeedback">Двигайте ползунки, чтобы увидеть, как меняется помеха.</div>
             <div class="notebook">
@@ -1544,10 +1571,13 @@
         drawInd8Distance(ctx, wireRight, lx1, (ly1 + ly2) / 2, distCm);
 
         let emfInst = 0;
+        let emfPeak = 0;
         if (f > 1 && I > 0 && areaCm2 > 0) {
-            emfInst = 0.02 * I * areaCm2 * apparentF * Math.sin(ind8.phase) / Math.max(1, distCm);
+            const base = 0.02 * I * areaCm2 * apparentF / Math.max(1, distCm);
+            emfPeak = Math.min(base, 99.9);
+            emfInst = emfPeak * Math.sin(ind8.phase);
         }
-        drawInd8EmfArrow(ctx, lx1, ly1, lx2, ly2, emfInst);
+        drawInd8EmfArrow(ctx, lx1, ly1, lx2, ly2, emfInst, emfPeak);
 
         ctx.fillStyle = '#4a5a7a';
         ctx.font = '11px "Roboto Mono", monospace';
@@ -1557,6 +1587,8 @@
 
         const emfEl = document.getElementById('indResult');
         if (emfEl) emfEl.textContent = emfInst.toFixed(1);
+        const peakEl = document.getElementById('indPeak');
+        if (peakEl) peakEl.textContent = emfPeak.toFixed(1);
 
         const fbEl = document.getElementById('indFeedback');
         if (fbEl) {
@@ -1706,22 +1738,28 @@
         ctx.fillText('d = ' + distCm.toFixed(1) + ' см', (x1 + x2) / 2, y - 6);
     }
 
-    function drawInd8EmfArrow(ctx, x1, y1, x2, y2, emf) {
+    function drawInd8EmfArrow(ctx, x1, y1, x2, y2, emf, peak) {
         const maxEmf = 30;
-        const ratio = Math.min(1, Math.abs(emf) / maxEmf);
-        if (ratio < 0.03) return;
+        const instRatio = Math.min(1, Math.abs(emf) / maxEmf);
+        const peakRatio = Math.min(1, Math.abs(peak) / maxEmf);
+        if (peakRatio < 0.02 && instRatio < 0.02) return;
 
         const cx = (x1 + x2) / 2;
         const cy = (y1 + y2) / 2;
-        const r = Math.min(x2 - x1, y2 - y1) * 0.28;
-        if (r < 8) return;
+        const baseR = Math.min(x2 - x1, y2 - y1) * 0.28;
+        if (baseR < 8) return;
 
-        const alpha = 0.35 + ratio * 0.6;
-        const clockwise = emf >= 0;
-        const lw = 2 + ratio * 3;
+        // Длина дуги зависит от АМПЛИТУДЫ (peakRatio), а не от мгновенного значения
+        // Это убирает «мельтешение» длины при высокой частоте
+        const spanFactor = 0.25 + 0.75 * peakRatio;
+        const lw = 1.5 + instRatio * 3.5;
+        const alpha = 0.25 + instRatio * 0.7;
 
-        const A = -Math.PI * 0.85;
-        const B = Math.PI * 0.55;
+        const A = -Math.PI * 0.85 * spanFactor;
+        const B = Math.PI * 0.55 * spanFactor;
+        const r = baseR;
+
+        const clockwise = emf >= 0;
 
         ctx.save();
         ctx.translate(cx, cy);
@@ -1746,7 +1784,7 @@
             tang = A - Math.PI / 2;
         }
 
-        const size = 6 + ratio * 6;
+        const size = 5 + instRatio * 7;
         const tipX = hx + Math.cos(tang) * size;
         const tipY = hy + Math.sin(tang) * size;
         const perpX = Math.cos(tang + Math.PI / 2);
@@ -1767,12 +1805,13 @@
         ctx.restore();
         ctx.lineCap = 'butt';
 
+        // Подпись: амплитуда (средняя), чтобы не мельтешило
         ctx.fillStyle = '#8b1a1a';
-        ctx.font = 'bold 12px "Roboto Mono", monospace';
+        ctx.font = 'bold 11px "Roboto Mono", monospace';
         ctx.textAlign = 'center';
         ctx.textBaseline = 'middle';
         const sign = emf >= 0 ? '+' : '−';
-        ctx.fillText(sign + Math.abs(emf).toFixed(1) + ' мВ', cx, cy + r + 18);
+        ctx.fillText(sign + ' ' + Math.abs(peak).toFixed(1) + ' мВ', cx, cy + r + 18);
     }
 
     // === СЦЕНА 9: Ёмкостная наводка ===
@@ -2053,7 +2092,15 @@
         drawCap8Source(ctx, s, Uinst);
         drawCap8Receiver(ctx, r, Uinst, Uabs, areaCm2);
         drawCap8Distance(ctx, srcRight, recvLeft, (overlapTop + overlapBot) / 2, distCm);
-        drawCap8CurrentArrow(ctx, srcRight, recvLeft, overlapTop, overlapBot, Uinst, f);
+
+        let vInst = 0;
+        let vPeak = 0;
+        if (f > 1 && U > 0 && areaCm2 > 0) {
+            const base = 0.02 * U * areaCm2 * apparentF / Math.max(1, distCm * distCm);
+            vPeak = Math.min(base, 99.9);
+            vInst = vPeak * Math.sin(cap8.phase);
+        }
+        drawCap8CurrentArrow(ctx, srcRight, recvLeft, overlapTop, overlapBot, vInst, vPeak, f);
 
         ctx.fillStyle = '#4a5a7a';
         ctx.font = '11px "Roboto Mono", monospace';
@@ -2061,15 +2108,10 @@
         ctx.textBaseline = 'alphabetic';
         ctx.fillText('S = ' + areaCm2.toFixed(0) + ' см²', r.x1 - 4, r.y1 - 24);
 
-        let vInst = 0;
-        if (f > 1 && U > 0 && areaCm2 > 0) {
-            vInst = 0.02 * U * areaCm2 * apparentF * Math.sin(cap8.phase) / Math.max(1, distCm * distCm);
-            if (vInst > 99.9) vInst = 99.9;
-            if (vInst < -99.9) vInst = -99.9;
-        }
-
         const resEl = document.getElementById('capResult');
         if (resEl) resEl.textContent = vInst.toFixed(1);
+        const peakEl = document.getElementById('capPeak');
+        if (peakEl) peakEl.textContent = vPeak.toFixed(1);
 
         const fbEl = document.getElementById('capFeedback');
         if (fbEl) {
@@ -2239,21 +2281,26 @@
         ctx.fillText('d = ' + distCm.toFixed(1) + ' см', (x1 + x2) / 2, y - 6);
     }
 
-    function drawCap8CurrentArrow(ctx, x1, x2, top, bot, Uinst, f) {
+    function drawCap8CurrentArrow(ctx, x1, x2, top, bot, inst, peak, f) {
         if (f <= 1) return;
         const midX = (x1 + x2) / 2;
         const midY = (top + bot) / 2;
         if (!isFinite(midY)) return;
 
-        const Iinst = -Math.sin(cap8.phase);
-        const ratio = Math.abs(Iinst);
-        const alpha = 0.4 + ratio * 0.55;
-        const lw = 2 + ratio * 2;
+        const instRatio = Math.min(1, Math.abs(inst) / 30);
+        const peakRatio = Math.min(1, Math.abs(peak) / 30);
+        if (peakRatio < 0.02 && instRatio < 0.02) return;
+
+        const alpha = 0.25 + instRatio * 0.7;
+        const lw = 1.5 + instRatio * 2.5;
 
-        const arrowLen = Math.min(40, (x2 - x1) * 0.3);
-        if (arrowLen < 10) return;
+        const baseLen = Math.min(40, (x2 - x1) * 0.3);
+        if (baseLen < 6) return;
+        // Длина стрелки зависит от АМПЛИТУДЫ (peak), а не от мгновенного значения
+        // Это убирает «мельтешение» длины
+        const arrowLen = baseLen * (0.25 + 0.75 * peakRatio);
 
-        const dir = Iinst >= 0 ? 1 : -1;
+        const dir = inst >= 0 ? 1 : -1;
         const tipX = midX + dir * arrowLen;
         const tailX = midX - dir * arrowLen * 0.4;
 
@@ -2265,7 +2312,7 @@
         ctx.lineTo(tipX, midY);
         ctx.stroke();
 
-        const size = 6 + ratio * 5;
+        const size = 5 + instRatio * 5;
         ctx.beginPath();
         ctx.moveTo(tipX, midY);
         ctx.lineTo(tipX - dir * size, midY - size * 0.6);
@@ -2275,11 +2322,13 @@
         ctx.fill();
         ctx.lineCap = 'butt';
 
+        // Подпись: амплитуда (средняя), чтобы не мельтешило
         ctx.fillStyle = '#8b1a1a';
-        ctx.font = 'bold 10px "Roboto Mono", monospace';
+        ctx.font = 'bold 11px "Roboto Mono", monospace';
         ctx.textAlign = 'center';
         ctx.textBaseline = 'top';
-        ctx.fillText('ток смещения', midX, midY + 12);
+        const sign = inst >= 0 ? '+' : '−';
+        ctx.fillText(sign + ' ' + Math.abs(peak).toFixed(1) + ' мВ', midX, midY + 14);
     }
 
     // === СЦЕНА 10: Гальваническая наводка ===

+ 13 - 1
ПМ.03.01/3.1.400/001/specification.md

@@ -202,7 +202,19 @@
 - расстояние max → поле слабое;<br>
 - площадь min → мало заряда на приёмнике.
 
-
+<td> 8 </td><td> Механизм 2 · ёмкостный / Механизм 1 · индуктивный</td><td> В обоих сценах линия тока в приемнике не изменяется при изменении параметров прибора. </td><td> Надо: чем больше наводка, тем длиннее линия. Надо добавить еще один выводимы параметр: Среднее напряжение / ток для соответствующих сцен, потому-что при высокой частоте мгновенное значение сильно мельтешит</td><td> 3.1.400/001_m2_2 </td>
+</tr><tr valign="top" textalign="left">
+<td colspan=5> 
+<b>1. Длина дуги/стрелки теперь зависит от амплитуды, а не мельтешит.</b><br>
+Для индуктивной наводки (сцена 8) в drawInd8EmfArrow добавлен параметр peak. Угол дуги (spanFactor) теперь привязан к амплитуде: spanFactor = 0.25 + 0.75 * peakRatio. То есть при слабой наводке дуга занимает ~25% от базового сегмента, при сильной — 100%. При этом цвет/толщина/направление стрелки по-прежнему реагируют на мгновенное значение — видно, что поле переменное, но общий размер дуги стабилен и отражает амплитуду.<br>
+Аналогично для ёмкостной наводки (сцена 9) в drawCap8CurrentArrow добавлен параметр peak. Длина стрелки: arrowLen = baseLen * (0.25 + 0.75 * peakRatio).<br>
+<b>2. Добавлен выводимый параметр "Амплитуда (средняя)".</b><br>
+В индикаторах сцен 8 и 9 появилась вторая строка. Мгновенное значение (indResult, capResult) по-прежнему мельтешит с частотой, а амплитуда (indPeak, capPeak) — стабильная и показывает реальную интенсивность наводки. Это тот самый параметр, который нужен для оценки степени утечки, когда частота высокая.<br>
+<b>3. Индикатор перестроен в две строки.</b><br>
+В CSS добавлен класс .indicator .row для гибкой раскладки. Мгновенное значение — крупным шрифтом (24px), амплитуда — поменьше (16px), с меньшей прозрачностью. Визуально иерархия сохраняется.<br>
+<b>4. Подписи под стрелками.</b><br>
+В сцене 8 подпись + X мВ под дугой теперь показывает амплитуду, а не мгновенное значение — чтобы не мельтешила. Знак +/− по-прежнему отражает мгновенное направление.<br>
+В сцене 9 аналогично: + X мВ под стрелкой тока смещения — амплитуда.
 </tr></table>
 ---