/*! * @brief intersects a polygon with a map, adding any results to output map * * @param[out] resultMap output map (must be allocated) * @param[in] polygon to be intersected * @param[in] map intersected against * @param[in] lock to use when adding output polygons to result map * */ void OverlayOnePolygonWithMap(Polygon_map_t *resultMap, RPolygon *myPoly, Polygon_map_t *map2, tbb::spin_mutex *rMutex) { int r1, g1, b1, r2, g2, b2; int myr=0; int myg=0; int myb=0; int p1Area = myPoly->area(); for(unsigned int j=1; (j < map2->size()) && (p1Area > 0); j++) { RPolygon *p2 = (*map2)[j]; RPolygon *pnew; int newxMin, newxMax, newyMin, newyMax; myPoly->getColor(&r1, &g1, &b1); if(PolygonsOverlap(myPoly, p2, newxMin, newyMin, newxMax, newyMax)) { p2->getColor(&r2, &g2, &b2); myr = r1 + r2; myg = g1 + g2; myb = b1 + b2; pnew = RPolygon::alloc_RPolygon(newxMin, newyMin, newxMax, newyMax, myr, myg, myb); p1Area -= pnew->area(); // when all the area of the polygon is accounted for, we can quit. if(rMutex) { tbb::spin_mutex::scoped_lock lock(*rMutex); #if _DEBUG pnew->print(int(resultMap->size())); #endif resultMap->push_back(pnew); } else { #ifdef _DEBUG pnew->print(int(resultMap->size())); #endif resultMap->push_back(pnew); } } } }
bool CompOnePolygon(RPolygon &p1, RPolygon &p2) { int xl1, xh1, yl1, yh1; int xl2, xh2, yl2, yh2; p1.get(&xl1, &yl1, &xh1, &yh1); p2.get(&xl2, &yl2, &xh2, &yh2); if(yl1>yl2) return true; if(yl1<yl2) return false; return (xl1 > xl2); }
void split_at( Flagged_map_t& in_map, Flagged_map_t &left_out, Flagged_map_t &right_out, const T median) { left_out.reserve(in_map.size()); right_out.reserve(in_map.size()); for(Flagged_map_t::iterator i = in_map.begin(); i != in_map.end(); ++i ) { RPolygon *p = i->p(); if(p->xmax() < median) { // in left map left_out.push_back(*i); } else if(p->xmin() >= median) { right_out.push_back(*i); // in right map } else { // in both maps. left_out.push_back(*i); right_out.push_back(RPolygon_flagged(p, true)); } } }
void check_my_map() { assert(my_range.begin() <= my_range.end()); for(Flagged_map_t::iterator ci = my_map1.begin(); ci != my_map1.end(); ++ci) { RPolygon *rp = ci->p(); assert(rp->xmax() >= my_range.begin()); assert(rp->xmin() < my_range.end()); } for(Flagged_map_t::iterator ci = my_map2.begin(); ci != my_map2.end(); ++ci) { RPolygon *rp = ci->p(); assert(rp->xmax() >= my_range.begin()); assert(rp->xmin() < my_range.end()); } }
/*! * @brief functor for columnar parallel version * @param[in] r range of map to be operated on */ void operator()(const tbb::blocked_range<int> & r) const { #ifdef _DEBUG // if we are debugging, serialize the method. That way we can // see what is happening in each strip without the interleaving // confusing things. tbb::spin_mutex::scoped_lock lock(*m_rMutex); cout << unitbuf << "From " << r.begin() << " to " << r.end()-1 << std::endl; #endif // instead of handing out subsets of polygons from map1 to intersect // with the polygons in map2, we are handed a strip of the map from // [(r.begin(),0)-(r.end()-1,yMapSize)]. // // make a polygon with those values, and intersect with all the polygons // in map1 and map2, creating flagged polygon lists fmap1 and fmap2. // There are four possiblities: // // 1) a polygon is contained entirely within the strip. We just // add the polygon to our flagged map. // 2) the polygon will be partly contained in our strip, and partly // in the strip to our right (higher x values). Add the polygon // to our flagged map. // 3) the polygon is partly contained in our map, and partly in the // strip to our left. Add the polygon to our map, but flag it as // a duplicate. // 4) the polygons do not intersect. Don't add to flagged map. // // get yMapSize int r1, g1, b1, r2, g2, b2; int myr=-1; int myg=-1; int myb=-1; int i1, i2, i3, yMapSize; m_map1->at(0)->get(&i1, &i2, &i3, &yMapSize); RPolygon *slicePolygon = RPolygon::alloc_RPolygon(r.begin(), 0, r.end() - 1, yMapSize); Flagged_map_t *fmap1, *fmap2; fmap1 = new std::vector<RPolygon_flagged>; fmap1->reserve(m_map1->size()); fmap2 = new Flagged_map_t; fmap2->reserve(m_map2->size()); PRINT_DEBUG(std::endl << "Map1 -------------------"); for(unsigned int i=1; i<m_map1->size(); i++) { int xl, yl, xh, yh; RPolygon *px = m_map1->at(i); if(PolygonsOverlap(slicePolygon, px, xl, yl, xh, yh)) { bool is_duplicate = false; int pxl, pyl, pxh, pyh; int indx = (int)(fmap1->size()); fmap1->resize(indx+1); fmap1->at(indx).setp(px); px->get(&pxl, &pyl, &pxh, &pyh); if(pxl < xl) { is_duplicate = true; } //fmap1->at(indx).setp(px); fmap1->at(indx).setDuplicate(is_duplicate); PRINT_DEBUG(" Polygon " << *px << " is in map, is_duplicate=" << is_duplicate); } } PRINT_DEBUG(std::endl << "Map2 -------------------"); for(unsigned int i=1; i<m_map2->size(); i++) { int xl, yl, xh, yh; RPolygon *px = m_map2->at(i); if(PolygonsOverlap(slicePolygon, px, xl, yl, xh, yh)) { bool is_duplicate = false; int pxl, pyl, pxh, pyh; int indx = (int)(fmap2->size()); fmap2->resize(indx+1); fmap2->at(indx).setp(px); px->get(&pxl, &pyl, &pxh, &pyh); if(pxl < xl) { is_duplicate = true; } fmap2->at(indx).setDuplicate(is_duplicate); PRINT_DEBUG(" Polygon " << *px << " is in map, is_duplicate=" << is_duplicate); } } // When intersecting polygons from fmap1 and fmap2, if BOTH are flagged // as duplicate, don't add the result to the output map. We can still // intersect them, because we are keeping track of how much of the polygon // is left over from intersecting, and quitting when the polygon is // used up. for(unsigned int ii=0; ii < fmap1->size(); ii++) { RPolygon *p1 = fmap1->at(ii).p(); bool is_dup = fmap1->at(ii).isDuplicate(); int parea = p1->area(); p1->getColor(&r1, &g1, &b1); for(unsigned int jj=0;(jj < fmap2->size()) && (parea > 0); jj++) { int xl, yl, xh, yh; RPolygon *p2 = fmap2->at(jj).p(); if(PolygonsOverlap(p1, p2, xl, yl, xh, yh)) { if(!(is_dup && fmap2->at(jj).isDuplicate())) { p2->getColor(&r2, &g2, &b2); myr = r1 + r2; myg = g1 + g2; myb = b1 + b2; RPolygon *pnew = RPolygon::alloc_RPolygon(xl, yl, xh, yh, myr, myg, myb); #ifdef _DEBUG #else tbb::spin_mutex::scoped_lock lock(*m_rMutex); #endif (*m_resultMap).push_back(pnew); } parea -= (xh-xl+1)*(yh-yl+1); } } } delete fmap1; delete fmap2; RPolygon::free_RPolygon( slicePolygon ); }