Creating Random Rectangles Without Overlap

Hey guys, so I know that there are other posts about this topic but they don’t really seem to help. Other solutions make use of arrayList and class, which I was not taught. And so I was wondering if it is possible to achieve this using what I’ve coded.

In the code below, I’m trying to generate 6 random rectangles that don’t overlap. The code within the enclosed by the line of === is my attempt at populating the arrays, and using a while and for loop to check each of the distances, however, they still overlap.

Thanks!
(I know the variable names are confusing. What I’ve posted is only a small part of what I need to do)

``````int rectSize = 80;

float [] rectxCoords = new float [6];
float [] rectyCoords = new float [6];

void drawRects(float x, float y) {
rectMode(CENTER);
fill(230, 0, 0);
rect(x, y, rectSize, 120);
}

void setup() {
size(1200, 900);
//BACKGROUND
fill(#FF7E7E);
rect(0, 0, width/3, height);

//===========================================
int i=0;
while (i<6) {
rectxCoords[i]=random(rectSize/2, 400-rectSize/2);
rectyCoords[i]=random(250, 850);
for (int j=0; j<6; j++) {
rectxCoords[j]=random(rectSize/2, 400-rectSize/2);
rectyCoords[j]=random(250, 850);

float d=dist(rectxCoords[i], rectyCoords[i], rectxCoords[j], rectyCoords[j]);
if (d<90) {
rectxCoords[i]=rectxCoords[j];
rectyCoords[i]=rectyCoords[j];
i++;
}
}
}
//======================================================
}

void draw() {
for (int i=0; i<6; i++) {
drawRects(rectxCoords[i], rectyCoords[i]);
}
}
``````

Hello,

I was working towards assisting you but you tagged your topic as homework and then untagged it.

Is it homework or not?

`:)`

yes it is sorry haha

Hey @jSmith and welcome! I see how you’re breaking down the problem and i think you have a lot of good ideas even though it’s not working yet. I have a few questions just to have an idea of what you’re thinking.

• Why is the rectangle width a variable `rectSize` and the height is hard coded to `120`?
• Why did you use a `while` loop instead of a `for` loop to populate the coordinates?
• Why did you do the `for` loop inside the `while` loop?
• You said you haven’t learned things like ArrayList and classes. Have you learned recursion or functions? And will your teacher be ok with you learning some things on your own or do they want you to stick to what you’ve learned? (There are several ways to accomplish this but some techniques will be way easier than others.)

One hint is, you’re doing the same thing twice in your code, setting the coordinates to random values, and then replacing those with another set of random values.

Another hint: The incrementer `i++` won’t increment itself every time where you put it. (But that’s less important because i might suggest not using a `while` loop.)

And my last hint for now: Think about checking how far away each new set of coords is from all the previous ones. I feel like that’s what you might have been going for with your nested loops, but the execution is a bit off.

1 Like

It is possible.

These are some hints using your approach:

`````` while(i < 6)
{
println(i);                                           //useful
boolean flag = true;                                  //start over
float x = random(rectSize/2, 400-rectSize/2);
float y = random(rectSize/2, 400-rectSize/2);

//Check to see if new random x,y is not overlapping each point in array
for (int j=0; j<6; j++)
{
float d = dist(rectxCoords[j], rectyCoords[j], x, y);
println(d);

// if (d<90)
// set the flag to false

//else it must be true and update the array with the new point and increment i
}
}
``````

`:)`

UPDATE: I updated in a post below…

This worked for your approach:

I almost did not help you… but you did put in a worthy initial effort.

Thanks for your help! I updated the code to include some of the advice you gave, however, I think I’m having a problem with updating the array. What I believe is happening (with what I wrote) is it is finding a coordinate with a distance over 90, but then when it finds that coordinate, it sets every point in the array to that one coordinate.

Any other hints?

(Sorry I didn’t seem serious. I take my academic work very seriously).

`````` int i=0;
while (i<6) {
println("i =" + i);
boolean flag = true;
float x =random(rectSize/2, 400-rectSize/2);
float y =random(250, 850);

for (int j=0; j<6; j++) {
rectxCoords[j]=random(rectSize/2, 400-rectSize/2);
rectyCoords[j]=random(250, 850);
float d=dist(rectxCoords[j], rectyCoords[j], x, y);
println("d="+d);

if (d<90) {
flag=false;
} else {
flag=true;
rectxCoords[j]=x;
rectyCoords[j]=y;
i++;
}
}
}
``````

What is it that you want to update? Look back at your original code.

`:)`

Watch where you put the `i++` incrementers. It’s still not going to increment every time through the `while loop`

``````while (condition)
{
stuff
more stuff

for (condition)
{
stuff

if (condition)
{
stuff
}
else
{
stuff
}
}

i++
} // End of While Loop. incrementer i++ should be the last thing before
// this if you want it to increment each time through the while loop
``````

But instead of incrementing through your `while` using `i`, you want the `while` conditional to be a boolean that you’re using?

Hello,

In my haste to strip down the code to share I may have edited it too quickly…

This is a snippet of what worked using your code example:

``````    for (int j=0; j<6; j++)
{
float d = dist(rectxCoords[j], rectyCoords[j], x, y);
println(d);
if (d < dist)
{
//set flag
}
}

if(flag)
{
// add to array and increment i
}
``````

Keep in mind I have many different versions sorting out your initial example and tried to stick with that.
And many new versions that all work… I like a challenge.

Sometimes you just have to learn from the initial exploration, examples (even those that do not work) and start over.

The settings/resetting of boolean flags is an important concept that can be useful.

And you can use println() statements to watch the flow of your code; you can print i, j or a message “I am here!”.

You will get there.

`:)`

1 Like

Some tips building off your original ideas:

• Use a variable for rectWidth and rectHeight instead of rectSize
• You can still use float arrays for you X and Y coords

In `setup()`:

• Instead of using a `while loop`, use a `for loop` for the number of coordinates
• Pick random X and Y coords for each rectangle
• Before you pick the next set of coordinates, call a function that checks the distances for X and Y coords individually and pas the for loop’s increment `i` as an argument

In your `checkDistances()` function:

• You don’t need to compare the first set of coords to any before it because there are none
• You can’t check any coords that haven’t been created yet so your `for loop` incrementer needs to keep that in mind
• The `dist()` function will give you the distance between coordinate pairs. But, remember, the rectangle’s center to the corner is longer than the center to the edge. Maybe just compare x coords and y coords separately?
• Remember if you don’t use `dist()`, the result could be positive or negative depending on which direction on the screen you’re going.
• If the distance is too close, you need new coords and to check the previous coords again.
1 Like

@jSmith

Yup. This. You can see by our hints that we both built on your initial ideas and went in different directions with it, using different techniques. Both work.

Hopefully the different techniques provide different ways of thinking that help you figure things out better, and don’t add confusion.

And another pro-tip:
If you find one of our suggestions works well for you, copy it. Not ctrl-c/ctrl-v copy. I mean, go through it line by line, rewriting the code by hand, following the logic, and writing your own comments explaining what happens each step. The physical code is less important than understanding the logic behind it.

1 Like

@RFullum @glv
Thank you both of you for your help! I’ll give it another attempt.

2 Likes