Skip to content

Commit

Permalink
Optimize and simplify forceMinimize() visible area algorithm
Browse files Browse the repository at this point in the history
A diagram for understanding the algorithm:

    +————————————————————————————————+
    |                                |
    |    D                           |
    |           +--------------------|——————+
    |           |                    |      |
    |      +----+--------------+     |  C   |
    |      :    :              |     |      |
    |      :    :   +- - - - - +-----|------|————+
    |      :    :   .          :     |      |    |
    |      :    :   .          :     |      |    |
    |      :    :   . 1  2  3  :     |      |    |
    |      :    :   . 1  2  3  :     |      |    |
    |      :    :   . 1  2  3  :     |      |    |
    |      :    +--------------------|——————+    |
    |      :        : 1  2     :     |           |
    |      :        : 1  2     :     |           |
    |      :        : 1  2     :     |           |
    +————————————————————————————————+           |
           |        : 1        |                 |
           |    B   : 1        |         A       |
           +————————+——————————+                 |
                    |                            |
                    +————————————————————————————+

    (I(A, B, ...) is the area of the intersection of the rectangles.)

    (1) = I(A, B)
    (2) = I(A, B, D)
    (3) = I(A, B, C, D)

    VisibleArea(A) = Area(A) - (1) + (2) - (3) + ...


The algorithm was and is (for four rectangles):

    VisibleArea(A) =

    = Area(A)
    - I(A, B)
    - I(A, C)
    - I(A, D)
    + I(A, B, C)
    + I(A, B, D)
    + I(A, C, D)
    - I(A, B, C, D)

    = Area(A)
    - I(A, B)
    + I(A, B, C)
    - I(A, B, C, D)
    + I(A, B, D)
    - I(A, C)
    + I(A, C, D)
    - I(A, D)


This implementation exploits the fact that I(A, B, C) = I(I(A, B), C),
and passes the result of I(A, B) to the computation of I(A, B, C).
  • Loading branch information
twiss committed Sep 29, 2016
1 parent 986adab commit cde6141
Showing 1 changed file with 19 additions and 17 deletions.
36 changes: 19 additions & 17 deletions laskyawm.js
Original file line number Diff line number Diff line change
Expand Up @@ -577,24 +577,9 @@ function forceMinimize() {
};
}).reverse();

for(var i = 0, len = windows.length; i < len; i++) {
for(var i = windows.length; --i >= 0;) {
var win = windows[i];
for(var amount = 0, sign = 1, area = 0; amount <= i; amount++, sign *= -1) {
for(var b = 0; b < Math.pow(2, i); b++) {
if(b.toString(2).replace(/0/g, '').length === amount) {
var x1 = win.x1, y1 = win.y1, x2 = win.x2, y2 = win.y2;
for(var j = 0; j < len; j++) {
if(Math.pow(2, j) & b) {
if(windows[j].x1 > x1) x1 = windows[j].x1;
if(windows[j].y1 > y1) y1 = windows[j].y1;
if(windows[j].x2 < x2) x2 = windows[j].x2;
if(windows[j].y2 < y2) y2 = windows[j].y2;
}
}
area += sign * O(x1, y1, x2, y2);
}
}
}
var area = add(1, i, win.x1, win.y1, win.x2, win.y2, windows);
if(area === 0) {
win.div.classList.add('force-minimized');
win.div.classList.add('minimized');
Expand All @@ -607,6 +592,23 @@ function forceMinimize() {
positionMinimized();
}

function add(sign, i, _x1, _y1, _x2, _y2, windows) {
var area = sign * O(_x1, _y1, _x2, _y2);

for(var j = i; --j >= 0;) {
var x1 = _x1, y1 = _y1, x2 = _x2, y2 = _y2;

if(windows[j].x1 > x1) x1 = windows[j].x1;
if(windows[j].y1 > y1) y1 = windows[j].y1;
if(windows[j].x2 < x2) x2 = windows[j].x2;
if(windows[j].y2 < y2) y2 = windows[j].y2;

area += add(-sign, j, x1, y1, x2, y2, windows);
}

return area;
}

function O(x1, y1, x2, y2) {
return Math.max(0, x2 - x1) * Math.max(0, y2 - y1);
}
Expand Down

0 comments on commit cde6141

Please sign in to comment.