1

I’m generating multiple, random sized, circular elements using the Raphael JavaScript library but because it’s random a lot of the circular elements being generate overlap or cover each other. What I wanted to know, is there any way with JavaScript to tell if one element is in already in particular position so to avoid the overlapping? Essentially, I want to create random elements on a canvas, of a random size that don’t overlap or cover each other.

There's a couple of test files I created here to give you an idea of what I'm doing. The first one generates random objects and the second link sets them to a grid to stop the overlapping.

http://files.nicklowman.co.uk/movies/raphael_test_01/

http://files.nicklowman.co.uk/movies/raphael_test_03/

screenm0nkey
  • 18,405
  • 17
  • 57
  • 75

2 Answers2

1

The easiest way is to create an object and give it a repulsive force that degrades towards zero at it's edge. As you drop these objects onto the canvas the objects will push away from each other until they reach a point of equilibrium.

graham.reeds
  • 16,230
  • 17
  • 74
  • 137
  • WOW. I'm not entirely sure what you've just said but as it's the only answer and it sounds bloody good I'll mark it as correct and then look up what you've posted and see if I can create it. It's probably a bit cheeky but would you know of any examples I can look at. Many, many thanks – screenm0nkey Mar 10 '10 at 16:50
  • I can't tell whether this was a glib answer or a real one, but if the latter, I'd love to know more. Google offers no help that I can discern, but if this kind of edge detection is possible, I'd surely like to know how. – Rob Wilkerson Apr 14 '10 at 18:53
  • 1
    I know I'm late to the party, but to "un-overlap" objects in the manner described by the answer, use a force-directed graph algorithm: http://en.wikipedia.org/wiki/Force-based_algorithms_%28graph_drawing%29 – David Eads Jul 29 '11 at 18:58
1

Your examples aren't working for me, so I cannot visualize your exact scenario.

Before you "drop" an element on the canvas, you could query the positions of your other elements and do some calculations to check if the new element will overlap.

A very simple example of this concept using circle elements might look like this:

function overlap(circ1, circ2) {
    var attrs = ["cx", "cy", "r"];
    var c1 = circ1.attr(attrs);
    var c2 = circ2.attr(attrs);
    var dist = Math.sqrt(Math.pow(c1.cx - c2.cx ,2) + Math.pow(c1.cy - c2.cy, 2));
    return (dist < (c1.r + c2.r));
}
var next_drop = paper.circle(x, y, r);  
for (var i in circles) {
    if (overlap(next_drop, circles[i])) {
        // do something
    }
}

Of course calculating just where you're going to place a circle after you've determined it overlaps with others is a little more complicated.

joxl
  • 287
  • 1
  • 4
  • 9