views:

216

answers:

6

Given n squares with edge length l, how can I determine the minimum radius r of the circle so that I can distribute all squares evenly along the perimeter of the circle without them overlapping? (Constraint: the first square will always be positioned at 12 o'clock.)

Followup question: how can I place n identical rectangles with height h and width w?

example

+11  A: 
Carl Smotricz
sounds good! i'll give it a go later today and if everything checks out your answer will be accepted, sir! :)
n3rd
@carl, having problems following. a) if circle is much-too-small then squares intersect, i.e. the minimum distance between squares is 0 b)the minimum distance between midpoints is not zero, it is positive number, but I fail to see the relation between that and diameter c) last paragraph 'distance between the circles'?
Unreason
@Unreason: Last thing first, you caught a typo. s/circles/squares/. Corrected. (a) to see if squares intersect, it is a necessary (but not sufficient) condition that the distance on either the X or Y axis between their midpoints is less or equal to the length of a square's side (only works for equally sized squares). So you don't have to bother checking if parts of the squares' perimeters overlap, you just make sure midpoints not too close.
Carl Smotricz
@Unreason: (b) if you position your squares on your circle and find a pair of midpoints that are only 50% of the "touching" distance apart in either X or Y, then you need to double the size of the circle and you'll be done. i.e. you make the circle bigger in inverse proportion to how much too small that minimum distance is.
Carl Smotricz
I'm afraid I'm still not following. When the squares are initially placed, they are distributed evenly across the circle. Thus, the minimum distance between a square and its neighbours is the same for all squares.Also, where does the size of the squares come into play? If two squars are at the same height (or width), their difference in x (or y) is 0, what now? Maybe you can elaborate a little bit :)
n3rd
@n3rd Nope, your first sentence is incorrect. If the squares were little circles, then indeed their distances would be independent of their orientation. But as they are squares and always oriented the same way, their corners stick out in different ways depending on where they are on the circle, i.e. they are not symmetric.
Carl Smotricz
@n3rd: My pseudo-coded example may make things a bit clearer too. I'm almost ready to write code for this anyway.
Carl Smotricz
I've started doing this in Java. First result here: http://ideone.com/WgAET . I need to output graphics, though. Hang on.
Carl Smotricz
@carl: Oh, I see. I was thinking you were referring to the distance between the square's midpoints. My bad.
n3rd
@Carl, that was my point, the scaling factor is not directly proportional to the distance, but you are on the right track and have to find the factor to scale by. I'll try to give it a try.
Unreason
Sorry about all the breathless reports. After some tweaking, I now have it working correctly; I can produce diagrams showing angularly equispaced boxes with some of them exactly touching.
Carl Smotricz
@Unreason: Now I can state with confidence: The scaling factor needs to be exactly the factor by which, in the worst case, the maximum (X or Y) distance between two adjacent boxes is too small.
Carl Smotricz
@Carl, I've put in the answer, but it is only descriptive for now.
Unreason
+1 I agree, it is directly proportional; I've taken a different path by solving for l and it boils down to the same formulas as you have. One note - in your source you comment `start assuming minimum distance dMin = 1.0`; but it is actually maximum distance (dMin in all solutions is < 1.0). Not a bug, but got me running in circles for a while trying to understand the code.
Unreason
@Carl How do I adapt Your program to work with arbitrary edge lengths of the rects?
Dave
@Dave, here's my contribution - I modified Carls solution to work with h x w rectangles :) http://ideone.com/eP1oX . However, this will show you one thing - even for h/w = 3 (which is a small menu, I guess) you will not get evenly spaced menu items - the assumption that you should place the center of rectangles on i*(2*pi)/n is flawed (if you want it too look nice) and I think you will want to reevaluate your requirements.
Unreason
@Dave, Unreason: Hehe, the problem is a lot easier when h == w! I don't have a very clear idea of how to extend it to rectangles in an aesthetically pleasing way. I think I'd generate a new set of angles by stretching an equal-angled circle to the proportions of the rectangle and then mapping the angles back to the circle; and then using Unreason's algorithm to size the circle.
Carl Smotricz
@Dave, also the algorithm might have problems with extremely high rectangles at pi/2 (and 3*pi/2) or extremely wide at 0, pi (also depending on the number of rectangles) because only the two consecutive rectangles are checked, and in the the above cases it is possible for noncosecutive rectangles to intersect when consecutive only touch.
Unreason
@Dave, like your idea of stretch and shrink, but I think that visually the best would be to look for a solution where the distance between rectangles is equal (or in another words if the requirement for the equality of angles is removed there exists a circle with lesser r; and algorithm to find it)
Unreason
@Carl, `set size square` makes aspect ratio 1:1 in gnuplot
Unreason
+4  A: 

