Wave propagation, diffraction, interference

Task:

Wave propagation, diffraction, interference

Interactive Wave Lab

Welcome to the interactive wave lab! Here you can explore three essential wave phenomena: propagation, diffraction, and interference.

Select an experiment:

1.5 Гц
20

Wave Propagation

Waves propagate in all directions from a source at a constant speed.

🌐 Wave Propagation

Waves transfer energy without transferring matter. They propagate from the source in concentric circles.

  • Propagation speed depends on the medium
  • Amplitude determines wave intensity
  • Frequency remains constant during propagation

🎯 Practical Applications

🎵 Acoustics

Concert hall design considers sound wave interference

📡 Radio Communication

Diffraction allows radio waves to bend around mountains and buildings

🔬 Optics

Light interference is used in lasers and holography

🌊 Oceanography

Studying ocean waves helps predict weather

0.5) { ctx.globalAlpha = intensity * (amplitude / 40); ctx.beginPath(); ctx.moveTo(x, 0); ctx.lineTo(x, canvas.height); ctx.stroke(); } } ctx.globalAlpha = 1; // Дифрагированные волны справа от щели const slitSource = { x: barrierX, y: slitY }; for (let angle = -Math.PI/2; angle <= Math.PI/2; angle += Math.PI/20) { const maxDist = canvas.width - barrierX; for (let dist = 0; dist < maxDist; dist += 3) { const x = slitSource.x + dist * Math.cos(angle); const y = slitSource.y + dist * Math.sin(angle); if (x >= barrierX && x < canvas.width && y >= 0 && y < canvas.height) { const wavePhase = (dist / waveLength - time * frequency) * 2 * Math.PI; const waveValue = Math.sin(wavePhase); const distanceFactor = Math.max(0, 1 - dist / maxDist); const angleFactor = Math.cos(angle) * Math.cos(angle); if (waveValue > 0.3) { const intensity = waveValue * distanceFactor * angleFactor * (amplitude / 40); if (intensity > 0.1) { ctx.fillStyle = 'rgba(255, 152, 0, ' + intensity + ')'; ctx.fillRect(x-1, y-1, 2, 2); } } } } } // Подписи (отодвинули от краев) ctx.fillStyle = '#fff'; ctx.font = '12px Arial'; ctx.textAlign = 'center'; ctx.fillText("Slit", barrierX, Math.max(30, 20)); ctx.fillText("Diffraction", Math.min(barrierX + 80, canvas.width - 50), Math.max(slitY - 40, 30)); } // Рисование интерференции от двух щелей с экраном function drawInterference() { ctx.clearRect(0, 0, canvas.width, canvas.height); const barrierX = canvas.width * 0.25; const screenX = canvas.width * 0.6; // Экран ближе к щелям const slitDistance = 50; const centerY = canvas.height / 2; const slit1Y = centerY - slitDistance/2; const slit2Y = centerY + slitDistance/2; const slitWidth = 6; const waveSpeed = 50; const waveLength = waveSpeed / frequency; // Рисуем барьер с двумя щелями ctx.fillStyle = '#444'; ctx.fillRect(barrierX - 3, 0, 6, slit1Y - slitWidth/2); ctx.fillRect(barrierX - 3, slit1Y + slitWidth/2, 6, slit2Y - slitWidth/2 - (slit1Y + slitWidth/2)); ctx.fillRect(barrierX - 3, slit2Y + slitWidth/2, 6, canvas.height - (slit2Y + slitWidth/2)); // Падающие волны слева ctx.strokeStyle = 'rgba(33, 150, 243, 0.6)'; ctx.lineWidth = 1; for (let x = 0; x < barrierX; x += waveLength/3) { const wavePhase = (x / waveLength - time * frequency) * 2 * Math.PI; const intensity = Math.sin(wavePhase); if (intensity > 0.5) { ctx.globalAlpha = intensity * 0.5; ctx.beginPath(); ctx.moveTo(x, 0); ctx.lineTo(x, canvas.height); ctx.stroke(); } } ctx.globalAlpha = 1; // Источники в щелях ctx.fillStyle = '#ff4444'; ctx.beginPath(); ctx.arc(barrierX, slit1Y, 3, 0, 2 * Math.PI); ctx.fill(); ctx.beginPath(); ctx.arc(barrierX, slit2Y, 3, 0, 2 * Math.PI); ctx.fill(); // Анимированные волны от источников ctx.strokeStyle = 'rgba(76, 175, 80, 0.3)'; ctx.lineWidth = 1; for (let i = 0; i < 5; i++) { const radius = (time * 30 + i * 25) % 120; // Уменьшили радиус if (radius > 5) { const alpha = Math.max(0, 0.3 - radius / 400); ctx.globalAlpha = alpha; // От первой щели ctx.beginPath(); ctx.arc(barrierX, slit1Y, radius, 0, 2 * Math.PI); ctx.stroke(); // От второй щели ctx.beginPath(); ctx.arc(barrierX, slit2Y, radius, 0, 2 * Math.PI); ctx.stroke(); } } ctx.globalAlpha = 1; // Экран справа ctx.fillStyle = '#222'; ctx.fillRect(screenX - 2, 0, 4, canvas.height); // Статичная интерференционная картина на экране const pattern = createInterferencePattern(); pattern.forEach(stripe => { const { y, color, alpha, width } = stripe; ctx.fillStyle = 'rgba(' + color[0] + ', ' + color[1] + ', ' + color[2] + ', ' + alpha + ')'; ctx.fillRect(screenX + 2, y, width, 1); }); // Подписи (размещены подальше от краев) ctx.fillStyle = '#fff'; ctx.font = '12px Arial'; ctx.textAlign = 'center'; // Подписи щелей const labelX = Math.max(barrierX - 25, 40); ctx.fillText("Slit 1", labelX, Math.max(slit1Y - 10, 20)); ctx.fillText("Slit 2", labelX, Math.min(slit2Y + 20, canvas.height - 10)); // Подпись экрана ctx.fillText("Screen", screenX, Math.max(canvas.height - 15, canvas.height - 10)); // Подпись интерференции (размещена безопасно) const interferenceX = Math.min(screenX + 30, canvas.width - 60); const interferenceY = Math.max(35, 25); ctx.font = '11px Arial'; ctx.fillText("Interference", interferenceX, interferenceY); } // Рисование бокового вида волны function drawSideView() { ctx.clearRect(0, 0, canvas.width, canvas.height); const centerY = canvas.height / 2; const waveLength = 100 / frequency; const maxAmplitude = Math.min(amplitude, canvas.height / 3); // Ось X ctx.strokeStyle = '#666'; ctx.lineWidth = 1; ctx.beginPath(); ctx.moveTo(0, centerY); ctx.lineTo(canvas.width, centerY); ctx.stroke(); // Разметка оси ctx.fillStyle = '#888'; ctx.font = '10px Arial'; ctx.textAlign = 'center'; for (let x = 0; x < canvas.width; x += waveLength) { if (x > 20 && x < canvas.width - 20) { // Отступ от краев ctx.beginPath(); ctx.moveTo(x, centerY - 5); ctx.lineTo(x, centerY + 5); ctx.stroke(); ctx.fillText('λ', x, centerY + 15); } } // Волна ctx.strokeStyle = '#4CAF50'; ctx.lineWidth = 3; ctx.beginPath(); for (let x = 0; x < canvas.width; x += 2) { const phase = (x / waveLength + time * frequency * 2) * 2 * Math.PI; const y = centerY - maxAmplitude * Math.sin(phase); if (x === 0) { ctx.moveTo(x, y); } else { ctx.lineTo(x, y); } } ctx.stroke(); // Стрелки амплитуды ctx.strokeStyle = '#ff4444'; ctx.lineWidth = 2; const arrowX = canvas.width * 0.25; // Стрелка вверх ctx.beginPath(); ctx.moveTo(arrowX, centerY); ctx.lineTo(arrowX, centerY - maxAmplitude); ctx.stroke(); // Стрелка вниз ctx.beginPath(); ctx.moveTo(arrowX, centerY); ctx.lineTo(arrowX, centerY + maxAmplitude); ctx.stroke(); // Подписи (размещены с отступом от краев) ctx.fillStyle = '#fff'; ctx.font = '14px Arial'; ctx.textAlign = 'left'; const labelY = Math.max(centerY - maxAmplitude - 10, 25); ctx.fillText("Amplitude", Math.max(arrowX - 20, 20), labelY); ctx.fillText('A = ' + amplitude, Math.max(arrowX - 20, 20), Math.max(labelY - 15, 15)); ctx.textAlign = 'center'; ctx.fillText("Propagation direction \u2192", canvas.width/2, Math.max(40, 30)); ctx.fillText("Frequency = " + frequency + " Hz", canvas.width/2, Math.min(canvas.height - 10, canvas.height - 20)); } // Анимация function animate() { if (!isAnimating) return; switch(currentExperiment) { case 'propagation': drawPropagation(); break; case 'diffraction': drawDiffraction(); break; case 'interference': drawInterference(); break; case 'sideview': drawSideView(); break; } time += 0.02; animationFrame = requestAnimationFrame(animate); } // Управление экспериментами window.switchExperiment = function(experiment) { const buttons = document.querySelectorAll('.experiment-btn'); const cards = document.querySelectorAll('.theory-card'); const info = document.getElementById('experimentInfo'); buttons.forEach(btn => btn.classList.remove('active')); cards.forEach(card => card.style.display = 'none'); currentExperiment = experiment; time = 0; const btnIds = { 'propagation': 'wavePropBtn', 'diffraction': 'diffractionBtn', 'interference': 'interferenceBtn', 'sideview': 'sideViewBtn' }; const activeBtn = document.getElementById(btnIds[experiment]); const activeCard = document.getElementById(experiment + 'Card'); if (activeBtn) activeBtn.classList.add('active'); if (activeCard) activeCard.style.display = 'block'; if (info) { const titles = { 'propagation': "Wave Propagation", 'diffraction': "Wave Diffraction", 'interference': "Wave Interference", 'sideview': "Wave Profile" }; const descriptions = { 'propagation': "Waves propagate from the source in concentric circles.", 'diffraction': "The wave passes through the slit and spreads out like a fan.", 'interference': "Two slits create a static interference pattern on the screen.", 'sideview': "A sinusoidal wave moves through space." }; info.innerHTML = '

