std::vector< hash_region_t<inner_region_t> > region_subtract_many(const hash_region_t<inner_region_t> &minuend, const std::vector< hash_region_t<inner_region_t> >& subtrahends) { std::vector< hash_region_t<inner_region_t> > buf; std::vector< hash_region_t<inner_region_t> > temp_result_buf; buf.push_back(minuend); for (typename std::vector< hash_region_t<inner_region_t> >::const_iterator s = subtrahends.begin(); s != subtrahends.end(); ++s) { for (typename std::vector< hash_region_t<inner_region_t> >::const_iterator m = buf.begin(); m != buf.end(); ++m) { // Subtract s from m, push back onto temp_result_buf. // (See the "subtraction drawing" after this function.) // We first subtract m.inner - s.inner, combining the // difference with m's hash interval to create a set of // regions w. Then m.inner is intersected with s.inner, // and the hash range is formed from subtracting s's hash // range from m's, possibly creating x and/or z. const std::vector<inner_region_t> s_vec(1, s->inner); const std::vector<inner_region_t> w_inner = region_subtract_many(m->inner, s_vec); for (typename std::vector<inner_region_t>::const_iterator it = w_inner.begin(); it != w_inner.end(); ++it) { temp_result_buf.push_back(hash_region_t<inner_region_t>(m->beg, m->end, *it)); } // This outer conditional check is unnecessary, but it // might improve performance because we avoid trying an // unnecessary region intersection. if (m->beg < s->beg || s->end < m->end) { inner_region_t isect = region_intersection(m->inner, s->inner); if (!region_is_empty(isect)) { // Add x, if it exists. if (m->beg < s->beg) { temp_result_buf.push_back(hash_region_t<inner_region_t>(m->beg, std::min(s->beg, m->end), isect)); } // Add z, if it exists. if (s->end < m->end) { temp_result_buf.push_back(hash_region_t<inner_region_t>(std::max(m->beg, s->end), m->end, isect)); } } } } buf.swap(temp_result_buf); temp_result_buf.clear(); } return buf; }
hash_region_t<inner_region_t> region_intersection(const hash_region_t<inner_region_t> &r1, const hash_region_t<inner_region_t> &r2) { if (r1.end <= r2.beg || r2.end <= r1.beg) { return hash_region_t<inner_region_t>(); } inner_region_t inner_intersection = region_intersection(r1.inner, r2.inner); if (region_is_empty(inner_intersection)) { return hash_region_t<inner_region_t>(); } return hash_region_t<inner_region_t>(std::max(r1.beg, r2.beg), std::min(r1.end, r2.end), inner_intersection); }
QuadTreeNodeData::REGION_INTERSECTION_FLAG QuadTree::region_intersection(const iterator_base & it, const CG_Region & region ) { RS_Hatch * hatch = region.hatch; if(!hatch->hasHole()) return region_intersection(it, region.contour_points ); const RS_Vector * _p_tr = it->tr(); const RS_Vector * _p_tl = it->tl(); const RS_Vector * _p_br = it->br(); const RS_Vector * _p_bl = it->bl(); RS_Line line1(0, RS_LineData(*_p_bl, *_p_br)); if(hatch->hasIntersectionWithEdge(&line1)) return QuadTreeNodeData::INTERSECTION_REGION; RS_Line line2(0, RS_LineData(*_p_br, *_p_tr)); if(hatch->hasIntersectionWithEdge(&line2)) return QuadTreeNodeData::INTERSECTION_REGION; RS_Line line3(0, RS_LineData(*_p_tl, *_p_tr)); if(hatch->hasIntersectionWithEdge(&line3)) return QuadTreeNodeData::INTERSECTION_REGION; RS_Line line4(0, RS_LineData(*_p_bl, *_p_tl)); if(hatch->hasIntersectionWithEdge(&line4)) return QuadTreeNodeData::INTERSECTION_REGION; bool this_point_on_hatch; if(RS_Information::isPointInsideContour(*_p_bl, hatch, &this_point_on_hatch)) return QuadTreeNodeData::IN_REGION; if(it->has_point(hatch->getData().internal_point)) return QuadTreeNodeData::COVER_REGION; return QuadTreeNodeData::OUT_REGION; /* unsigned int n_point_in_region = 0; bool has_point_on_region=false; { bool this_point_on_hatch; n_point_in_region += RS_Information::isPointInsideContour(*_p_tr, hatch, &this_point_on_hatch); if(this_point_on_hatch) has_point_on_region=true; n_point_in_region += RS_Information::isPointInsideContour(*_p_tl, hatch, &this_point_on_hatch); if(this_point_on_hatch) has_point_on_region=true; n_point_in_region += RS_Information::isPointInsideContour(*_p_br, hatch, &this_point_on_hatch); if(this_point_on_hatch) has_point_on_region=true; n_point_in_region += RS_Information::isPointInsideContour(*_p_bl, hatch, &this_point_on_hatch); if(this_point_on_hatch) has_point_on_region=true; } std::cout<<n_point_in_region<<std::endl; if(has_point_on_region) { std::cout<<"INTERSECTION_REGION"<<std::endl; return QuadTreeNodeData::INTERSECTION_REGION; } if(n_point_in_region==4) { return QuadTreeNodeData::IN_REGION; } if(n_point_in_region==0) { if(it->has_point(hatch->getData().internal_point)) return QuadTreeNodeData::COVER_REGION; else return QuadTreeNodeData::OUT_REGION; } if(n_point_in_region>0 && n_point_in_region<4) return QuadTreeNodeData::INTERSECTION_REGION; */ }