annotate DEPENDENCIES/generic/include/boost/polygon/detail/polygon_45_touch.hpp @ 125:34e428693f5d vext

Vext -> Repoint
author Chris Cannam
date Thu, 14 Jun 2018 11:15:39 +0100
parents 2665513ce2d3
children
rev   line source
Chris@16 1 /*
Chris@16 2 Copyright 2008 Intel Corporation
Chris@16 3
Chris@16 4 Use, modification and distribution are subject to the Boost Software License,
Chris@16 5 Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
Chris@16 6 http://www.boost.org/LICENSE_1_0.txt).
Chris@16 7 */
Chris@16 8 #ifndef BOOST_POLYGON_POLYGON_45_TOUCH_HPP
Chris@16 9 #define BOOST_POLYGON_POLYGON_45_TOUCH_HPP
Chris@16 10 namespace boost { namespace polygon{
Chris@16 11
Chris@16 12 template <typename Unit>
Chris@16 13 struct polygon_45_touch {
Chris@16 14
Chris@16 15 typedef point_data<Unit> Point;
Chris@16 16 typedef typename coordinate_traits<Unit>::manhattan_area_type LongUnit;
Chris@16 17
Chris@16 18 template <typename property_map>
Chris@16 19 static inline void merge_property_maps(property_map& mp, const property_map& mp2, bool subtract = false) {
Chris@16 20 property_map newmp;
Chris@16 21 newmp.reserve(mp.size() + mp2.size());
Chris@16 22 std::size_t i = 0;
Chris@16 23 std::size_t j = 0;
Chris@16 24 while(i != mp.size() && j != mp2.size()) {
Chris@16 25 if(mp[i].first < mp2[j].first) {
Chris@16 26 newmp.push_back(mp[i]);
Chris@16 27 ++i;
Chris@16 28 } else if(mp[i].first > mp2[j].first) {
Chris@16 29 newmp.push_back(mp2[j]);
Chris@16 30 if(subtract) newmp.back().second *= -1;
Chris@16 31 ++j;
Chris@16 32 } else {
Chris@16 33 int count = mp[i].second;
Chris@16 34 if(subtract) count -= mp2[j].second;
Chris@16 35 else count += mp2[j].second;
Chris@16 36 if(count) {
Chris@16 37 newmp.push_back(mp[i]);
Chris@16 38 newmp.back().second = count;
Chris@16 39 }
Chris@16 40 ++i;
Chris@16 41 ++j;
Chris@16 42 }
Chris@16 43 }
Chris@16 44 while(i != mp.size()) {
Chris@16 45 newmp.push_back(mp[i]);
Chris@16 46 ++i;
Chris@16 47 }
Chris@16 48 while(j != mp2.size()) {
Chris@16 49 newmp.push_back(mp2[j]);
Chris@16 50 if(subtract) newmp.back().second *= -1;
Chris@16 51 ++j;
Chris@16 52 }
Chris@16 53 mp.swap(newmp);
Chris@16 54 }
Chris@16 55
Chris@16 56 class CountTouch {
Chris@16 57 public:
Chris@16 58 inline CountTouch() : counts() {}
Chris@16 59 //inline CountTouch(int count) { counts[0] = counts[1] = count; }
Chris@16 60 //inline CountTouch(int count1, int count2) { counts[0] = count1; counts[1] = count2; }
Chris@16 61 inline CountTouch(const CountTouch& count) : counts(count.counts) {}
Chris@16 62 inline bool operator==(const CountTouch& count) const { return counts == count.counts; }
Chris@16 63 inline bool operator!=(const CountTouch& count) const { return !((*this) == count); }
Chris@16 64 //inline CountTouch& operator=(int count) { counts[0] = counts[1] = count; return *this; }
Chris@16 65 inline CountTouch& operator=(const CountTouch& count) { counts = count.counts; return *this; }
Chris@16 66 inline int& operator[](int index) {
Chris@16 67 std::vector<std::pair<int, int> >::iterator itr =
Chris@16 68 std::lower_bound(counts.begin(), counts.end(),
Chris@16 69 std::make_pair(index, int(0)));
Chris@16 70 if(itr != counts.end() && itr->first == index) {
Chris@16 71 return itr->second;
Chris@16 72 }
Chris@16 73 itr = counts.insert(itr, std::make_pair(index, int(0)));
Chris@16 74 return itr->second;
Chris@16 75 }
Chris@16 76 // inline int operator[](int index) const {
Chris@16 77 // std::vector<std::pair<int, int> >::const_iterator itr = counts.begin();
Chris@16 78 // for( ; itr != counts.end() && itr->first <= index; ++itr) {
Chris@16 79 // if(itr->first == index) {
Chris@16 80 // return itr->second;
Chris@16 81 // }
Chris@16 82 // }
Chris@16 83 // return 0;
Chris@16 84 // }
Chris@16 85 inline CountTouch& operator+=(const CountTouch& count){
Chris@16 86 merge_property_maps(counts, count.counts, false);
Chris@16 87 return *this;
Chris@16 88 }
Chris@16 89 inline CountTouch& operator-=(const CountTouch& count){
Chris@16 90 merge_property_maps(counts, count.counts, true);
Chris@16 91 return *this;
Chris@16 92 }
Chris@16 93 inline CountTouch operator+(const CountTouch& count) const {
Chris@16 94 return CountTouch(*this)+=count;
Chris@16 95 }
Chris@16 96 inline CountTouch operator-(const CountTouch& count) const {
Chris@16 97 return CountTouch(*this)-=count;
Chris@16 98 }
Chris@16 99 inline CountTouch invert() const {
Chris@16 100 CountTouch retval;
Chris@16 101 retval -= *this;
Chris@16 102 return retval;
Chris@16 103 }
Chris@16 104 std::vector<std::pair<int, int> > counts;
Chris@16 105 };
Chris@16 106
Chris@16 107 typedef std::pair<std::pair<Unit, std::map<Unit, std::set<int> > >, std::map<int, std::set<int> > > map_graph_o;
Chris@16 108 typedef std::pair<std::pair<Unit, std::map<Unit, std::set<int> > >, std::vector<std::set<int> > > vector_graph_o;
Chris@16 109
Chris@16 110 template <typename cT>
Chris@16 111 static void process_previous_x(cT& output) {
Chris@16 112 std::map<Unit, std::set<int> >& y_prop_map = output.first.second;
Chris@16 113 for(typename std::map<Unit, std::set<int> >::iterator itr = y_prop_map.begin();
Chris@16 114 itr != y_prop_map.end(); ++itr) {
Chris@16 115 for(std::set<int>::iterator inner_itr = itr->second.begin();
Chris@16 116 inner_itr != itr->second.end(); ++inner_itr) {
Chris@16 117 std::set<int>& output_edges = (*(output.second))[*inner_itr];
Chris@16 118 std::set<int>::iterator inner_inner_itr = inner_itr;
Chris@16 119 ++inner_inner_itr;
Chris@16 120 for( ; inner_inner_itr != itr->second.end(); ++inner_inner_itr) {
Chris@16 121 output_edges.insert(output_edges.end(), *inner_inner_itr);
Chris@16 122 std::set<int>& output_edges_2 = (*(output.second))[*inner_inner_itr];
Chris@16 123 output_edges_2.insert(output_edges_2.end(), *inner_itr);
Chris@16 124 }
Chris@16 125 }
Chris@16 126 }
Chris@16 127 y_prop_map.clear();
Chris@16 128 }
Chris@16 129
Chris@16 130 struct touch_45_output_functor {
Chris@16 131 template <typename cT>
Chris@16 132 void operator()(cT& output, const CountTouch& count1, const CountTouch& count2,
Chris@16 133 const Point& pt, int , direction_1d ) {
Chris@16 134 Unit& x = output.first.first;
Chris@16 135 std::map<Unit, std::set<int> >& y_prop_map = output.first.second;
Chris@16 136 if(pt.x() != x) process_previous_x(output);
Chris@16 137 x = pt.x();
Chris@16 138 std::set<int>& output_set = y_prop_map[pt.y()];
Chris@16 139 for(std::vector<std::pair<int, int> >::const_iterator itr1 = count1.counts.begin();
Chris@16 140 itr1 != count1.counts.end(); ++itr1) {
Chris@16 141 if(itr1->second > 0) {
Chris@16 142 output_set.insert(output_set.end(), itr1->first);
Chris@16 143 }
Chris@16 144 }
Chris@16 145 for(std::vector<std::pair<int, int> >::const_iterator itr2 = count2.counts.begin();
Chris@16 146 itr2 != count2.counts.end(); ++itr2) {
Chris@16 147 if(itr2->second > 0) {
Chris@16 148 output_set.insert(output_set.end(), itr2->first);
Chris@16 149 }
Chris@16 150 }
Chris@16 151 }
Chris@16 152 };
Chris@16 153 typedef typename std::pair<Point,
Chris@16 154 typename boolean_op_45<Unit>::template Scan45CountT<CountTouch> > Vertex45Compact;
Chris@16 155 typedef std::vector<Vertex45Compact> TouchSetData;
Chris@16 156
Chris@16 157 struct lessVertex45Compact {
Chris@16 158 bool operator()(const Vertex45Compact& l, const Vertex45Compact& r) {
Chris@16 159 return l.first < r.first;
Chris@16 160 }
Chris@16 161 };
Chris@16 162
Chris@16 163 // template <typename TSD>
Chris@16 164 // static void print_tsd(TSD& tsd) {
Chris@16 165 // for(std::size_t i = 0; i < tsd.size(); ++i) {
Chris@16 166 // std::cout << tsd[i].first << ": ";
Chris@16 167 // for(unsigned int r = 0; r < 4; ++r) {
Chris@16 168 // std::cout << r << " { ";
Chris@16 169 // for(std::vector<std::pair<int, int> >::iterator itr = tsd[i].second[r].counts.begin();
Chris@16 170 // itr != tsd[i].second[r].counts.end(); ++itr) {
Chris@16 171 // std::cout << itr->first << "," << itr->second << " ";
Chris@16 172 // } std::cout << "} ";
Chris@16 173 // }
Chris@16 174 // } std::cout << std::endl;
Chris@16 175 // }
Chris@16 176
Chris@16 177 // template <typename T>
Chris@16 178 // static void print_scanline(T& t) {
Chris@16 179 // for(typename T::iterator itr = t.begin(); itr != t.end(); ++itr) {
Chris@16 180 // std::cout << itr->x << "," << itr->y << " " << itr->rise << " ";
Chris@16 181 // for(std::vector<std::pair<int, int> >::iterator itr2 = itr->count.counts.begin();
Chris@16 182 // itr2 != itr->count.counts.end(); ++itr2) {
Chris@16 183 // std::cout << itr2->first << ":" << itr2->second << " ";
Chris@16 184 // } std::cout << std::endl;
Chris@16 185 // }
Chris@16 186 // }
Chris@16 187
Chris@16 188 template <typename graph_type>
Chris@16 189 static void performTouch(graph_type& graph, TouchSetData& tsd) {
Chris@16 190
Chris@16 191 polygon_sort(tsd.begin(), tsd.end(), lessVertex45Compact());
Chris@16 192 typedef std::vector<std::pair<Point, typename boolean_op_45<Unit>::template Scan45CountT<CountTouch> > > TSD;
Chris@16 193 TSD tsd_;
Chris@16 194 tsd_.reserve(tsd.size());
Chris@16 195 for(typename TouchSetData::iterator itr = tsd.begin(); itr != tsd.end(); ) {
Chris@16 196 typename TouchSetData::iterator itr2 = itr;
Chris@16 197 ++itr2;
Chris@16 198 for(; itr2 != tsd.end() && itr2->first == itr->first; ++itr2) {
Chris@16 199 (itr->second) += (itr2->second); //accumulate
Chris@16 200 }
Chris@16 201 tsd_.push_back(std::make_pair(itr->first, itr->second));
Chris@16 202 itr = itr2;
Chris@16 203 }
Chris@16 204 std::pair<std::pair<Unit, std::map<Unit, std::set<int> > >, graph_type*> output
Chris@16 205 (std::make_pair(std::make_pair((std::numeric_limits<Unit>::max)(), std::map<Unit, std::set<int> >()), &graph));
Chris@16 206 typename boolean_op_45<Unit>::template Scan45<CountTouch, touch_45_output_functor> scanline;
Chris@16 207 for(typename TSD::iterator itr = tsd_.begin(); itr != tsd_.end(); ) {
Chris@16 208 typename TSD::iterator itr2 = itr;
Chris@16 209 ++itr2;
Chris@16 210 while(itr2 != tsd_.end() && itr2->first.x() == itr->first.x()) {
Chris@16 211 ++itr2;
Chris@16 212 }
Chris@16 213 scanline.scan(output, itr, itr2);
Chris@16 214 itr = itr2;
Chris@16 215 }
Chris@16 216 process_previous_x(output);
Chris@16 217 }
Chris@16 218
Chris@16 219 template <typename iT>
Chris@16 220 static void populateTouchSetData(TouchSetData& tsd, iT begin, iT end, int nodeCount) {
Chris@16 221 for( ; begin != end; ++begin) {
Chris@16 222 Vertex45Compact vertex;
Chris@16 223 vertex.first = typename Vertex45Compact::first_type(begin->pt.x() * 2, begin->pt.y() * 2);
Chris@16 224 tsd.push_back(vertex);
Chris@16 225 for(unsigned int i = 0; i < 4; ++i) {
Chris@16 226 if(begin->count[i]) {
Chris@16 227 tsd.back().second[i][nodeCount] += begin->count[i];
Chris@16 228 }
Chris@16 229 }
Chris@16 230 }
Chris@16 231 }
Chris@16 232
Chris@16 233 };
Chris@16 234
Chris@16 235
Chris@16 236 }
Chris@16 237 }
Chris@16 238 #endif