Example #1
0
void csRectRegion::Exclude (const csRect &nrect)
{
  // Ignore an empty rect
  if (nrect.IsEmpty ())
    return;

  // If there are no rects in the region, just leave.
  if (region.IsEmpty())
    return;

  size_t i;
  csRect rect (nrect);

  /// Clear the fragment buffer
  for (i = 0; i < FRAGMENT_BUFFER_SIZE; ++i)
    fragment[i].MakeEmpty ();

  // Otherwise, we have to see if this rect overlaps or touches any other.
  for (i = 0; i < region.GetSize(); i++)
  {
    csRect r1 (region[i]);
    csRect r2 (rect);

    // Check to see if these even touch
    if (r2.Intersects (r1) == false) continue;

    // Check to see if the inclusion rect is totally dominated by the
    // exclusion rect.
    r1.Exclude (r2);
    if (r1.IsEmpty ())
    {
      region.DeleteIndex (i);
      i--;
      continue;
    }

    // Check to see if the exclusion rect is totally dominated by the
    // exclusion rect
    r1.Set (region[i]);
    r2.Exclude (r1);
    if (r2.IsEmpty ())
    {
      r2.Set (rect);
      region.DeleteIndex (i);
      fragmentContainedRect (r1, r2);
      i = 0;
      continue;
    }

    r2.Set (rect);

    // This part is similiar to Include, except that we are trying to remove
    // a portion.  Instead of calling chopEdgeIntersection, we actually have
    // to fragment rect1 and chop off an edge of the excluding rect.  This
    // code should be handled inside fragment rect.

    // Kill rect from list
    region.DeleteIndex (i);
    i--;

    // Fragment it
    fragmentRect (r1, r2, MODE_EXCLUDE);
  }
}
Example #2
0
void csRectRegion::Include (const csRect &nrect)
{
  // Ignore an empty rect
  if (nrect.IsEmpty ())
    return;

  // If there are no rects in the region, add this and leave.
  if (region.IsEmpty())
  {
    region.Push (nrect);
    return;
  }

  size_t i;
  bool no_fragments;
  csRect rect (nrect);

  /// Clear the fragment buffer
  for (i = 0; i < FRAGMENT_BUFFER_SIZE; ++i) fragment[i].MakeEmpty ();

  do
  {
    bool untouched = true;

    no_fragments = true;

    // Otherwise, we have to see if this rect creates a union with any other
    // rectangles.
    size_t last_to_consider = region.GetSize();
    for (i = 0; i < last_to_consider; i++)
    {
      csRect &r1 = region[i];
      csRect r2 (rect);

      // Check to see if these even touch, if not, next.
      if (r2.Intersects (r1) == false) continue;

      // If r1 totally contains rect, then we leave.
      r2.Exclude (r1);
      if (r2.IsEmpty ())
      {
        // Mark it so we don't add it in
        untouched = false;
        break;
      }

      // If rect totally contains r1, then we kill r1 from the list.
      r2.Set (r1);
      r2.Exclude (rect);

      if (r2.IsEmpty ())
      {
        // Kill from list
        region.DeleteIndex (i);
        i--;
        last_to_consider--;
        // Iterate
        continue;
      }

      /*
      // Otherwise we have to do the most irritating part: A full split
      // operation that may create other rects that need to be tested against
      // the database recursively.  For this algorithm, we fragment the
      // one that is already in the database, that way we don't cause more
      // tests: we already know that that rect is good.
      r2.Set (rect);

      // Kill rect from list
      region.DeleteIndex (i);

      // Fragment it
      fragmentRect (r1, r2, MODE_INCLUDE);
      */

      r2.Set (rect);
      nkSplit (r1, r2);
      region.DeleteIndex (i);
      i--;
      last_to_consider--;
      // Mark it
      //      untouched = true;
    } // end for

    // In the end, we need to put the rect on the stack
    if (!rect.IsEmpty () && untouched)
      region.Push (rect);

    // Check and see if we have fragments to consider
    for (i = 0; i < FRAGMENT_BUFFER_SIZE; ++i)
    {
      if (!(fragment[i].IsEmpty ()))
      {
        rect.Set (fragment[i]);
        fragment[i].MakeEmpty ();
        no_fragments = false;
        break;
      }
    }
  } while (!no_fragments);
}