Skip to content

Instantly share code, notes, and snippets.

@azazdeaz
Last active August 29, 2015 14:01
Show Gist options
  • Save azazdeaz/58ee810bdd420d1dc074 to your computer and use it in GitHub Desktop.
Save azazdeaz/58ee810bdd420d1dc074 to your computer and use it in GitHub Desktop.
Find the closest free place for a rectangle
//demo: http://jsfiddle.net/azazdeaz/qH3Y7/
//cut a rect from the free places
function cut(map, rect) {
var oldR, added = 0, ti, ri, bi, li;
function add(t, r, b, l) {
map.push(createRect(t, r, b, l));
++added;
}
for (var i = 0; i < map.length - added; ++i) {
if (testCollision(map[i], rect)) {
oldR = map.splice(i--, 1)[0];
ti = oldR.t < rect.t;
ri = oldR.r > rect.r;
bi = oldR.b > rect.b;
li = oldR.l < rect.l;
if (ti) add(oldR.t, oldR.r, rect.t, oldR.l);
if (ri) add(oldR.t, oldR.r, oldR.b, rect.r);
if (bi) add(rect.b, oldR.r, oldR.b, oldR.l);
if (li) add(oldR.t, rect.l, oldR.b, oldR.l);
}
}
}
//return with the x, y offset for the closest free position
function getNearestPos(map, rect) {
var rw = rect.r - rect.l,
rh = rect.b - rect.t,
dist, dx, dy, nx, ny, nd;
map.forEach(function (area) {
if (area.r - area.l >= rw && area.b - area.t >= rh) { //area is big enough
dx = area.r < rect.r ? area.r - rect.r : (area.l > rect.l ? area.l - rect.l : 0);
dy = area.b < rect.b ? area.b - rect.b : (area.t > rect.t ? area.t - rect.t : 0);
dist = Math.sqrt(dx*dx + dy*dy);
if (nd === undefined || dist < nd) {
nd = dist;
nx = dx;
ny = dy;
}
}
});
if (nd === undefined) {
return;
}
else {
return {x: nx, y: ny};
}
}
function testCollision(r0, r1) {
return r1.r > r0.l && r1.l < r0.r &&
r1.b > r0.t && r1.t < r0.b;
}
function createRect(top, right, bottom, left) {
return {t: top, r: right, b: bottom, l: left};
}
//optimise the map by remove the areas fully overlapped by other areas
function cleanup(map) {
for (var i = 0; i < map.length; ++i) {
for (var j = 0; j < map.length; ++j) {
if (i !== j) {
if (map[i].l <= map[j].l &&
map[i].r >= map[j].r &&
map[i].t <= map[j].t &&
map[i].b >= map[j].b)
{
map.splice(j, 1);
if (--j < i) {
--i;
}
}
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment