You've Reached the Center of the Internet
It's a blog
Landau-Squire Flow
I made a simulation of a Landau-Squire jet with javascript. Check it out! You can click on this gif to take you to the simulation page. It looks way better there.
This is the Navier-Stokes solution to a tiny submerged point jet. Imagine a thin needle injecting fluid into the middle of bath full of little tracer particles. Code below.
var c = document.getElementById("myCanvas");
c.addEventListener(‘click’, onClick, false)
var ctx = c.getContext("2d");
var ball_list = [];
var is_paused = false;
window.onblur = function() {
if (!is_paused) {
pause();
}
};
function onClick() {
if (is_paused) {
unpause();
} else {
pause();
}
}
function pause() {
is_paused = true;
ctx.globalAlpha=0.2;
ctx.fillRect(360,140,100,300)
ctx.fillRect(540,140,100,300)
ctx.font = "30px Arial";
ctx.fillText("Click to unpause",390,500);
ctx.globalAlpha=1;
}
function unpause() {
is_paused = false;
}
function Ball(x, y) {
return {
x: x,
y: y,
draw: function() {
ctx.fillRect(this.x,this.y,2,2)
},
update: function() {
var xp = (this.x – c.width/2 )/c.width;
var yp = (this.y – c.height/2)/c.height;
this.x += (1 * xp * xp – yp * yp) / (Math.pow(xp * xp + yp * yp, 1.5))
this.y += (1.5 * xp * yp) / (Math.pow(xp * xp + yp * yp, 1.5))
}
}
}
function clearCanvas() {
ctx.clearRect(0, 0, c.width, c.height);
ball_list.forEach(function(ball, i) {
if ((ball.x < 0) || (ball.x > c.width) || (ball.y < 0) || (ball.y > c.height)) {
ball_list.splice(i, 1);
}
ball.draw();
})
}
function update() {
ball_list.forEach(function(ball) {
ball.update();
})
}
function draw() {
clearCanvas();
ball_list.forEach(function(ball) {
ball.draw();
})
}
function loop() {
if (!is_paused) {
update();
draw();
}
}
function addTracers() {
if (!is_paused) {
var n_tracer = 10;
var step = c.height / n_tracer;
var rand = 9;
for (var x = step/2; x < c.width; x += step) {
for (var y = step/2; y < c.height; y+= step) {
ball_list.push(Ball(x + rand * (Math.random() – 0.5), y + rand * (Math.random() – 0.5)));
}
}
console.log(ball_list.length)
}
}
setInterval(loop, 1000/60);
setInterval(addTracers, 1000/1);