File indexing completed on 2024-11-16 09:28:45
0001
0002
0003
0004
0005
0006
0007
0008 #ifndef BOOST_POLYGON_PROPERTY_MERGE_45_HPP
0009 #define BOOST_POLYGON_PROPERTY_MERGE_45_HPP
0010 namespace boost { namespace polygon{
0011
0012 template <typename Unit, typename property_type>
0013 struct polygon_45_property_merge {
0014
0015 typedef point_data<Unit> Point;
0016 typedef typename coordinate_traits<Unit>::manhattan_area_type LongUnit;
0017
0018 template <typename property_map>
0019 static inline void merge_property_maps(property_map& mp, const property_map& mp2, bool subtract = false) {
0020 polygon_45_touch<Unit>::merge_property_maps(mp, mp2, subtract);
0021 }
0022
0023 class CountMerge {
0024 public:
0025 inline CountMerge() : counts() {}
0026
0027
0028 inline CountMerge(const CountMerge& count) : counts(count.counts) {}
0029 inline bool operator==(const CountMerge& count) const { return counts == count.counts; }
0030 inline bool operator!=(const CountMerge& count) const { return !((*this) == count); }
0031
0032 inline CountMerge& operator=(const CountMerge& count) { counts = count.counts; return *this; }
0033 inline int& operator[](property_type index) {
0034 std::vector<std::pair<int, int> >::iterator itr = lower_bound(counts.begin(), counts.end(), std::make_pair(index, int(0)));
0035 if(itr != counts.end() && itr->first == index) {
0036 return itr->second;
0037 }
0038 itr = counts.insert(itr, std::make_pair(index, int(0)));
0039 return itr->second;
0040 }
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050 inline CountMerge& operator+=(const CountMerge& count){
0051 merge_property_maps(counts, count.counts, false);
0052 return *this;
0053 }
0054 inline CountMerge& operator-=(const CountMerge& count){
0055 merge_property_maps(counts, count.counts, true);
0056 return *this;
0057 }
0058 inline CountMerge operator+(const CountMerge& count) const {
0059 return CountMerge(*this)+=count;
0060 }
0061 inline CountMerge operator-(const CountMerge& count) const {
0062 return CountMerge(*this)-=count;
0063 }
0064 inline CountMerge invert() const {
0065 CountMerge retval;
0066 retval -= *this;
0067 return retval;
0068 }
0069 std::vector<std::pair<property_type, int> > counts;
0070 };
0071
0072
0073 struct merge_45_output_functor {
0074 template <typename cT>
0075 void operator()(cT& output, const CountMerge& count1, const CountMerge& count2,
0076 const Point& pt, int rise, direction_1d end) {
0077 typedef typename cT::key_type keytype;
0078 keytype left;
0079 keytype right;
0080 int edgeType = end == LOW ? -1 : 1;
0081 for(typename std::vector<std::pair<property_type, int> >::const_iterator itr = count1.counts.begin();
0082 itr != count1.counts.end(); ++itr) {
0083 left.insert(left.end(), (*itr).first);
0084 }
0085 for(typename std::vector<std::pair<property_type, int> >::const_iterator itr = count2.counts.begin();
0086 itr != count2.counts.end(); ++itr) {
0087 right.insert(right.end(), (*itr).first);
0088 }
0089 if(left == right) return;
0090 if(!left.empty()) {
0091
0092 output[left].insert_clean(typename boolean_op_45<Unit>::Vertex45(pt, rise, -edgeType));
0093 }
0094 if(!right.empty()) {
0095
0096 output[right].insert_clean(typename boolean_op_45<Unit>::Vertex45(pt, rise, edgeType));
0097 }
0098 }
0099 };
0100
0101 typedef typename std::pair<Point,
0102 typename boolean_op_45<Unit>::template Scan45CountT<CountMerge> > Vertex45Compact;
0103 typedef std::vector<Vertex45Compact> MergeSetData;
0104
0105 struct lessVertex45Compact {
0106 bool operator()(const Vertex45Compact& l, const Vertex45Compact& r) {
0107 return l.first < r.first;
0108 }
0109 };
0110
0111 template <typename output_type>
0112 static void performMerge(output_type& result, MergeSetData& tsd) {
0113
0114 polygon_sort(tsd.begin(), tsd.end(), lessVertex45Compact());
0115 typedef std::vector<std::pair<Point, typename boolean_op_45<Unit>::template Scan45CountT<CountMerge> > > TSD;
0116 TSD tsd_;
0117 tsd_.reserve(tsd.size());
0118 for(typename MergeSetData::iterator itr = tsd.begin(); itr != tsd.end(); ) {
0119 typename MergeSetData::iterator itr2 = itr;
0120 ++itr2;
0121 for(; itr2 != tsd.end() && itr2->first == itr->first; ++itr2) {
0122 (itr->second) += (itr2->second);
0123 }
0124 tsd_.push_back(std::make_pair(itr->first, itr->second));
0125 itr = itr2;
0126 }
0127 typename boolean_op_45<Unit>::template Scan45<CountMerge, merge_45_output_functor> scanline;
0128 for(typename TSD::iterator itr = tsd_.begin(); itr != tsd_.end(); ) {
0129 typename TSD::iterator itr2 = itr;
0130 ++itr2;
0131 while(itr2 != tsd_.end() && itr2->first.x() == itr->first.x()) {
0132 ++itr2;
0133 }
0134 scanline.scan(result, itr, itr2);
0135 itr = itr2;
0136 }
0137 }
0138
0139 template <typename iT>
0140 static void populateMergeSetData(MergeSetData& tsd, iT begin, iT end, property_type property) {
0141 for( ; begin != end; ++begin) {
0142 Vertex45Compact vertex;
0143 vertex.first = typename Vertex45Compact::first_type(begin->pt.x() * 2, begin->pt.y() * 2);
0144 tsd.push_back(vertex);
0145 for(unsigned int i = 0; i < 4; ++i) {
0146 if(begin->count[i]) {
0147 tsd.back().second[i][property] += begin->count[i];
0148 }
0149 }
0150 }
0151 }
0152
0153 };
0154
0155
0156
0157 }
0158 }
0159
0160 #endif