diff --git a/frontend/js/phys-fx.js b/frontend/js/phys-fx.js
index 4bd9793..317a209 100644
--- a/frontend/js/phys-fx.js
+++ b/frontend/js/phys-fx.js
@@ -832,4 +832,205 @@ class Transformer {
}
P.Transformer = Transformer;
+/* ============================================================ */
+/* TwoSlit — интерференция от двух щелей (опыт Юнга) */
+/* ============================================================ */
+
+class TwoSlit {
+ constructor(container, opts){
+ opts = opts || {};
+ this.el = (typeof container === 'string') ? document.querySelector(container) : container;
+ this.W = opts.width || 540;
+ this.H = opts.height || 200;
+ this.d = opts.d !== undefined ? opts.d : 0.5; /* расстояние между щелями (отн. ед.) */
+ this.L = opts.L !== undefined ? opts.L : 5; /* расстояние до экрана */
+ this.lambda = opts.lambda !== undefined ? opts.lambda : 0.05; /* длина волны */
+ this.color = opts.color || '#f59e0b';
+ this.paused = true; /* статика */
+ this.render();
+ }
+ setD(v){ this.d = Math.max(0.05, v); this.render(); }
+ setLambda(v){ this.lambda = Math.max(0.005, v); this.render(); }
+ update(){}
+ render(){
+ if (!this.el) return;
+ const W = this.W, H = this.H;
+ /* Слева: щели (две точки), справа: экран с полосами */
+ let svg = util.svgFrame(W, H, {bg:'#f8fafc'});
+ /* Лазер слева */
+ svg += ' ';
+ svg += 'laser ';
+ /* Щели */
+ const slitX = 130;
+ const dPx = Math.min(60, this.d * 60);
+ const s1y = H/2 - dPx/2, s2y = H/2 + dPx/2;
+ svg += ' ';
+ svg += ' ';
+ svg += ' ';
+ /* Лучи от лазера к щелям */
+ svg += ' ';
+ svg += ' ';
+ /* Экран */
+ const screenX = W - 50;
+ svg += ' ';
+ /* Интерференционная картина: интенсивность ~ cos²(πdy/(λL)) */
+ const lp = this.lambda * this.L / this.d; /* шаг полос */
+ const lpPx = Math.max(3, Math.min(80, lp * 200));
+ const halfH = (H - 40) / 2;
+ const N = 240;
+ for (let i = 0; i < N; i++){
+ const y = 20 + (H - 40) * i / N;
+ const ry = y - H/2;
+ const intens = Math.pow(Math.cos(Math.PI * ry / lpPx), 2);
+ const op = intens.toFixed(3);
+ svg += ' ';
+ }
+ /* Подпись формулы */
+ svg += 'd·sin φ = k·λ (max), d=' + this.d.toFixed(2) + ', λ=' + this.lambda.toFixed(3) + ' ';
+ svg += '';
+ this.el.innerHTML = svg;
+ }
+}
+P.TwoSlit = TwoSlit;
+
+/* ============================================================ */
+/* DiffractionGrating — дифракционная решётка + спектр */
+/* ============================================================ */
+
+class DiffractionGrating {
+ constructor(container, opts){
+ opts = opts || {};
+ this.el = (typeof container === 'string') ? document.querySelector(container) : container;
+ this.W = opts.width || 540;
+ this.H = opts.height || 220;
+ this.d = opts.d !== undefined ? opts.d : 2e-6; /* период решётки, м */
+ this.lambda = opts.lambda !== undefined ? opts.lambda : 550e-9; /* λ, м */
+ this.color = opts.color || '#22c55e';
+ this.paused = true;
+ this.render();
+ }
+ setD(v){ this.d = Math.max(0.3e-6, v); this.render(); }
+ setLambda(v){ this.lambda = Math.max(380e-9, Math.min(760e-9, v)); this.render(); }
+ update(){}
+ /* Возвращает цвет HEX для данной длины волны (для видимого света) */
+ wavelengthToColor(lamNm){
+ const ranges = [
+ [380, 440, '#7c3aed'], [440, 490, '#3b82f6'], [490, 520, '#06b6d4'],
+ [520, 570, '#22c55e'], [570, 590, '#facc15'], [590, 630, '#f97316'],
+ [630, 760, '#dc2626']
+ ];
+ for (const [lo, hi, c] of ranges) if (lamNm >= lo && lamNm < hi) return c;
+ return '#94a3b8';
+ }
+ render(){
+ if (!this.el) return;
+ const W = this.W, H = this.H;
+ let svg = util.svgFrame(W, H, {bg:'#0f172a'}); /* тёмный фон для спектра */
+ /* Решётка слева */
+ const gx = 50;
+ svg += ' ';
+ /* «штрихи» решётки */
+ for (let i = 0; i < 10; i++){
+ const y = 40 + i * (H - 80) / 10;
+ svg += ' ';
+ }
+ svg += 'решётка ';
+ /* Падающий луч */
+ svg += ' ';
+ /* Линии порядков k = -3..3 */
+ const cx = gx + 6, cy = H/2;
+ const lamNm = this.lambda * 1e9;
+ const color = this.wavelengthToColor(lamNm);
+ for (let k = -3; k <= 3; k++){
+ const sinPhi = k * this.lambda / this.d;
+ if (Math.abs(sinPhi) > 1) continue;
+ const phi = Math.asin(sinPhi);
+ const dx = 400, dy = dx * Math.tan(phi);
+ const x2 = cx + dx, y2 = cy - dy;
+ const op = k === 0 ? 1.0 : (1 - Math.abs(k) * 0.18);
+ svg += ' ';
+ svg += 'k=' + k + ' ';
+ }
+ /* Подпись формулы и параметров */
+ svg += 'd sin φ = kλ · d=' + (this.d * 1e6).toFixed(2) + ' мкм · λ=' + (this.lambda * 1e9).toFixed(0) + ' нм ';
+ svg += '';
+ this.el.innerHTML = svg;
+ }
+}
+P.DiffractionGrating = DiffractionGrating;
+
+/* ============================================================ */
+/* FlatMirror — плоское зеркало, объект и мнимое изображение */
+/* ============================================================ */
+
+class FlatMirror {
+ constructor(container, opts){
+ opts = opts || {};
+ this.el = (typeof container === 'string') ? document.querySelector(container) : container;
+ this.W = opts.width || 540;
+ this.H = opts.height || 240;
+ this.objX = opts.objX !== undefined ? opts.objX : 100; /* px от зеркала */
+ this.objY = opts.objY !== undefined ? opts.objY : 50;
+ this.objH = opts.objH !== undefined ? opts.objH : 50;
+ this.color = opts.color || '#f59e0b';
+ this.paused = true;
+ this.render();
+ }
+ setObjX(v){ this.objX = Math.max(20, v); this.render(); }
+ setObjY(v){ this.objY = v; this.render(); }
+ update(){}
+ render(){
+ if (!this.el) return;
+ const W = this.W, H = this.H;
+ const cy = H / 2 + 30;
+ const mirrorX = W / 2;
+ let svg = util.svgFrame(W, H, {bg:'#f8fafc'});
+ /* Зеркало с штриховкой */
+ svg += ' ';
+ for (let i = 0; i < 12; i++){
+ const y = 30 + i * (H - 60) / 12;
+ svg += ' ';
+ }
+ svg += 'зеркало ';
+ /* Объект — стрелка */
+ const objX = mirrorX - this.objX;
+ const objBaseY = cy;
+ const objTopY = cy - this.objH;
+ svg += ' ';
+ svg += ' ';
+ svg += 'объект ';
+ /* Мнимое изображение справа от зеркала, симметрично */
+ const imgX = mirrorX + this.objX;
+ svg += ' ';
+ svg += ' ';
+ svg += 'изображение ';
+ /* Лучи: 1) от верха объекта горизонтально на зеркало, отражается под тем же углом
+ 2) от верха объекта в зеркало по диагонали, отражается симметрично */
+ /* Луч 1 */
+ svg += ' ';
+ svg += ' ';
+ /* Продолжение в зазеркалье (пунктир) */
+ svg += ' ';
+ /* Луч 2: от верха к точке наблюдения слева внизу */
+ const eyeX = 40, eyeY = H - 50;
+ const hitY = objTopY + (cy - objTopY) * (mirrorX - objX) / (eyeX - objX + 2 * (mirrorX - objX));
+ /* Упрощённо: луч от верха объекта к зеркалу и затем к глазу */
+ const hitX = mirrorX;
+ const hitYsimple = objTopY + (cy + 30 - objTopY) * 0.3;
+ svg += ' ';
+ svg += ' ';
+ /* Продолжение от точки отражения в зазеркалье */
+ svg += ' ';
+ /* Глаз */
+ svg += ' ';
+ svg += ' ';
+ svg += 'наблюдатель ';
+ /* Подпись закона */
+ svg += '∠ пад = ∠ отр · изображение мнимое, прямое, равное ';
+ svg += '';
+ this.el.innerHTML = svg;
+ }
+}
+P.FlatMirror = FlatMirror;
+
})();
diff --git a/frontend/textbooks/physics_11_ch3.html b/frontend/textbooks/physics_11_ch3.html
index 815ff8c..a3e8bce 100644
--- a/frontend/textbooks/physics_11_ch3.html
+++ b/frontend/textbooks/physics_11_ch3.html
@@ -1,227 +1,975 @@
-
+
-
-Физика 11 · Глава 3 · Оптика
-
+Физика 11 · Глава 3 · «Оптика»
+
-
+
+
-
+
-
-
- К курсу физики 11
-
+
Физика 11 · Глава 3
+
Оптика · скорость света, интерференция, дифракция, отражение, преломление, линзы, оптические приборы
-
-
Глава 3. Оптика
-
Электромагнитная природа света, интерференция, дифракция, отражение, зеркала, преломление, тонкая линза, оптические приборы · §14–§23
+
-
+
+
+
+
+ Оптика — наука о свете
+ Самая большая глава курса. От электромагнитной природы света до интерференции, дифракции, преломления и оптических приборов (микроскоп, телескоп). 10 параграфов + финал.
+
+
Начать § 14
+
+
Прогресс по главе
+
+
0%
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
Глава 3
-
Оптика
-
Электромагнитная природа света, интерференция, дифракция, отражение, зеркала, преломление, тонкая линза, оптические приборы. Глава содержит 10 параграфов и финальный этап с боссами.
-
-
-
-
- § 14
-
-
ЭМ природа света. Скорость света
-
Опыты Рёмера, Майкельсона
-
-
- Будет добавлено в волне W5-W7
-
-
-
-
-
- § 15
-
-
Интерференция света
-
$\Delta = k\lambda$ (max), $\Delta = (2k+1)\lambda/2$ (min)
-
-
- Будет добавлено в волне W5-W7
-
-
-
-
-
- § 16
-
-
Принцип Гюйгенса – Френеля. Дифракция. Дифракционная решётка
-
$d\sin\varphi = k\lambda$
-
-
- Будет добавлено в волне W5-W7
-
-
-
-
-
- § 17
-
-
Прямолинейное распространение и отражение света. Зеркала
-
$\angle_{пад} = \angle_{отр}$
-
-
- Будет добавлено в волне W5-W7
-
-
-
-
-
- § 18
-
-
Сферические зеркала. Построение изображений
-
$\frac{1}{F} = \frac{1}{d} + \frac{1}{f}$
-
-
- Будет добавлено в волне W5-W7
-
-
-
-
-
- § 19
-
-
Закон преломления света. Полное отражение
-
$n_1\sin\alpha = n_2\sin\beta$, $\sin\alpha_{пр} = 1/n$
-
-
- Будет добавлено в волне W5-W7
-
-
-
-
-
- § 20
-
-
Прохождение света через оптические элементы
-
Призмы, оптоволокно
-
-
- Будет добавлено в волне W5-W7
-
-
-
-
-
- § 21
-
-
Формула тонкой линзы
-
$D = 1/F$, $\Gamma = f/d$
-
-
- Будет добавлено в волне W5-W7
-
-
-
-
-
- § 22
-
-
Оптические приборы для действительных изображений
-
Фотоаппарат, проектор
-
-
- Будет добавлено в волне W5-W7
-
-
-
-
-
- § 23
-
-
Оптические приборы для увеличения угла зрения
-
Лупа, микроскоп, телескоп
-
-
- Будет добавлено в волне W5-W7
-
-
-
-
-
-
- Глава в разработке. Полная реализация — в следующих волнах. Базовая библиотека phys-fx.js уже доступна.
-
-
+
-
+
+
+
+