Clear Filters
Clear Filters

Random squares/rectangles in a square

70 views (last 30 days)
Tony Haines
Tony Haines on 24 May 2024 at 17:29
Commented: William Rose on 28 May 2024 at 12:54
I have a square of size 1, that is (0,1)x(0,1). In this square, I would like to create random squares or rectangles of various sizes where none of them share an edge with each other. Meaning, I want them randomly spaced out. Then, i would like to save the values or coordinates within each squares to compare them with an input (x,y) such that (x,y) has value 1 if it's in the square, and zero if it's not.
I want to repeat this(random sampling of squares) for 5 different samples.
Thanks!

Accepted Answer

William Rose
William Rose on 25 May 2024 at 1:14
So you want option B. OK.
Ns=5; % number of squares
P=zeros(4,2,Ns); % vertex coords
s=zeros(Ns,1); % side lengths
anyOverlaps=1; % =0 if no squares overlap
inSquare=zeros(Ns,1); % =1 when point is in square i
j=0; % initialize counter
while anyOverlaps>0
for i=1:Ns
LL=rand(1,2); % lower left coords of square: [x1,y1]
s(i)=(1-max(LL))*rand(1,1); % side length
P(:,:,i)=[LL; LL+[s(i),0]; LL+[s(i),s(i)]; LL+[0,s(i)]]; % vertex coords
pgon(i)=polyshape(P(:,:,i)); % create square polygon
end
tf=overlaps(pgon);
anyOverlaps=sum(tf,'All')-Ns;
j=j+1;
end
fprintf('After %d attempts, we found %d non-overlapping squares.\n',j,Ns)
After 2 attempts, we found 5 non-overlapping squares.
fprintf('Minimum, maximum side lengths = %.3f, %.3f.\n',min(s),max(s))
Minimum, maximum side lengths = 0.011, 0.167.
fprintf('Total area covered by squares=%.3f.\n',sum(s.^2))
Total area covered by squares=0.049.
Now we have 5 "random" non-overlapping squares.
Pick a point (x,y) and see if it is in any of the squares.
x=rand(1,1); y=rand(1,1);
for i=1:Ns
inSquare(i)=inpolygon(x,y,P(:,1,i),P(:,2,i));
end
fprintf('Point (x,y) is in %d square(s).\n',sum(inSquare,'all'))
Point (x,y) is in 1 square(s).
Plot the point and the squares.
figure
for i=1:Ns
plot(pgon(i)); hold on;
end
plot(x,y,'r*')
axis equal; xlim([0,1]); ylim([0,1])
I had to run the script above at least 10 times before I got a case where the point was in one of the squares.
  5 Comments
Tony Haines
Tony Haines on 27 May 2024 at 17:41
Yes, that's right. If I had N squares, then the size of square N+1 has to satisfy the non-overlapping rule with the N previously choses squares and also fit the remaining vacant space. And sice the dimension of square N+1 is randomly chosen using rand(), this allows for any number of square sizes. Out of 1000 iterations, I found 192 squares satisfying the conditions.
Note: some of the squares look close together but they acutually do not touch.

Sign in to comment.

More Answers (1)

William Rose
William Rose on 24 May 2024 at 18:57
Do you want
A. One random square inside the unit square, and you want choose that random square 5 times, and each time you want to see if a random point (x,y) falls within the random square?
or
B. Five "random" non-overlapping little squares inside the unit square. If this is the case, then the 5 little squares are not really random, since the location and size of each is constrained by the square(s) already chosen.
or something else? I assume you want A. I will do A, with six examples, instead of five. I will use one random point and compare it to six different squares.
x=rand(1,1); y=rand(1,1); % point of reference
pointInSquare=zeros(1,6); % initialize array for whether point is in the square
figure
for i=0:1
for j=0:2
BL=rand(1,2); %x,y coords of bottom left corner of random square inside the unit square
s=(1-max(BL))*rand(1,1); % side length
P=[BL; BL+[0,s]; BL+[s,s]; BL+[s,0]]; % array of vertices of square
pgon=polyshape(P); % create square polygon
pointInSquare(3*i+j+1)=inpolygon(x,y,P(:,1),P(:,2)); % =1 if x,y in or on square
subplot(2,3,3*i+j+1);
plot(pgon); hold on; plot(x,y,'r*'); axis equal; xlim([0,1]); ylim([0,1])
end
end
fprintf('(x,y) in square for %d square(s).\n',sum(pointInSquare));
(x,y) in square for 1 square(s).
Try it.
  1 Comment
Tony Haines
Tony Haines on 24 May 2024 at 20:08
I was thinking along the line of option B. I wanted for example, 6 non-overlapping squares(of varying sizes) inside the unit square. And then to check if a random point (x,y) is in any of those 6 non-overlapping squares.

Sign in to comment.

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!