Randomly places HTML elements in a large div without overlapping

random

#1

Hello

I created this code to randomly place some HTML elements in a larger div element without any of them overlapping eachother or going outside the borders of the large div element.

It works fine 90% of the time, but sometimes the website crashes.
I believe this bug is happening because the code is placing two elements so they are overlapping...

I have tried for a few hours but I cannot find a way to rerun the loop and attempt to replace the overlapped element somewhere else.

IMPORTANT! I need ALL the element to be place in the large div element. None of them must be forgotten.
The only acceptable time for it to be forgotten is when there is absolutely no chance for it to be place in the large div element.

This is the code so far:

var min_x = document.getElementById("allProjects").offsetLeft;
var max_x = min_x + document.getElementById("allProjects").offsetWidth - 300;
var min_y = document.getElementById("allProjects").offsetTop;
var max_y = min_y + document.getElementById("allProjects").offsetHeight - 300;
var filled_areas = new Array();

$('.projects').each(function() {
    var rand_x = 0;
    var rand_y = 0;
    var area;
    do {
        rand_x = Math.round(min_x + ((max_x - min_x) * (Math.random() % 1)));
        rand_y = Math.round(min_y + ((max_y - min_y) * (Math.random() % 1)));
        area = {
            x: rand_x,
            y: rand_y,
            width: $(this).width(),
            height: $(this).height()
        };
    } while(check_overlap(area));
    filled_areas.push(area);
    $(this).css({left: rand_x, top: rand_y});
});

function check_overlap(area) {
    for (var i = 0; i < filled_areas.length; i++) {

        check_area = filled_areas[i];

        var bottom1 = area.y + area.height;
        var bottom2 = check_area.y + check_area.height;
        var top1 = area.y;
        var top2 = check_area.y;
        var left1 = area.x;
        var left2 = check_area.x;
        var right1 = area.x + area.width;
        var right2 = check_area.x + check_area.width;
        if (bottom1 < top2 || top1 > bottom2 || right1 < left2 || left1 > right2) {
            continue;
        }
        return true;
    }
    return false;
}

Please anyone help me fix this code so it won't crash but rather retry the loop

thanks,


#2

The trouble with 'randomly placing things to fill an area without overlapping' is "What happens if the random placement becomes impossible."

IE: Let me dumb it down very very much and give the super-hyperbolic example.

Take a large, square DIV.
Cut it in two, so you've got 2 half-DIV sized rectangles.
Now, you can 'randomly' place the rectangles into the div. The first one, no problem.
The second one... you can ONLY place down IF the first one randomly chose to be placed at the exact edge of the div. Not very likely.
If the loop doesnt have a fail-safe condition, it's possible to place the objects in such a way that the loop will never complete. Doesnt matter how many times you retry.

Basically, decide on a threshold of failure. If the object you're trying to slot in can't be placed after X attempts, declare the entire pattern a failure and start again.


#3

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.