Question about a bug in my code

Hi all,
I have created this code which aimes on a square which is taken from the top-left corner to the x and y values of the mouse when the mouse is pressed. Those 2 values are rectX and rectY. Two lines from the x-axis and the y-axis intersect and as you might see, gets closer and closer to the center of the square.
Now, for the problem, when I move it after the lines intersect in the center to a different place. It hadn’t recalibrated most of the time. If the x and y axis of the rectangle is greater than the x and y values it does. If the x axis of the rectangle is greater than the x values of the line it does, and if y axis of the rectangle is greater than the y values of the line it does.
Is there a way to fix this?
Please try this code for yourself.
Thanks, Adi

float a = 1;
float b = 100;
float c = 1;
float d = 100;
int rectX;
int rectY;
void mousePressed() {
  rectX = mouseX;
  rectY = mouseY;
}
void setup() {
  rectMode(CENTER);
  frameRate(10);
}
void draw() {
  println(frameCount);
  background(#9CA0A0);
  float x = random(a, b);
  float y = random(c, d);
  rect(rectX,rectY, 5, 5);
  line(x, 0, x, height);
  line(0, y, width, y);
  if (y>rectX) {
    d=d-1;//d=100
  }
  if (y<rectX) {
    c=c+1;//c=1
  }
  if (x>rectY) {
    b=b-1;//b=100
  }
  if (x<rectY) {
    a=a+1;//a=1
  }
}
1 Like

Two things I noticed

  1. in the if statements you compare y with rectX and x with rectY
  2. If the rectangle starts outside the range [a to b, c to d] then the result is undefined.
    This code seems to fix the problem as far as I understand it.
float a, b, c, d;
int rectX;
int rectY;

void mousePressed() {
  rectX = mouseX;
  if (a > mouseX) a = 0;
  if (b < mouseX) b = width;
  rectY = mouseY;
  if (c > mouseY) c = 0;
  if (d < mouseY) d = height;
}
void setup() {
  rectMode(CENTER);
  a = 0;
  b = width; 
  c = 0;
  d = height;
  frameRate(10);
  rectX = int(random(0, width));
  rectY = int(random(0, height));
}
void draw() {
  println(frameCount);
  background(#9CA0A0);
  float x = random(a, b);
  float y = random(c, d);
  rect(rectX, rectY, 5, 5);
  line(x, 0, x, height);
  line(0, y, width, y);
  if (y>rectY) {
    d=d-1;//d=100
  }
  if (y<rectY) {
    c=c+1;//c=1
  }
  if (x>rectX) {
    b=b-1;//b=100
  }
  if (x<rectX) {
    a=a+1;//a=1
  }
}
1 Like

Hello, and welcome to the forum!

Nice to have you here!

I am not sure what you intend to do.

You change a,b,c,d; in my code we change x,y so that it moves to the rect

Chrisir


float a = 1;
float b = 100;
float c = 1;
float d = 100;

int rectX;
int rectY;

float x = random(a, b);
float y = random(c, d);

void mousePressed() {
  rectX = mouseX;
  rectY = mouseY;
}

void setup() {
  size(200, 200); 
  rectMode(CENTER);
  frameRate(10);
}

void draw() {
  // println(frameCount);
  background(#9CA0A0);

  rect(rectX, rectY, 
    5, 5);

  line(x, 0, x, height);
  line(0, y, width, y);

  if (y>rectY) {
    y=y-1;//d=100
  }
  if (y<rectY) {
    y=y+1;//c=1
  }
  if (x>rectX) {
    x=x-1;//b=100
  }
  if (x<rectX) {
    x=x+1;//a=1
  }
}
//
1 Like

Thanks, boath of those those ways worked and gave me other ideas.
It is a pleasure to be here.

1 Like

That’s really nice to hear!

Thank you for your words!

1 Like

Thanks,
While I was coding I came across another problem. I was trying to merge both of the codes shown by the two of you. First I would “Quark’s code” to be implemented then I would like “Chrisir’s code” to be implemented. So I made this:

But the while statement locks the whole code.
Is there a way to get around that?

float a, b, c, d;
int rectX;
int rectY;

void mousePressed() {
rectX = mouseX;
if (a > mouseX) a = 0;
if (b < mouseX) b = width;
rectY = mouseY;
if (c > mouseY) c = 0;
if (d < mouseY) d = height;
}
void setup() {
rectMode(CENTER);
a = 0;
b = width;
c = 0;
d = height;
frameRate(10);
rectX = int(random(0, width));
rectY = int(random(0, height));
}
void draw() {
println(frameCount);
background(#9CA0A0);
float x = random(a, b);
float y = random(c, d);
rect(rectX, rectY, 5, 5);
line(x, 0, x, height);
line(0, y, width, y);
while (x!=rectX || y!=rectY){
if (y>rectY) {
d=d-1;//d=100
}
if (y<rectY) {
c=c+1;//c=1
}
if (x>rectX) {
b=b-1;//b=100
}
if (x<rectX) {
a=a+1;//a=1
}
}
if (x==rectX||y==rectY) {
if (y>rectY) {
y=y-1;//d=100
}
if (y<rectY) {
y=y+1;//c=1
}
if (x>rectX) {
x=x-1;//b=100
}
if (x<rectX) {
x=x+1;//a=1
}
}
}

1 Like

this is a little confusing

maybe you can describe the behavior you want to achieve.

Shure. First the two line would appear randomly, next they would keep on moving randomly, each time getting closer and closer because the a,b and c,d variables are being adjusted to rectX and rectY by the “if” statements. However, after the lines reach the rectX and rectY and they are moved to a different place, the two lines will start moving there by adding and subtracting to the x and y variables directly instead of subtracting from the a,b,c,d variables.

1 Like

Yeah, while locks the whole code.

Replace it with if.

When you do so you’ll find that this:

is hard to achieve.

Because this condition if (x==rectX||y==rectY) { is true only briefly. As soon as you press the mouse, it is no longer true, and the Sketch will fall back into the old behavior, using ab and cd.

Solution

To avoid this, use an extra variable secondState that stores the fact that we once reached the state / situation where the condition if (x==rectX||y==rectY) is true.

  • Set secondState to true in this case.
  • (initially secondState is false)

THEN you can evaluate this boolean variable secondState and tell the Sketch to behave differently once if (x==rectX||y==rectY) { was true one time (or even if (x==rectX && y==rectY) using AND instead of OR).

  • I made this Sketch “twoPhases1” and will post it if you show your attempt.

Warmest regards,

Chrisir

1 Like

Thank you very much I will start working as soon as I can.

1 Like

I am having trouble with declaring the the new variables. Things are acting up. The place where I declare the new variables (right below) it says duplicate variable x2, y2 and the same over at the if statement. If I try to remove the float when from where I am declaring x2 and y2, it says that there are some troubles with the boolean. Is there an alternative approach to the problem?

void draw() {
float x1 = random(a, b);
float y1 = random(c, d);
boolean x2,y2= false;
float y2 = y1;
float x2 = x1;

if (x1==rectX && y1==rectY) {
boolean x2, y2 =true;
}
if (y2>rectY) {
y2=y2-1;//d=100
}
if (y2<rectY) {
y2=y2+1;//c=1
}
if (x2>rectX) {
x2=x2-1;//b=100
}
if (x2<rectX) {
x2=x2+1;//a=1
}
}

Hello,

Take a close look at your unformatted code.

You are attempting to declare variables as boolean and then declare them as float in the next line.

I did not look any further; unformatted code is difficult to read.

Please format your code as a courtesy to others:
https://discourse.processing.org/faq#format-your-code

:)

1 Like

Ah, you misunderstood my post.

Please go back to your version with while (x!=rectX || y!=rectY){.

Replace the while with if.

You have to big if sections now representing your 2 main behaviors.

Test, you’ll see it won’t work.

Hence introduce the new variable.

Before setup():

boolean secondState = false;

and then use it in the 2nd if.

if(secondState) {

Set secondState to true when if (x==rectX && y==rectY)

if (x==rectX && y==rectY) {
     secondState  = true; 
}

Chrisir

So, I keep the same x and y variables, but give them “a second state” ?

Yes in fact the whole Sketch get a new state, a new behavior

In fact, you tried this with your two major sections:

BEHAVIOR ONE -------------------------------------------

while (x!=rectX || y!=rectY) {
  if (y>rectY) {
    d=d-1;//d=100
  }
  if (y<rectY) {
    c=c+1;//c=1
  }
  if (x>rectX) {
    b=b-1;//b=100
  }
  if (x<rectX) {
    a=a+1;//a=1
  }
}

BEHAVIOR TWO ------------------------------------------- 

if (x==rectX||y==rectY) {
  if (y>rectY) {
    y=y-1;//d=100
  }
  if (y<rectY) {
    y=y+1;//c=1
  }
  if (x>rectX) {
    x=x-1;//b=100
  }
  if (x<rectX) {
    x=x+1;//a=1
  }
}

Chrisir

1 Like

My plan is to make 2 functions behavior one and behavior two, and when,

if (x==rectX && y==rectY) {}

is true, behavior one’s boolean value will be false and behavior two’s value will be true.

Good plan!

Try it and then come back here

Actually the two boolean you mentioned: when they are complementary maybe you only need one: the secondState

1 Like

I tried using sedondState, but I couldn’t do it, then I made this:
But it says the two new functions are locale, and when I change their boolean value in the if statement, it considers them new variables.

float a, b, c, d;

int rectX;

int rectY;

void mousePressed () {

rectX = mouseX;

if (a > mouseX) a = 0;

if (b < mouseX) b = width;

rectY = mouseY;

if (c > mouseY) c = 0;

if (d < mouseY) d = height;

}

float x1 = random(a, b);

float y1 = random(c, d);

boolean bing1 = true;

boolean bing2 = false;

void bing1 () {

if (y1>rectY) {

d=d-1; //d=100

}

if (y1<rectY) {

c=c+1; //c=1

}

if (x1>rectX) {

b=b-1; //b=100

}

if (x1<rectX) {

a=a+1; //a=1

}

}

void bing2 () {

if (y1>rectY) {

y1=y1-1; //d=100

}

if (y1<rectY) {

y1=y1+1; //c=1

}

if (x1>rectX) {

x1=x1-1; //b=100

}

if (x1<rectX) {

x1=x1+1; //a=1

}

}

void setup () {

rectMode(CENTER);

a = 0;

b = width;

c = 0;

d = height;

frameRate(10);

rectX = int (random(0, width));

rectY = int (random(0, height));

}

void draw () {

background(#9CA0A0);

rect(rectX, rectY, 5, 5);

line(x1, 0, x1, height);

line(0, y1, width, y1);

bing1();

if (x1==rectX && y1==rectY) {

boolean bing1 = false;

boolean bing2 = true;

}

bing1();

bing2();

}

1 Like

Sorry this is taking soo long…

but good job!

OK, some might consider it unwise to give the same names to function and boolean variables (bing1/bing2)


This:

    boolean bing1 = false;
    boolean bing2 = true;

definitely is unwise since by repeating the word boolean you make 2 new variables with the same name which is not what you want.

instead just say

    bing1 = false;
    bing2 = true;

You call the function bing1() twice.


You call both functions bing1 and bing2 without checking the boolean variables bing1 and bing2.

That’s also not good.

Remember that draw() runs automatically 60 times per second automatically

This means in this section

  bing1();

  if (x1==rectX && y1==rectY) {

that he does NOT run bing1() as long as the condition is not met yet.
Instead he just calls bing1() once and just runs on to the condition.
Therefore you need to control the functions bing1() and bing2() with the 2 variables of the same name:

if(bing1)   // when true !!!!!!!!!!!
     bing1();

  if (x1==rectX && y1==rectY) {
     bing1 = false;
     bing2 = true;
  }

if(bing2)   // when true !!!!!!!!!!!
  bing2();

I think in the function bing1 you forgot

  x1 = random(a, b);
  y1 = random(c, d);

Warm regards,

Chrisir

Full Sketch

(don’t look when you want to do it on your own!!!)

  • a
  • b
  • c
  • d
  • e
  • f
  • g
  • h
  • i
  • j

(don’t look when you want to do it on your own!!!)

float a, b, c, d;

int rectX;
int rectY;

void mousePressed () {

rectX = mouseX;

if (a > mouseX) a = 0;

if (b < mouseX) b = width;

rectY = mouseY;

if (c > mouseY) c = 0;

if (d < mouseY) d = height;
}

float x1 = random(a, b);

float y1 = random(c, d);

boolean bBing1 = true;
boolean bBing2 = false;

// -------------------------------------------------------------------------------------

void bing1 () {
// working with abcd

if (y1>rectY) {

d=d-1; //d=100   d = yMax

}

if (y1<rectY) {

c=c+1; //c=1      c = yMin

}

if (x1>rectX) {

b=b-1; //b=100    b = xMax

}

if (x1<rectX) {

a=a+1; //a=1        a = xMin

}

x1 = random(a, b);
y1 = random(c, d);
}

void bing2 () {
// working directly

if (y1>rectY) {

y1=y1-1; //d=100

}

if (y1<rectY) {

y1=y1+1; //c=1

}

if (x1>rectX) {

x1=x1-1; //b=100

}

if (x1<rectX) {

x1=x1+1; //a=1

}
}

// ------------------------------------------------------------------------

void setup () {

rectMode(CENTER);

a = 0;
b = width;

c = 0;
d = height;

frameRate(10);

rectX = int (random(0, width));
rectY = int (random(0, height));
}

void draw () {

background(#9CA0A0);

// target
rect(rectX, rectY, 5, 5);

line(x1, 0, x1, height);
line(0, y1, width, y1);

if (bBing1) // when true !!!
bing1();

// go to 2nd state / phase
if (x1==rectX && y1==rectY) {
bBing1 = false;
bBing2 = true;
}

if (bBing2) // when true !!!
bing2();
}
//

1 Like

Thanks, I had a few more problems, but I would probably be able to resolve them with your code. This was a great learning experience. :smiley:

I do have another question though.

boolean bBing1 = true;
boolean bBing2 = false;

and

if (x1==rectX && y1==rectY) {
bBing1 = false;
bBing2 = true;
}

You say “bbing1” and “bbing2” why not just “bing1” and “bing2” like they were declared.

Thanks Again,
Adi