# Help with animation doppler sound-wave propagation

**URL:** <https://discourse.processing.org/t/help-with-animation-doppler-sound-wave-propagation/40429>\
**Category:** Coding Questions\
**Created:** [January 3, 2023, 2:45pm UTC](https://discourse.processing.org/t/help-with-animation-doppler-sound-wave-propagation/40429 "2023-01-03T14:45:10Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![Tilman](https://avatars.discourse-cdn.com/v4/letter/t/90db22/32.png) [@Tilman](https://discourse.processing.org/u/Tilman)\
**Post date:** [January 3, 2023, 2:45pm UTC](https://discourse.processing.org/t/help-with-animation-doppler-sound-wave-propagation/40429/1 "2023-01-03T14:45:10Z")

</div>

Hi!  
I am trying to create an abstract animation visualizing how sound waves propagate emitting from a moving object. Basically circles growing in radius while the x position of the object changes.

Like in this animation:

[![](https://img.youtube.com/vi/6lb1P3CKC_w/maxresdefault.jpg "Doppler Sound Waves") ](https://www.youtube.com/watch?v=6lb1P3CKC_w)

In my code I am missing the characteristic of a sphere constantly emitted from the object. Something needs to be done with opacity and re-trigger. To match the characteristics of the animation in the youtube video. Maybe some one has an idea that could help me? Thank you!

Here is what I got:

```auto
let xpos = 0;
let ypos = 200;
let radius = 0;
let interval = 0.5;
let waves = [];
function setup() {
  createCanvas(800, 400);
}

function draw() {
  background(0, 255);
  xpos += 6;
// object emitting sound
    fill(255);
    ellipse(xpos + 6, ypos, 10);
  
  
  
  for (let i = 0; i < 1; i++) {
    waves.push(new Wave(xpos, ypos, radius));
  }

  for (let wave of waves) {
    wave.update();
    wave.show();
  }

  for (let i = waves.length - 1; i >= 0; i--) {
    if (waves[i].finished()) {
      waves.splice(i, 1);
    }
  }
}

class Wave {
  constructor(x, y, radius) {
    this.pos = createVector(x, y);
    this.radius = radius;
    this.lifetime = 255;
  }

  finished() {
    return this.lifetime < 0;
  }

  update() {
    this.radius += 40;
    this.lifetime -= 9;
  }

  show() {
    stroke(255, this.lifetime);
    strokeWeight(2);
    noFill(0);
    stroke(255, this.lifetime);
    strokeWeight(1);
    ellipse(this.pos.x, this.pos.y, this.radius);
  }
}

```

---

<div class="post-metadata">

**Author:** ![Chrisir](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/chrisir/32/45_2.png) [@Chrisir](https://discourse.processing.org/u/Chrisir)\
**Post date:** [January 3, 2023, 7:09pm UTC](https://discourse.processing.org/t/help-with-animation-doppler-sound-wave-propagation/40429/2 "2023-01-03T19:09:31Z")

</div>

maybe it’s a kind of optical illusion

when a circle increases its radius, it takes the position of the last circle and so on. So it looks like nothing moves but the circle do move.

you can see this with random speed of circle growing:

```auto
let xpos = 9;
let ypos = 200;
let radius = 20;
let interval = 0.5;
let waves = [];

function setup() {
  createCanvas(800, 400);
  frameRate(1);
}

function draw() {
  background(0, 255);

  xpos += 15;
  // object emitting sound
  fill(255);
  ellipse(xpos + 6, ypos, 10);

  for (let i = 0; i < 2; i++) {
    waves.push(new Wave(xpos, ypos, radius));
  }

  for (let wave of waves) {
    wave.update();
    wave.show();
  }

  for (let i = waves.length - 1; i >= 0; i--) {
    if (waves[i].finished()) {
      waves.splice(i, 1);
    }
  }
}

class Wave {
  constructor(x, y, radius) {
    this.pos = createVector(x, y);
    this.radius = radius;
    this.lifetime = 255;
    this.speed = random(17, 88);
  }

  finished() {
    return this.lifetime < 0;
  }

  update() {
    this.radius += this.speed;
    this.lifetime -= 9;
  }

  show() {
    stroke(255, this.lifetime);
    strokeWeight(2);
    noFill(0);
    // stroke(255, this.lifetime);
    stroke(255);
    strokeWeight(1);
    ellipse(this.pos.x, this.pos.y, this.radius);
  }
}

```

---

<div class="post-metadata">

**Author:** ![Tilman](https://avatars.discourse-cdn.com/v4/letter/t/90db22/32.png) [@Tilman](https://discourse.processing.org/u/Tilman)\
**Post date:** [January 3, 2023, 7:26pm UTC](https://discourse.processing.org/t/help-with-animation-doppler-sound-wave-propagation/40429/3 "2023-01-03T19:26:38Z")

</div>

@Chrisir that´s interesting… Thank you! Experimenting further here

---

<div class="post-metadata">

**Author:** ![Tilman](https://avatars.discourse-cdn.com/v4/letter/t/90db22/32.png) [@Tilman](https://discourse.processing.org/u/Tilman)\
**Post date:** [January 3, 2023, 9:51pm UTC](https://discourse.processing.org/t/help-with-animation-doppler-sound-wave-propagation/40429/4 "2023-01-03T21:51:38Z")

</div>

@Chrisir I think I made it look a bit better through some additional opacity animation  
It still looks unexpected but is should be a quiet adequate representation as it looks like in this more scientific visualization I found here:

[![](https://img.youtube.com/vi/ZRGg7e9b5wY/maxresdefault.jpg "Doppler Effect Animation") ](https://www.youtube.com/watch?v=ZRGg7e9b5wY)

```auto
let xpos = 0;
let ypos = 200;
let radius = 80;
let interval = 5;
let waves = [];
let opacity = 0;

function setup() {
  createCanvas(windowWidth, windowHeight);
  frameRate(20);
}

function draw() {
  background(0);
  if (frameCount % (interval * 2) == 0) {
    opacity = 180;
  } else {
    opacity = 50;
  }

  // object emitting sound moving
  xpos = 800 * sin(((frameCount % 60) * TAU) / 60) + width / 2;
  ypos = 200;

  fill(255);
  noStroke(0);
  ellipse(xpos, ypos, 30);
  

  //generate soundvaves
  for (let i = 0; i < 1; i++) {
    waves.push(new Wave(xpos, ypos, radius, opacity));
  }

  for (let wave of waves) {
    wave.update();
    wave.show();
  }
  
//loudness out finish
  for (let i = waves.length - 1; i >= 0; i--) {
    if (waves[i].finished()) {
      waves.splice(i, 1);
    }
  }
}
//soundwaves
class Wave {
  constructor(xpos, ypos, radius, opacity) {
    this.pos = createVector(xpos, ypos);
    this.radius = radius;
    this.lifetime = 255;
    this.speed = 200;
    this.opacity = opacity;
  }

  finished() {
    return this.lifetime < 0;
  }

  update() {
    this.radius += this.speed;
    this.lifetime -= 30;
  }

  show() {
    noFill(0);
    stroke(this.opacity, this.lifetime);
    strokeWeight(4);
    ellipse(this.pos.x, this.pos.y, this.radius);
  }
}

```

---

<div class="post-metadata">

**Author:** ![Tilman](https://avatars.discourse-cdn.com/v4/letter/t/90db22/32.png) [@Tilman](https://discourse.processing.org/u/Tilman)\
**Post date:** [January 3, 2023, 9:54pm UTC](https://discourse.processing.org/t/help-with-animation-doppler-sound-wave-propagation/40429/5 "2023-01-03T21:54:56Z")

</div>

mhhh after watching this video I just posted from youtube… maybe I could jet a smoother result if I would scale the circles instead of increasing the radius…

or maybe it looks better because it all happens slower…

---

<div class="post-metadata">

**Author:** ![Tilman](https://avatars.discourse-cdn.com/v4/letter/t/90db22/32.png) [@Tilman](https://discourse.processing.org/u/Tilman)\
**Post date:** [January 3, 2023, 9:55pm UTC](https://discourse.processing.org/t/help-with-animation-doppler-sound-wave-propagation/40429/6 "2023-01-03T21:55:55Z")

</div>

I´ll try some more tomorrow again sigh 🙂

---

<div class="post-metadata">

**Author:** ![Tilman](https://avatars.discourse-cdn.com/v4/letter/t/90db22/32.png) [@Tilman](https://discourse.processing.org/u/Tilman)\
**Post date:** [January 4, 2023, 11:06am UTC](https://discourse.processing.org/t/help-with-animation-doppler-sound-wave-propagation/40429/7 "2023-01-04T11:06:06Z")

</div>

Finally I have it. I guess it was a bad idea to start from an old particle emiter patch… that handled the array differently… But now I started from scratch and have it working!

```auto
let timer = 0;
let soundwaves = [];
let period = 50;
let y = 0;
let x = 0;

function setup() {
  createCanvas(windowWidth, windowHeight);
}

function draw() {
  background(0);
  y = windowHeight / 2;
  x = 900 * sin(((frameCount % 1800) * TAU) / 1800) + width / 2;
  circle(x, y, 20);

  if (millis() >= 500 + timer) {
    let s = new Soundwave(x, y, 0, 0);
    soundwaves.push(s);
    timer = millis();
  }

  noFill(0);
  stroke(255);
  strokeWeight(1);
  for (let i = 0; i < soundwaves.length; i++) {
    soundwaves[i].show();
    soundwaves[i].update();
  }
}

class Soundwave {
  constructor(x, y, r, e) {
    this.x = x;
    this.y = y;
    this.r = r;
    this.e = e;
  }

  update() {
    this.e += 8;
    this.r = this.e;
  }

  show() {
    stroke(255);
    strokeWeight(2);
    noFill();
    circle(this.x, this.y, this.r);
  }
}

```

---

<div class="post-metadata">

**Author:** ![Tilman](https://avatars.discourse-cdn.com/v4/letter/t/90db22/32.png) [@Tilman](https://discourse.processing.org/u/Tilman)\
**Post date:** [January 4, 2023, 9:14pm UTC](https://discourse.processing.org/t/help-with-animation-doppler-sound-wave-propagation/40429/8 "2023-01-04T21:14:10Z")

</div>

meanwhile I experimented with WEBGL to animate everything in 3D  
Now I run into two problems here. One is not WEBGL specific.

The none WEBGL specific issue: In line 52:  
I wish to splice out the oldest (highest radius) soundwave from the array every 2 seconds. But it does not seem to work correctly and causes a hickup in the animation.

The problem that occured with WEBGL In line 37:  
Why doesn´t this sphere move as the x position of the class Soundwaves do? They share the same x and y values

```auto
let timer = 0;
let timersplice = 0;

let soundwaves = [];
let period = 50;
let y = 0;
let x = 0;
let angle1 = 0;
let objperiod = 0.012;

function setup() {
  createCanvas(1000, 1000, WEBGL);
}

function draw() {
  background(0);

  //camera and lightning
  camera(0, 1000, 1000, 0, 0, 0, 0, 1, 0);
  let dx = 1 - width / 2;
  let dy = -1 - height / 2;
  let v = createVector(-dx, -dy, 0);
  let v2 = createVector(dx, dy, 0);
  v.normalize();
  v2.normalize();
  ambientMaterial(255);
  directionalLight(255, 0, 0, v2);
  directionalLight(0, 0, 255, v);
  ambientLight(0, 0, 50);

  //move object and sound waves x and y;
  let ampx = (0.3 * width) / 2;
  x = map(cos(angle1), -1, 1, ampx, -ampx);
  y = 0;
  angle1 += objperiod;

  //Problem: why doesn´t this sphere move as the x position of the class Soundwaves do? They share the same x and y values
  translate(x, y, 0);
  sphere(40);

  //emit soundwave every 500ms
  if (millis() >= 500 + timer) {
    let s = new Soundwave(x, y, 0, 0);
    soundwaves.push(s);
    timer = millis();
  }

  for (let i = 0; i < soundwaves.length; i++) {
    soundwaves[i].show();
    soundwaves[i].update();
  }
  //Problem: I wish to splice out the oldest (highest radius) soundwave from the array every 2 seconds. But it does not seem to work correctly and causes a hickup in the animation.
  for (let i = soundwaves.length - 1; i >= 0; i--) {
    if (millis() >= 2000 + timersplice) {
      soundwaves.splice(i, 1);
      timersplice = millis();
    }
  }
}

class Soundwave {
  constructor(x, y, radius, expand) {
    this.x = x;
    this.y = y;
    this.radius = radius;
    this.expand = expand;
  }

  update() {
    this.expand += 8;
    this.radius = this.expand;
  }

  show() {
    noStroke(0);
    translate(this.x, this.y, 0);
    torus(this.radius, 10, 80, 12);
  }
}

```

---

<div class="post-metadata">

**Author:** ![Tilman](https://avatars.discourse-cdn.com/v4/letter/t/90db22/32.png) [@Tilman](https://discourse.processing.org/u/Tilman)\
**Post date:** [January 5, 2023, 11:44am UTC](https://discourse.processing.org/t/help-with-animation-doppler-sound-wave-propagation/40429/9 "2023-01-05T11:44:33Z")

</div>

Now I feel I have a good version also splicing out after a number of max circles has been reached. I post the 2D version here as it´s final for me:

```auto
let soundwaves = [];
let interval;
let maxSoundwaves = 10;

let y = 0;
let x = 0;
let angle = 0;
let period = 0.006;

function setup() {
  createCanvas(windowWidth, windowHeight);
  //add soundwave on interval
  interval = setInterval(addSoundwave, 600);
}

function addSoundwave() {
  //add soundwave on interval
  let s = new Soundwave(x, y, 0, 0);
  soundwaves.push(s);
  //remove soundwave when max limit
  if (soundwaves.length >= maxSoundwaves) {
    soundwaves.splice(s, 1);
  }
}

function draw() {
  background(0);

  //move object and sound waves x;
  let ampx = 1 * width;
  x = map(sin(angle), -1, 1, 0, ampx);
  y = 500;
  angle += period;

  //object
  fill(255);
  circle(x, y, 20);

  for (let soundwave of soundwaves) {
    soundwave.show();
    soundwave.update();
  }
}

class Soundwave {
  constructor(x, y, radius, expand) {
    this.x = x;
    this.y = y;
    this.radius = radius;
    this.expand = expand;
    this.speedofsound = 8;
  }

  update() {
    this.expand += this.speedofsound;
    this.radius = this.expand;
  }

  show() {
    //CIRCLE
    noFill(0);
    stroke(255);
    strokeWeight(10);
    circle(this.x, this.y, this.radius);
  }
}

```

I still have problems aligning torus the same way when using WEBGL but I´ll make a seperate thread on this.

---

<div class="post-metadata">

**Author:** ![GoToLoop](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/gotoloop/32/86_2.png) [@GoToLoop](https://discourse.processing.org/u/GoToLoop)\
**Post date:** [January 5, 2023, 11:51am UTC](https://discourse.processing.org/t/help-with-animation-doppler-sound-wave-propagation/40429/10 "2023-01-05T11:51:08Z")

</div>

This discussion reminds me of this very old sketch: 🌊  
[“Wave Trios”](http://studio.processingtogether.com/sp/pad/export/ro.9lTJ6qSlmCidk)
