How do I integrate dist() into my current code?

Below is a simple program I am trying to build up.

When the Ball object and Donut object intersect I would like:
1/ the ball to turn red
2/ the donut to turn blue
3/ the background to be a random color
When there is no intersection of objects return to noFill and background to (255).

I have currently placed pseudocode that i have commented out in the area I believe the actual code would appear. However, as a beginner I am struggling with how to integrate.

Any guidance is most appreciated.

``````Ball b;
Donut d;

void setup() {
size(400, 400);
b = new Ball();
d = new Donut();
}
void draw() {
background(255);
b.display();
b.move();
b.bounce();
//b.intersect();

d.display();
d.move();
d.bounce();
//d.intersect();
}
class Ball {
int x;
int y;
int r;
int speed;

Ball() {
x = 0;
y = height/2;
r = 50;
speed = 5;
}

void display() {
noFill();
strokeWeight(3);
ellipse(x + r/2, y, r, r);
}
void move() {
x = x + speed;
}
void bounce() {
if ((x >= width - r)||(x <= 0)) {
speed = speed *-1;
}
}
//void intersect() {
//  float distance = dist(x, y, donut.x, donut.y);
//  while (distance < r + donut.r) {
//    background(random(255));
//    fill(255, 0, 0, 50);
//  }
}
class Donut {
int x;
float y;
int r;
float speed;

Donut() {
x = width/2;
y = 50;
r = 50;
speed = random(1, 5);
}
void display() {
noFill();
strokeWeight(3);
ellipse(x, y, r, r);
ellipse(x, y, r*2, r*2);
}
void move() {
y = y + speed;
}
void bounce() {
if ((y >= height - r)||(y <= 50)) {
speed = speed *-1;
}
}
//void intersect() {
//  float distance = dist(x, y, ball.x, ball.y);
//  while (distance < r + donut.r) {
//    fill(0, 0, 255, 50);
//  }
}
``````
1 Like

This is a second iteration trying to integrate disc() for intersection following an example in Dan Shiffmanâ€™s Learning Processing. Though I donâ€™t know if this is a proper application.

``````Ball b;
Donut d;

