Bài tập:
Sự truyền sóng, nhiễu xạ, giao thoa
Phòng thí nghiệm sóng tương tác
Chào mừng bạn đến với phòng thí nghiệm sóng tương tác! Tại đây, bạn có thể nghiên cứu ba hiện tượng sóng quan trọng nhất: sự truyền sóng, nhiễu xạ và giao thoa.
Chọn thí nghiệm:
📡 Truyền sóng
🌊 Nhiễu xạ
⚡ Giao thoa
📊 Biên dạng sóng
Sự truyền sóng
Sóng truyền đi mọi hướng từ nguồn với tốc độ không đổi.
🌐 Sự truyền sóng
Sóng truyền năng lượng mà không truyền vật chất. Chúng lan rộng từ nguồn theo các đường tròn đồng tâm.
Tốc độ truyền sóng phụ thuộc vào môi trường
Biên độ xác định cường độ của sóng
Tần số không đổi trong quá trình truyền sóng
🌊 Nhiễu xạ sóng
Nhiễu xạ là khả năng sóng uốn quanh các vật cản và đi qua các khe hẹp.
Rõ rệt hơn khi kích thước vật cản tương đương với bước sóng
Sau khe hẹp, sóng tỏa ra hình quạt
Giải thích sự truyền âm thanh quanh góc tường
⚡ Giao thoa sóng
Giao thoa là sự chồng chéo của các sóng từ hai nguồn kết hợp (thí nghiệm khe Young).
Vân sáng - giao thoa cực đại
Vân tối - giao thoa cực tiểu
Khoảng cách giữa các vân phụ thuộc vào bước sóng
📊 Biên dạng sóng
Góc nhìn ngang cho thấy dạng sóng - hình sin di chuyển trong không gian.
Biên độ - độ lệch cực đại so với vị trí cân bằng
Bước sóng phụ thuộc vào tần số và tốc độ
Tần số càng cao, bước sóng càng ngắn
🎯 Ứng dụng thực tế
🎵 Âm học
Thiết kế phòng hòa nhạc có tính đến sự giao thoa của sóng âm
📡 Truyền thông vô tuyến
Nhiễu xạ cho phép sóng vô tuyến uốn quanh núi và tòa nhà
🔬 Quang học
Giao thoa ánh sáng được dùng trong laser và ảnh ba chiều
🌊 Hải dương học
Nghiên cứu sóng biển giúp dự báo thời tiết
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("Khe h\u1eb9p", barrierX, Math.max(30, 20));
ctx.fillText("Nhi\u1ec5u x\u1ea1", 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("Khe 1", labelX, Math.max(slit1Y - 10, 20));
ctx.fillText("Khe 2", labelX, Math.min(slit2Y + 20, canvas.height - 10));
// Подпись экрана
ctx.fillText("M\u00e0n h\u00ecnh", 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("Giao thoa", 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("Bi\u00ean \u0111\u1ed9", 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("H\u01b0\u1edbng truy\u1ec1n s\u00f3ng \u2192", canvas.width/2, Math.max(40, 30));
ctx.fillText("T\u1ea7n s\u1ed1 = " + 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': "S\u1ef1 truy\u1ec1n s\u00f3ng",
'diffraction': "Nhi\u1ec5u x\u1ea1 s\u00f3ng",
'interference': "Giao thoa s\u00f3ng",
'sideview': "Bi\u00ean d\u1ea1ng s\u00f3ng"
};
const descriptions = {
'propagation': "S\u00f3ng lan truy\u1ec1n t\u1eeb ngu\u1ed3n theo c\u00e1c v\u00f2ng tr\u00f2n \u0111\u1ed3ng t\u00e2m.",
'diffraction': "S\u00f3ng \u0111i qua khe h\u1eb9p v\u00e0 t\u1ecfa ra h\u00ecnh qu\u1ea1t.",
'interference': "Hai khe h\u1eb9p t\u1ea1o ra l\u01b0\u1edbi giao thoa t\u0129nh tr\u00ean m\u00e0n h\u00ecnh.",
'sideview': "S\u00f3ng h\u00ecnh sin di chuy\u1ec3n trong kh\u00f4ng gian."
};
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 Ch\u1ea1y";
} else {
isAnimating = true;
animate();
btn.textContent = "\u23f8\ufe0f T\u1ea1m d\u1eebng";
}
};
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;">