Skip to content

Commit

Permalink
Update double slit sim
Browse files Browse the repository at this point in the history
  • Loading branch information
TheTrustyPwo committed May 12, 2024
1 parent 5b9234b commit f0e1deb
Show file tree
Hide file tree
Showing 5 changed files with 82 additions and 33 deletions.
12 changes: 6 additions & 6 deletions sim5.html
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,16 @@
<canvas width="1000px" height="500px"></canvas>

<div class="slitWidth">
<input type="range" min="20" max="80" step="10" value="50" class="slider" id="slitWidthInput">
Slit Width: <span id="slitWidthValue">50</span> px
<input type="range" min="1" max="3" step="0.1" value="2.0" class="slider" id="slitWidthInput">
Slit Width: <span id="slitWidthValue">2.0</span> 渭m
</div>
<div class="slitSeparation">
<input type="range" min="50" max="200" step="10" value="100" class="slider" id="slitSeparationInput">
Slit Separation: <span id="slitSeparationValue">100</span> px
<input type="range" min="1" max="5" step="0.1" value="4.0" class="slider" id="slitSeparationInput">
Slit Separation: <span id="slitSeparationValue">4.0</span> 渭m
</div>
<div class="wavelength">
<input type="range" min="5" max="20" step="1" value="10" class="slider" id="wavelengthInput">
Wavelength: <span id="wavelengthValue">10</span> px
<input type="range" min="380" max="780" step="10" value="500" class="slider" id="wavelengthInput">
Wavelength: <span id="wavelengthValue">500</span> nm
</div>

<script type="module" src="static/js/sim5.js"></script>
Expand Down
2 changes: 1 addition & 1 deletion static/js/sim4.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ const c = cvs.getContext('2d');
const wavelengthInput = document.getElementById("wavelengthInput");
const slitWidthInput = document.getElementById("slitWidthInput");

