// phys.js — модуль физических хелперов для учебника Физика 10 // Экспорт в window.PHYS = { ... } (function(){ 'use strict'; // === Стрелка вектора (2D) === function drawArrow(x1, y1, x2, y2, color, width, headSize) { width = width || 2; headSize = headSize || 10; const dx = x2 - x1, dy = y2 - y1; const len = Math.sqrt(dx*dx + dy*dy); if (len < 1e-6) return ''; const ux = dx / len, uy = dy / len; const px = -uy, py = ux; const h = headSize, w = headSize * 0.6; const bx = x2 - ux*h, by = y2 - uy*h; const lx = bx + px*w, ly = by + py*w; const rx = bx - px*w, ry = by - py*w; return `` + ``; } // === Линии электрического поля от точечного заряда === function fieldLinesPointCharge(cx, cy, sign, scale, numLines) { numLines = numLines || 16; scale = scale || 80; let s = ''; const color = sign > 0 ? '#dc2626' : '#2563eb'; for (let i = 0; i < numLines; i++) { const a = 2 * Math.PI * i / numLines; const r1 = 18, r2 = scale; const x1 = cx + r1*Math.cos(a), y1 = cy + r1*Math.sin(a); const x2 = cx + r2*Math.cos(a), y2 = cy + r2*Math.sin(a); if (sign > 0) s += drawArrow(x1, y1, x2, y2, color, 1.4, 7); else s += drawArrow(x2, y2, x1, y1, color, 1.4, 7); } return s; } // === Обозначение заряда (кружок с +/-) === function chargeMark(cx, cy, sign, r, label) { r = r || 14; const color = sign > 0 ? '#dc2626' : '#2563eb'; const fill = sign > 0 ? '#fecaca' : '#bfdbfe'; let s = ''; s += ``; if (sign > 0) { s += ``; s += ``; } else { s += ``; } if (label) { s += `${label}`; } return s; } // === Магнитное поле сквозь экран (сетка крестиков или точек) === function magneticFieldGrid(x0, y0, w, h, cols, rows, direction) { // direction: 'in' = крест (× — вошло в плоскость), 'out' = точка (• — вышло) let s = ''; const dx = w / (cols - 1), dy = h / (rows - 1); const color = '#7c3aed'; for (let i = 0; i < cols; i++) { for (let j = 0; j < rows; j++) { const cx = x0 + i * dx, cy = y0 + j * dy; s += ``; if (direction === 'in') { s += ``; s += ``; } else { s += ``; } } } return s; } // === Молекула газа (частица) === function molecule(x, y, r, color) { r = r || 4; color = color || '#2563eb'; return ``; } // === Симуляция газа (упругое столкновение со стенками) === function createGasSim(opts) { opts = opts || {}; const N = opts.N || 30; const W = opts.W || 320; const H = opts.H || 220; const baseSpeed = opts.speed || 60; // px/s const r = opts.r || 4; const particles = []; for (let i = 0; i < N; i++) { particles.push({ x: r + Math.random() * (W - 2*r), y: r + Math.random() * (H - 2*r), vx: (Math.random() - 0.5) * 2 * baseSpeed, vy: (Math.random() - 0.5) * 2 * baseSpeed }); } return { W: W, H: H, r: r, particles: particles, step(dt) { for (const p of particles) { p.x += p.vx * dt; p.y += p.vy * dt; if (p.x < r) { p.x = r; p.vx = -p.vx; } if (p.x > W - r) { p.x = W - r; p.vx = -p.vx; } if (p.y < r) { p.y = r; p.vy = -p.vy; } if (p.y > H - r) { p.y = H - r; p.vy = -p.vy; } } }, render(color) { color = color || '#2563eb'; return particles.map(p => molecule(p.x, p.y, r, color)).join(''); }, setSpeed(scale) { for (const p of particles) { p.vx *= scale; p.vy *= scale; } } }; } // === Электрические схемы: компоненты === // orientation: 'h' (горизонтально, по умолчанию) или 'v' (вертикально) function batteryEMF(x, y, EMF, orientation) { orientation = orientation || 'h'; let s = ''; if (orientation === 'h') { s += ``; s += ``; s += `+`; s += ``; if (EMF !== undefined) s += `ε = ${EMF}`; } else { s += ``; s += ``; if (EMF !== undefined) s += `ε = ${EMF}`; } return s; } function resistor(x, y, R, orientation) { orientation = orientation || 'h'; let s = ''; if (orientation === 'h') { s += ``; if (R !== undefined) s += `R = ${R}`; } else { s += ``; if (R !== undefined) s += `R = ${R}`; } return s; } function capacitorSymbol(x, y, C, orientation) { orientation = orientation || 'h'; let s = ''; if (orientation === 'h') { s += ``; s += ``; if (C !== undefined) s += `C = ${C}`; } return s; } function ammeterSymbol(x, y, r) { r = r || 14; return `` + `A`; } function voltmeterSymbol(x, y, r) { r = r || 14; return `` + `V`; } function lightbulbSymbol(x, y, r) { r = r || 14; let s = ''; s += ``; s += ``; s += ``; return s; } function inductorSymbol(x, y, L, orientation) { orientation = orientation || 'h'; let s = ''; if (orientation === 'h') { for (let i = 0; i < 4; i++) { const cx = x - 15 + i * 10; s += ``; } if (L !== undefined) s += `L = ${L}`; } return s; } function wire(x1, y1, x2, y2) { return ``; } // === Эталонные константы === const CONST = { k: 9e9, // Кулона e: 1.6e-19, // элементарный заряд eps0: 8.85e-12, // электрическая постоянная kB: 1.38e-23, // Больцмана NA: 6.022e23, // Авогадро R: 8.314, // универсальная газовая c: 3e8, // скорость света g: 9.8, // ускорение свободного падения atm: 101325, // 1 атм в Па T0: 273.15 // ноль Цельсия в К }; // === Конвертеры единиц === function celsiusToKelvin(t) { return t + 273.15; } function kelvinToCelsius(T) { return T - 273.15; } function atmToPa(p) { return p * 101325; } function paToAtm(p) { return p / 101325; } function litersToM3(V) { return V / 1000; } function m3ToLiters(V) { return V * 1000; } // === Экспорт === window.PHYS = { drawArrow: drawArrow, fieldLinesPointCharge: fieldLinesPointCharge, chargeMark: chargeMark, magneticFieldGrid: magneticFieldGrid, molecule: molecule, createGasSim: createGasSim, batteryEMF: batteryEMF, resistor: resistor, capacitorSymbol: capacitorSymbol, ammeterSymbol: ammeterSymbol, voltmeterSymbol: voltmeterSymbol, lightbulbSymbol: lightbulbSymbol, inductorSymbol: inductorSymbol, wire: wire, CONST: CONST, celsiusToKelvin: celsiusToKelvin, kelvinToCelsius: kelvinToCelsius, atmToPa: atmToPa, paToAtm: paToAtm, litersToM3: litersToM3, m3ToLiters: m3ToLiters }; })();