void setup() {
size(400, 400);
b = new Ball();
d = new Donut();
}
void draw() {
background(255);
b.display();
b.move();
b.bounce();

d.display();
d.move();
d.bounce();
}
//trying to follow D Shiffman example here
if (ball.intersect(donut)) {
ball.change();
donut.change();
}
}
class Ball {
int x;
int y;
int r;
int speed;

Ball() {
x = 0;
y = height/2;
r = 50;
speed = 5;
}

void display() {
noFill();
strokeWeight(3);
ellipse(x + r/2, y, r, r);
}
void move() {
x = x + speed;
}
void bounce() {
if ((x >= width - r)||(x <= 0)) {
speed = speed *-1;
}
}
void change(){
fill(255, 0, 0, 50); //fill ellipse with red + alpha 50 only during intersection
}
//following D Shiffman boolean example
boolean intersect(Donut d){
float distance = dist(x, y, d.x, d.y);
if (distance < r + d.r){
return true;
}else{
return false
}
}
class Donut {
int x;
float y;
int r;
float speed;

Donut() {
x = width/2;
y = 50;
r = 50;
speed = random(1, 5);
}
void display() {
noFill();
strokeWeight(3);
ellipse(x, y, r, r);
ellipse(x, y, r*2, r*2);
}
void move() {
y = y + speed;
}
void bounce() {
if ((y >= height - r)||(y <= 50)) {
speed = speed *-1;
}
}
void change() {
fill(0, 0, 255, 50); //fill donut with blue + alpha 50 only during intersection with ball object
}
}
``````

(I havenâ€™t looked at your 2nd post; I just used your 1st post)

core idea is to set a flag isBlue and isRed to handle the fill color when they hit

To avoid that the background color flickers during the time they are close to each other I use the variable `firstTime`.

`firstTime` letâ€™s the background color change only the first time of each touching of the objects.

``````

Ball b;
Donut d;

color backgroundColor = 255;

void setup() {
size(400, 400);
b = new Ball();
d = new Donut();
}

void draw() {
background(backgroundColor);
b.display();
b.move();
b.bounce();
b.intersect();

d.display();
d.move();
d.bounce();
d.intersect();
}

// ==================================================================

class Ball {
int x;
int y;
int r;
int speed;

boolean isBlue=false;

boolean firstTime=true; // for background

Ball() {
x = 0;
y = height/2;
r = 50;
speed = 5;
}

void display() {
noFill();
if (isBlue)
fill(255, 0, 0, 50);
strokeWeight(3);
ellipse(x + r/2, y, r, r);
}
void move() {
x = x + speed;
}
void bounce() {
if ((x >= width - r)||(x <= 0)) {
speed = speed *-1;
}
}
void intersect() {
float distance = dist(x, y, d.x, d.y);
if (distance < r + d.r) {
if (firstTime)
backgroundColor = color(random(255));
isBlue=true;
firstTime=false;
} else {
firstTime=true;
}
}
//
}//class

// ==================================================================

class Donut {
int x;
float y;
int r;
float speed;

boolean isRed=false;

Donut() {
x = width/2;
y = 50;
r = 50;
speed = random(1, 5);
}
void display() {
noFill();
if (isRed)
fill(0, 0, 255, 50);
strokeWeight(3);
ellipse(x, y, r, r);
ellipse(x, y, r*2, r*2);
}
void move() {
y = y + speed;
}
void bounce() {
if ((y >= height - r)||(y <= 50)) {
speed = speed *-1;
}
}
void intersect() {
float distance = dist(x, y, b.x, b.y);
if (distance < r + d.r) {
isRed=true;
}
}
//
}//class
//
``````

new version with a more donut-like blue

``````Ball b;
Donut d;

color backgroundColor = 255;

void setup() {
size(400, 400);
b = new Ball();
d = new Donut();
}

void draw() {
background(backgroundColor);
b.display();
b.move();
b.bounce();
b.intersect();

d.display();
d.move();
d.bounce();
d.intersect();
}

// ==================================================================

class Ball {
int x;
int y;
int r;
int speed;

boolean isBlue=false;

boolean firstTime=true; // for background

Ball() {
x = 0;
y = height/2;
r = 50;
speed = 5;
}

void display() {
noFill();
if (isBlue)
fill(255, 0, 0, 50);
strokeWeight(3);
ellipse(x + r/2, y, r, r);
}
void move() {
x = x + speed;
}
void bounce() {
if ((x >= width - r)||(x <= 0)) {
speed = speed *-1;
}
}
void intersect() {
float distance = dist(x, y, d.x, d.y);
if (distance < r + d.r) {
if (firstTime)
backgroundColor = color(random(255));
isBlue=true;
firstTime=false;
} else {
firstTime=true;
}
}
//
}//class

// ==================================================================

class Donut {
int x;
float y;
int r;
float speed;

boolean isRed=false;

Donut() {
x = width/2;
y = 50;
r = 50;
speed = random(1, 5);
}
void display() {
noFill();
if (isRed)
fill(0, 0, 255, 50);
strokeWeight(3);
ellipse(x, y, r*2, r*2);

fill(backgroundColor);
ellipse(x, y, r, r);
}

void move() {
y = y + speed;
}
void bounce() {
if ((y >= height - r)||(y <= 50)) {
speed = speed *-1;
}
}
void intersect() {
float distance = dist(x, y, b.x, b.y);
if (distance < r + d.r) {
isRed=true;
}
}
//
}//class
//
``````
2 Likes

Thank you @Chrisir!
I need to study this a bit but I think I understand. I may have a follow up question.

1 Like

The noFill() gets overwritten by the following ifâ€¦fillâ€¦ statement

Try the sketch without the firstTime variable to see the background flickering

I commented out all reference to firstTime variable and the background remains always at 255. Iâ€™m not seeing any change.

This line together with the background line in draw() using this variable makes the background flicker

Here is a version without the firstTime variable

Here you see the background flickering during the time the two objects touch

``````
Ball b;
Donut d;

color backgroundColor = 255;

void setup() {
size(400, 400);
b = new Ball();
d = new Donut();
}

void draw() {
background(backgroundColor);
b.display();
b.move();
b.bounce();
b.intersect();

d.display();
d.move();
d.bounce();
d.intersect();
}

// ==================================================================

class Ball {
int x;
int y;
int r;
int speed;

boolean isBlue=false;

Ball() {
x = 0;
y = height/2;
r = 50;
speed = 5;
}

void display() {
noFill();
if (isBlue)
fill(255, 0, 0, 50);
strokeWeight(3);
ellipse(x + r/2, y, r, r);
}
void move() {
x = x + speed;
}
void bounce() {
if ((x >= width - r)||(x <= 0)) {
speed = speed *-1;
}
}
void intersect() {
float distance = dist(x, y, d.x, d.y);
if (distance < r + d.r) {
backgroundColor = color(random(255));
isBlue=true;
}//if
}//method
//
}//class

// ==================================================================

class Donut {
int x;
float y;
int r;
float speed;

boolean isRed=false;

Donut() {
x = width/2;
y = 50;
r = 50;
speed = random(1, 5);
}
void display() {
noFill();
if (isRed)
fill(0, 0, 255, 50);
strokeWeight(3);
ellipse(x, y, r, r);
ellipse(x, y, r*2, r*2);
}
void move() {
y = y + speed;
}
void bounce() {
if ((y >= height - r)||(y <= 50)) {
speed = speed *-1;
}
}
void intersect() {
float distance = dist(x, y, b.x, b.y);
if (distance < r + d.r) {
isRed=true;
}
}
//
}//class
//
``````

You could set isRed and isBlue back to false when the distance of the 2 objects is far again, so they would lose their color

Thanks again @Chrisir!

Some follow up questions. The first one regarding syntax:

I have marked in comments next to areas in question.

``````void display() {
noFill();
if (isRed) // { why no curly bracket here?
fill(0, 0, 255, 50);
/* } why no curly bracket here? I thought curly brackets
always surround the command to execute in the if-statement */
strokeWeight(3);
ellipse(x, y, r*2, r*2);
``````

This also happens here:

``````void intersect() {
float distance = dist(x, y, d.x, d.y);
if (distance < r + d.r) {
if (firstTime) // { why no curly bracket here?
backgroundColor = color(random(255));
/* } why no curly bracket here? I initially thought
when if is nested within another if but that's not
the case in the display() function above. Is it a shortcut? */

isBlue=true;
firstTime=false;
} else {
firstTime=true;
}
``````
1 Like

When there is only ONE command, no curly brackets are needed.

It is common though to use them anyway

You can see from the indent how the if works

But curly brackets are allowed of course (and better style I guess)

2 Likes

Thatâ€™s good to know regarding the curly brackets, Thank you @Chrisir.

One more question:
I currently read the firstTime boolean code as:

When the objects intersect firstTime = true starts random pick of color, then;

firstTime=false stops the random picking of colors, then;

}else{ firstTime=true returns to the original state.

Itâ€™s a little confusing in code form, and I want to make sure I am translating / understanding the concept and steps correctly as a means to stop the flicker.

Is my translation from code form to concept correct?

The variable firstTime has the purpose that the change of the background color is done only the first time an intersection is detected and not throughout the intersection time.

(Thatâ€™s because draw() runs so fast that the intersection is detected many times)

To achieve this, in case of an intersection we evaluate firstTime and change the color only when itâ€™s true. We set the variable to false then, so we store the information that we changed the color and wonâ€™t change it again.

When we evaluate the variable again because the intersection is still there, the variable is false and then we donâ€™t change the color.

The variable has fulfilled its purpose.

Problem

Now when the intersection is over and a new one occurs, the variable firstTime would still be false so we wonâ€™t change the background color also we wanted to do this since itâ€™s a new intersection. Thatâ€™s a problem.

To improve this, the else part of the if-clause (when no intersection has been detected) sets the variable to true saying for the next intersection detection itâ€™s the first time we detect the intersection and we havenâ€™t changed the color for the upcoming intersection. Problem solved.

Please note how the name firstTime reflects this purpose nicely. It says itâ€™s the first time I detected this current intersection.

1 Like

Thank you this excellent explanation @Chrisir!
I now understand.

1 Like