Tugas:
Perambatan gelombang, difraksi, interferensi
Laboratorium gelombang interaktif
Selamat datang di laboratorium gelombang interaktif! Di sini kamu bisa mempelajari tiga fenomena gelombang terpenting: perambatan, difraksi, dan interferensi.
Pilih eksperimen:
📡 Perambatan
🌊 Difraksi
⚡ Interferensi
📊 Profil Gelombang
Perambatan Gelombang
Gelombang merambat ke segala arah dari sumber dengan kecepatan konstan.
🌐 Perambatan Gelombang
Gelombang membawa energi tanpa memindahkan materi. Mereka merambat dari sumber dalam lingkaran konsentris.
Kecepatan rambat tergantung pada medium
Amplitudo menentukan intensitas gelombang
Frekuensi tetap konstan saat merambat
🌊 Difraksi Gelombang
Difraksi adalah kemampuan gelombang untuk membelok di sekitar rintangan dan melewati celah sempit.
Lebih jelas saat ukuran rintangan sebanding dengan panjang gelombang
Gelombang menyebar seperti kipas setelah melewati celah
Menjelaskan mengapa suara bisa terdengar di balik tikungan
⚡ Interferensi Gelombang
Interferensi adalah perpaduan gelombang dari dua sumber koheren (celah ganda Young).
Garis terang - interferensi konstruktif
Garis gelap - interferensi destruktif
Jarak antar garis tergantung pada panjang gelombang
📊 Profil Gelombang
Tampilan samping menunjukkan bentuk gelombang - sinusoida yang bergerak di ruang angkasa.
Amplitudo - simpangan maksimum dari titik setimbang
Panjang gelombang tergantung pada frekuensi dan kecepatan
Semakin tinggi frekuensi, semakin pendek panjang gelombang
🎯 Aplikasi Praktis
🎵 Akustik
Desain gedung konser memperhitungkan interferensi gelombang suara
📡 Komunikasi Radio
Difraksi memungkinkan gelombang radio melewati gunung dan bangunan
🔬 Optik
Interferensi cahaya digunakan dalam laser dan holografi
🌊 Oseanografi
Mempelajari gelombang laut membantu memprediksi cuaca
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("Celah", barrierX, Math.max(30, 20));
ctx.fillText("Difraksi", 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("Celah 1", labelX, Math.max(slit1Y - 10, 20));
ctx.fillText("Celah 2", labelX, Math.min(slit2Y + 20, canvas.height - 10));
// Подпись экрана
ctx.fillText("Layar", 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("Interferensi", 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("Amplitudo", 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("Arah perambatan \u2192", canvas.width/2, Math.max(40, 30));
ctx.fillText("Frekuensi = " + 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': "Perambatan Gelombang",
'diffraction': "Difraksi Gelombang",
'interference': "Interferensi Gelombang",
'sideview': "Profil Gelombang"
};
const descriptions = {
'propagation': "Gelombang merambat dari sumber dalam lingkaran konsentris.",
'diffraction': "Gelombang melewati celah dan menyebar seperti kipas.",
'interference': "Dua celah menciptakan pola interferensi statis pada layar.",
'sideview': "Gelombang sinusoidal bergerak di ruang angkasa."
};
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 Putar";
} else {
isAnimating = true;
animate();
btn.textContent = "\u23f8\ufe0f Jeda";
}
};
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;">