Placing squares randomly in a Room - random

I have pondered this problem for several years now and think it to be impossible but I have to ask to ensure.
A rectangular room that has an arbitrary WIDTH, and HEIGHT. The goal is to place squares in the room randomly without any overlaps and without any of them being outside the room. Placement is not aligned to any grid. In addition each square placed should be uniformly randomly positioned in any valid place.
Think of: In the real world taking a handful of scrabble pieces and throwing them in a cardboard box.
A bad way I found to do this:
for( i=0; i < total_squares; i++){
rx = random(WIDTH); ry = random(HEIGHT);
if(no_collision(rx,ry)){
place_square(rx, ry);
}
else{
i--; //alternative_way i=0; unplace_all_squares();
}
}
This works if the room is sufficiently large, but I wanted it to work in a room that could barely fit each square. Then the loop could get stuck since there is no place valid place. An alternative is setting i to zero in the else and removing all the squares placed. That will work but could take nearly infinite time.
Another way is to have the square slide off overlaps but that biases the placement to close to other squares.
So I came to the conclusion I can't help the bias because of how collision biases the square to a position in the room and my vapid solution would have bias in it if it ever completed. But I am not sure.
I was using game maker for this but pseduo-code or any language would be fine.

Related

what algorithm or approach for placing rectangles without overlapp

I have a big rectangle of size 12*12. Now I have 6 rectangles already placed on the floor of that rectangle. I know the center coordinate of that pre-placed module. Now I have few another 14 rectangles to place upon that floor of that rectangle. How to do so?
here all my pre placed block those having center coordinate as say (2,5),(5,7),(9,2),(7,8),(11,9),(3,11).
Now how could I place 14 another rectangle in this floor so that it would not over lap with any preplaced block.
I would like to code in MATLAB..but what approach should I follow?
If a nice even placement is important, I suggest you look up simulated force-based graph layout. In this problem, you'll use simulated forces pushing the rectangles apart and also away from the border rectangle according to Coulomb's law. The initial configuration is randomly selected. You'll want to give the rectangles mass proportional to their area, I think. You don't have any spring forces due to edges, which makes it easier. The iteration to solve the differential equations of motion will be easy in Matlab. Or there may well be a toolkit to do it for you. Animations of these algorithms are fun.
Unfortunately with constrained problems like this, the fixed rectangles can form barriers that prevent the moving rectangles from getting to a non-overlapping solution. (Think of the case where the fixed rectangles are in a line down the middle and all the moving ones get "trapped" on one side or the other. The same thing happens in graph layout if some nodes have fixed locations.) There are various strategies for overcoming these bad cases. One is to start with no fixed objects at all, let the moving rectangles come to an equilibrium, then add the fixed ones one at a time, largest first, allowing the system regain equilibrium each time. Another, simpler one is just to start from different random initial conditions until you find one that works. There are also approaches related to simulated annealing, which is too big a topic to discuss here.
Here is a function to check overlap for two rectangles. you could loop it to check for more number of rectangles based on #Dov's idea.
For two rectangles Ri, i = 1,2, with centers (xi,yi) and half-lengths of their sides ai,bi > 0 (assuming that the sides are aligned with the coordinate axes).
Here is my implementation based on above equation:
In my code i've taken xcPosition and ycPosition as the center position of the rectangle.
Also length and breadth are the magnitude of sides of the rectangle.
function [ overLap, pivalue ] = checkOverlap( xcPosition1,ycPosition1,xcPosition2,ycPosition2,length1,breadth1,length2,breadth2 )
pix = max((xcPosition2 - xcPosition1 -(length1/2)-(length2/2)),(xcPosition1 -xcPosition2 -(length2/2)-(length1/2)));
piy = max((ycPosition2 - ycPosition1 -(breadth1/2)-(breadth2/2)),(ycPosition1 -ycPosition2 -(breadth2/2)-(breadth1/2)));
pivalue = max(pix, piy);
if (pivalue < 0)
overLap = 1; %// Overlap exists
else
overLap = 0; %// No overlap
end
end
You could also use the pivalue to know the degree of overlap or Non-overlap
The Pseudo-code for looping would be something like this:
for i = 1 : 14
for j = 1 : i-1 + 6 already placed parts
%// check for overlap using the above function here
%// place the part if there is no overlap
end
end
With such a small number, put each rectangle in a list. Each time you add a new rectangle, make sure the new one does not overlap with any of the existing ones.
This is O(n^2), so if you plan to increase to 10^3 or more rectangles you will need a better algorithm, but otherwise you're fine.
Now if your problem specifies that you might not be able to fit them all, then you will have to backtrack and keep trying different places. That is an N! problem, but if you have a lot of open space, many solutions will be possible.

How to get minimum-sized rectangle that contains certain rectangles?