const simulation = new SingleSlitSimulation(cvs, c, wavelengthInput.value, slitWidthInput.value * 1000);
const simulation = new SingleSlitSimulation(cvs, c);
const animate = () => {
simulation.update();

Expand Down
5 changes: 2 additions & 3 deletions static/js/sim5.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ const slitSeparationInput = document.getElementById("slitSeparationInput");

const simulation = new DoubleSlitSimulation(cvs, c)
const animate = () => {
c.clearRect(0, 0, cvs.width, cvs.height);
simulation.update();

setTimeout(() => {
Expand All @@ -25,12 +24,12 @@ wavelengthInput.oninput = () => {

slitWidthInput.oninput = () => {
document.getElementById("slitWidthValue").innerText = slitWidthInput.value;
simulation.setSlitWidth(slitWidthInput.value);
simulation.setSlitWidth(slitWidthInput.value * 1000);
}

slitSeparationInput.oninput = () => {
document.getElementById("slitSeparationValue").innerText = slitSeparationInput.value;
simulation.setSlitSeparation(slitSeparationInput.value);
simulation.setSlitSeparation(slitSeparationInput.value * 1000);
}


Expand Down
94 changes: 72 additions & 22 deletions static/js/simulations/doubleSlit.js
Original file line number Diff line number Diff line change
@@ -1,48 +1,51 @@
import {Simulation} from "./index.js";
import {Screen} from "../shared/screen.js";
import {interpolate} from "../utils/color.js";
import {interpolate, w2h} from "../utils/color.js";
import {distance} from "../utils/math.js";
import {DoubleSlit} from "../shared/slit.js";

class DoubleSlitSimulation extends Simulation {
constructor(cvs, c, wavelength = 20) {
constructor(cvs, c, wavelength = 500, slitWidth = 2000, slitSeparation = 4000) {
super(cvs, c);
this.wavelength = wavelength;
this.screen = new Screen(cvs, c, 0.85 * cvs.width, cvs.height / 2, cvs.height - 50);
this.slit = new DoubleSlit(cvs, c, 0.15 * cvs.width, cvs.height / 2, cvs.height - 50, 50, 100);

this.waveColor1 = "#ce2b15";
this.waveColor2 = "#000000";
this.slit = new DoubleSlit(cvs, c, 0.15 * cvs.width, cvs.height / 2, cvs.height - 50, slitWidth / this.ypx2nm, slitSeparation / this.ypx2nm);

this.t = 0;
this.dt = 1 / 60;

this.cache = {}
this.cache = {};
this.redraw = true;
}

evaluate = (theta) => {
theta = Math.round(theta * 1000) / 1000;
if (theta in this.cache) return this.cache[theta];
const sine = Math.sin(theta);
const cs = Math.cos(Math.PI * this.slit.separation * sine / this.wavelength);
const tmp = Math.sin(Math.PI * this.slit.width * sine / this.wavelength) / (Math.PI * this.slit.width * sine / this.wavelength);
const cs = Math.cos(Math.PI * this.slit.separation * this.ypx2nm * sine / this.wavelength);
const a = Math.PI * this.slit.width * this.ypx2nm * sine / this.wavelength
const tmp = Math.sin(a) / a;
this.cache[theta] = cs * cs * tmp * tmp;
return this.cache[theta];
}

update = () => {
this.t += this.dt;
this.screen.draw();
this.slit.draw();
this.plotIntensity();

if (this.redraw) {
this.c.clearRect(0, 0, this.cvs.width, this.cvs.height);
this.screen.draw();
this.slit.draw();
this.plotIntensity();
this.redraw = false;
} else this.c.clearRect(this.slit.x + 2.5, 0, this.screen.x - this.slit.x - 5, this.cvs.height);


this.c.save();
for (let x = this.slit.x; x <= this.screen.x - 10; x += 5) {
this.displayMeasurements();
for (let x = 0; x < this.screen.x - 3; x += 5) {
for (let y = 0; y <= this.cvs.height; y += 5) {
const theta = Math.atan2(y - this.slit.y, x - this.slit.x);
this.c.globalAlpha = Math.max(Math.min(1.5 * this.evaluate(theta), 1), 0.15);
const dist = distance(this.slit.x, this.slit.y, x, y);
this.c.fillStyle = interpolate(this.waveColor1, this.waveColor2, (1 + (Math.sin(dist / this.wavelength - 8 * this.t))) / 2);
this.c.globalAlpha = this.intensityAt(x, y);
this.c.fillStyle = this.colorAt(x, y);
this.c.fillRect(x, y, 3, 3);
}
}
Expand All @@ -51,38 +54,85 @@ class DoubleSlitSimulation extends Simulation {

plotIntensity = () => {
this.c.beginPath();
this.c.strokeStyle = "#d94444";
this.c.lineWidth = 3;
this.c.strokeStyle = this.color;
for (let y = 0; y <= this.cvs.height; y++) {
const theta = Math.atan2(y - this.slit.y, this.screen.x - this.slit.x);
const theta = Math.atan2((y - this.slit.y) * this.ypx2nm, (this.screen.x - this.slit.x) * this.xpx2nm);
const intensity = this.evaluate(theta) * 100;
if (y === 0) this.c.moveTo(this.screen.x + 5 + intensity, y);
else this.c.lineTo(this.screen.x + 5 + intensity, y);
}
this.c.stroke();
}

displayMeasurements = () => {
this.c.save();
this.c.beginPath();
this.c.moveTo(this.slit.x, this.cvs.height * 0.9);
this.c.lineTo(this.screen.x, this.cvs.height * 0.9);
this.c.strokeStyle = "#179e7e";
this.c.stroke();
this.c.translate((this.slit.x + this.screen.x) / 2, this.cvs.height * 0.9 - 18);
this.c.font = "20px arial";
this.c.textAlign = "center";
this.c.fillStyle = "#179e7e";
this.c.fillText(`${(this.screen.x - this.slit.x) * this.xpx2nm} nm`, 0, 10);
this.c.restore();
}

setWavelength = (wavelength) => {
this.wavelength = wavelength;
this.redraw = true;
this.cache = {};
}

setSlitWidth = (slitWidth) => {
this.slit.width = slitWidth;
this.slit.width = slitWidth / this.ypx2nm;
this.redraw = true;
this.cache = {};
}

setSlitSeparation = (slitSeparation) => {
this.slit.separation = slitSeparation;
this.slit.separation = slitSeparation / this.ypx2nm;
this.redraw = true;
this.cache = {};
}

intensityAt = (x, y) => {
if (x < this.slit.x) return 1;
const theta = Math.atan2((y - this.slit.y) * this.ypx2nm, (x - this.slit.x) * this.xpx2nm);
let intensity = this.evaluate(theta);
// Following line is unscientific, only for visual effects
if (Math.abs(theta) > Math.asin(this.wavelength / this.slit.width / this.ypx2nm)) intensity *= 3;
return intensity;
}

colorAt = (x, y) => {
const dist = (x < this.slit.x ? x * this.xpx2nm : distance(this.slit.x * this.xpx2nm, this.slit.y * this.ypx2nm, x * this.xpx2nm, y * this.ypx2nm));
const v = 2 * dist / this.wavelength - 10 * this.t;
const factor = (1 + Math.cos(v)) / 2;
return interpolate("#000000", this.color, factor);
}

mouseDown = (event) => {};

mouseUp = (event) => {};

mouseMove = (event, x, y) => {
this.screen.x = Math.max(Math.min(x, this.screen.maxX), this.screen.minX);
this.redraw = true;
}

get xpx2nm() {
return 20;
}

get ypx2nm() {
return 20;
}

get color() {
return w2h(this.wavelength);
}
}

Expand Down
2 changes: 1 addition & 1 deletion static/js/simulations/singleSlit.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import {distance} from "../utils/math.js";
import {Slit} from "../shared/slit.js";

class SingleSlitSimulation extends Simulation {
constructor(cvs, c, wavelength = 300, slitWidth = 50) {
constructor(cvs, c, wavelength = 500, slitWidth = 2000) {
super(cvs, c);
this.wavelength = wavelength;
this.screen = new Screen(cvs, c, 0.85 * cvs.width, cvs.height / 2, cvs.height - 20);
Expand Down

0 comments on commit f0e1deb

Please sign in to comment.