class Doppler{ constructor(){ this.waves = []; this.source = new Source(this.waves); this.vel = 1; } update(){ let wavesToRemove = [] this.waves.forEach(w => w.update(this.vel, wavesToRemove)); wavesToRemove.forEach((w, i) => this.waves.splice(i, 1)); this.source.update(this.vel); } updateMode(){ let mode = $('#mode_holder input[name=mode]:checked').val(); console.log('New mode: ' + mode); this.source.mode = mode; this.source.reset(); } display(){ this.waves.forEach(w => w.display()); this.source.display(); } } class Source{ constructor(waves){ this.waves = waves; this.radius = 20; this.pos = createVector(width / 4, height / 2); this.vel = createVector(10, 0); this.angle = 0; } reset(){ this.pos = createVector(width / 4, height / 2); this.vel = createVector(10, 0); this.angle = 0; } update(vel){ this.angle += 0.03 * vel; this.move(vel); if (mouseIsPressed) this.trySendWave(vel); } move(vel){ let x, y, size; switch (this.mode){ case MODE.FREE: x = mouseX; y = mouseY; break; case MODE.STRAIGHT_LEFT: x = this.pos.x - this.vel.x * vel; y = height / 2; if (x < 0) x = width; break; case MODE.STRAIGHT_RIGHT: x = this.pos.x + this.vel.x * vel; y = height / 2; if (x > width) x = 0; break; case MODE.STRAIGHT_BOTH: x = this.pos.x + this.vel.x * vel; y = height / 2; if (x < 0 || x > width) this.vel.x *= -1; break; case MODE.SMOOTH_HORIZONTAL: size = Math.min(width, height) * 0.8; x = width / 2 + sin(this.angle) * size / 2; y = height / 2; break; case MODE.SMOOTH_VERTICAL: size = Math.min(width, height) * 0.8; x = width / 2; y = height / 2 + cos(this.angle) * size / 2; break; case MODE.CIRCLE: size = Math.min(width, height) * 0.8; x = width / 2 + sin(this.angle) * size / 2; y = height / 2 + cos(this.angle) * size / 2; break; } this.pos.x = x; this.pos.y = y; } trySendWave(vel){ if (frameCount % int(2 / vel) === 0){ this.waves.push(new Wave(this.pos.x, this.pos.y, this.radius)); } } display(){ fill(255, 0, 0); stroke(255, 0, 0); strokeWeight(1); ellipse(this.pos.x, this.pos.y, this.radius, this.radius); } } class Wave{ constructor(x, y, r){ this.pos = createVector(x, y); this.radius = r; this.vel = 35; } get isRemoveable(){ return this.radius > width * 2.1; } update(vel, removeables){ this.grow(vel); if (this.isRemoveable) removeables.push(this); } grow(vel){ this.radius += this.vel * vel; } display(){ noFill(); stroke(255); strokeWeight(1); ellipse(this.pos.x, this.pos.y, this.radius, this.radius); } } let MODE = { FREE: 'free', STRAIGHT_LEFT: 'straight_left', STRAIGHT_RIGHT: 'straight_right', STRAIGHT_BOTH: 'straight_both', SMOOTH_HORIZONTAL: 'smooth_horizontal', SMOOTH_VERTICAL: 'smooth_vertical', CIRCLE: 'circle' }