Recently I am thinking of an algorithm that can calculate the minimum-sized rectangle that contains certain rectangles.
The goal of this algorithm is to generate a big rectangle that I can put all given smaller rectangles in. One of these smaller rectangles should not partly or entirely overlap another. And before I put smaller rectangles in the big rectangle, I can rotate them 90 degrees or not. The big rectangle should be as small as it can be.
Does anyone have some clues about it?
I was researching on this issue for some time. And I've come up with a solution reference to some links and articles about this issue. Here are two of the names of articles:,. You can google and download them if you want to read these articles.
It's a pity that none of the articles can exactly solve my problem. Because what I want is neither to check if certain rectangles can be put into a fix-sized large rectangle nor a best area-allocating method that cost long time to result. So I have to balance between time and effect. I do this:
1.I prepare a list of candidate points and add the left-top point to it.
2.I place rectangles one by one into the large rectangle.
3.Every time when I place a rectangle, I check all candidate points to see if I can put the rectangle on the point. And I just keep the best two or three ones(best means minimum-sized if this rectangle is the last one).
4.I choose a candidate point to place the rectangle and replace one point to two points(right-top point and left-bottom one of the rectangle) if they are checked valid to place the next rectangle.
5.I recursively do step 3 to place a next rectangle.
I use C++ language do coding so I can code like this:
void computeMinimunRects(int index, Array objects, Array candidates, RectChecker checker)
{
if (index == objects.count()){
checkresult(objects);// finished putting all rectangles
return;
}
int c = 2;// or 3 which based on objects.count()
SortPoint possibles;// SortPoint sort all input points by total area from small to big.
for (int i = 0; i<candidates.count(); i++){
if (checkput(candidates[i], objects[index].size))// check if objects[index].size can put on candidates[i] point
possibles.insert(candidates[i], objects[index].size);// input all needed value and sort them.
}
for(int i = 0; i<c; i++){
Point pt = possibles[i].pt;
Size size = possibles[i].size;
Rect rect(pt, size);
candidate.remove(pt);// replace point with two ones.
candidate.add(rect.right_top());
candidate.add(rect.left_bottom());
computeMinimunRects(index+1, objects, candidates, checker);// recursively input rectangle
candidates.remove(rect.right_top());// revert all changes
candidates.remove(rect.left_bottom());
candidates.add(pt);
}
}

Generating points uniformly on a sphere

I'm interested in generating points that are 'uniformly' (and non-randomly) distributed around a sphere, much like the dimples of a golf ball or the vertices of the hexagons on a soccer ball. Are there well defined algorithms to do this?
Note: I know that the points are not really 'uniformly' distributed on a sphere, but they are distributed in a way that the distribution of points looks the same from any direction that looks straight at any of the points - this is what I am interested in.
Subdividing an octahedron and normalizing the vertices afterwards gives very good results. Look here for more details. Paul Bourke has a lot of interesting stuff.
Here's some psuedo C++ code I wrote up in five minutes now:
/* Assume 'data' initially holds vertices for eight triangles (an octahedron) */
void GenerateSphere(float radius, std::vector<Vector3f>& data, int accum=10)
{
assert( !(data.size() % 3) );
std::vector<Vector3f> newData;
for(int i=0; i<data.size(); i+=3){
/* Tesselate each triangle into three new ones */
Vector3f centerPoint = (data[i] + data[i+1] + data[i+2]) / 3.0f;
/* triangle 1*/
newData.push_back(data[i+0]);
newData.push_back(data[i+1]);
newData.push_back(centerPoint);
/* triangle 2*/
newData.push_back(data[i+1]);
newData.push_back(data[i+2]);
newData.push_back(centerPoint);
/* triangle 3*/
newData.push_back(centerPoint);
newData.push_back(data[i+2]);
newData.push_back(data[i+0]);
}
data = newData;
if(!accum){
/* We're done. Normalize the vertices,
multiply by the radius and return. */
for(int i=0; i<data.size(); ++i){
data[i].normalize();
data[i] *= radius;
}
} else {
/* Decrease recursion counter and iterate again */
GenerateSphere(radius, data, accum-1);
}
return;
}
This code will work with any polyhedron made of counter-clockwise triangles, but octahedrons are best.
Choose u,v randomly from [0,1].
2πu is longitude.
asin(2v-1) is latitude.
Only two random variables, and no rejections.
By the way, my link collection has a new address: http://bendwavy.org/sphere.htm
And I've copied it over to http://cgafaq.info/wiki/Evenly_distributed_points_on_sphere
While this article talks about randomly picking points on a sphere, it is also about drawing points from a uniform distribution while at the same time taking the sphere characteristic into consideration. I guess it's still a decent read for your question:
http://mathworld.wolfram.com/SpherePointPicking.html
depending on your needs http://iquilezles.untergrund.net/www/articles/patchedsphere/patchedsphere.htm
may work well too. not exactly uniform, but very fast to compute.
Here's a simple way to do it.
Randomly, sample from the unit cube, [0, 1]^3
Test for inclusion in the sphere. Reject if the sampled point is not in the sphere of diameter 1 that is contained in the unit cube, and go to step 1.
Normalize the point to be on the surface of the sphere, by projecting the point outward from the center of the sphere.
This will typically succeed after a few samples. If you want, you can also reject samples that are near the center of the sphere to minimize rounding errors and help make the distribution closer to uniform.
if you're okay with having only certain allowable numbers of vertices, then the subdivision methods above are definitely the way to go. if you want an arbitrarily-specified number of vertices, then i recommend:
first, distribute points randomly and uniformly over the sphere.
i talk at length about doing this at http://elenzil.com/progs/randompoints .
i believe my method is at least as performant as that at worlfram.
second, "relax" the distribution by treating the points as a particle system where each particle repels every other particle. the difficulty here is making sure the system doesn't become unstable, and deciding when to stop. i have an example of this here: http://elenzil.com/progs/separate unfortunately these were the days before i included source code with my projects, so that code is lost.
I tried once the following algorithm:
start with a regular tetrahedron with the submits on the sphere.
pick one of the triangles with the biggest surface (initially it will be any of the 4 sides)
replace selected face with a 3 sided pyramid where the 4th point is the elevation of the face center to the sphere surface.
repeat until enough points have been created.
This works as long as precision does not ruin uniformity.
The resulting points form figures akin to a geode.
You don't need to compute any surface, since each new triangle is no greater than all previous ones. Simply handle them in FIFO order.