' + titles[experiment] + '

' + descriptions[experiment] + '

'; } }; // Обновление параметров волн window.updateWaveParams = function() { const freqSlider = document.getElementById('frequencySlider'); const ampSlider = document.getElementById('amplitudeSlider'); const freqValue = document.getElementById('frequencyValue'); const ampValue = document.getElementById('amplitudeValue'); if (freqSlider && freqValue) { frequency = parseFloat(freqSlider.value); freqValue.textContent = frequency + " Hz"; } if (ampSlider && ampValue) { amplitude = parseFloat(ampSlider.value); ampValue.textContent = amplitude; } // Пересчитать интерференционную картину при изменении параметров interferencePattern = null; }; // Управление анимацией window.toggleWaveAnimation = function() { const btn = document.getElementById('playPauseWaveBtn'); if (!btn) return; if (isAnimating) { isAnimating = false; cancelAnimationFrame(animationFrame); btn.textContent = "\u25b6\ufe0f Play"; } else { isAnimating = true; animate(); btn.textContent = "\u23f8\ufe0f Pause"; } }; window.resetWaveAnimation = function() { time = 0; if (!isAnimating) { switch(currentExperiment) { case 'propagation': drawPropagation(); break; case 'diffraction': drawDiffraction(); break; case 'interference': drawInterference(); break; case 'sideview': drawSideView(); break; } } }; // Запуск анимации animate(); })()" style="display: none;">
Tekst kopieret
Færdig
Fejl