Тепловые явления — как энергия переходит между телами
Внутренняя энергия зависит от температуры тела. Тепло передаётся теплопроводностью, конвекцией и излучением. При нагревании, плавлении и кипении нужно разное количество теплоты.
{ const y = yToPx(t); svg.appendChild(P8Helpers.svg.el('line', { x1: pad.l, y1: y, x2: pad.l + plotW, y2: y, stroke: '#e5e7eb' })); svg.appendChild(P8Helpers.svg.el('text', { x: pad.l - 6, y: y + 3, 'font-family':"'JetBrains Mono',monospace", 'font-size': 10, fill: 'var(--p8-muted,#64748b)', 'text-anchor':'end', text: t+'°' })); }); const phaseRegions = [ { from: -20, to: 0, fill: '#bfdbfe', name: 'лёд' }, { from: 0, to: 100, fill: '#7dd3fc', name: 'вода' }, { from: 100, to: 120, fill: '#fde68a', name: 'пар' } ]; phaseRegions.forEach(r => { const y1 = yToPx(r.from), y2 = yToPx(r.to); svg.appendChild(P8Helpers.svg.el('rect', { x: pad.l, y: y2, width: plotW, height: y1 - y2, fill: r.fill, opacity: 0.18 })); svg.appendChild(P8Helpers.svg.el('text', { x: pad.l + plotW - 6, y: (y1 + y2) / 2 + 3, 'font-family':"'Inter',sans-serif", 'font-size': 10, 'font-weight': 700, fill: 'var(--p8-text)', 'text-anchor': 'end', text: r.name })); }); svg.appendChild(P8Helpers.svg.el('line', { x1: pad.l, y1: yToPx(0), x2: pad.l + plotW, y2: yToPx(0), stroke: '#0f172a', 'stroke-width': 1, 'stroke-dasharray': '3 3' })); svg.appendChild(P8Helpers.svg.el('line', { x1: pad.l, y1: yToPx(100), x2: pad.l + plotW, y2: yToPx(100), stroke: '#0f172a', 'stroke-width': 1, 'stroke-dasharray': '3 3' })); svg.appendChild(P8Helpers.svg.el('line', { x1: pad.l, y1: pad.t + plotH, x2: pad.l + plotW, y2: pad.t + plotH, stroke: '#0f172a' })); svg.appendChild(P8Helpers.svg.el('text', { x: pad.l + plotW / 2, y: H - 6, 'font-family':"'Inter',sans-serif", 'font-size': 11, 'font-weight': 700, fill: 'var(--p8-text)', 'text-anchor': 'middle', text: 'Время, с' })); const path = P8Helpers.svg.el('path', { d: '', fill: 'none', stroke: 'var(--th-mid, #f97316)', 'stroke-width': 3, 'stroke-linejoin': 'round', 'stroke-linecap': 'round' }); svg.appendChild(path); function updatePath(){ if (!points.length) return; const d = points.map((p, i) => (i === 0 ? 'M' : 'L') + tToPx(p.t).toFixed(1) + ',' + yToPx(p.T).toFixed(1)).join(' '); path.setAttribute('d', d); } function currentT(){ return points[points.length-1].T; } function currentPhase(T){ if (T < 0) return 'лёд'; if (T < 0.5 && energyAccumulated < lambda * m) return 'плавление'; if (T < 100) return 'вода'; if (T < 100.5 && energyAccumulated < (lambda + r_vap) * m) return 'кипение'; return 'пар'; } function tick(dt){ if (!running) return; const energy = power * dt; let T = currentT(); let newT = T; if (T < 0) { const dT = energy / (c_ice * m); newT = T + dT; if (newT > 0) newT = 0; } else if (T < 0.5 && energyAccumulated < lambda * m) { energyAccumulated += energy; newT = 0; if (energyAccumulated >= lambda * m) newT = 0.5; } else if (T < 100) { const dT = energy / (c_water * m); newT = T + dT; if (newT > 100) newT = 100; } else if (T < 100.5 && energyAccumulated < (lambda + r_vap) * m) { energyAccumulated += energy; newT = 100; if (energyAccumulated >= (lambda + r_vap) * m) newT = 100.5; } else if (T < 120) { const dT = energy / (c_water * m); newT = T + dT; if (newT > 120) newT = 120; } else { running = false; } const lastP = points[points.length-1]; points.push({ t: lastP.t + dt, T: newT }); if (points.length > 600) points.shift(); updatePath(); document.getElementById('p8-iv6-temp').textContent = Math.round(newT); document.getElementById('p8-iv6-phase').textContent = currentPhase(newT); if (lastP.t > 300) running = false; } const raf = P8Anim.raf(dt => tick(Math.min(dt * 4, 0.5))); const pwrInp = document.getElementById('p8-iv6-pwr'); const pwrLab = document.getElementById('p8-iv6-pwr-val'); pwrInp.oninput = () => { power = +pwrInp.value; pwrLab.textContent = power; }; document.getElementById('p8-iv6-play').onclick = () => { if (!running) { running = true; raf.start(); if (window.addXp) addXp(10, 'p8-iv6-melt'); } }; document.getElementById('p8-iv6-reset').onclick = () => { running = false; raf.stop(); energyAccumulated = 0; points = [{ t: 0, T: -20 }]; updatePath(); document.getElementById('p8-iv6-temp').textContent = '-20'; document.getElementById('p8-iv6-phase').textContent = 'лёд'; }; updatePath(); } function _initP6_iv6(){ const sb = document.getElementById('p6-iv6-sandbox'); if (!sb || !window.P8Helpers || !window.P8Anim) return; const svg = P8Helpers.svg.create(560, 240); svg.setAttribute('width','100%'); svg.setAttribute('height','100%'); svg.style.display='block'; sb.appendChild(svg); const v1 = { x: 140, y: 130, m: 0.5, T: 80 }; const v2 = { x: 420, y: 130, m: 1.0, T: 20 }; const finalState = { active: false, T: 50 }; function drawVessel(x, y, m, T){ const g = P8Helpers.svg.el('g', { transform: 'translate('+x+','+y+')' }); const ht = 30 + m * 50; const w = 70; g.appendChild(P8Helpers.svg.el('rect', { x:-w/2, y:-ht, width:w, height:ht, rx:6, fill:'rgba(255,255,255,.6)', stroke:'#0f172a', 'stroke-width':1.5 })); g.appendChild(P8Helpers.svg.el('rect', { x:-w/2+3, y:-ht+5, width:w-6, height:ht-8, rx:4, fill: P8Helpers.thermal.tempColor(T/100) })); g.appendChild(P8Helpers.svg.el('text', { x:0, y:18, 'font-family':"'JetBrains Mono',monospace", 'font-size':11, 'font-weight':700, fill:'#0f172a', 'text-anchor':'middle', text: 'm='+m.toFixed(1)+' кг' })); g.appendChild(P8Helpers.svg.el('text', { x:0, y:32, 'font-family':"'JetBrains Mono',monospace", 'font-size':11, 'font-weight':700, fill:'#0f172a', 'text-anchor':'middle', text: 'T='+Math.round(T)+'°C' })); return g; } function redraw(){ svg.innerHTML = ''; if (!finalState.active) { svg.appendChild(drawVessel(v1.x, v1.y, v1.m, v1.T)); svg.appendChild(drawVessel(v2.x, v2.y, v2.m, v2.T)); } else { svg.appendChild(drawVessel(280, 130, v1.m + v2.m, finalState.T)); svg.appendChild(P8Helpers.svg.el('text', { x:280, y:60, 'font-family':"'Unbounded',sans-serif", 'font-size':14, 'font-weight':800, fill:'var(--th-mid,#f97316)', 'text-anchor':'middle', text: 'T_итог = '+Math.round(finalState.T)+' °C' })); } } function bindScrub(inputId, valId, obj, prop){ const input = document.getElementById(inputId); const lab = document.getElementById(valId); if (!input || !lab) return; input.addEventListener('input', () => { const v = parseFloat(input.value); obj[prop] = v; lab.textContent = v.toFixed(prop === 'm' ? 1 : 0); if (finalState.active) { finalState.active = false; document.getElementById('p6-iv6-tf').textContent = '—'; } redraw(); }); } bindScrub('p6-iv6-m1', 'p6-iv6-m1-val', v1, 'm'); bindScrub('p6-iv6-t1', 'p6-iv6-t1-val', v1, 'T'); bindScrub('p6-iv6-m2', 'p6-iv6-m2-val', v2, 'm'); bindScrub('p6-iv6-t2', 'p6-iv6-t2-val', v2, 'T'); document.getElementById('p6-iv6-mix').onclick = () => { const T = (v1.m * v1.T + v2.m * v2.T) / (v1.m + v2.m); finalState.active = true; P8Anim.tween({ from: v1.T, to: T, duration: 1200, easing: 'cubicInOut', onUpdate: t => { finalState.T = t; redraw(); document.getElementById('p6-iv6-tf').textContent = Math.round(t); } }); if (window.addXp) addXp(10, 'p6-iv6-mix'); }; document.getElementById('p6-iv6-reset').onclick = () => { finalState.active = false; document.getElementById('p6-iv6-tf').textContent = '—'; redraw(); }; redraw(); } function _initP3_iv6(){ const sb = document.getElementById('p3-iv6-sandbox'); if (!sb || !window.P8Helpers || !window.P8Drag || !window.P8Anim) return; const svg = P8Helpers.svg.create(560, 300); svg.setAttribute('width','100%'); svg.setAttribute('height','100%'); svg.style.display='block'; sb.appendChild(svg); const burner = P8Helpers.svg.el('g', { transform: 'translate(80, 240)' }); burner.appendChild(P8Helpers.svg.el('rect', { x:-32, y:-8, width:64, height:32, rx:4, fill:'#475569' })); burner.appendChild(P8Helpers.svg.el('rect', { x:-26, y:-22, width:52, height:14, rx:7, fill:'#dc2626' })); burner.appendChild(P8Helpers.svg.el('text', { x:0, y:48, 'font-family':"'Inter',sans-serif", 'font-size':11, 'font-weight':700, fill:'#475569', 'text-anchor':'middle', text:'Горелка (drop)' })); svg.appendChild(burner); const rods = [ { name:'Медь', lam:400, color:'#b45309', x:200, y:50 }, { name:'Серебро', lam:430, color:'#9ca3af', x:300, y:50 }, { name:'Стекло', lam:0.8, color:'#bae6fd', x:400, y:50 }, { name:'Дерево', lam:0.15,color:'#a16207', x:500, y:50 } ]; const rodEls = []; rods.forEach(rod => { const g = P8Helpers.svg.el('g', { transform: 'translate('+rod.x+','+rod.y+')' }); const segments = 12; const segs = []; for (let s = 0; s < segments; s++) { const r = P8Helpers.svg.el('rect', { x: -55 + s * (110/segments), y: -10, width: 110/segments, height: 20, fill: rod.color, stroke: 'none' }); g.appendChild(r); segs.push(r); } g.appendChild(P8Helpers.svg.el('rect', { x:-55, y:-10, width:110, height:20, rx:3, fill:'none', stroke:'#0f172a', 'stroke-width':1.5 })); g.appendChild(P8Helpers.svg.el('text', { x:0, y:-18, 'font-family':"'Inter',sans-serif", 'font-size':11, 'font-weight':700, fill:'#0f172a', 'text-anchor':'middle', text: rod.name })); g.appendChild(P8Helpers.svg.el('text', { x:0, y:30, 'font-family':"'JetBrains Mono',monospace", 'font-size':9, 'font-weight':600, fill:'var(--p8-muted, #64748b)', 'text-anchor':'middle', text: 'λ='+rod.lam })); svg.appendChild(g); rodEls.push({ rod, g, segs, x: rod.x, y: rod.y }); }); let simLoop = null; let simTime = 0; const matEl = document.getElementById('p3-iv6-mat'); const lamEl = document.getElementById('p3-iv6-lam'); const tendEl = document.getElementById('p3-iv6-tend'); function resetColors(rodObj){ rodObj.segs.forEach(s => s.setAttribute('fill', rodObj.rod.color)); } function startSim(rodObj){ if (simLoop) simLoop.stop(); simTime = 0; const lamNorm = Math.min(1, Math.log10(rodObj.rod.lam + 1) / Math.log10(500)); simLoop = P8Anim.raf(dt => { simTime += dt; const speed = lamNorm * 0.8 + 0.04; rodObj.segs.forEach((seg, i) => { const pos = i / (rodObj.segs.length - 1); const heat = Math.max(0, Math.min(1, speed * simTime - pos)); seg.setAttribute('fill', P8Helpers.thermal.tempColor(heat * 0.85 + 0.1)); }); const endHeat = Math.max(0, Math.min(1, speed * simTime - 0.95)); const tEnd = Math.round(20 + endHeat * 80); if (tendEl) tendEl.textContent = tEnd; if (simTime > 30) simLoop.stop(); }); simLoop.start(); if (matEl) matEl.textContent = rodObj.rod.name; if (lamEl) lamEl.textContent = rodObj.rod.lam; } rodEls.forEach((rodObj, i) => { P8Drag.attach(rodObj.g, { container: svg, onMove: (ev, pos) => { rodObj.x = pos.x; rodObj.y = pos.y; rodObj.g.setAttribute('transform', 'translate('+rodObj.x+','+rodObj.y+')'); }, onEnd: (ev, pos) => { if (Math.abs(pos.x - 80) < 70 && Math.abs(pos.y - 240) < 50) { rodEls.forEach((other, j) => { if (j !== i) resetColors(other); }); startSim(rodObj); if (window.addXp) addXp(10, 'p3-iv6-conduct'); } } }); }); svg.appendChild(P8Helpers.svg.el('text', { x: 280, y: 290, 'font-family': "'Inter', sans-serif", 'font-size': 10, fill: 'var(--p8-muted, #64748b)', 'text-anchor': 'middle', text: 'Перетащи стержень на горелку • Чем выше λ — тем быстрее цвет дойдёт до конца' })); } doctype html>
Внутренняя энергия зависит от температуры тела. Тепло передаётся теплопроводностью, конвекцией и излучением. При нагревании, плавлении и кипении нужно разное количество теплоты.