Random Tile layout

I need to place tiles on a large grid radiating from a central point in a way that looks organic and random. New tiles will need to find an open space on the grid that is touching at least 1 other tile.
Can anyone point me in the right to direction to anything that might help with this?
Or some basic concepts I can read up on that are in this vein?
For example, in this picture, there is a shape already created (yellow) and I may be receiving a new tile, that may be 1x1, 2x2, or 3x3. Trying to find a good way to figure out where I can place the new tile so that it will be touching the maximum amount of current tiles.
Picture:
alt text http://osomer.com/grid.JPG
Alternatively, you could approach this problem as the yellow tiles "eroding" away at the blue/background. To do this, at every step, have a yellow tile add a fixed number to the "erosion sum" E of all of the background tiles neighboring it in a cardinal direction (and perhaps maybe a fraction of that to the background tiles neighboring it diagonally).
Then, when it comes time to place a new tile, you can, for each background tile, pick a random number from 0 to E; the greatest one is "eroded" away. Alternatively, you could do a simple weighted random choice, with E being their weights.
For 2x2 or 3x3 tiles, you can pick only from tiles that suitably "fit" a 2x2 or 3x3 square in it (that is, a 2x2 or 3x3 the eroded tile on its edge, so that it doesn't cause overlap with already-placed tiles). But really, you're never going to get something looking as natural as one-by-one erosion/tile placement.
You can save time recalculating erosion sums by having them persist with each iteration, only, when you add a new tile, up the erosion sums of the ones around it (a simple +=). At this point, it is essentially the same as another answer suggested, albeit with a different perspective/philosophy.
A sample grid of Erosion Sums E, with direct cardinal neighbors being +4, and diagonal neighbors being +1:
Erosion Sums http://img199.imageshack.us/img199/4766/erosion.png
The ones with a higher E are most likely to be "eroded" away; for example, in this one, the two little inlets on the west and south faces are most likely to be eroded away by the yellow, followed by the smaller bays on the north and east faces. Least likely are the ones barely touching the yellow by one corner. You can decide which one either by assigning a random number from 0 to E for each tile and eroding the one with the highest random number, or doing a simple weighted random selection, or by any decision method of your choice.
For purely random, you start with an empty grid and a "candidate" list (also empty).
Place the first tile in the centre of the grid, then add each adjacent tile to the one you just placed into the "candidate" list. Then, each turn, choose a random entry in the "candidate" list and place a tile there. Look at each adjancent grid location next to where you just placed the tile, and for each one that is also empty, put it on the "candidate" list for the next time around (if not already there).
To avoid creating holes in your tile grid, increase the probability of selecting a grid location based on the number of adjacent tiles that are already filled (so if only one adjacent tile is already filled, it has low probably. If they're all filled, it'll have a very high probability).
In pseudo code:
grid = new array[width,height];
candidates = new list();
function place_tile(x,y) {
// place the tile at the given location
grid[x,y] = 1;
// loop through all the adjacent grid locations around the one
// we just placed
for(y1 = y - 1; y1 < y + 1; y1++) {
for(x1 = x - 1; x1 < x + 1; x1++) {
// if this location doesn't have a tile and isn't already in
// the candidate list, add it
if (grid[x,y] != 1 && !candidates.contains(x1,y1)) {
candidates.add(x1,y1);
}
}
}
}
// place the first tile in the centre
place_tile(width/2, height/2);
while (!finished) {
// choose a random tile from the candidate list
int index = rand(0, candidates.length - 1);
// place a tile at that location (remove the entry from
// the candidate list)
x, y = candidates[index];
candidates.remove(index);
place_tile(x, y);
}
The problem with your question is that 'organic and random' can be many different things.
Let me show two links
generating random fractal terrain (look at section 'Cloudy Skies' and imagine that you turn it to b/w, or in your case yellow/background).
simulating erosion (look at the image under 'erode')
The two above samples are 'organic and random' to me, but you might not be satisfied with those. So, I think you will have to better define what is 'organic and random'.
For now, I'll take your definition of the guiding rule for adding new tiles (but don't think it is necessarily the same problem), which I read as:
Given two shapes (assuming bitmaps)
find the relative position of the
shapes such that the number of
touching sides is maximum
I will also assume
overlap is not allowed
you can leave holes inside the resulting, merged shape
you can not rotate shapes
Under such conditions you need to test less then xy solutions and in each you need to
- discard it if there is an overlap
- discard it if they do not touch
- if they touch then count the number of edges that are common
All three of the above tests can be done in constant time by scanning all the yellow tiles (number of which is konstx*y)
So, the above can be easily done in O(n^4), is that good enough for you?
Compute a random spanning tree for the dual graph, that is, the grid whose vertices are the centers of your cells. For that, start at the center of the grid and do a random depth-first search. Then plot cells fro increasing tree distance from the center.

