fix(phys8): закрытие критических проблем ревью — миграции, ✓→✓, ConvectionSim
- Удалены legacy миграции 009/010/015 (создавали несуществующие physics-8-thermal/electro/optics) - 037_physics_8_hub.sql сделана self-sufficient: INSERT OR IGNORE родителя + UPDATE - 7 шт. literal ✓ заменены на ✓ в physics_8_lab.html (правило проекта) - В phys.js добавлен createConvectionSim — главный визуал §4 (тороидальный поток частиц) закрытие плана Phase 0 Физики 8
This commit is contained in:
@@ -353,6 +353,81 @@ function phaseGraphTT(W, H, pad, points, tMaxAll, TminAll, TmaxAll) {
|
||||
return { svg: s, toX: toX, toY: toY };
|
||||
}
|
||||
|
||||
// === Анимация конвекции — тороидальный поток частиц ===
|
||||
// Используется в §4 Физики 8 (главный визуал «конвекция в жидкости/газе»).
|
||||
// opts: { N — число частиц (default 24), w, h — размеры области, speed (отн. ед., default 1),
|
||||
// tHot, tCold — температуры для окраски (default 100, 20) }.
|
||||
function createConvectionSim(opts) {
|
||||
opts = opts || {};
|
||||
const N = opts.N || 24;
|
||||
const w = opts.w || 220;
|
||||
const h = opts.h || 140;
|
||||
const speed = opts.speed != null ? opts.speed : 1;
|
||||
const tHot = opts.tHot != null ? opts.tHot : 100;
|
||||
const tCold = opts.tCold != null ? opts.tCold : 20;
|
||||
// Каждая частица движется по фазе вдоль контура прямоугольника:
|
||||
// правая сторона — вверх (нагрев / подъём), верхняя — влево, левая — вниз (охлаждение), нижняя — вправо.
|
||||
const parts = new Array(N);
|
||||
for (let i = 0; i < N; i++) parts[i] = { phase: i / N };
|
||||
return {
|
||||
N: N, w: w, h: h, speed: speed,
|
||||
_tHot: tHot, _tCold: tCold,
|
||||
setSpeed(v) { this.speed = v; },
|
||||
setHot(v) { this._tHot = v; },
|
||||
setCold(v) { this._tCold = v; },
|
||||
step(dt) {
|
||||
const dPhase = 0.18 * this.speed * dt;
|
||||
for (let i = 0; i < this.N; i++) {
|
||||
parts[i].phase = (parts[i].phase + dPhase) % 1;
|
||||
if (parts[i].phase < 0) parts[i].phase += 1;
|
||||
}
|
||||
},
|
||||
// Возвращает координаты частицы (cx, cy) и температуру по её положению.
|
||||
// phase ∈ [0,1): 0..0.25 — правая (подъём, t→tHot), 0.25..0.5 — верх (t=tHot),
|
||||
// 0.5..0.75 — левая (опускание, t→tCold), 0.75..1 — низ (t=tCold).
|
||||
_xy(phase, x, y) {
|
||||
const margin = 12;
|
||||
const W = this.w - 2 * margin;
|
||||
const H = this.h - 2 * margin;
|
||||
let lx, ly, t;
|
||||
if (phase < 0.25) {
|
||||
const k = phase / 0.25;
|
||||
lx = W; ly = H * (1 - k);
|
||||
t = this._tCold + (this._tHot - this._tCold) * k;
|
||||
} else if (phase < 0.5) {
|
||||
const k = (phase - 0.25) / 0.25;
|
||||
lx = W * (1 - k); ly = 0;
|
||||
t = this._tHot;
|
||||
} else if (phase < 0.75) {
|
||||
const k = (phase - 0.5) / 0.25;
|
||||
lx = 0; ly = H * k;
|
||||
t = this._tHot - (this._tHot - this._tCold) * k;
|
||||
} else {
|
||||
const k = (phase - 0.75) / 0.25;
|
||||
lx = W * k; ly = H;
|
||||
t = this._tCold;
|
||||
}
|
||||
return { cx: x + margin + lx, cy: y + margin + ly, t: t };
|
||||
},
|
||||
render(x, y) {
|
||||
const tMin = Math.min(this._tCold, this._tHot);
|
||||
const tMax = Math.max(this._tCold, this._tHot);
|
||||
let s = '';
|
||||
// Контур сосуда
|
||||
s += `<rect x="${x}" y="${y}" width="${this.w}" height="${this.h}" fill="#dbeafe" stroke="#0f172a" stroke-width="1.5" rx="6"/>`;
|
||||
// Нагреватель снизу (красная полоса)
|
||||
s += `<rect x="${x + 8}" y="${y + this.h - 6}" width="${this.w - 16}" height="6" fill="#dc2626" opacity="0.85" rx="3"/>`;
|
||||
// Частицы
|
||||
for (let i = 0; i < this.N; i++) {
|
||||
const p = this._xy(parts[i].phase, x, y);
|
||||
const c = tempColor(p.t, tMin, tMax);
|
||||
s += `<circle cx="${p.cx.toFixed(1)}" cy="${p.cy.toFixed(1)}" r="4" fill="${c}" stroke="#0f172a" stroke-width="0.6" opacity="0.9"/>`;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// === Электронные хелперы для электрических задач ===
|
||||
// Параллельное и последовательное сопротивление
|
||||
function Rseries() {
|
||||
@@ -374,6 +449,7 @@ window.PHYS = {
|
||||
thermometer: thermometer,
|
||||
calorimeter: calorimeter,
|
||||
createHeatBar: createHeatBar,
|
||||
createConvectionSim: createConvectionSim,
|
||||
phaseGraphTT: phaseGraphTT,
|
||||
Rseries: Rseries,
|
||||
Rparallel: Rparallel,
|
||||
|
||||
Reference in New Issue
Block a user