I would calculate an upper bound of the minimum radius, by working with circles enclosing the squares instead of with the squares themselves.

My calculation results in:

Rmin <= X / (sqrt(2) * sin (180/N) )

Where: X is the square side length, and N is the required number of squares.

I assume that the circles are positioned such that their centers fall on the big circle's circumference.

-- EDIT --

Using the idea of Dave in the comment below, we can also calculate a nice lower bound, by considering the circles to be inside the squares (thus having radius X/2). This bound is:

Rmin >= X / (2 * sin (180/N) )

Eyal Schneider
using this upper bound why not advance and make a binary search for the smallest radius that causes no rects to intersect? Runtime O(n * log Rmin)
Dave
Dave
@Dave: Nice idea, especially with both bounds. Please ignore my last comment.
Eyal Schneider
Heh, after seeing a comment stating that n3rd was putting together a (radial) menu, I started thinking that using circles to display the menu items would look better than squares (Neverwinter Nights, anyone?), and this meshes quite well with that, too.
JAB
+1  A: 

As already noted, the problem of positioning n points equally spaced round the circumference of a circle is trivial. The (not-terribly) difficult part of the problem is to figure out the radius of the circle needed to give a pleasing layout of the squares. I suggest you follow one of the other answers and think of the squares being inside a circular 'buffer' big enough to contain the square and enough space to satisfy your aesthetic requirements. Then check the formula for the chord length between the centres of neighbouring squares. Now you have the angle, at the centre of the circle, subtended by the chord between square centres, and can easily compute the radius of the circle from the trigonometry of a triangle.

And, as to your follow up question: I suggest that you work out the problem for squares of side length min(h,w) on a circle, then transform the squares to rectangles and the circle to an ellipse with eccentricity h/w (or w/h).

High Performance Mark
A: 

You start with an arbitrary circle (e.g., with a diameter of (* n l)) and position the squares evenly on the circumference. Then you go through each pair of adjacent squares and:

  • calculate the straight line connecting their mid points,
  • calculate the intersection of this line with the intervening square sides (M1 and M2 are the mid points, S1 and S2 the corresponding intersections with the square side:

                    S2         S1
    M1--------------*----------*---------------M2
    
    
    ------------------------
    |                      |
    |                      |
    |                      |
    |                      |
    |          M1          |
    |           \          |
    |            \         |
    |      -------*------- +--------
    |      |       \       |       |
    |      |        \      |       |
    -------+---------*------       |
           |          \            |
           |           M2          |
           |                       |
           |                       |
           |                       |
           |                       |
           -------------------------
    
  • calculate the scale factor you would need to make S1 and S2 fall together (simply the ratio of the sum of M1-S1 and S2-M2 to M1-M2), and

finally scale the circle by the maximum of the found scale factors.

Edit: This is the exact solution. However, a little thought can optimize this further for speed:

  • You only need to do this for the squares closest to 45° (if n is even) resp. 45° and 135° (if n is odd; actually, you might prove that only one of these is necessary).
  • For large n, the optimal spacing of the squares on the circle will quickly approach the length of a diagonal of a square. You could thus precompute the scaling factors for a few small n (up to a dozen or so), and then have a good enough approximation with the diagonal.
Svante
No, I don't think that yields an optimal solution. You are asking for a scale where the corners are just touching. I discovered that this makes the circle much too large; it's only necessary for one set of sides (either the horizontal or vertical) to touch.
Carl Smotricz
No, I did not write nor mean the corners. I am writing about the intersection of the connecting line between the centres of two neighbouring squares with the squares' edges.
Svante
@Carl Smotricz: I added a rough sketch.
Svante
@Svante From my point of view You overlook that, when scaling down (reducing the radius of the circle), the relative position between the rects changes too and therefore invalidates the values S2 and S1.
Dave
When scaling down, the relative position does _not_ change. Think about it: the angle of the line connecting the mid points is only dependent on _n_, the number of squares.
Svante
I think I stand corrected. Thanks to your diagram, this looks like it could well work.
Carl Smotricz
A: 

I would solve it like this:

To find the relation between the radius r and length l let's analyze dimensionless representation

  • get the centres on a circle (x1,y1)..(xn,yn)
  • from each center get lower right corner of the i-th square and upper left corner of the i+1-th square
  • the two points should either have equal x or equal y, whichever yields smaller l
  • procedure should be repeated for each center and the one that yields smallest l is the final solution.

This is the optimal solution and can be solved it terms of r = f(l). The solution can be adapted to rectangles by adjusting the formula for xLR[i] and yUL[i+1].

Will try to give some pseudo code.

EDIT:
There's a bug in the procedure, lower right and upper left are not necessary closest points for two neighbouring squares/rectangles.

Unreason
A: 
Mau