# Change Ball's Color After Collision

Hello! I’m trying to make a simulation about hard-sphere collision with some modifications and I’ve been stuck for days.
This is the output :

However, I want the blue ball to turn its color to red after collided with a red ball. My codes are below.

1. Main script
``````Ball[] balls;
int numBalls = 500 ;

void setup() {
size(500, 500);
balls = new Ball[numBalls];
for (int i = 0; i < numBalls; i++) {
balls[i] = new Ball(random(width), random(height));
}
}

void draw() {
background(255);
for (int i = 0; i < balls.length/3; i++) {
balls[i].display(255, 0, 0);
balls[i].move();
}

for (int j = balls.length/3 + 1; j < 2*balls.length/3; j++) {
balls[j].display(0, 255, 0);
balls[j].move();
}
for (int k = (2*balls.length/3) + 1; k < balls.length; k++) {
balls[k].display(0, 0, 255);
balls[k].move();
}
textSize(40);
textMode(LEFT);
fill(0);
text("", width/4+100, 200);

for(int i = 0; i < balls.length-1; i++){
for(int j = i+1; j<balls.length; j++){
collision(balls[i], balls[j]);
}
}

}
void collision(Ball b1, Ball b2){
// This solution fixes the glitch that occurs
// with multiple ball collisions.

float dx = b2.x - b1.x;
float dy = b2.y - b1.y;
float dist = sqrt(dx*dx+dy*dy);

float angle = atan2(dy,dx);
float sin = sin(angle), cos = cos(angle);

float x1 = 0, y1 = 0;
float x2 = dx*cos+dy*sin;
float y2 = dy*cos-dx*sin;

// rotate velocity
float vx1 = b1.vx*cos+b1.vy*sin;
float vy1 = b1.vy*cos-b1.vx*sin;
float vx2 = b2.vx*cos+b2.vy*sin;
float vy2 = b2.vy*cos-b2.vx*sin;

// resolve the 1D case
float vx1final = ((b1.mass-b2.mass)*vx1+2*b2.mass*vx2)/(b1.mass+b2.mass);
float vx2final = ((b2.mass-b1.mass)*vx2+2*b1.mass*vx1)/(b1.mass+b2.mass);

vx1 = vx1final;
vx2 = vx2final;

// fix the glitch by moving ball part equal to the overlap
// see video for more details(https://youtu.be/guWIF87CmBg)

float absV = abs(vx1)+abs(vx2);
x1 += vx1/absV*overlap;
x2 += vx2/absV*overlap;

// rotate the relative positions back
float x1final = x1*cos-y1*sin;
float y1final = y1*cos+x1*sin;
float x2final = x2*cos-y2*sin;
float y2final = y2*cos+x2*sin;

// finally compute the new absolute positions
b2.x = b1.x + x2final;
b2.y = b1.y + y2final;

b1.x = b1.x + x1final;
b1.y = b1.y + y1final;

//rotate vel back
b1.vx = vx1*cos-vy1*sin;
b1.vy = vy1*cos+vx1*sin;
b2.vx = vx2*cos-vy2*sin;
b2.vy = vy2*cos+vx2*sin;

}

}
``````
1. Ball object
``````class Ball {
float vx, vy, mass;
Ball(float x_, float y_) {
x = x_;
y = y_;
vy = random(-1, 1);
vx = random(-1, 1);
}
void display(float colora,float colorb, float colorc) {
fill(colora, colorb, colorc);
}
void move() {
x += vx;
y += vy;
if (x > width - radius) {
vx = -vx;
}
vx = -vx;
}
if (y > height - radius) {
vy = -vy;
}
vy = -vy;
}
}
}
``````
1 Like

I would choose to store a color inside the Ball class itself. Then, when you initialize the class, you could have the constructor be:

``````color c;
...
Ball(float x_, float y_, color c_) {
x = x_;
y = y_;
vy = random(-1, 1);
vx = random(-1, 1);
c = c_;
}
``````

and your display method would just be

``````  void display() {
fill(c);
}
``````

this cleans up a lot of stuff, since now in your setup method:

``````  for (int i = 0; i < numBalls; i++) {
color temp;
switch (i % 3) {
case 0:
temp = color(255, 0, 0);
break;
...
}
balls[i] = new Ball(random(width), random(height), temp);
}
``````

with this approach now, you can implement wherever your balls collide something like:

``````if (ball 1 is red)
make ball 2's color red
else if (ball 2 is red)
make ball 1's color red
``````
3 Likes

Thank you for the reply, I will try to apply your suggestion.