function set_wave(host) {
let wave_html = Array.from($(host).text())
.map((val, index) => {
return `<span index="${index}" style="position: relative">${val}</span>`;
})
.join('');
$(host).html(wave_html);
let elems = $(host).children();
const n = elems.length;
const c = 1;
const damping = 0.95;
const dx = 1.0 / (n + 1);
const dt = Math.min(dx / c, 1.0 / 60.0);
let x = Array(n).fill(0);
let x_p = Array(n).fill(0);
elems.mouseover((ev) => {
const id = parseInt(ev.target.getAttribute('index'));
x[id] = x[id] * 1.01 + 0.1;
});
setInterval(() => {
let u = Array(n).fill(0);
let cdtdx = Math.pow((c * dt) / dx, 2);
u[0] = 2 * x[0] - x_p[0] + cdtdx * (0 - 2 * x[0] + x[1]);
u[n - 1] = 2 * x[n - 1] - x_p[n - 1] + cdtdx * (x[n - 2] - 2 * x[n - 1] + 0);
for (let i = 1; i < n - 1; i++) {
u[i] = 2 * x[i] - x_p[i] + cdtdx * (x[i - 1] - 2 * x[i] + x[i + 1]);
}
for (let i = 0; i < n; i++) {
x_p[i] = x[i];
x[i] = u[i] * damping;
}
elems.each((i, elem) => {
$(elem).css('top', `${x[i] * 30}px`);
});
}, dt * 1000.0);
}
$(document).ready(() => {
set_wave('#wave');
});