Packing rectangles for compact representation

I am looking for pointers to the solution of the following problem: I have a set of rectangles, whose height is known and x-positions also and I want to pack them in the more compact form. With a little drawing (where all rectangles are of the same width, but the width may vary in real life), i would like, instead of.
-r1-
-r2--
-r3--
-r4-
-r5--
something like.
-r1- -r3--
-r2-- -r4-
-r5--
All hints will be appreciated. I am not necessarily looking for "the" best solution.
Your problem is a simpler variant, but you might get some tips reading about heuristics developed for the "binpacking" problem. There has been a lot written about this, but this page is a good start.
Topcoder had a competition to solve the 3D version of this problem. The winner discussed his approach here, it might be an interesting read for you.
Are the rectangles all of the same height? If they are, and the problem is just which row to put each rectangle in, then the problem boils down to a series of constraints over all pairs of rectangles (X,Y) of the form "rectangle X cannot be in the same row as rectangle Y" when rectangle X overlaps in the x-direction with rectangle Y.
A 'greedy' algorithm for this sorts the rectangles from left to right, then assigns each rectangle in turn to the lowest-numbered row in which it fits. Because the rectangles are being processed from left to right, one only needs to worry about whether the left hand edge of the current rectangle will overlap any other rectangles, which simplifies the overlap detection algorithm somewhat.
I can't prove that this is gives the optimal solution, but on the other hand can't think of any counterexamples offhand either. Anyone?
Something like this?
Sort your collection of rectangles by x-position
write a method that checks which rectangles are present on a certain interval of the x-axis
Collection<Rectangle> overlaps (int startx, int endx, Collection<Rectangle> rects){
...
}
loop over the collection of rectangles
Collection<Rectangle> toDraw;
Collection<Rectangle> drawn;
foreach (Rectangle r in toDraw){
Collection<Rectangle> overlapping = overlaps (r.x, r.x+r.width, drawn);
int y = 0;
foreach(Rectangle overlapRect in overlapping){
y += overlapRect.height;
}
drawRectangle(y, Rectangle);
drawn.add(r);
}
Put a tetris-like game into you website. Generate the blocks that fall and the size of the play area based on your paramters. Award points to players based on the compactness (less free space = more points) of their design. Get your website visitors to perform the work for you.
I had worked on a problem like this before. The most intuitive picture is probably one where the large rectangles are on the bottom, and the smaller ones are on top, kinda like putting them all in a container and shaking it so the heavy ones fall to the bottom. So to accomplish this, first sort your array in order of decreasing area (or width) -- we will process the large items first and build the picture ground up.
Now the problem is to assign y-coordinates to a set of rectangles whose x-coordinates are given, if I understand you correctly.
Iterate over your array of rectangles. For each rectangle, initialize the rectangle's y-coordinate to 0. Then loop by increasing this rectangle's y-coordinate until it does not intersect with any of the previously placed rectangles (you need to keep track of which rectangles have been previously placed). Commit to the y-coordinate you just found, and continue on to process the next rectangle.

Resources