You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
154 lines
3.7 KiB
154 lines
3.7 KiB
2 years ago
|
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'
|
||
|
}
|