void Region::Consolidate() { // Optimize region by consolidating adjacent rectangles. for (int i = 0; i < fNumRects; i++) { for (int j = fNumRects - 1; j > i; j--) { Rect &rect1 = fRects[i]; Rect &rect2 = fRects[j]; if (rect1.top == rect2.top && rect1.bottom == rect2.bottom) { if (rect1.right + 1 == rect2.left) { rect1.right = rect2.right; RemoveRect(j); } else if (rect2.right + 1 == rect1.left) { rect1.left = rect2.left; RemoveRect(j); } } else if (rect1.left == rect2.left && rect1.right == rect2.right) { if (rect1.top == rect2.bottom + 1) { rect1.top = rect2.top; RemoveRect(j); } else if (rect1.bottom + 1 == rect2.top) { rect1.bottom = rect2.bottom; RemoveRect(j); } } } } }
Region& Region::ConstrainTo(const Rect &rect) { BeginOperation(); for (int i = fNumRects - 1; i >= 0; i--) { fRects[i].left = max(rect.left, fRects[i].left); fRects[i].right = min(rect.right, fRects[i].right); fRects[i].top = max(rect.top, fRects[i].top); fRects[i].bottom = min(rect.bottom, fRects[i].bottom); if (!fRects[i].Valid()) RemoveRect(i); } EndOperation(); return *this; }
RTREE_TEMPLATE void RTREE_QUAL::Remove(const ELEMTYPE a_min[NUMDIMS], const ELEMTYPE a_max[NUMDIMS], const DATATYPE& a_dataId) { #ifdef _DEBUG for (int index = 0; index < NUMDIMS; ++index) { ASSERT(a_min[index] <= a_max[index]); } #endif //_DEBUG Rect rect; for (int axis = 0; axis < NUMDIMS; ++axis) { rect.m_min[axis] = a_min[axis]; rect.m_max[axis] = a_max[axis]; } RemoveRect(&rect, a_dataId, &m_root); }
Region& Region::Exclude(const Rect &excludeRect) { BeginOperation(); int index = 0; int rectsToCheck = fNumRects; while (index < rectsToCheck) { Rect &clipRect = fRects[index]; if (!excludeRect.Intersects(clipRect)) { index++; continue; } // This clip rect intersects the excluded rect, and could be divided into // as many as eight pieces. Test for each case. Note that none of these // rectangles overlap!!!! Rect quad1(clipRect.left, clipRect.top, excludeRect.left - 1, excludeRect.top - 1); if (SPLIT_TEST(clipRect, quad1)) { quad1.Intersect(clipRect); AddRect(quad1); } Rect quad2(excludeRect.left, clipRect.top, excludeRect.right, excludeRect.top - 1); if (SPLIT_TEST(clipRect, quad2)) { quad2.Intersect(clipRect); AddRect(quad2); } Rect quad3(excludeRect.right + 1, clipRect.top, clipRect.right, excludeRect.top - 1); if (SPLIT_TEST(clipRect, quad3)) { quad3.Intersect(clipRect); AddRect(quad3); } Rect quad4(clipRect.left, excludeRect.top, excludeRect.left - 1, excludeRect.bottom); if (SPLIT_TEST(clipRect, quad4)) { quad4.Intersect(clipRect); AddRect(quad4); } Rect quad5(excludeRect.right + 1, excludeRect.top, clipRect.right, excludeRect.bottom); if (SPLIT_TEST(clipRect, quad5)) { quad5.Intersect(clipRect); AddRect(quad5); } Rect quad6(clipRect.left, excludeRect.bottom + 1, excludeRect.left - 1, clipRect.bottom); if (SPLIT_TEST(clipRect, quad6)) { quad6.Intersect(clipRect); AddRect(quad6); } Rect quad7(excludeRect.left, excludeRect.bottom + 1, excludeRect.right, clipRect.bottom); if (SPLIT_TEST(clipRect, quad7)) { quad7.Intersect(clipRect); AddRect(quad7); } Rect quad8(excludeRect.right + 1, excludeRect.bottom + 1, clipRect.right, clipRect.bottom); if (SPLIT_TEST(clipRect, quad8)) { quad8.Intersect(clipRect); AddRect(quad8); } // This rect has been split, remove it. Note we don't // change the index RemoveRect(index); rectsToCheck--; } EndOperation(); return *this; }