# Using dist(); for collision detection

**URL:** <https://discourse.processing.org/t/using-dist-for-collision-detection/40050>\
**Category:** Coding Questions\
**Tags:** homework\
**Created:** [December 7, 2022, 11:33am UTC](https://discourse.processing.org/t/using-dist-for-collision-detection/40050 "2022-12-07T11:33:32Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![LeckereKrokette](https://avatars.discourse-cdn.com/v4/letter/l/b77776/32.png) [@LeckereKrokette](https://discourse.processing.org/u/LeckereKrokette)\
**Post date:** [December 7, 2022, 11:33am UTC](https://discourse.processing.org/t/using-dist-for-collision-detection/40050/1 "2022-12-07T11:33:32Z")

</div>

Hello processing community. I want to make a mini game where you control a ellipse and have to avoid other ellipse. I first wanted the “opponents” to repel each other. For this I initialized 10 ellipses in an array. But when I try to use the dist function to see if the radius overlaps, it only shows that the dist function doesn’t expect a float parameters. Are there other solutions or can you convert your array in some way so that it is still possible to use dist.

```auto
int ballCount = 10;
float r = 60;
float angle=10;
float[] x = new float[ballCount];
float[] y = new float[ballCount];
float[] xSpeed = new float[ballCount];
float[] ySpeed = new float[ballCount];

void gegner(){
  for(int j = 0; j < ballCount; j++){

    x[j] += xSpeed[j];
    if(x[j] < 133 || x[j] > width-130){
      xSpeed[j] *= -1;
    }

    y[j] += ySpeed[j];
    if(y[j] < 133 || y[j] > height-130){
      ySpeed[j] *= -1;
    } 
    
    
    if(dist(x=xSpeed, y=xSpeed, x[j], y[j]) < r)

{
   if(xSpeed >0){
     xSpeed = -1;
    }
   else if(xSpeed < 0){
      xSpeed = 1;
    }
    if(ySpeed > 0){
      ySpeed = -1;
    }
    else if(ySpeed < 0){
      ySpeed = 1;
    }
    
 }
  
  stroke(0);
fill(0);
    ellipse(x[j], y[j],r,r);
    fill(#2BFF03);
    rect(x[j], y[j],20,20);  
}}

void setup(){
size (800,800);
for(int j = 0; j < ballCount; j++){
    x[j] = random(200,800);
    y[j] = random(200,800);
    xSpeed[j] = random(2.5, 3);
    ySpeed[j] = random(2.5, 3);}
}

void draw() {
  background(0);

gegner();

}

```

---

<div class="post-metadata">

**Author:** ![sableraph](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/sableraph/32/251_2.png) [@sableraph](https://discourse.processing.org/u/sableraph)\
**Post date:** [December 7, 2022, 11:42am UTC](https://discourse.processing.org/t/using-dist-for-collision-detection/40050/2 "2022-12-07T11:42:54Z")

</div>

The problem with your code is that you are trying to pass in an array as a parameter to the “dist()” function, but the “dist()” function expects individual x and y coordinates as parameters. To fix this issue, you can simply use the values from the x and y arrays in the “dist()” function instead of passing in the entire array.

For example, to calculate the distance between the first and second ellipse in your array, you can use the following code:

```auto
if(dist(x[0], y[0], x[1], y[1]) < r)

```

You can then use a loop to check the distance between each ellipse in the array and apply the necessary changes to the x and y speeds if the distance is less than the radius.

_Note: part of this message was generated with ChatGPT_

---

<div class="post-metadata">

**Author:** ![LeckereKrokette](https://avatars.discourse-cdn.com/v4/letter/l/b77776/32.png) [@LeckereKrokette](https://discourse.processing.org/u/LeckereKrokette)\
**Post date:** [December 7, 2022, 12:12pm UTC](https://discourse.processing.org/t/using-dist-for-collision-detection/40050/3 "2022-12-07T12:12:09Z")

</div>

Thanks, I’m a lot closer now. The problem that now exists is that if, for example, I let the 2 ellipse bounce off the rest, it is completely frozen. But the others are completely normal and bounce off the 2 ellipse. But if I now want to let all of them bounce, of one another if(dist(x[j], y[j], x[j], y[j]) \< r), the problem with the freeze applys onto all ellipses.

```auto
int ballCount = 10;
float r = 60;
float angle=10;
float[] x = new float[ballCount];
float[] y = new float[ballCount];
float[] xSpeed = new float[ballCount];
float[] ySpeed = new float[ballCount];

void gegner(){
  for(int j = 0; j < ballCount; j++){

    x[j] += xSpeed[j];
    if(x[j] < 133 || x[j] > width-130){
      xSpeed[j] *= -1;
    }

    y[j] += ySpeed[j];
    if(y[j] < 133 || y[j] > height-130){
      ySpeed[j] *= -1;
    } if(dist(x[1], y[1], x[j], y[j]) < r){
    xSpeed[j] *= -1;
    ySpeed[j] *= -1;
    }
  stroke(0);
fill(0);
    ellipse(x[j], y[j],r,r);
    fill(#2BFF03);
    rect(x[j]-10, y[j]-10,20,20);  
} }

void setup(){
size (800,800);
for(int j = 0; j < ballCount; j++){
    x[j] = random(200,600);
    y[j] = random(200,600);
    xSpeed[j] = random(2.5, 3);
    ySpeed[j] = random(2.5, 3);}
}

void draw() {
  background(255);

gegner();

}

```

---

<div class="post-metadata">

**Author:** ![sableraph](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/sableraph/32/251_2.png) [@sableraph](https://discourse.processing.org/u/sableraph)\
**Post date:** [December 7, 2022, 12:25pm UTC](https://discourse.processing.org/t/using-dist-for-collision-detection/40050/4 "2022-12-07T12:25:27Z")

</div>

The issue is that your code is only checking for a collision between the ~~first~~ second ball and the other balls:

```auto
if(dist(x[1], y[1], x[j], y[j]) < r)

```

You need to add a nested loop to check for collisions between all of the balls.

Here is an example of how you can do this:

```auto
for(int i = 0; i < ballCount; i++){
  for(int j = 0; j < ballCount; j++){
    if(i != j && dist(x[i], y[i], x[j], y[j]) < r){
      xSpeed[i] *= -1;
      ySpeed[i] *= -1;
      xSpeed[j] *= -1;
      ySpeed[j] *= -1;
    }
  }
}

```

This code checks for a collision between each pair of balls and reverses their speed if they are colliding. It also ensures that a ball does not collide with itself by checking if `i` and `j` are the same. You can add this code inside your `gegner()` function.

A more object oriented approach would be to create a `Ball` class with a method that takes an array of Balls and checks for collisions against all of them.

_Note: part of this message was generated with ChatGPT_

---

<div class="post-metadata">

**Author:** ![quark](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/quark/32/26_2.png) [@quark](https://discourse.processing.org/u/quark)\
**Post date:** [December 7, 2022, 5:22pm UTC](https://discourse.processing.org/t/using-dist-for-collision-detection/40050/5 "2022-12-07T17:22:54Z")

</div>

> [@sableraph](#):
>
> ```auto
> for(int i = 0; i < ballCount; i++){
> for(int j = 0; j < ballCount; j++){
> if(i != j && dist(x[i], y[i], x[j], y[j]) < r){
> xSpeed[i] *= -1;
> ySpeed[i] *= -1;
> xSpeed[j] *= -1;
> ySpeed[j] *= -1;
> }
> }
> }
> 
> ```

You can make this double loop more efficient with

```auto
for(int i = 0; i < ballCount - 1; i++){
  for(int j = i + 1; j < ballCount; j++){
    if(dist(x[i], y[i], x[j], y[j]) < r){
      xSpeed[i] *= -1;
      ySpeed[i] *= -1;
      xSpeed[j] *= -1;
      ySpeed[j] *= -1;
    }
  }
}

```

It reduces the number of tests by half and avoids having to compare i and j because it is now impossible for them to be equal

---

<div class="post-metadata">

**Author:** ![quark](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/quark/32/26_2.png) [@quark](https://discourse.processing.org/u/quark)\
**Post date:** [December 7, 2022, 6:24pm UTC](https://discourse.processing.org/t/using-dist-for-collision-detection/40050/6 "2022-12-07T18:24:32Z")

</div>

I just realised that there is an algorithmic logic error in the double loop code presented by @sableRalph

Consider a system with 4 balls this table identifies the collision tests

```
+ = collision test
- = no collision test

          i = 
        0 1 2 3
    0 - + + +    
j 1 + - + +
= 2 + + - +
    3 + + + -
```

Notice that for any pairs of balls where `i != j` two tests are performed and the speed will be multiplied by -1 twice, in other words multiplied by 1 so no change of direction

> [@sableraph](#):
>
> A more object oriented approach would be to create a `Ball` class with a method that takes an array of Balls and checks for collisions against all of them.

This type of problem is well suited to OO programming but this is not a good idea because  
you end up sending the same array to every ball thus having the same problem that I have just described.

Personally I would perform the collision detection outside the ball class (in the main sketch or another class used to manage the application.

---

<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:** [December 8, 2022, 2:12am UTC](https://discourse.processing.org/t/using-dist-for-collision-detection/40050/7 "2022-12-08T02:12:46Z")

</div>

Example w/ double loop circle collision detection:  
[“Linked Balls”](http://Studio.ProcessingTogether.com/sp/pad/export/ro.989GaZC5t7EkE)
