Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Optimize and simplify forceMinimize() visible area algorithm
A diagram for understanding the algorithm (D on top, A on the bottom): ┌────────────────────────────────┐ │ │ │ D │ │ ┌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌├──────┐ │ ┆ │ │ │ ┌╌╌╌╌┆--------------┐ │ C │ │ ┆ ┆ : │ │ │ ┆ ┆ ┌ - - - - -:-----│╌╌╌╌╌╌├────┐ │ ┆ ┆ . : │ │ │ │ ┆ ┆ . : │ │ │ │ ┆ ┆ . * : │ │ │ │ ┆ ┆ . : │ │ │ │ ┆ ┆ . : │ │ │ │ ┆ └╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌├──────┘ │ │ ┆ : ┆ │ │ │ ┆ : ┆ │ │ │ ┆ : ┆ │ │ └──────┬───────────────────┬─────┘ │ │ ┆ │ │ │ B ┆ │ A │ └────────┬──────────┘ │ │ │ └────────────────────────────┘ We want the visible area of A. Let's subtract B and C from A: (I(A, B): the area of the intersection of A and B) Area(A) - I(A, B) - I(A, C) However, B and C overlap, so there's an area which we've subtracted from A twice (marked with a * in the diagram above.) So we add that back again once: … + I(A, B, C) Now let's subtract D, and add back the parts of D that overlap with what we've already subtracted: … - I(A, D) + I(A, B, D) + I(A, C, D) - I(A, B, C, D) So the complete sum 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) More generally: we take every subset of the rectangles on top of A, and add or subtract (depending on subset.length % 2) the intersection of those rectangles and A. 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). To see that this is useful, we reorder the sum above: VisibleArea(A) = 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)
- Loading branch information