Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>Probably the most efficient way would be computing a rectangle-rectangle subtraction that may seem difficult and with a lot of cases, but indeed it's not that hard:</p> <pre><code>struct Rect{ int x0, y0, x1, y1; Rect(int x0, int y0, int x1, int y1) : x0(x0), y0(y0), x1(x1), y1(y1) {} }; std::vector&lt;Rect&gt; subtract(const Rect&amp; a, const Rect&amp; b) { std::vector&lt;Rect&gt; result; if (a.y1 &lt;= b.y0 || a.y0 &gt;= b.y1 || a.x1 &lt;= b.x0 || a.x0 &gt;= b.x1) { // Trivial case: rectangles are not overlapping result.push_back(a); } else { int ystart = a.y0, yend = a.y1; if (ystart &lt; b.y0) { // Something visible above result.push_back(Rect(a.x0, ystart, a.x1, b.y0)); ystart = b.y0; } if (yend &gt; b.y1) { // Something visible below result.push_back(Rect(a.x0, b.y1, a.x1, yend)); yend = b.y1; } if (a.x0 &lt; b.x0) { // Something visible on the left result.push_back(Rect(a.x0, ystart, b.x0, yend)); } if (a.x1 &gt; b.x1) { // Something visible on the right result.push_back(Rect(b.x1, ystart, a.x1, yend)); } } return result; } </code></pre> <p>The above function given two rectangles <code>A</code> and <code>B</code> returns a vector of rectangles with the result of <code>A-B</code>. This vector may be empty (<code>B</code> covers <code>A</code>) or may have from one to four rectangles (four is when <code>B</code> is stricly contained in <code>A</code>, thus the result will be a rectangle with a rectangular hole in it).</p> <p>Using this function you can easily compute <code>new-old</code> and <code>old-new</code> areas.</p> <p>Note that the coordinate schema used in the above code assumes the point-base coordinate system (not a pixel-based coordinate system):</p> <p><img src="https://i.stack.imgur.com/LENHg.png" alt="enter image description here"></p> <p>In the above picture note that horizontal X coordinates of rectangles go from 0 to W (not W-1) and vertical Y coordinates go from 0 to H (and not to H-1).</p> <p>Pixels are just rectangles of area 1 with coordinates <code>(x, y)-(x+1, y+1)</code>; the center of this pixel is <code>(x+0.5, y+0.5)</code>. A rectangle with <code>x0==x1</code> or <code>y0==y1</code> is empty.</p> <p>Note also that the code assumes (and returns) non-empty oriented rectangles, i.e. <code>x0&lt;x1 &amp;&amp; y0&lt;y1</code>.</p> <p>This approach of separating the concept of pixel coordinate from the concept of point coordinate simplifies a lot of the pixel math: for example rectangle area is <code>width*height</code> and not <code>(width-1)*(height-1)</code>.</p> <p>A little program to test with your input case is the following</p> <pre><code>void print_result(const char *name, const std::vector&lt;Rect&gt;&amp; rects) { printf("Result '%s' (%i rects):\n", name, int(rects.size())); for (int i=0,n=rects.size(); i&lt;n; i++) { printf(" %i) (%i, %i) - (%i, %i)\n", i+1, rects[i].x0, rects[i].y0, rects[i].x1, rects[i].y1); } } int main() { Rect A(1, 1, 6, 6); Rect B(3, 2, 8, 7); print_result("A-B", subtract(A, B)); print_result("B-A", subtract(B, A)); return 0; } </code></pre> <p>and the output of this program is</p> <pre><code>Result 'A-B' (2 rects): 1) (1, 1) - (6, 2) 2) (1, 2) - (3, 6) Result 'B-A' (2 rects): 1) (3, 6) - (8, 7) 2) (6, 2) - (8, 6) </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload