// ---------------------------------------------------------------------------- // Description : Rectangular geometry // ---------------------------------------------------------------------------- // (c) Copyright 1997 by iXiONmedia, all rights reserved. // ---------------------------------------------------------------------------- #include #include // rectangle ----------------------------------------------------------------- template void ixion::rectangle::unite(rectangle const &rect) { A[0] = NUM_MIN(A[0],rect.A[0]); A[1] = NUM_MIN(A[1],rect.A[1]); B[0] = NUM_MAX(B[0],rect.B[0]); B[1] = NUM_MAX(B[1],rect.B[1]); } template void ixion::rectangle::intersect(rectangle const &rect) { A[0] = NUM_MAX(A[0],rect.A[0]); A[1] = NUM_MAX(A[1],rect.A[1]); B[0] = NUM_MIN(B[0],rect.B[0]); B[1] = NUM_MIN(B[1],rect.B[1]); if (isEmpty()) clear(); } // region -------------------------------------------------------------------- template void ixion::region::add(rectangle const &rect) { subtract(rect); Rects.push_back(rect); } template void ixion::region::intersect(rectangle const &rect) { iterator first = begin(),last = end(); while (first != last) first++->intersect(rect); deleteEmptyRectangles(); } template void ixion::region::subtract(rectangle const &rect) { iterator first = begin(),last = end(); std::vector< rectangle > newrects; while (first != last) { if (rect.doesIntersect(*first)) { rectangle upper(rect.A[0],first->A[1],rect.B[0],rect.A[1]); rectangle lower(rect.A[0],rect.B[1],rect.B[0],first->B[1]); rectangle left(first->A[0],first->A[1],rect.A[0],first->B[1]); rectangle right(rect.B[0],first->A[1],first->B[0],first->B[1]); if (!upper.isEmpty()) newrects.push_back(upper); if (!lower.isEmpty()) newrects.push_back(lower); if (!left.isEmpty()) newrects.push_back(left); if (!right.isEmpty()) newrects.push_back(right); first++; } else newrects.push_back(*first++); } Rects.swap(newrects); } template void ixion::region::deleteEmptyRectangles() { iterator first = begin(),last = end(); std::vector< rectangle > newrects; while (first != last) { if (!first->isEmpty()) newrects.push_back(*first); first++; } Rects.swap(newrects); } template bool ixion::region::contains(coord_vector const &point) const { const_iterator first = begin(),last = end(); while (first != last) { if (first->doesContain(point)) return true; first++; } return false; } template bool ixion::region::intersects(rectangle const &rect) const { const_iterator first = begin(),last = end(); while (first != last) { if (first->doesIntersect(rect)) return true; first++; } return false; }