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_FORMATION_HPP
|
Chris@16
|
9 #define BOOST_POLYGON_POLYGON_45_FORMATION_HPP
|
Chris@16
|
10 namespace boost { namespace polygon{
|
Chris@16
|
11
|
Chris@16
|
12 template <typename T, typename T2>
|
Chris@16
|
13 struct PolyLineByConcept {};
|
Chris@16
|
14
|
Chris@16
|
15 template <typename T>
|
Chris@16
|
16 class PolyLine45PolygonData;
|
Chris@16
|
17 template <typename T>
|
Chris@16
|
18 class PolyLine45HoleData;
|
Chris@16
|
19
|
Chris@16
|
20 //polygon45formation algorithm
|
Chris@16
|
21 template <typename Unit>
|
Chris@16
|
22 struct polygon_45_formation : public boolean_op_45<Unit> {
|
Chris@16
|
23 typedef point_data<Unit> Point;
|
Chris@16
|
24 typedef polygon_45_data<Unit> Polygon45;
|
Chris@16
|
25 typedef polygon_45_with_holes_data<Unit> Polygon45WithHoles;
|
Chris@16
|
26 typedef typename boolean_op_45<Unit>::Vertex45 Vertex45;
|
Chris@16
|
27 typedef typename boolean_op_45<Unit>::lessVertex45 lessVertex45;
|
Chris@16
|
28 typedef typename boolean_op_45<Unit>::Count2 Count2;
|
Chris@16
|
29 typedef typename boolean_op_45<Unit>::Scan45Count Scan45Count;
|
Chris@16
|
30 typedef std::pair<Point, Scan45Count> Scan45Vertex;
|
Chris@16
|
31 typedef typename boolean_op_45<Unit>::template
|
Chris@16
|
32 Scan45<Count2, typename boolean_op_45<Unit>::template boolean_op_45_output_functor<0> > Scan45;
|
Chris@16
|
33
|
Chris@16
|
34 class PolyLine45 {
|
Chris@16
|
35 public:
|
Chris@16
|
36 typedef typename std::list<Point>::const_iterator iterator;
|
Chris@16
|
37
|
Chris@16
|
38 // default constructor of point does not initialize x and y
|
Chris@16
|
39 inline PolyLine45() : points() {} //do nothing default constructor
|
Chris@16
|
40
|
Chris@16
|
41 // initialize a polygon from x,y values, it is assumed that the first is an x
|
Chris@16
|
42 // and that the input is a well behaved polygon
|
Chris@16
|
43 template<class iT>
|
Chris@16
|
44 inline PolyLine45& set(iT inputBegin, iT inputEnd) {
|
Chris@16
|
45 points.clear(); //just in case there was some old data there
|
Chris@16
|
46 while(inputBegin != inputEnd) {
|
Chris@16
|
47 points.insert(points.end(), *inputBegin);
|
Chris@16
|
48 ++inputBegin;
|
Chris@16
|
49 }
|
Chris@16
|
50 return *this;
|
Chris@16
|
51 }
|
Chris@16
|
52
|
Chris@16
|
53 // copy constructor (since we have dynamic memory)
|
Chris@16
|
54 inline PolyLine45(const PolyLine45& that) : points(that.points) {}
|
Chris@16
|
55
|
Chris@16
|
56 // assignment operator (since we have dynamic memory do a deep copy)
|
Chris@16
|
57 inline PolyLine45& operator=(const PolyLine45& that) {
|
Chris@16
|
58 points = that.points;
|
Chris@16
|
59 return *this;
|
Chris@16
|
60 }
|
Chris@16
|
61
|
Chris@16
|
62 // get begin iterator, returns a pointer to a const Unit
|
Chris@16
|
63 inline iterator begin() const { return points.begin(); }
|
Chris@16
|
64
|
Chris@16
|
65 // get end iterator, returns a pointer to a const Unit
|
Chris@16
|
66 inline iterator end() const { return points.end(); }
|
Chris@16
|
67
|
Chris@16
|
68 inline std::size_t size() const { return points.size(); }
|
Chris@16
|
69
|
Chris@16
|
70 //public data member
|
Chris@16
|
71 std::list<Point> points;
|
Chris@16
|
72 };
|
Chris@16
|
73
|
Chris@16
|
74 class ActiveTail45 {
|
Chris@16
|
75 private:
|
Chris@16
|
76 //data
|
Chris@16
|
77 PolyLine45* tailp_;
|
Chris@16
|
78 ActiveTail45 *otherTailp_;
|
Chris@16
|
79 std::list<ActiveTail45*> holesList_;
|
Chris@16
|
80 bool head_;
|
Chris@16
|
81 public:
|
Chris@16
|
82
|
Chris@16
|
83 /**
|
Chris@16
|
84 * @brief iterator over coordinates of the figure
|
Chris@16
|
85 */
|
Chris@16
|
86 typedef typename PolyLine45::iterator iterator;
|
Chris@16
|
87
|
Chris@16
|
88 /**
|
Chris@16
|
89 * @brief iterator over holes contained within the figure
|
Chris@16
|
90 */
|
Chris@16
|
91 typedef typename std::list<ActiveTail45*>::const_iterator iteratorHoles;
|
Chris@16
|
92
|
Chris@16
|
93 //default constructor
|
Chris@16
|
94 inline ActiveTail45() : tailp_(0), otherTailp_(0), holesList_(), head_(0) {}
|
Chris@16
|
95
|
Chris@16
|
96 //constructor
|
Chris@16
|
97 inline ActiveTail45(const Vertex45& vertex, ActiveTail45* otherTailp = 0) :
|
Chris@16
|
98 tailp_(0), otherTailp_(0), holesList_(), head_(0) {
|
Chris@16
|
99 tailp_ = new PolyLine45;
|
Chris@16
|
100 tailp_->points.push_back(vertex.pt);
|
Chris@16
|
101 bool headArray[4] = {false, true, true, true};
|
Chris@16
|
102 bool inverted = vertex.count == -1;
|
Chris@16
|
103 head_ = headArray[vertex.rise+1] ^ inverted;
|
Chris@16
|
104 otherTailp_ = otherTailp;
|
Chris@16
|
105 }
|
Chris@16
|
106
|
Chris@16
|
107 inline ActiveTail45(Point point, ActiveTail45* otherTailp, bool head = true) :
|
Chris@16
|
108 tailp_(0), otherTailp_(0), holesList_(), head_(0) {
|
Chris@16
|
109 tailp_ = new PolyLine45;
|
Chris@16
|
110 tailp_->points.push_back(point);
|
Chris@16
|
111 head_ = head;
|
Chris@16
|
112 otherTailp_ = otherTailp;
|
Chris@16
|
113
|
Chris@16
|
114 }
|
Chris@16
|
115 inline ActiveTail45(ActiveTail45* otherTailp) :
|
Chris@16
|
116 tailp_(0), otherTailp_(0), holesList_(), head_(0) {
|
Chris@16
|
117 tailp_ = otherTailp->tailp_;
|
Chris@16
|
118 otherTailp_ = otherTailp;
|
Chris@16
|
119 }
|
Chris@16
|
120
|
Chris@16
|
121 //copy constructor
|
Chris@16
|
122 inline ActiveTail45(const ActiveTail45& that) :
|
Chris@16
|
123 tailp_(0), otherTailp_(0), holesList_(), head_(0) { (*this) = that; }
|
Chris@16
|
124
|
Chris@16
|
125 //destructor
|
Chris@16
|
126 inline ~ActiveTail45() {
|
Chris@16
|
127 destroyContents();
|
Chris@16
|
128 }
|
Chris@16
|
129
|
Chris@16
|
130 //assignment operator
|
Chris@16
|
131 inline ActiveTail45& operator=(const ActiveTail45& that) {
|
Chris@16
|
132 tailp_ = new PolyLine45(*(that.tailp_));
|
Chris@16
|
133 head_ = that.head_;
|
Chris@16
|
134 otherTailp_ = that.otherTailp_;
|
Chris@16
|
135 holesList_ = that.holesList_;
|
Chris@16
|
136 return *this;
|
Chris@16
|
137 }
|
Chris@16
|
138
|
Chris@16
|
139 //equivalence operator
|
Chris@16
|
140 inline bool operator==(const ActiveTail45& b) const {
|
Chris@16
|
141 return tailp_ == b.tailp_ && head_ == b.head_;
|
Chris@16
|
142 }
|
Chris@16
|
143
|
Chris@16
|
144 /**
|
Chris@16
|
145 * @brief get the pointer to the polyline that this is an active tail of
|
Chris@16
|
146 */
|
Chris@16
|
147 inline PolyLine45* getTail() const { return tailp_; }
|
Chris@16
|
148
|
Chris@16
|
149 /**
|
Chris@16
|
150 * @brief get the pointer to the polyline at the other end of the chain
|
Chris@16
|
151 */
|
Chris@16
|
152 inline PolyLine45* getOtherTail() const { return otherTailp_->tailp_; }
|
Chris@16
|
153
|
Chris@16
|
154 /**
|
Chris@16
|
155 * @brief get the pointer to the activetail at the other end of the chain
|
Chris@16
|
156 */
|
Chris@16
|
157 inline ActiveTail45* getOtherActiveTail() const { return otherTailp_; }
|
Chris@16
|
158
|
Chris@16
|
159 /**
|
Chris@16
|
160 * @brief test if another active tail is the other end of the chain
|
Chris@16
|
161 */
|
Chris@16
|
162 inline bool isOtherTail(const ActiveTail45& b) const { return &b == otherTailp_; }
|
Chris@16
|
163
|
Chris@16
|
164 /**
|
Chris@16
|
165 * @brief update this end of chain pointer to new polyline
|
Chris@16
|
166 */
|
Chris@16
|
167 inline ActiveTail45& updateTail(PolyLine45* newTail) { tailp_ = newTail; return *this; }
|
Chris@16
|
168
|
Chris@16
|
169 inline bool join(ActiveTail45* tail) {
|
Chris@16
|
170 if(tail == otherTailp_) {
|
Chris@16
|
171 //std::cout << "joining to other tail!\n";
|
Chris@16
|
172 return false;
|
Chris@16
|
173 }
|
Chris@16
|
174 if(tail->head_ == head_) {
|
Chris@16
|
175 //std::cout << "joining head to head!\n";
|
Chris@16
|
176 return false;
|
Chris@16
|
177 }
|
Chris@16
|
178 if(!tailp_) {
|
Chris@16
|
179 //std::cout << "joining empty tail!\n";
|
Chris@16
|
180 return false;
|
Chris@16
|
181 }
|
Chris@16
|
182 if(!(otherTailp_->head_)) {
|
Chris@16
|
183 otherTailp_->copyHoles(*tail);
|
Chris@16
|
184 otherTailp_->copyHoles(*this);
|
Chris@16
|
185 } else {
|
Chris@16
|
186 tail->otherTailp_->copyHoles(*this);
|
Chris@16
|
187 tail->otherTailp_->copyHoles(*tail);
|
Chris@16
|
188 }
|
Chris@16
|
189 PolyLine45* tail1 = tailp_;
|
Chris@16
|
190 PolyLine45* tail2 = tail->tailp_;
|
Chris@16
|
191 if(head_) std::swap(tail1, tail2);
|
Chris@16
|
192 tail1->points.splice(tail1->points.end(), tail2->points);
|
Chris@16
|
193 delete tail2;
|
Chris@16
|
194 otherTailp_->tailp_ = tail1;
|
Chris@16
|
195 tail->otherTailp_->tailp_ = tail1;
|
Chris@16
|
196 otherTailp_->otherTailp_ = tail->otherTailp_;
|
Chris@16
|
197 tail->otherTailp_->otherTailp_ = otherTailp_;
|
Chris@16
|
198 tailp_ = 0;
|
Chris@16
|
199 tail->tailp_ = 0;
|
Chris@16
|
200 tail->otherTailp_ = 0;
|
Chris@16
|
201 otherTailp_ = 0;
|
Chris@16
|
202 return true;
|
Chris@16
|
203 }
|
Chris@16
|
204
|
Chris@16
|
205 /**
|
Chris@16
|
206 * @brief associate a hole to this active tail by the specified policy
|
Chris@16
|
207 */
|
Chris@16
|
208 inline ActiveTail45* addHole(ActiveTail45* hole) {
|
Chris@16
|
209 holesList_.push_back(hole);
|
Chris@16
|
210 copyHoles(*hole);
|
Chris@16
|
211 copyHoles(*(hole->otherTailp_));
|
Chris@16
|
212 return this;
|
Chris@16
|
213 }
|
Chris@16
|
214
|
Chris@16
|
215 /**
|
Chris@16
|
216 * @brief get the list of holes
|
Chris@16
|
217 */
|
Chris@16
|
218 inline const std::list<ActiveTail45*>& getHoles() const { return holesList_; }
|
Chris@16
|
219
|
Chris@16
|
220 /**
|
Chris@16
|
221 * @brief copy holes from that to this
|
Chris@16
|
222 */
|
Chris@16
|
223 inline void copyHoles(ActiveTail45& that) { holesList_.splice(holesList_.end(), that.holesList_); }
|
Chris@16
|
224
|
Chris@16
|
225 /**
|
Chris@16
|
226 * @brief find out if solid to right
|
Chris@16
|
227 */
|
Chris@16
|
228 inline bool solidToRight() const { return !head_; }
|
Chris@16
|
229 inline bool solidToLeft() const { return head_; }
|
Chris@16
|
230
|
Chris@16
|
231 /**
|
Chris@16
|
232 * @brief get vertex
|
Chris@16
|
233 */
|
Chris@16
|
234 inline Point getPoint() const {
|
Chris@16
|
235 if(head_) return tailp_->points.front();
|
Chris@16
|
236 return tailp_->points.back();
|
Chris@16
|
237 }
|
Chris@16
|
238
|
Chris@16
|
239 /**
|
Chris@16
|
240 * @brief add a coordinate to the polygon at this active tail end, properly handle degenerate edges by removing redundant coordinate
|
Chris@16
|
241 */
|
Chris@16
|
242 inline void pushPoint(Point point) {
|
Chris@16
|
243 if(head_) {
|
Chris@16
|
244 //if(tailp_->points.size() < 2) {
|
Chris@16
|
245 // tailp_->points.push_front(point);
|
Chris@16
|
246 // return;
|
Chris@16
|
247 //}
|
Chris@16
|
248 typename std::list<Point>::iterator iter = tailp_->points.begin();
|
Chris@16
|
249 if(iter == tailp_->points.end()) {
|
Chris@16
|
250 tailp_->points.push_front(point);
|
Chris@16
|
251 return;
|
Chris@16
|
252 }
|
Chris@16
|
253 Unit firstY = (*iter).y();
|
Chris@16
|
254 Unit firstX = (*iter).x();
|
Chris@16
|
255 ++iter;
|
Chris@16
|
256 if(iter == tailp_->points.end()) {
|
Chris@16
|
257 tailp_->points.push_front(point);
|
Chris@16
|
258 return;
|
Chris@16
|
259 }
|
Chris@16
|
260 if((iter->y() == point.y() && firstY == point.y()) ||
|
Chris@16
|
261 (iter->x() == point.x() && firstX == point.x())){
|
Chris@16
|
262 --iter;
|
Chris@16
|
263 *iter = point;
|
Chris@16
|
264 } else {
|
Chris@16
|
265 tailp_->points.push_front(point);
|
Chris@16
|
266 }
|
Chris@16
|
267 return;
|
Chris@16
|
268 }
|
Chris@16
|
269 //if(tailp_->points.size() < 2) {
|
Chris@16
|
270 // tailp_->points.push_back(point);
|
Chris@16
|
271 // return;
|
Chris@16
|
272 //}
|
Chris@16
|
273 typename std::list<Point>::reverse_iterator iter = tailp_->points.rbegin();
|
Chris@16
|
274 if(iter == tailp_->points.rend()) {
|
Chris@16
|
275 tailp_->points.push_back(point);
|
Chris@16
|
276 return;
|
Chris@16
|
277 }
|
Chris@16
|
278 Unit firstY = (*iter).y();
|
Chris@16
|
279 Unit firstX = (*iter).x();
|
Chris@16
|
280 ++iter;
|
Chris@16
|
281 if(iter == tailp_->points.rend()) {
|
Chris@16
|
282 tailp_->points.push_back(point);
|
Chris@16
|
283 return;
|
Chris@16
|
284 }
|
Chris@16
|
285 if((iter->y() == point.y() && firstY == point.y()) ||
|
Chris@16
|
286 (iter->x() == point.x() && firstX == point.x())){
|
Chris@16
|
287 --iter;
|
Chris@16
|
288 *iter = point;
|
Chris@16
|
289 } else {
|
Chris@16
|
290 tailp_->points.push_back(point);
|
Chris@16
|
291 }
|
Chris@16
|
292 }
|
Chris@16
|
293
|
Chris@16
|
294 /**
|
Chris@16
|
295 * @brief joins the two chains that the two active tail tails are ends of
|
Chris@16
|
296 * checks for closure of figure and writes out polygons appropriately
|
Chris@16
|
297 * returns a handle to a hole if one is closed
|
Chris@16
|
298 */
|
Chris@16
|
299
|
Chris@16
|
300 template <class cT>
|
Chris@16
|
301 static inline ActiveTail45* joinChains(Point point, ActiveTail45* at1, ActiveTail45* at2, bool solid,
|
Chris@16
|
302 cT& output) {
|
Chris@16
|
303 if(at1->otherTailp_ == at2) {
|
Chris@16
|
304 //if(at2->otherTailp_ != at1) std::cout << "half closed error\n";
|
Chris@16
|
305 //we are closing a figure
|
Chris@16
|
306 at1->pushPoint(point);
|
Chris@16
|
307 at2->pushPoint(point);
|
Chris@16
|
308 if(solid) {
|
Chris@16
|
309 //we are closing a solid figure, write to output
|
Chris@16
|
310 //std::cout << "test1\n";
|
Chris@16
|
311 at1->copyHoles(*(at1->otherTailp_));
|
Chris@16
|
312 //std::cout << "test2\n";
|
Chris@16
|
313 //Polygon45WithHolesImpl<PolyLine45PolygonData> poly(polyData);
|
Chris@16
|
314 //std::cout << poly << "\n";
|
Chris@16
|
315 //std::cout << "test3\n";
|
Chris@16
|
316 typedef typename cT::value_type pType;
|
Chris@16
|
317 output.push_back(pType());
|
Chris@16
|
318 typedef typename geometry_concept<pType>::type cType;
|
Chris@16
|
319 typename PolyLineByConcept<Unit, cType>::type polyData(at1);
|
Chris@16
|
320 assign(output.back(), polyData);
|
Chris@16
|
321 //std::cout << "test4\n";
|
Chris@16
|
322 //std::cout << "delete " << at1->otherTailp_ << "\n";
|
Chris@16
|
323 //at1->print();
|
Chris@16
|
324 //at1->otherTailp_->print();
|
Chris@16
|
325 delete at1->otherTailp_;
|
Chris@16
|
326 //at1->print();
|
Chris@16
|
327 //at1->otherTailp_->print();
|
Chris@16
|
328 //std::cout << "test5\n";
|
Chris@16
|
329 //std::cout << "delete " << at1 << "\n";
|
Chris@16
|
330 delete at1;
|
Chris@16
|
331 //std::cout << "test6\n";
|
Chris@16
|
332 return 0;
|
Chris@16
|
333 } else {
|
Chris@16
|
334 //we are closing a hole, return the tail end active tail of the figure
|
Chris@16
|
335 return at1;
|
Chris@16
|
336 }
|
Chris@16
|
337 }
|
Chris@16
|
338 //we are not closing a figure
|
Chris@16
|
339 at1->pushPoint(point);
|
Chris@16
|
340 at1->join(at2);
|
Chris@16
|
341 delete at1;
|
Chris@16
|
342 delete at2;
|
Chris@16
|
343 return 0;
|
Chris@16
|
344 }
|
Chris@16
|
345
|
Chris@16
|
346 inline void destroyContents() {
|
Chris@16
|
347 if(otherTailp_) {
|
Chris@16
|
348 //std::cout << "delete p " << tailp_ << "\n";
|
Chris@16
|
349 if(tailp_) delete tailp_;
|
Chris@16
|
350 tailp_ = 0;
|
Chris@16
|
351 otherTailp_->otherTailp_ = 0;
|
Chris@16
|
352 otherTailp_->tailp_ = 0;
|
Chris@16
|
353 otherTailp_ = 0;
|
Chris@16
|
354 }
|
Chris@16
|
355 for(typename std::list<ActiveTail45*>::iterator itr = holesList_.begin(); itr != holesList_.end(); ++itr) {
|
Chris@16
|
356 //std::cout << "delete p " << (*itr) << "\n";
|
Chris@16
|
357 if(*itr) {
|
Chris@16
|
358 if((*itr)->otherTailp_) {
|
Chris@16
|
359 delete (*itr)->otherTailp_;
|
Chris@16
|
360 (*itr)->otherTailp_ = 0;
|
Chris@16
|
361 }
|
Chris@16
|
362 delete (*itr);
|
Chris@16
|
363 }
|
Chris@16
|
364 (*itr) = 0;
|
Chris@16
|
365 }
|
Chris@16
|
366 holesList_.clear();
|
Chris@16
|
367 }
|
Chris@16
|
368
|
Chris@16
|
369 // inline void print() {
|
Chris@16
|
370 // std::cout << this << " " << tailp_ << " " << otherTailp_ << " " << holesList_.size() << " " << head_ << "\n";
|
Chris@16
|
371 // }
|
Chris@16
|
372
|
Chris@16
|
373 static inline std::pair<ActiveTail45*, ActiveTail45*> createActiveTail45sAsPair(Point point, bool solid,
|
Chris@16
|
374 ActiveTail45* phole, bool fractureHoles) {
|
Chris@16
|
375 ActiveTail45* at1 = 0;
|
Chris@16
|
376 ActiveTail45* at2 = 0;
|
Chris@16
|
377 if(phole && fractureHoles) {
|
Chris@16
|
378 //std::cout << "adding hole\n";
|
Chris@16
|
379 at1 = phole;
|
Chris@16
|
380 //assert solid == false, we should be creating a corner with solid below and to the left if there was a hole
|
Chris@16
|
381 at2 = at1->getOtherActiveTail();
|
Chris@16
|
382 at2->pushPoint(point);
|
Chris@16
|
383 at1->pushPoint(point);
|
Chris@16
|
384 } else {
|
Chris@16
|
385 at1 = new ActiveTail45(point, at2, solid);
|
Chris@16
|
386 at2 = new ActiveTail45(at1);
|
Chris@16
|
387 at1->otherTailp_ = at2;
|
Chris@16
|
388 at2->head_ = !solid;
|
Chris@16
|
389 if(phole)
|
Chris@16
|
390 at2->addHole(phole); //assert fractureHoles == false
|
Chris@16
|
391 }
|
Chris@16
|
392 return std::pair<ActiveTail45*, ActiveTail45*>(at1, at2);
|
Chris@16
|
393 }
|
Chris@16
|
394
|
Chris@16
|
395 };
|
Chris@16
|
396
|
Chris@16
|
397 template <typename ct>
|
Chris@16
|
398 class Vertex45CountT {
|
Chris@16
|
399 public:
|
Chris@16
|
400 typedef ct count_type;
|
Chris@16
|
401 inline Vertex45CountT()
|
Chris@16
|
402 #ifndef BOOST_POLYGON_MSVC
|
Chris@16
|
403 : counts()
|
Chris@16
|
404 #endif
|
Chris@16
|
405 { counts[0] = counts[1] = counts[2] = counts[3] = 0; }
|
Chris@16
|
406 //inline Vertex45CountT(ct count) { counts[0] = counts[1] = counts[2] = counts[3] = count; }
|
Chris@16
|
407 inline Vertex45CountT(const ct& count1, const ct& count2, const ct& count3,
|
Chris@16
|
408 const ct& count4)
|
Chris@16
|
409 #ifndef BOOST_POLYGON_MSVC
|
Chris@16
|
410 : counts()
|
Chris@16
|
411 #endif
|
Chris@16
|
412 {
|
Chris@16
|
413 counts[0] = count1;
|
Chris@16
|
414 counts[1] = count2;
|
Chris@16
|
415 counts[2] = count3;
|
Chris@16
|
416 counts[3] = count4;
|
Chris@16
|
417 }
|
Chris@16
|
418 inline Vertex45CountT(const Vertex45& vertex)
|
Chris@16
|
419 #ifndef BOOST_POLYGON_MSVC
|
Chris@16
|
420 : counts()
|
Chris@16
|
421 #endif
|
Chris@16
|
422 {
|
Chris@16
|
423 counts[0] = counts[1] = counts[2] = counts[3] = 0;
|
Chris@16
|
424 (*this) += vertex;
|
Chris@16
|
425 }
|
Chris@16
|
426 inline Vertex45CountT(const Vertex45CountT& count)
|
Chris@16
|
427 #ifndef BOOST_POLYGON_MSVC
|
Chris@16
|
428 : counts()
|
Chris@16
|
429 #endif
|
Chris@16
|
430 {
|
Chris@16
|
431 (*this) = count;
|
Chris@16
|
432 }
|
Chris@16
|
433 inline bool operator==(const Vertex45CountT& count) const {
|
Chris@16
|
434 for(unsigned int i = 0; i < 4; ++i) {
|
Chris@16
|
435 if(counts[i] != count.counts[i]) return false;
|
Chris@16
|
436 }
|
Chris@16
|
437 return true;
|
Chris@16
|
438 }
|
Chris@16
|
439 inline bool operator!=(const Vertex45CountT& count) const { return !((*this) == count); }
|
Chris@16
|
440 inline Vertex45CountT& operator=(ct count) {
|
Chris@16
|
441 counts[0] = counts[1] = counts[2] = counts[3] = count; return *this; }
|
Chris@16
|
442 inline Vertex45CountT& operator=(const Vertex45CountT& count) {
|
Chris@16
|
443 for(unsigned int i = 0; i < 4; ++i) {
|
Chris@16
|
444 counts[i] = count.counts[i];
|
Chris@16
|
445 }
|
Chris@16
|
446 return *this;
|
Chris@16
|
447 }
|
Chris@16
|
448 inline ct& operator[](int index) { return counts[index]; }
|
Chris@16
|
449 inline ct operator[](int index) const {return counts[index]; }
|
Chris@16
|
450 inline Vertex45CountT& operator+=(const Vertex45CountT& count){
|
Chris@16
|
451 for(unsigned int i = 0; i < 4; ++i) {
|
Chris@16
|
452 counts[i] += count.counts[i];
|
Chris@16
|
453 }
|
Chris@16
|
454 return *this;
|
Chris@16
|
455 }
|
Chris@16
|
456 inline Vertex45CountT& operator-=(const Vertex45CountT& count){
|
Chris@16
|
457 for(unsigned int i = 0; i < 4; ++i) {
|
Chris@16
|
458 counts[i] -= count.counts[i];
|
Chris@16
|
459 }
|
Chris@16
|
460 return *this;
|
Chris@16
|
461 }
|
Chris@16
|
462 inline Vertex45CountT operator+(const Vertex45CountT& count) const {
|
Chris@16
|
463 return Vertex45CountT(*this)+=count;
|
Chris@16
|
464 }
|
Chris@16
|
465 inline Vertex45CountT operator-(const Vertex45CountT& count) const {
|
Chris@16
|
466 return Vertex45CountT(*this)-=count;
|
Chris@16
|
467 }
|
Chris@16
|
468 inline Vertex45CountT invert() const {
|
Chris@16
|
469 return Vertex45CountT()-=(*this);
|
Chris@16
|
470 }
|
Chris@16
|
471 inline Vertex45CountT& operator+=(const Vertex45& element){
|
Chris@16
|
472 counts[element.rise+1] += element.count; return *this;
|
Chris@16
|
473 }
|
Chris@16
|
474 inline bool is_45() const {
|
Chris@16
|
475 return counts[0] != 0 || counts[2] != 0;
|
Chris@16
|
476 }
|
Chris@16
|
477 private:
|
Chris@16
|
478 ct counts[4];
|
Chris@16
|
479 };
|
Chris@16
|
480
|
Chris@16
|
481 typedef Vertex45CountT<int> Vertex45Count;
|
Chris@16
|
482
|
Chris@16
|
483 // inline std::ostream& operator<< (std::ostream& o, const Vertex45Count& c) {
|
Chris@16
|
484 // o << c[0] << ", " << c[1] << ", ";
|
Chris@16
|
485 // o << c[2] << ", " << c[3];
|
Chris@16
|
486 // return o;
|
Chris@16
|
487 // }
|
Chris@16
|
488
|
Chris@16
|
489 template <typename ct>
|
Chris@16
|
490 class Vertex45CompactT {
|
Chris@16
|
491 public:
|
Chris@16
|
492 Point pt;
|
Chris@16
|
493 ct count;
|
Chris@16
|
494 typedef typename boolean_op_45<Unit>::template Vertex45T<typename ct::count_type> Vertex45T;
|
Chris@16
|
495 inline Vertex45CompactT() : pt(), count() {}
|
Chris@16
|
496 inline Vertex45CompactT(const Point& point, int riseIn, int countIn) : pt(point), count() {
|
Chris@16
|
497 count[riseIn+1] = countIn;
|
Chris@16
|
498 }
|
Chris@16
|
499 template <typename ct2>
|
Chris@16
|
500 inline Vertex45CompactT(const typename boolean_op_45<Unit>::template Vertex45T<ct2>& vertex) : pt(vertex.pt), count() {
|
Chris@16
|
501 count[vertex.rise+1] = vertex.count;
|
Chris@16
|
502 }
|
Chris@16
|
503 inline Vertex45CompactT(const Vertex45CompactT& vertex) : pt(vertex.pt), count(vertex.count) {}
|
Chris@16
|
504 inline Vertex45CompactT& operator=(const Vertex45CompactT& vertex){
|
Chris@16
|
505 pt = vertex.pt; count = vertex.count; return *this; }
|
Chris@16
|
506 inline bool operator==(const Vertex45CompactT& vertex) const {
|
Chris@16
|
507 return pt == vertex.pt && count == vertex.count; }
|
Chris@16
|
508 inline bool operator!=(const Vertex45CompactT& vertex) const { return !((*this) == vertex); }
|
Chris@16
|
509 inline bool operator==(const std::pair<Point, Point>& vertex) const { return false; }
|
Chris@16
|
510 inline bool operator!=(const std::pair<Point, Point>& vertex) const { return !((*this) == vertex); }
|
Chris@16
|
511 inline bool operator<(const Vertex45CompactT& vertex) const {
|
Chris@16
|
512 if(pt.x() < vertex.pt.x()) return true;
|
Chris@16
|
513 if(pt.x() == vertex.pt.x()) {
|
Chris@16
|
514 return pt.y() < vertex.pt.y();
|
Chris@16
|
515 }
|
Chris@16
|
516 return false;
|
Chris@16
|
517 }
|
Chris@16
|
518 inline bool operator>(const Vertex45CompactT& vertex) const { return vertex < (*this); }
|
Chris@16
|
519 inline bool operator<=(const Vertex45CompactT& vertex) const { return !((*this) > vertex); }
|
Chris@16
|
520 inline bool operator>=(const Vertex45CompactT& vertex) const { return !((*this) < vertex); }
|
Chris@16
|
521 inline bool haveVertex45(int index) const { return count[index]; }
|
Chris@16
|
522 inline Vertex45T operator[](int index) const {
|
Chris@16
|
523 return Vertex45T(pt, index-1, count[index]); }
|
Chris@16
|
524 };
|
Chris@16
|
525
|
Chris@16
|
526 typedef Vertex45CompactT<Vertex45Count> Vertex45Compact;
|
Chris@16
|
527
|
Chris@16
|
528 // inline std::ostream& operator<< (std::ostream& o, const Vertex45Compact& c) {
|
Chris@16
|
529 // o << c.pt << ", " << c.count;
|
Chris@16
|
530 // return o;
|
Chris@16
|
531 // }
|
Chris@16
|
532
|
Chris@16
|
533 class Polygon45Formation {
|
Chris@16
|
534 private:
|
Chris@16
|
535 //definitions
|
Chris@16
|
536 typedef std::map<Vertex45, ActiveTail45*, lessVertex45> Polygon45FormationData;
|
Chris@16
|
537 typedef typename Polygon45FormationData::iterator iterator;
|
Chris@16
|
538 typedef typename Polygon45FormationData::const_iterator const_iterator;
|
Chris@16
|
539
|
Chris@16
|
540 //data
|
Chris@16
|
541 Polygon45FormationData scanData_;
|
Chris@16
|
542 Unit x_;
|
Chris@16
|
543 int justBefore_;
|
Chris@16
|
544 int fractureHoles_;
|
Chris@16
|
545 public:
|
Chris@16
|
546 inline Polygon45Formation() : scanData_(), x_((std::numeric_limits<Unit>::min)()), justBefore_(false), fractureHoles_(0) {
|
Chris@16
|
547 lessVertex45 lessElm(&x_, &justBefore_);
|
Chris@16
|
548 scanData_ = Polygon45FormationData(lessElm);
|
Chris@16
|
549 }
|
Chris@16
|
550 inline Polygon45Formation(bool fractureHoles) : scanData_(), x_((std::numeric_limits<Unit>::min)()), justBefore_(false), fractureHoles_(fractureHoles) {
|
Chris@16
|
551 lessVertex45 lessElm(&x_, &justBefore_);
|
Chris@16
|
552 scanData_ = Polygon45FormationData(lessElm);
|
Chris@16
|
553 }
|
Chris@16
|
554 inline Polygon45Formation(const Polygon45Formation& that) :
|
Chris@16
|
555 scanData_(), x_((std::numeric_limits<Unit>::min)()), justBefore_(false), fractureHoles_(0) { (*this) = that; }
|
Chris@16
|
556 inline Polygon45Formation& operator=(const Polygon45Formation& that) {
|
Chris@16
|
557 x_ = that.x_;
|
Chris@16
|
558 justBefore_ = that.justBefore_;
|
Chris@16
|
559 fractureHoles_ = that.fractureHoles_;
|
Chris@16
|
560 lessVertex45 lessElm(&x_, &justBefore_);
|
Chris@16
|
561 scanData_ = Polygon45FormationData(lessElm);
|
Chris@16
|
562 for(const_iterator itr = that.scanData_.begin(); itr != that.scanData_.end(); ++itr){
|
Chris@16
|
563 scanData_.insert(scanData_.end(), *itr);
|
Chris@16
|
564 }
|
Chris@16
|
565 return *this;
|
Chris@16
|
566 }
|
Chris@16
|
567
|
Chris@16
|
568 //cT is an output container of Polygon45 or Polygon45WithHoles
|
Chris@16
|
569 //iT is an iterator over Vertex45 elements
|
Chris@16
|
570 //inputBegin - inputEnd is a range of sorted iT that represents
|
Chris@16
|
571 //one or more scanline stops worth of data
|
Chris@16
|
572 template <class cT, class iT>
|
Chris@16
|
573 void scan(cT& output, iT inputBegin, iT inputEnd) {
|
Chris@16
|
574 //std::cout << "1\n";
|
Chris@16
|
575 while(inputBegin != inputEnd) {
|
Chris@16
|
576 //std::cout << "2\n";
|
Chris@16
|
577 x_ = (*inputBegin).pt.x();
|
Chris@16
|
578 //std::cout << "SCAN FORMATION " << x_ << "\n";
|
Chris@16
|
579 //std::cout << "x_ = " << x_ << "\n";
|
Chris@16
|
580 //std::cout << "scan line size: " << scanData_.size() << "\n";
|
Chris@16
|
581 inputBegin = processEvent_(output, inputBegin, inputEnd);
|
Chris@16
|
582 }
|
Chris@16
|
583 }
|
Chris@16
|
584
|
Chris@16
|
585 private:
|
Chris@16
|
586 //functions
|
Chris@16
|
587 template <class cT, class cT2>
|
Chris@16
|
588 inline std::pair<int, ActiveTail45*> processPoint_(cT& output, cT2& elements, Point point,
|
Chris@16
|
589 Vertex45Count& counts, ActiveTail45** tails, Vertex45Count& incoming) {
|
Chris@16
|
590 //std::cout << point << "\n";
|
Chris@16
|
591 //std::cout << counts[0] << " ";
|
Chris@16
|
592 //std::cout << counts[1] << " ";
|
Chris@16
|
593 //std::cout << counts[2] << " ";
|
Chris@16
|
594 //std::cout << counts[3] << "\n";
|
Chris@16
|
595 //std::cout << incoming[0] << " ";
|
Chris@16
|
596 //std::cout << incoming[1] << " ";
|
Chris@16
|
597 //std::cout << incoming[2] << " ";
|
Chris@16
|
598 //std::cout << incoming[3] << "\n";
|
Chris@16
|
599 //join any closing solid corners
|
Chris@16
|
600 ActiveTail45* returnValue = 0;
|
Chris@16
|
601 int returnCount = 0;
|
Chris@16
|
602 for(int i = 0; i < 3; ++i) {
|
Chris@16
|
603 //std::cout << i << "\n";
|
Chris@16
|
604 if(counts[i] == -1) {
|
Chris@16
|
605 //std::cout << "fixed i\n";
|
Chris@16
|
606 for(int j = i + 1; j < 4; ++j) {
|
Chris@16
|
607 //std::cout << j << "\n";
|
Chris@16
|
608 if(counts[j]) {
|
Chris@16
|
609 if(counts[j] == 1) {
|
Chris@16
|
610 //std::cout << "case1: " << i << " " << j << "\n";
|
Chris@16
|
611 //if a figure is closed it will be written out by this function to output
|
Chris@16
|
612 ActiveTail45::joinChains(point, tails[i], tails[j], true, output);
|
Chris@16
|
613 counts[i] = 0;
|
Chris@16
|
614 counts[j] = 0;
|
Chris@16
|
615 tails[i] = 0;
|
Chris@16
|
616 tails[j] = 0;
|
Chris@16
|
617 }
|
Chris@16
|
618 break;
|
Chris@16
|
619 }
|
Chris@16
|
620 }
|
Chris@16
|
621 }
|
Chris@16
|
622 }
|
Chris@16
|
623 //find any pairs of incoming edges that need to create pair for leading solid
|
Chris@16
|
624 //std::cout << "checking case2\n";
|
Chris@16
|
625 for(int i = 0; i < 3; ++i) {
|
Chris@16
|
626 //std::cout << i << "\n";
|
Chris@16
|
627 if(incoming[i] == 1) {
|
Chris@16
|
628 //std::cout << "fixed i\n";
|
Chris@16
|
629 for(int j = i + 1; j < 4; ++j) {
|
Chris@16
|
630 //std::cout << j << "\n";
|
Chris@16
|
631 if(incoming[j]) {
|
Chris@16
|
632 if(incoming[j] == -1) {
|
Chris@16
|
633 //std::cout << "case2: " << i << " " << j << "\n";
|
Chris@16
|
634 //std::cout << "creating active tail pair\n";
|
Chris@16
|
635 std::pair<ActiveTail45*, ActiveTail45*> tailPair =
|
Chris@16
|
636 ActiveTail45::createActiveTail45sAsPair(point, true, 0, fractureHoles_ != 0);
|
Chris@16
|
637 //tailPair.first->print();
|
Chris@16
|
638 //tailPair.second->print();
|
Chris@16
|
639 if(j == 3) {
|
Chris@16
|
640 //vertical active tail becomes return value
|
Chris@16
|
641 returnValue = tailPair.first;
|
Chris@16
|
642 returnCount = 1;
|
Chris@16
|
643 } else {
|
Chris@16
|
644 Vertex45 vertex(point, i -1, incoming[i]);
|
Chris@16
|
645 //std::cout << "new element " << j-1 << " " << -1 << "\n";
|
Chris@16
|
646 elements.push_back(std::pair<Vertex45, ActiveTail45*>(Vertex45(point, j -1, -1), tailPair.first));
|
Chris@16
|
647 }
|
Chris@16
|
648 //std::cout << "new element " << i-1 << " " << 1 << "\n";
|
Chris@16
|
649 elements.push_back(std::pair<Vertex45, ActiveTail45*>(Vertex45(point, i -1, 1), tailPair.second));
|
Chris@16
|
650 incoming[i] = 0;
|
Chris@16
|
651 incoming[j] = 0;
|
Chris@16
|
652 }
|
Chris@16
|
653 break;
|
Chris@16
|
654 }
|
Chris@16
|
655 }
|
Chris@16
|
656 }
|
Chris@16
|
657 }
|
Chris@16
|
658
|
Chris@16
|
659 //find any active tail that needs to pass through to an incoming edge
|
Chris@16
|
660 //we expect to find no more than two pass through
|
Chris@16
|
661
|
Chris@16
|
662 //find pass through with solid on top
|
Chris@16
|
663 //std::cout << "checking case 3\n";
|
Chris@16
|
664 for(int i = 0; i < 4; ++i) {
|
Chris@16
|
665 //std::cout << i << "\n";
|
Chris@16
|
666 if(counts[i] != 0) {
|
Chris@16
|
667 if(counts[i] == 1) {
|
Chris@16
|
668 //std::cout << "fixed i\n";
|
Chris@16
|
669 for(int j = 3; j >= 0; --j) {
|
Chris@16
|
670 if(incoming[j] != 0) {
|
Chris@16
|
671 if(incoming[j] == 1) {
|
Chris@16
|
672 //std::cout << "case3: " << i << " " << j << "\n";
|
Chris@16
|
673 //tails[i]->print();
|
Chris@16
|
674 //pass through solid on top
|
Chris@16
|
675 tails[i]->pushPoint(point);
|
Chris@16
|
676 //std::cout << "after push\n";
|
Chris@16
|
677 if(j == 3) {
|
Chris@16
|
678 returnValue = tails[i];
|
Chris@16
|
679 returnCount = -1;
|
Chris@16
|
680 } else {
|
Chris@16
|
681 elements.push_back(std::pair<Vertex45, ActiveTail45*>(Vertex45(point, j -1, incoming[j]), tails[i]));
|
Chris@16
|
682 }
|
Chris@16
|
683 tails[i] = 0;
|
Chris@16
|
684 counts[i] = 0;
|
Chris@16
|
685 incoming[j] = 0;
|
Chris@16
|
686 }
|
Chris@16
|
687 break;
|
Chris@16
|
688 }
|
Chris@16
|
689 }
|
Chris@16
|
690 }
|
Chris@16
|
691 break;
|
Chris@16
|
692 }
|
Chris@16
|
693 }
|
Chris@16
|
694 //std::cout << "checking case 4\n";
|
Chris@16
|
695 //find pass through with solid on bottom
|
Chris@16
|
696 for(int i = 3; i >= 0; --i) {
|
Chris@16
|
697 if(counts[i] != 0) {
|
Chris@16
|
698 if(counts[i] == -1) {
|
Chris@16
|
699 for(int j = 0; j < 4; ++j) {
|
Chris@16
|
700 if(incoming[j] != 0) {
|
Chris@16
|
701 if(incoming[j] == -1) {
|
Chris@16
|
702 //std::cout << "case4: " << i << " " << j << "\n";
|
Chris@16
|
703 //pass through solid on bottom
|
Chris@16
|
704 tails[i]->pushPoint(point);
|
Chris@16
|
705 if(j == 3) {
|
Chris@16
|
706 returnValue = tails[i];
|
Chris@16
|
707 returnCount = 1;
|
Chris@16
|
708 } else {
|
Chris@16
|
709 //std::cout << "new element " << j-1 << " " << incoming[j] << "\n";
|
Chris@16
|
710 elements.push_back(std::pair<Vertex45, ActiveTail45*>(Vertex45(point, j -1, incoming[j]), tails[i]));
|
Chris@16
|
711 }
|
Chris@16
|
712 tails[i] = 0;
|
Chris@16
|
713 counts[i] = 0;
|
Chris@16
|
714 incoming[j] = 0;
|
Chris@16
|
715 }
|
Chris@16
|
716 break;
|
Chris@16
|
717 }
|
Chris@16
|
718 }
|
Chris@16
|
719 }
|
Chris@16
|
720 break;
|
Chris@16
|
721 }
|
Chris@16
|
722 }
|
Chris@16
|
723
|
Chris@16
|
724 //find the end of a hole or the beginning of a hole
|
Chris@16
|
725
|
Chris@16
|
726 //find end of a hole
|
Chris@16
|
727 for(int i = 0; i < 3; ++i) {
|
Chris@16
|
728 if(counts[i] != 0) {
|
Chris@16
|
729 for(int j = i+1; j < 4; ++j) {
|
Chris@16
|
730 if(counts[j] != 0) {
|
Chris@16
|
731 //std::cout << "case5: " << i << " " << j << "\n";
|
Chris@16
|
732 //we are ending a hole and may potentially close a figure and have to handle the hole
|
Chris@16
|
733 returnValue = ActiveTail45::joinChains(point, tails[i], tails[j], false, output);
|
Chris@16
|
734 tails[i] = 0;
|
Chris@16
|
735 tails[j] = 0;
|
Chris@16
|
736 counts[i] = 0;
|
Chris@16
|
737 counts[j] = 0;
|
Chris@16
|
738 break;
|
Chris@16
|
739 }
|
Chris@16
|
740 }
|
Chris@16
|
741 break;
|
Chris@16
|
742 }
|
Chris@16
|
743 }
|
Chris@16
|
744 //find beginning of a hole
|
Chris@16
|
745 for(int i = 0; i < 3; ++i) {
|
Chris@16
|
746 if(incoming[i] != 0) {
|
Chris@16
|
747 for(int j = i+1; j < 4; ++j) {
|
Chris@16
|
748 if(incoming[j] != 0) {
|
Chris@16
|
749 //std::cout << "case6: " << i << " " << j << "\n";
|
Chris@16
|
750 //we are beginning a empty space
|
Chris@16
|
751 ActiveTail45* holep = 0;
|
Chris@16
|
752 if(counts[3] == 0) holep = tails[3];
|
Chris@16
|
753 std::pair<ActiveTail45*, ActiveTail45*> tailPair =
|
Chris@16
|
754 ActiveTail45::createActiveTail45sAsPair(point, false, holep, fractureHoles_ != 0);
|
Chris@16
|
755 if(j == 3) {
|
Chris@16
|
756 returnValue = tailPair.first;
|
Chris@16
|
757 returnCount = -1;
|
Chris@16
|
758 } else {
|
Chris@16
|
759 //std::cout << "new element " << j-1 << " " << incoming[j] << "\n";
|
Chris@16
|
760 elements.push_back(std::pair<Vertex45, ActiveTail45*>(Vertex45(point, j -1, incoming[j]), tailPair.first));
|
Chris@16
|
761 }
|
Chris@16
|
762 //std::cout << "new element " << i-1 << " " << incoming[i] << "\n";
|
Chris@16
|
763 elements.push_back(std::pair<Vertex45, ActiveTail45*>(Vertex45(point, i -1, incoming[i]), tailPair.second));
|
Chris@16
|
764 incoming[i] = 0;
|
Chris@16
|
765 incoming[j] = 0;
|
Chris@16
|
766 break;
|
Chris@16
|
767 }
|
Chris@16
|
768 }
|
Chris@16
|
769 break;
|
Chris@16
|
770 }
|
Chris@16
|
771 }
|
Chris@16
|
772 //assert that tails, counts and incoming are all null
|
Chris@16
|
773 return std::pair<int, ActiveTail45*>(returnCount, returnValue);
|
Chris@16
|
774 }
|
Chris@16
|
775
|
Chris@16
|
776 template <class cT, class iT>
|
Chris@16
|
777 inline iT processEvent_(cT& output, iT inputBegin, iT inputEnd) {
|
Chris@16
|
778 //std::cout << "processEvent_\n";
|
Chris@16
|
779 justBefore_ = true;
|
Chris@16
|
780 //collect up all elements from the tree that are at the y
|
Chris@16
|
781 //values of events in the input queue
|
Chris@16
|
782 //create vector of new elements to add into tree
|
Chris@16
|
783 ActiveTail45* verticalTail = 0;
|
Chris@16
|
784 int verticalCount = 0;
|
Chris@16
|
785 iT currentIter = inputBegin;
|
Chris@16
|
786 std::vector<iterator> elementIters;
|
Chris@16
|
787 std::vector<std::pair<Vertex45, ActiveTail45*> > elements;
|
Chris@16
|
788 while(currentIter != inputEnd && currentIter->pt.x() == x_) {
|
Chris@16
|
789 //std::cout << "loop\n";
|
Chris@16
|
790 Unit currentY = (*currentIter).pt.y();
|
Chris@16
|
791 iterator iter = lookUp_(currentY);
|
Chris@16
|
792 //int counts[4] = {0, 0, 0, 0};
|
Chris@16
|
793 Vertex45Count counts;
|
Chris@16
|
794 ActiveTail45* tails[4] = {0, 0, 0, verticalTail};
|
Chris@16
|
795 //std::cout << "finding elements in tree\n";
|
Chris@16
|
796 while(iter != scanData_.end() &&
|
Chris@16
|
797 iter->first.evalAtX(x_) == currentY) {
|
Chris@16
|
798 //std::cout << "loop2\n";
|
Chris@16
|
799 elementIters.push_back(iter);
|
Chris@16
|
800 int index = iter->first.rise + 1;
|
Chris@16
|
801 //std::cout << index << " " << iter->first.count << "\n";
|
Chris@16
|
802 counts[index] = iter->first.count;
|
Chris@16
|
803 tails[index] = iter->second;
|
Chris@16
|
804 ++iter;
|
Chris@16
|
805 }
|
Chris@16
|
806 //int incoming[4] = {0, 0, 0, 0};
|
Chris@16
|
807 Vertex45Count incoming;
|
Chris@16
|
808 //std::cout << "aggregating\n";
|
Chris@16
|
809 do {
|
Chris@16
|
810 //std::cout << "loop3\n";
|
Chris@16
|
811 Vertex45Compact currentVertex(*currentIter);
|
Chris@16
|
812 incoming += currentVertex.count;
|
Chris@16
|
813 ++currentIter;
|
Chris@16
|
814 } while(currentIter != inputEnd && currentIter->pt.y() == currentY &&
|
Chris@16
|
815 currentIter->pt.x() == x_);
|
Chris@16
|
816 //now counts and tails have the data from the left and
|
Chris@16
|
817 //incoming has the data from the right at this point
|
Chris@16
|
818 //cancel out any end points
|
Chris@16
|
819 //std::cout << counts[0] << " ";
|
Chris@16
|
820 //std::cout << counts[1] << " ";
|
Chris@16
|
821 //std::cout << counts[2] << " ";
|
Chris@16
|
822 //std::cout << counts[3] << "\n";
|
Chris@16
|
823 //std::cout << incoming[0] << " ";
|
Chris@16
|
824 //std::cout << incoming[1] << " ";
|
Chris@16
|
825 //std::cout << incoming[2] << " ";
|
Chris@16
|
826 //std::cout << incoming[3] << "\n";
|
Chris@16
|
827 if(verticalTail) {
|
Chris@16
|
828 counts[3] = -verticalCount;
|
Chris@16
|
829 }
|
Chris@16
|
830 incoming[3] *= -1;
|
Chris@16
|
831 for(unsigned int i = 0; i < 4; ++i) incoming[i] += counts[i];
|
Chris@16
|
832 //std::cout << "calling processPoint_\n";
|
Chris@16
|
833 std::pair<int, ActiveTail45*> result = processPoint_(output, elements, Point(x_, currentY), counts, tails, incoming);
|
Chris@16
|
834 verticalCount = result.first;
|
Chris@16
|
835 verticalTail = result.second;
|
Chris@16
|
836 //if(verticalTail) std::cout << "have vertical tail\n";
|
Chris@16
|
837 //std::cout << "verticalCount: " << verticalCount << "\n";
|
Chris@16
|
838 if(verticalTail && !verticalCount) {
|
Chris@16
|
839 //we got a hole out of the point we just processed
|
Chris@16
|
840 //iter is still at the next y element above the current y value in the tree
|
Chris@16
|
841 //std::cout << "checking whether ot handle hole\n";
|
Chris@16
|
842 if(currentIter == inputEnd ||
|
Chris@16
|
843 currentIter->pt.x() != x_ ||
|
Chris@16
|
844 currentIter->pt.y() >= iter->first.evalAtX(x_)) {
|
Chris@16
|
845 //std::cout << "handle hole here\n";
|
Chris@16
|
846 if(fractureHoles_) {
|
Chris@16
|
847 //std::cout << "fracture hole here\n";
|
Chris@16
|
848 //we need to handle the hole now and not at the next input vertex
|
Chris@16
|
849 ActiveTail45* at = iter->second;
|
Chris@16
|
850 Point point(x_, iter->first.evalAtX(x_));
|
Chris@16
|
851 verticalTail->getOtherActiveTail()->pushPoint(point);
|
Chris@16
|
852 iter->second = verticalTail->getOtherActiveTail();
|
Chris@16
|
853 at->pushPoint(point);
|
Chris@16
|
854 verticalTail->join(at);
|
Chris@16
|
855 delete at;
|
Chris@16
|
856 delete verticalTail;
|
Chris@16
|
857 verticalTail = 0;
|
Chris@16
|
858 } else {
|
Chris@16
|
859 //std::cout << "push hole onto list\n";
|
Chris@16
|
860 iter->second->addHole(verticalTail);
|
Chris@16
|
861 verticalTail = 0;
|
Chris@16
|
862 }
|
Chris@16
|
863 }
|
Chris@16
|
864 }
|
Chris@16
|
865 }
|
Chris@16
|
866 //std::cout << "erasing\n";
|
Chris@16
|
867 //erase all elements from the tree
|
Chris@16
|
868 for(typename std::vector<iterator>::iterator iter = elementIters.begin();
|
Chris@16
|
869 iter != elementIters.end(); ++iter) {
|
Chris@16
|
870 //std::cout << "erasing loop\n";
|
Chris@16
|
871 scanData_.erase(*iter);
|
Chris@16
|
872 }
|
Chris@16
|
873 //switch comparison tie breaking policy
|
Chris@16
|
874 justBefore_ = false;
|
Chris@16
|
875 //add new elements into tree
|
Chris@16
|
876 //std::cout << "inserting\n";
|
Chris@16
|
877 for(typename std::vector<std::pair<Vertex45, ActiveTail45*> >::iterator iter = elements.begin();
|
Chris@16
|
878 iter != elements.end(); ++iter) {
|
Chris@16
|
879 //std::cout << "inserting loop\n";
|
Chris@16
|
880 scanData_.insert(scanData_.end(), *iter);
|
Chris@16
|
881 }
|
Chris@16
|
882 //std::cout << "end processEvent\n";
|
Chris@16
|
883 return currentIter;
|
Chris@16
|
884 }
|
Chris@16
|
885
|
Chris@16
|
886 inline iterator lookUp_(Unit y){
|
Chris@16
|
887 //if just before then we need to look from 1 not -1
|
Chris@16
|
888 return scanData_.lower_bound(Vertex45(Point(x_, y), -1+2*justBefore_, 0));
|
Chris@16
|
889 }
|
Chris@16
|
890
|
Chris@16
|
891 };
|
Chris@16
|
892
|
Chris@16
|
893 template <typename stream_type>
|
Chris@16
|
894 static inline bool testPolygon45FormationRect(stream_type& stdcout) {
|
Chris@16
|
895 stdcout << "testing polygon formation\n";
|
Chris@16
|
896 Polygon45Formation pf(true);
|
Chris@16
|
897 std::vector<Polygon45> polys;
|
Chris@16
|
898 std::vector<Vertex45> data;
|
Chris@16
|
899 data.push_back(Vertex45(Point(0, 0), 0, 1));
|
Chris@16
|
900 data.push_back(Vertex45(Point(0, 0), 2, 1));
|
Chris@16
|
901 data.push_back(Vertex45(Point(0, 10), 2, -1));
|
Chris@16
|
902 data.push_back(Vertex45(Point(0, 10), 0, -1));
|
Chris@16
|
903 data.push_back(Vertex45(Point(10, 0), 0, -1));
|
Chris@16
|
904 data.push_back(Vertex45(Point(10, 0), 2, -1));
|
Chris@16
|
905 data.push_back(Vertex45(Point(10, 10), 2, 1));
|
Chris@16
|
906 data.push_back(Vertex45(Point(10, 10), 0, 1));
|
Chris@16
|
907 polygon_sort(data.begin(), data.end());
|
Chris@16
|
908 pf.scan(polys, data.begin(), data.end());
|
Chris@16
|
909 stdcout << "result size: " << polys.size() << "\n";
|
Chris@16
|
910 for(std::size_t i = 0; i < polys.size(); ++i) {
|
Chris@16
|
911 stdcout << polys[i] << "\n";
|
Chris@16
|
912 }
|
Chris@16
|
913 stdcout << "done testing polygon formation\n";
|
Chris@16
|
914 return true;
|
Chris@16
|
915 }
|
Chris@16
|
916
|
Chris@16
|
917 template <typename stream_type>
|
Chris@16
|
918 static inline bool testPolygon45FormationP1(stream_type& stdcout) {
|
Chris@16
|
919 stdcout << "testing polygon formation\n";
|
Chris@16
|
920 Polygon45Formation pf(true);
|
Chris@16
|
921 std::vector<Polygon45> polys;
|
Chris@16
|
922 std::vector<Vertex45> data;
|
Chris@16
|
923 data.push_back(Vertex45(Point(0, 0), 1, 1));
|
Chris@16
|
924 data.push_back(Vertex45(Point(0, 0), 2, 1));
|
Chris@16
|
925 data.push_back(Vertex45(Point(0, 10), 2, -1));
|
Chris@16
|
926 data.push_back(Vertex45(Point(0, 10), 1, -1));
|
Chris@16
|
927 data.push_back(Vertex45(Point(10, 10), 1, -1));
|
Chris@16
|
928 data.push_back(Vertex45(Point(10, 10), 2, -1));
|
Chris@16
|
929 data.push_back(Vertex45(Point(10, 20), 2, 1));
|
Chris@16
|
930 data.push_back(Vertex45(Point(10, 20), 1, 1));
|
Chris@16
|
931 polygon_sort(data.begin(), data.end());
|
Chris@16
|
932 pf.scan(polys, data.begin(), data.end());
|
Chris@16
|
933 stdcout << "result size: " << polys.size() << "\n";
|
Chris@16
|
934 for(std::size_t i = 0; i < polys.size(); ++i) {
|
Chris@16
|
935 stdcout << polys[i] << "\n";
|
Chris@16
|
936 }
|
Chris@16
|
937 stdcout << "done testing polygon formation\n";
|
Chris@16
|
938 return true;
|
Chris@16
|
939 }
|
Chris@16
|
940 //polygon45set class
|
Chris@16
|
941
|
Chris@16
|
942 template <typename stream_type>
|
Chris@16
|
943 static inline bool testPolygon45FormationP2(stream_type& stdcout) {
|
Chris@16
|
944 stdcout << "testing polygon formation\n";
|
Chris@16
|
945 Polygon45Formation pf(true);
|
Chris@16
|
946 std::vector<Polygon45> polys;
|
Chris@16
|
947 std::vector<Vertex45> data;
|
Chris@16
|
948 data.push_back(Vertex45(Point(0, 0), 0, 1));
|
Chris@16
|
949 data.push_back(Vertex45(Point(0, 0), 1, -1));
|
Chris@16
|
950 data.push_back(Vertex45(Point(10, 0), 0, -1));
|
Chris@16
|
951 data.push_back(Vertex45(Point(10, 0), 1, 1));
|
Chris@16
|
952 data.push_back(Vertex45(Point(10, 10), 1, 1));
|
Chris@16
|
953 data.push_back(Vertex45(Point(10, 10), 0, -1));
|
Chris@16
|
954 data.push_back(Vertex45(Point(20, 10), 1, -1));
|
Chris@16
|
955 data.push_back(Vertex45(Point(20, 10), 0, 1));
|
Chris@16
|
956 polygon_sort(data.begin(), data.end());
|
Chris@16
|
957 pf.scan(polys, data.begin(), data.end());
|
Chris@16
|
958 stdcout << "result size: " << polys.size() << "\n";
|
Chris@16
|
959 for(std::size_t i = 0; i < polys.size(); ++i) {
|
Chris@16
|
960 stdcout << polys[i] << "\n";
|
Chris@16
|
961 }
|
Chris@16
|
962 stdcout << "done testing polygon formation\n";
|
Chris@16
|
963 return true;
|
Chris@16
|
964 }
|
Chris@16
|
965 //polygon45set class
|
Chris@16
|
966
|
Chris@16
|
967 template <typename stream_type>
|
Chris@16
|
968 static inline bool testPolygon45FormationStar1(stream_type& stdcout) {
|
Chris@16
|
969 stdcout << "testing polygon formation\n";
|
Chris@16
|
970 Polygon45Formation pf(true);
|
Chris@16
|
971 std::vector<Polygon45> polys;
|
Chris@16
|
972 std::vector<Vertex45> data;
|
Chris@16
|
973 // result == 0 8 -1 1
|
Chris@16
|
974 data.push_back(Vertex45(Point(0, 8), -1, 1));
|
Chris@16
|
975 // result == 0 8 1 -1
|
Chris@16
|
976 data.push_back(Vertex45(Point(0, 8), 1, -1));
|
Chris@16
|
977 // result == 4 0 1 1
|
Chris@16
|
978 data.push_back(Vertex45(Point(4, 0), 1, 1));
|
Chris@16
|
979 // result == 4 0 2 1
|
Chris@16
|
980 data.push_back(Vertex45(Point(4, 0), 2, 1));
|
Chris@16
|
981 // result == 4 4 2 -1
|
Chris@16
|
982 data.push_back(Vertex45(Point(4, 4), 2, -1));
|
Chris@16
|
983 // result == 4 4 -1 -1
|
Chris@16
|
984 data.push_back(Vertex45(Point(4, 4), -1, -1));
|
Chris@16
|
985 // result == 4 12 1 1
|
Chris@16
|
986 data.push_back(Vertex45(Point(4, 12), 1, 1));
|
Chris@16
|
987 // result == 4 12 2 1
|
Chris@16
|
988 data.push_back(Vertex45(Point(4, 12), 2, 1));
|
Chris@16
|
989 // result == 4 16 2 -1
|
Chris@16
|
990 data.push_back(Vertex45(Point(4, 16), 2, 1));
|
Chris@16
|
991 // result == 4 16 -1 -1
|
Chris@16
|
992 data.push_back(Vertex45(Point(4, 16), -1, -1));
|
Chris@16
|
993 // result == 6 2 1 -1
|
Chris@16
|
994 data.push_back(Vertex45(Point(6, 2), 1, -1));
|
Chris@16
|
995 // result == 6 14 -1 1
|
Chris@16
|
996 data.push_back(Vertex45(Point(6, 14), -1, 1));
|
Chris@16
|
997 // result == 6 2 -1 1
|
Chris@16
|
998 data.push_back(Vertex45(Point(6, 2), -1, 1));
|
Chris@16
|
999 // result == 6 14 1 -1
|
Chris@16
|
1000 data.push_back(Vertex45(Point(6, 14), 1, -1));
|
Chris@16
|
1001 // result == 8 0 -1 -1
|
Chris@16
|
1002 data.push_back(Vertex45(Point(8, 0), -1, -1));
|
Chris@16
|
1003 // result == 8 0 2 -1
|
Chris@16
|
1004 data.push_back(Vertex45(Point(8, 0), 2, -1));
|
Chris@16
|
1005 // result == 8 4 2 1
|
Chris@16
|
1006 data.push_back(Vertex45(Point(8, 4), 2, 1));
|
Chris@16
|
1007 // result == 8 4 1 1
|
Chris@16
|
1008 data.push_back(Vertex45(Point(8, 4), 1, 1));
|
Chris@16
|
1009 // result == 8 12 -1 -1
|
Chris@16
|
1010 data.push_back(Vertex45(Point(8, 12), -1, -1));
|
Chris@16
|
1011 // result == 8 12 2 -1
|
Chris@16
|
1012 data.push_back(Vertex45(Point(8, 12), 2, -1));
|
Chris@16
|
1013 // result == 8 16 2 1
|
Chris@16
|
1014 data.push_back(Vertex45(Point(8, 16), 2, 1));
|
Chris@16
|
1015 // result == 8 16 1 1
|
Chris@16
|
1016 data.push_back(Vertex45(Point(8, 16), 1, 1));
|
Chris@16
|
1017 // result == 12 8 1 -1
|
Chris@16
|
1018 data.push_back(Vertex45(Point(12, 8), 1, -1));
|
Chris@16
|
1019 // result == 12 8 -1 1
|
Chris@16
|
1020 data.push_back(Vertex45(Point(12, 8), -1, 1));
|
Chris@16
|
1021 polygon_sort(data.begin(), data.end());
|
Chris@16
|
1022 pf.scan(polys, data.begin(), data.end());
|
Chris@16
|
1023 stdcout << "result size: " << polys.size() << "\n";
|
Chris@16
|
1024 for(std::size_t i = 0; i < polys.size(); ++i) {
|
Chris@16
|
1025 stdcout << polys[i] << "\n";
|
Chris@16
|
1026 }
|
Chris@16
|
1027 stdcout << "done testing polygon formation\n";
|
Chris@16
|
1028 return true;
|
Chris@16
|
1029 }
|
Chris@16
|
1030
|
Chris@16
|
1031 template <typename stream_type>
|
Chris@16
|
1032 static inline bool testPolygon45FormationStar2(stream_type& stdcout) {
|
Chris@16
|
1033 stdcout << "testing polygon formation\n";
|
Chris@16
|
1034 Polygon45Formation pf(true);
|
Chris@16
|
1035 std::vector<Polygon45> polys;
|
Chris@16
|
1036 Scan45 scan45;
|
Chris@16
|
1037 std::vector<Vertex45 > result;
|
Chris@16
|
1038 std::vector<Scan45Vertex> vertices;
|
Chris@16
|
1039 //is a Rectnagle(0, 0, 10, 10);
|
Chris@16
|
1040 Count2 count(1, 0);
|
Chris@16
|
1041 Count2 ncount(-1, 0);
|
Chris@16
|
1042 vertices.push_back(Scan45Vertex(Point(0,4), Scan45Count(Count2(0, 0), count, ncount, Count2(0, 0))));
|
Chris@16
|
1043 vertices.push_back(Scan45Vertex(Point(16,4), Scan45Count(count, ncount, Count2(0, 0), Count2(0, 0))));
|
Chris@16
|
1044 vertices.push_back(Scan45Vertex(Point(8,12), Scan45Count(ncount, Count2(0, 0), count, Count2(0, 0))));
|
Chris@16
|
1045 count = Count2(0, 1);
|
Chris@16
|
1046 ncount = count.invert();
|
Chris@16
|
1047 vertices.push_back(Scan45Vertex(Point(0,8), Scan45Count(count, ncount, Count2(0, 0), Count2(0, 0))));
|
Chris@16
|
1048 vertices.push_back(Scan45Vertex(Point(16,8), Scan45Count(Count2(0, 0), count, ncount, Count2(0, 0))));
|
Chris@16
|
1049 vertices.push_back(Scan45Vertex(Point(8,0), Scan45Count(ncount, Count2(0, 0), count, Count2(0, 0))));
|
Chris@16
|
1050 sortScan45Vector(vertices);
|
Chris@16
|
1051 stdcout << "scanning\n";
|
Chris@16
|
1052 scan45.scan(result, vertices.begin(), vertices.end());
|
Chris@16
|
1053
|
Chris@16
|
1054 polygon_sort(result.begin(), result.end());
|
Chris@16
|
1055 pf.scan(polys, result.begin(), result.end());
|
Chris@16
|
1056 stdcout << "result size: " << polys.size() << "\n";
|
Chris@16
|
1057 for(std::size_t i = 0; i < polys.size(); ++i) {
|
Chris@16
|
1058 stdcout << polys[i] << "\n";
|
Chris@16
|
1059 }
|
Chris@16
|
1060 stdcout << "done testing polygon formation\n";
|
Chris@16
|
1061 return true;
|
Chris@16
|
1062 }
|
Chris@16
|
1063
|
Chris@16
|
1064 template <typename stream_type>
|
Chris@16
|
1065 static inline bool testPolygon45FormationStarHole1(stream_type& stdcout) {
|
Chris@16
|
1066 stdcout << "testing polygon formation\n";
|
Chris@16
|
1067 Polygon45Formation pf(true);
|
Chris@16
|
1068 std::vector<Polygon45> polys;
|
Chris@16
|
1069 std::vector<Vertex45> data;
|
Chris@16
|
1070 // result == 0 8 -1 1
|
Chris@16
|
1071 data.push_back(Vertex45(Point(0, 8), -1, 1));
|
Chris@16
|
1072 // result == 0 8 1 -1
|
Chris@16
|
1073 data.push_back(Vertex45(Point(0, 8), 1, -1));
|
Chris@16
|
1074 // result == 4 0 1 1
|
Chris@16
|
1075 data.push_back(Vertex45(Point(4, 0), 1, 1));
|
Chris@16
|
1076 // result == 4 0 2 1
|
Chris@16
|
1077 data.push_back(Vertex45(Point(4, 0), 2, 1));
|
Chris@16
|
1078 // result == 4 4 2 -1
|
Chris@16
|
1079 data.push_back(Vertex45(Point(4, 4), 2, -1));
|
Chris@16
|
1080 // result == 4 4 -1 -1
|
Chris@16
|
1081 data.push_back(Vertex45(Point(4, 4), -1, -1));
|
Chris@16
|
1082 // result == 4 12 1 1
|
Chris@16
|
1083 data.push_back(Vertex45(Point(4, 12), 1, 1));
|
Chris@16
|
1084 // result == 4 12 2 1
|
Chris@16
|
1085 data.push_back(Vertex45(Point(4, 12), 2, 1));
|
Chris@16
|
1086 // result == 4 16 2 -1
|
Chris@16
|
1087 data.push_back(Vertex45(Point(4, 16), 2, 1));
|
Chris@16
|
1088 // result == 4 16 -1 -1
|
Chris@16
|
1089 data.push_back(Vertex45(Point(4, 16), -1, -1));
|
Chris@16
|
1090 // result == 6 2 1 -1
|
Chris@16
|
1091 data.push_back(Vertex45(Point(6, 2), 1, -1));
|
Chris@16
|
1092 // result == 6 14 -1 1
|
Chris@16
|
1093 data.push_back(Vertex45(Point(6, 14), -1, 1));
|
Chris@16
|
1094 // result == 6 2 -1 1
|
Chris@16
|
1095 data.push_back(Vertex45(Point(6, 2), -1, 1));
|
Chris@16
|
1096 // result == 6 14 1 -1
|
Chris@16
|
1097 data.push_back(Vertex45(Point(6, 14), 1, -1));
|
Chris@16
|
1098 // result == 8 0 -1 -1
|
Chris@16
|
1099 data.push_back(Vertex45(Point(8, 0), -1, -1));
|
Chris@16
|
1100 // result == 8 0 2 -1
|
Chris@16
|
1101 data.push_back(Vertex45(Point(8, 0), 2, -1));
|
Chris@16
|
1102 // result == 8 4 2 1
|
Chris@16
|
1103 data.push_back(Vertex45(Point(8, 4), 2, 1));
|
Chris@16
|
1104 // result == 8 4 1 1
|
Chris@16
|
1105 data.push_back(Vertex45(Point(8, 4), 1, 1));
|
Chris@16
|
1106 // result == 8 12 -1 -1
|
Chris@16
|
1107 data.push_back(Vertex45(Point(8, 12), -1, -1));
|
Chris@16
|
1108 // result == 8 12 2 -1
|
Chris@16
|
1109 data.push_back(Vertex45(Point(8, 12), 2, -1));
|
Chris@16
|
1110 // result == 8 16 2 1
|
Chris@16
|
1111 data.push_back(Vertex45(Point(8, 16), 2, 1));
|
Chris@16
|
1112 // result == 8 16 1 1
|
Chris@16
|
1113 data.push_back(Vertex45(Point(8, 16), 1, 1));
|
Chris@16
|
1114 // result == 12 8 1 -1
|
Chris@16
|
1115 data.push_back(Vertex45(Point(12, 8), 1, -1));
|
Chris@16
|
1116 // result == 12 8 -1 1
|
Chris@16
|
1117 data.push_back(Vertex45(Point(12, 8), -1, 1));
|
Chris@16
|
1118
|
Chris@16
|
1119 data.push_back(Vertex45(Point(6, 4), 1, -1));
|
Chris@16
|
1120 data.push_back(Vertex45(Point(6, 4), 2, -1));
|
Chris@16
|
1121 data.push_back(Vertex45(Point(6, 8), -1, 1));
|
Chris@16
|
1122 data.push_back(Vertex45(Point(6, 8), 2, 1));
|
Chris@16
|
1123 data.push_back(Vertex45(Point(8, 6), -1, -1));
|
Chris@16
|
1124 data.push_back(Vertex45(Point(8, 6), 1, 1));
|
Chris@16
|
1125
|
Chris@16
|
1126 polygon_sort(data.begin(), data.end());
|
Chris@16
|
1127 pf.scan(polys, data.begin(), data.end());
|
Chris@16
|
1128 stdcout << "result size: " << polys.size() << "\n";
|
Chris@16
|
1129 for(std::size_t i = 0; i < polys.size(); ++i) {
|
Chris@16
|
1130 stdcout << polys[i] << "\n";
|
Chris@16
|
1131 }
|
Chris@16
|
1132 stdcout << "done testing polygon formation\n";
|
Chris@16
|
1133 return true;
|
Chris@16
|
1134 }
|
Chris@16
|
1135
|
Chris@16
|
1136 template <typename stream_type>
|
Chris@16
|
1137 static inline bool testPolygon45FormationStarHole2(stream_type& stdcout) {
|
Chris@16
|
1138 stdcout << "testing polygon formation\n";
|
Chris@16
|
1139 Polygon45Formation pf(false);
|
Chris@16
|
1140 std::vector<Polygon45WithHoles> polys;
|
Chris@16
|
1141 std::vector<Vertex45> data;
|
Chris@16
|
1142 // result == 0 8 -1 1
|
Chris@16
|
1143 data.push_back(Vertex45(Point(0, 8), -1, 1));
|
Chris@16
|
1144 // result == 0 8 1 -1
|
Chris@16
|
1145 data.push_back(Vertex45(Point(0, 8), 1, -1));
|
Chris@16
|
1146 // result == 4 0 1 1
|
Chris@16
|
1147 data.push_back(Vertex45(Point(4, 0), 1, 1));
|
Chris@16
|
1148 // result == 4 0 2 1
|
Chris@16
|
1149 data.push_back(Vertex45(Point(4, 0), 2, 1));
|
Chris@16
|
1150 // result == 4 4 2 -1
|
Chris@16
|
1151 data.push_back(Vertex45(Point(4, 4), 2, -1));
|
Chris@16
|
1152 // result == 4 4 -1 -1
|
Chris@16
|
1153 data.push_back(Vertex45(Point(4, 4), -1, -1));
|
Chris@16
|
1154 // result == 4 12 1 1
|
Chris@16
|
1155 data.push_back(Vertex45(Point(4, 12), 1, 1));
|
Chris@16
|
1156 // result == 4 12 2 1
|
Chris@16
|
1157 data.push_back(Vertex45(Point(4, 12), 2, 1));
|
Chris@16
|
1158 // result == 4 16 2 -1
|
Chris@16
|
1159 data.push_back(Vertex45(Point(4, 16), 2, 1));
|
Chris@16
|
1160 // result == 4 16 -1 -1
|
Chris@16
|
1161 data.push_back(Vertex45(Point(4, 16), -1, -1));
|
Chris@16
|
1162 // result == 6 2 1 -1
|
Chris@16
|
1163 data.push_back(Vertex45(Point(6, 2), 1, -1));
|
Chris@16
|
1164 // result == 6 14 -1 1
|
Chris@16
|
1165 data.push_back(Vertex45(Point(6, 14), -1, 1));
|
Chris@16
|
1166 // result == 6 2 -1 1
|
Chris@16
|
1167 data.push_back(Vertex45(Point(6, 2), -1, 1));
|
Chris@16
|
1168 // result == 6 14 1 -1
|
Chris@16
|
1169 data.push_back(Vertex45(Point(6, 14), 1, -1));
|
Chris@16
|
1170 // result == 8 0 -1 -1
|
Chris@16
|
1171 data.push_back(Vertex45(Point(8, 0), -1, -1));
|
Chris@16
|
1172 // result == 8 0 2 -1
|
Chris@16
|
1173 data.push_back(Vertex45(Point(8, 0), 2, -1));
|
Chris@16
|
1174 // result == 8 4 2 1
|
Chris@16
|
1175 data.push_back(Vertex45(Point(8, 4), 2, 1));
|
Chris@16
|
1176 // result == 8 4 1 1
|
Chris@16
|
1177 data.push_back(Vertex45(Point(8, 4), 1, 1));
|
Chris@16
|
1178 // result == 8 12 -1 -1
|
Chris@16
|
1179 data.push_back(Vertex45(Point(8, 12), -1, -1));
|
Chris@16
|
1180 // result == 8 12 2 -1
|
Chris@16
|
1181 data.push_back(Vertex45(Point(8, 12), 2, -1));
|
Chris@16
|
1182 // result == 8 16 2 1
|
Chris@16
|
1183 data.push_back(Vertex45(Point(8, 16), 2, 1));
|
Chris@16
|
1184 // result == 8 16 1 1
|
Chris@16
|
1185 data.push_back(Vertex45(Point(8, 16), 1, 1));
|
Chris@16
|
1186 // result == 12 8 1 -1
|
Chris@16
|
1187 data.push_back(Vertex45(Point(12, 8), 1, -1));
|
Chris@16
|
1188 // result == 12 8 -1 1
|
Chris@16
|
1189 data.push_back(Vertex45(Point(12, 8), -1, 1));
|
Chris@16
|
1190
|
Chris@16
|
1191 data.push_back(Vertex45(Point(6, 4), 1, -1));
|
Chris@16
|
1192 data.push_back(Vertex45(Point(6, 4), 2, -1));
|
Chris@16
|
1193 data.push_back(Vertex45(Point(6, 12), -1, 1));
|
Chris@16
|
1194 data.push_back(Vertex45(Point(6, 12), 2, 1));
|
Chris@16
|
1195 data.push_back(Vertex45(Point(10, 8), -1, -1));
|
Chris@16
|
1196 data.push_back(Vertex45(Point(10, 8), 1, 1));
|
Chris@16
|
1197
|
Chris@16
|
1198 polygon_sort(data.begin(), data.end());
|
Chris@16
|
1199 pf.scan(polys, data.begin(), data.end());
|
Chris@16
|
1200 stdcout << "result size: " << polys.size() << "\n";
|
Chris@16
|
1201 for(std::size_t i = 0; i < polys.size(); ++i) {
|
Chris@16
|
1202 stdcout << polys[i] << "\n";
|
Chris@16
|
1203 }
|
Chris@16
|
1204 stdcout << "done testing polygon formation\n";
|
Chris@16
|
1205 return true;
|
Chris@16
|
1206 }
|
Chris@16
|
1207
|
Chris@16
|
1208 template <typename stream_type>
|
Chris@16
|
1209 static inline bool testPolygon45Formation(stream_type& stdcout) {
|
Chris@16
|
1210 stdcout << "testing polygon formation\n";
|
Chris@16
|
1211 Polygon45Formation pf(false);
|
Chris@16
|
1212 std::vector<Polygon45WithHoles> polys;
|
Chris@16
|
1213 std::vector<Vertex45> data;
|
Chris@16
|
1214
|
Chris@16
|
1215 data.push_back(Vertex45(Point(0, 0), 0, 1));
|
Chris@16
|
1216 data.push_back(Vertex45(Point(0, 0), 2, 1));
|
Chris@16
|
1217 data.push_back(Vertex45(Point(0, 100), 2, -1));
|
Chris@16
|
1218 data.push_back(Vertex45(Point(0, 100), 0, -1));
|
Chris@16
|
1219 data.push_back(Vertex45(Point(100, 0), 0, -1));
|
Chris@16
|
1220 data.push_back(Vertex45(Point(100, 0), 2, -1));
|
Chris@16
|
1221 data.push_back(Vertex45(Point(100, 100), 2, 1));
|
Chris@16
|
1222 data.push_back(Vertex45(Point(100, 100), 0, 1));
|
Chris@16
|
1223
|
Chris@16
|
1224 data.push_back(Vertex45(Point(2, 2), 0, -1));
|
Chris@16
|
1225 data.push_back(Vertex45(Point(2, 2), 2, -1));
|
Chris@16
|
1226 data.push_back(Vertex45(Point(2, 10), 2, 1));
|
Chris@16
|
1227 data.push_back(Vertex45(Point(2, 10), 0, 1));
|
Chris@16
|
1228 data.push_back(Vertex45(Point(10, 2), 0, 1));
|
Chris@16
|
1229 data.push_back(Vertex45(Point(10, 2), 2, 1));
|
Chris@16
|
1230 data.push_back(Vertex45(Point(10, 10), 2, -1));
|
Chris@16
|
1231 data.push_back(Vertex45(Point(10, 10), 0, -1));
|
Chris@16
|
1232
|
Chris@16
|
1233 data.push_back(Vertex45(Point(2, 12), 0, -1));
|
Chris@16
|
1234 data.push_back(Vertex45(Point(2, 12), 2, -1));
|
Chris@16
|
1235 data.push_back(Vertex45(Point(2, 22), 2, 1));
|
Chris@16
|
1236 data.push_back(Vertex45(Point(2, 22), 0, 1));
|
Chris@16
|
1237 data.push_back(Vertex45(Point(10, 12), 0, 1));
|
Chris@16
|
1238 data.push_back(Vertex45(Point(10, 12), 2, 1));
|
Chris@16
|
1239 data.push_back(Vertex45(Point(10, 22), 2, -1));
|
Chris@16
|
1240 data.push_back(Vertex45(Point(10, 22), 0, -1));
|
Chris@16
|
1241
|
Chris@16
|
1242 polygon_sort(data.begin(), data.end());
|
Chris@16
|
1243 pf.scan(polys, data.begin(), data.end());
|
Chris@16
|
1244 stdcout << "result size: " << polys.size() << "\n";
|
Chris@16
|
1245 for(std::size_t i = 0; i < polys.size(); ++i) {
|
Chris@16
|
1246 stdcout << polys[i] << "\n";
|
Chris@16
|
1247 }
|
Chris@16
|
1248 stdcout << "done testing polygon formation\n";
|
Chris@16
|
1249 return true;
|
Chris@16
|
1250 }
|
Chris@16
|
1251
|
Chris@16
|
1252
|
Chris@16
|
1253 class Polygon45Tiling {
|
Chris@16
|
1254 private:
|
Chris@16
|
1255 //definitions
|
Chris@16
|
1256 typedef std::map<Vertex45, ActiveTail45*, lessVertex45> Polygon45FormationData;
|
Chris@16
|
1257 typedef typename Polygon45FormationData::iterator iterator;
|
Chris@16
|
1258 typedef typename Polygon45FormationData::const_iterator const_iterator;
|
Chris@16
|
1259
|
Chris@16
|
1260 //data
|
Chris@16
|
1261 Polygon45FormationData scanData_;
|
Chris@16
|
1262 Unit x_;
|
Chris@16
|
1263 int justBefore_;
|
Chris@16
|
1264 public:
|
Chris@16
|
1265 inline Polygon45Tiling() : scanData_(), x_((std::numeric_limits<Unit>::min)()), justBefore_(false) {
|
Chris@16
|
1266 lessVertex45 lessElm(&x_, &justBefore_);
|
Chris@16
|
1267 scanData_ = Polygon45FormationData(lessElm);
|
Chris@16
|
1268 }
|
Chris@16
|
1269 inline Polygon45Tiling(const Polygon45Tiling& that) :
|
Chris@16
|
1270 scanData_(), x_((std::numeric_limits<Unit>::min)()), justBefore_(false) { (*this) = that; }
|
Chris@16
|
1271 inline Polygon45Tiling& operator=(const Polygon45Tiling& that) {
|
Chris@16
|
1272 x_ = that.x_;
|
Chris@16
|
1273 justBefore_ = that.justBefore_;
|
Chris@16
|
1274 lessVertex45 lessElm(&x_, &justBefore_);
|
Chris@16
|
1275 scanData_ = Polygon45FormationData(lessElm);
|
Chris@16
|
1276 for(const_iterator itr = that.scanData_.begin(); itr != that.scanData_.end(); ++itr){
|
Chris@16
|
1277 scanData_.insert(scanData_.end(), *itr);
|
Chris@16
|
1278 }
|
Chris@16
|
1279 return *this;
|
Chris@16
|
1280 }
|
Chris@16
|
1281
|
Chris@16
|
1282 //cT is an output container of Polygon45 or Polygon45WithHoles
|
Chris@16
|
1283 //iT is an iterator over Vertex45 elements
|
Chris@16
|
1284 //inputBegin - inputEnd is a range of sorted iT that represents
|
Chris@16
|
1285 //one or more scanline stops worth of data
|
Chris@16
|
1286 template <class cT, class iT>
|
Chris@16
|
1287 void scan(cT& output, iT inputBegin, iT inputEnd) {
|
Chris@16
|
1288 //std::cout << "1\n";
|
Chris@16
|
1289 while(inputBegin != inputEnd) {
|
Chris@16
|
1290 //std::cout << "2\n";
|
Chris@16
|
1291 x_ = (*inputBegin).pt.x();
|
Chris@16
|
1292 //std::cout << "SCAN FORMATION " << x_ << "\n";
|
Chris@16
|
1293 //std::cout << "x_ = " << x_ << "\n";
|
Chris@16
|
1294 //std::cout << "scan line size: " << scanData_.size() << "\n";
|
Chris@16
|
1295 inputBegin = processEvent_(output, inputBegin, inputEnd);
|
Chris@16
|
1296 }
|
Chris@16
|
1297 }
|
Chris@16
|
1298
|
Chris@16
|
1299 private:
|
Chris@16
|
1300 //functions
|
Chris@16
|
1301
|
Chris@16
|
1302 inline void getVerticalPair_(std::pair<ActiveTail45*, ActiveTail45*>& verticalPair,
|
Chris@16
|
1303 iterator previter) {
|
Chris@16
|
1304 ActiveTail45* iterTail = (*previter).second;
|
Chris@16
|
1305 Point prevPoint(x_, previter->first.evalAtX(x_));
|
Chris@16
|
1306 iterTail->pushPoint(prevPoint);
|
Chris@16
|
1307 std::pair<ActiveTail45*, ActiveTail45*> tailPair =
|
Chris@16
|
1308 ActiveTail45::createActiveTail45sAsPair(prevPoint, true, 0, false);
|
Chris@16
|
1309 verticalPair.first = iterTail;
|
Chris@16
|
1310 verticalPair.second = tailPair.first;
|
Chris@16
|
1311 (*previter).second = tailPair.second;
|
Chris@16
|
1312 }
|
Chris@16
|
1313
|
Chris@16
|
1314 template <class cT, class cT2>
|
Chris@16
|
1315 inline std::pair<int, ActiveTail45*> processPoint_(cT& output, cT2& elements,
|
Chris@16
|
1316 std::pair<ActiveTail45*, ActiveTail45*>& verticalPair,
|
Chris@16
|
1317 iterator previter, Point point,
|
Chris@16
|
1318 Vertex45Count& counts, ActiveTail45** tails, Vertex45Count& incoming) {
|
Chris@16
|
1319 //std::cout << point << "\n";
|
Chris@16
|
1320 //std::cout << counts[0] << " ";
|
Chris@16
|
1321 //std::cout << counts[1] << " ";
|
Chris@16
|
1322 //std::cout << counts[2] << " ";
|
Chris@16
|
1323 //std::cout << counts[3] << "\n";
|
Chris@16
|
1324 //std::cout << incoming[0] << " ";
|
Chris@16
|
1325 //std::cout << incoming[1] << " ";
|
Chris@16
|
1326 //std::cout << incoming[2] << " ";
|
Chris@16
|
1327 //std::cout << incoming[3] << "\n";
|
Chris@16
|
1328 //join any closing solid corners
|
Chris@16
|
1329 ActiveTail45* returnValue = 0;
|
Chris@16
|
1330 std::pair<ActiveTail45*, ActiveTail45*> verticalPairOut;
|
Chris@16
|
1331 verticalPairOut.first = 0;
|
Chris@16
|
1332 verticalPairOut.second = 0;
|
Chris@16
|
1333 int returnCount = 0;
|
Chris@16
|
1334 for(int i = 0; i < 3; ++i) {
|
Chris@16
|
1335 //std::cout << i << "\n";
|
Chris@16
|
1336 if(counts[i] == -1) {
|
Chris@16
|
1337 //std::cout << "fixed i\n";
|
Chris@16
|
1338 for(int j = i + 1; j < 4; ++j) {
|
Chris@16
|
1339 //std::cout << j << "\n";
|
Chris@16
|
1340 if(counts[j]) {
|
Chris@16
|
1341 if(counts[j] == 1) {
|
Chris@16
|
1342 //std::cout << "case1: " << i << " " << j << "\n";
|
Chris@16
|
1343 //if a figure is closed it will be written out by this function to output
|
Chris@16
|
1344 ActiveTail45::joinChains(point, tails[i], tails[j], true, output);
|
Chris@16
|
1345 counts[i] = 0;
|
Chris@16
|
1346 counts[j] = 0;
|
Chris@16
|
1347 tails[i] = 0;
|
Chris@16
|
1348 tails[j] = 0;
|
Chris@16
|
1349 }
|
Chris@16
|
1350 break;
|
Chris@16
|
1351 }
|
Chris@16
|
1352 }
|
Chris@16
|
1353 }
|
Chris@16
|
1354 }
|
Chris@16
|
1355 //find any pairs of incoming edges that need to create pair for leading solid
|
Chris@16
|
1356 //std::cout << "checking case2\n";
|
Chris@16
|
1357 for(int i = 0; i < 3; ++i) {
|
Chris@16
|
1358 //std::cout << i << "\n";
|
Chris@16
|
1359 if(incoming[i] == 1) {
|
Chris@16
|
1360 //std::cout << "fixed i\n";
|
Chris@16
|
1361 for(int j = i + 1; j < 4; ++j) {
|
Chris@16
|
1362 //std::cout << j << "\n";
|
Chris@16
|
1363 if(incoming[j]) {
|
Chris@16
|
1364 if(incoming[j] == -1) {
|
Chris@16
|
1365 //std::cout << "case2: " << i << " " << j << "\n";
|
Chris@16
|
1366 //std::cout << "creating active tail pair\n";
|
Chris@16
|
1367 std::pair<ActiveTail45*, ActiveTail45*> tailPair =
|
Chris@16
|
1368 ActiveTail45::createActiveTail45sAsPair(point, true, 0, false);
|
Chris@16
|
1369 //tailPair.first->print();
|
Chris@16
|
1370 //tailPair.second->print();
|
Chris@16
|
1371 if(j == 3) {
|
Chris@16
|
1372 //vertical active tail becomes return value
|
Chris@16
|
1373 returnValue = tailPair.first;
|
Chris@16
|
1374 returnCount = 1;
|
Chris@16
|
1375 } else {
|
Chris@16
|
1376 Vertex45 vertex(point, i -1, incoming[i]);
|
Chris@16
|
1377 //std::cout << "new element " << j-1 << " " << -1 << "\n";
|
Chris@16
|
1378 elements.push_back(std::pair<Vertex45, ActiveTail45*>(Vertex45(point, j -1, -1), tailPair.first));
|
Chris@16
|
1379 }
|
Chris@16
|
1380 //std::cout << "new element " << i-1 << " " << 1 << "\n";
|
Chris@16
|
1381 elements.push_back(std::pair<Vertex45, ActiveTail45*>(Vertex45(point, i -1, 1), tailPair.second));
|
Chris@16
|
1382 incoming[i] = 0;
|
Chris@16
|
1383 incoming[j] = 0;
|
Chris@16
|
1384 }
|
Chris@16
|
1385 break;
|
Chris@16
|
1386 }
|
Chris@16
|
1387 }
|
Chris@16
|
1388 }
|
Chris@16
|
1389 }
|
Chris@16
|
1390
|
Chris@16
|
1391 //find any active tail that needs to pass through to an incoming edge
|
Chris@16
|
1392 //we expect to find no more than two pass through
|
Chris@16
|
1393
|
Chris@16
|
1394 //find pass through with solid on top
|
Chris@16
|
1395 //std::cout << "checking case 3\n";
|
Chris@16
|
1396 for(int i = 0; i < 4; ++i) {
|
Chris@16
|
1397 //std::cout << i << "\n";
|
Chris@16
|
1398 if(counts[i] != 0) {
|
Chris@16
|
1399 if(counts[i] == 1) {
|
Chris@16
|
1400 //std::cout << "fixed i\n";
|
Chris@16
|
1401 for(int j = 3; j >= 0; --j) {
|
Chris@16
|
1402 if(incoming[j] != 0) {
|
Chris@16
|
1403 if(incoming[j] == 1) {
|
Chris@16
|
1404 //std::cout << "case3: " << i << " " << j << "\n";
|
Chris@16
|
1405 //tails[i]->print();
|
Chris@16
|
1406 //pass through solid on top
|
Chris@16
|
1407 if(i != 3)
|
Chris@16
|
1408 tails[i]->pushPoint(point);
|
Chris@16
|
1409 //std::cout << "after push\n";
|
Chris@16
|
1410 if(j == 3) {
|
Chris@16
|
1411 returnValue = tails[i];
|
Chris@16
|
1412 returnCount = -1;
|
Chris@16
|
1413 } else {
|
Chris@16
|
1414 verticalPairOut.first = tails[i];
|
Chris@16
|
1415 std::pair<ActiveTail45*, ActiveTail45*> tailPair =
|
Chris@16
|
1416 ActiveTail45::createActiveTail45sAsPair(point, true, 0, false);
|
Chris@16
|
1417 verticalPairOut.second = tailPair.first;
|
Chris@16
|
1418 elements.push_back(std::pair<Vertex45, ActiveTail45*>(Vertex45(point, j -1, incoming[j]),
|
Chris@16
|
1419 tailPair.second));
|
Chris@16
|
1420 }
|
Chris@16
|
1421 tails[i] = 0;
|
Chris@16
|
1422 counts[i] = 0;
|
Chris@16
|
1423 incoming[j] = 0;
|
Chris@16
|
1424 }
|
Chris@16
|
1425 break;
|
Chris@16
|
1426 }
|
Chris@16
|
1427 }
|
Chris@16
|
1428 }
|
Chris@16
|
1429 break;
|
Chris@16
|
1430 }
|
Chris@16
|
1431 }
|
Chris@16
|
1432 //std::cout << "checking case 4\n";
|
Chris@16
|
1433 //find pass through with solid on bottom
|
Chris@16
|
1434 for(int i = 3; i >= 0; --i) {
|
Chris@16
|
1435 if(counts[i] != 0) {
|
Chris@16
|
1436 if(counts[i] == -1) {
|
Chris@16
|
1437 for(int j = 0; j < 4; ++j) {
|
Chris@16
|
1438 if(incoming[j] != 0) {
|
Chris@16
|
1439 if(incoming[j] == -1) {
|
Chris@16
|
1440 //std::cout << "case4: " << i << " " << j << "\n";
|
Chris@16
|
1441 //pass through solid on bottom
|
Chris@16
|
1442 if(i == 3) {
|
Chris@16
|
1443 //std::cout << "new element " << j-1 << " " << incoming[j] << "\n";
|
Chris@16
|
1444 if(j == 3) {
|
Chris@16
|
1445 returnValue = tails[i];
|
Chris@16
|
1446 returnCount = 1;
|
Chris@16
|
1447 } else {
|
Chris@16
|
1448 tails[i]->pushPoint(point);
|
Chris@16
|
1449 elements.push_back(std::pair<Vertex45, ActiveTail45*>(Vertex45(point, j -1, incoming[j]), tails[i]));
|
Chris@16
|
1450 }
|
Chris@16
|
1451 } else if(j == 3) {
|
Chris@16
|
1452 if(verticalPair.first == 0) {
|
Chris@16
|
1453 getVerticalPair_(verticalPair, previter);
|
Chris@16
|
1454 }
|
Chris@16
|
1455 ActiveTail45::joinChains(point, tails[i], verticalPair.first, true, output);
|
Chris@16
|
1456 returnValue = verticalPair.second;
|
Chris@16
|
1457 returnCount = 1;
|
Chris@16
|
1458 } else {
|
Chris@16
|
1459 if(verticalPair.first == 0) {
|
Chris@16
|
1460 getVerticalPair_(verticalPair, previter);
|
Chris@16
|
1461 }
|
Chris@16
|
1462 ActiveTail45::joinChains(point, tails[i], verticalPair.first, true, output);
|
Chris@16
|
1463 verticalPair.second->pushPoint(point);
|
Chris@16
|
1464 elements.push_back(std::pair<Vertex45, ActiveTail45*>(Vertex45(point, j -1, incoming[j]),
|
Chris@16
|
1465 verticalPair.second));
|
Chris@16
|
1466 }
|
Chris@16
|
1467 tails[i] = 0;
|
Chris@16
|
1468 counts[i] = 0;
|
Chris@16
|
1469 incoming[j] = 0;
|
Chris@16
|
1470 }
|
Chris@16
|
1471 break;
|
Chris@16
|
1472 }
|
Chris@16
|
1473 }
|
Chris@16
|
1474 }
|
Chris@16
|
1475 break;
|
Chris@16
|
1476 }
|
Chris@16
|
1477 }
|
Chris@16
|
1478
|
Chris@16
|
1479 //find the end of a hole or the beginning of a hole
|
Chris@16
|
1480
|
Chris@16
|
1481 //find end of a hole
|
Chris@16
|
1482 for(int i = 0; i < 3; ++i) {
|
Chris@16
|
1483 if(counts[i] != 0) {
|
Chris@16
|
1484 for(int j = i+1; j < 4; ++j) {
|
Chris@16
|
1485 if(counts[j] != 0) {
|
Chris@16
|
1486 //std::cout << "case5: " << i << " " << j << "\n";
|
Chris@16
|
1487 //we are ending a hole and may potentially close a figure and have to handle the hole
|
Chris@16
|
1488 tails[i]->pushPoint(point);
|
Chris@16
|
1489 verticalPairOut.first = tails[i];
|
Chris@16
|
1490 if(j == 3) {
|
Chris@16
|
1491 verticalPairOut.second = tails[j];
|
Chris@16
|
1492 } else {
|
Chris@16
|
1493 if(verticalPair.first == 0) {
|
Chris@16
|
1494 getVerticalPair_(verticalPair, previter);
|
Chris@16
|
1495 }
|
Chris@16
|
1496 ActiveTail45::joinChains(point, tails[j], verticalPair.first, true, output);
|
Chris@16
|
1497 verticalPairOut.second = verticalPair.second;
|
Chris@16
|
1498 }
|
Chris@16
|
1499 tails[i] = 0;
|
Chris@16
|
1500 tails[j] = 0;
|
Chris@16
|
1501 counts[i] = 0;
|
Chris@16
|
1502 counts[j] = 0;
|
Chris@16
|
1503 break;
|
Chris@16
|
1504 }
|
Chris@16
|
1505 }
|
Chris@16
|
1506 break;
|
Chris@16
|
1507 }
|
Chris@16
|
1508 }
|
Chris@16
|
1509 //find beginning of a hole
|
Chris@16
|
1510 for(int i = 0; i < 3; ++i) {
|
Chris@16
|
1511 if(incoming[i] != 0) {
|
Chris@16
|
1512 for(int j = i+1; j < 4; ++j) {
|
Chris@16
|
1513 if(incoming[j] != 0) {
|
Chris@16
|
1514 //std::cout << "case6: " << i << " " << j << "\n";
|
Chris@16
|
1515 //we are beginning a empty space
|
Chris@16
|
1516 if(verticalPair.first == 0) {
|
Chris@16
|
1517 getVerticalPair_(verticalPair, previter);
|
Chris@16
|
1518 }
|
Chris@16
|
1519 verticalPair.second->pushPoint(point);
|
Chris@16
|
1520 if(j == 3) {
|
Chris@16
|
1521 returnValue = verticalPair.first;
|
Chris@16
|
1522 returnCount = -1;
|
Chris@16
|
1523 } else {
|
Chris@16
|
1524 std::pair<ActiveTail45*, ActiveTail45*> tailPair =
|
Chris@16
|
1525 ActiveTail45::createActiveTail45sAsPair(point, true, 0, false);
|
Chris@16
|
1526 //std::cout << "new element " << j-1 << " " << incoming[j] << "\n";
|
Chris@16
|
1527 elements.push_back(std::pair<Vertex45, ActiveTail45*>(Vertex45(point, j -1, incoming[j]), tailPair.second));
|
Chris@16
|
1528 verticalPairOut.second = tailPair.first;
|
Chris@16
|
1529 verticalPairOut.first = verticalPair.first;
|
Chris@16
|
1530 }
|
Chris@16
|
1531 //std::cout << "new element " << i-1 << " " << incoming[i] << "\n";
|
Chris@16
|
1532 elements.push_back(std::pair<Vertex45, ActiveTail45*>(Vertex45(point, i -1, incoming[i]), verticalPair.second));
|
Chris@16
|
1533 incoming[i] = 0;
|
Chris@16
|
1534 incoming[j] = 0;
|
Chris@16
|
1535 break;
|
Chris@16
|
1536 }
|
Chris@16
|
1537 }
|
Chris@16
|
1538 break;
|
Chris@16
|
1539 }
|
Chris@16
|
1540 }
|
Chris@16
|
1541 verticalPair = verticalPairOut;
|
Chris@16
|
1542 //assert that verticalPair is either both null, or neither null
|
Chris@16
|
1543 //assert that returnValue is null if verticalPair is not null
|
Chris@16
|
1544 //assert that tails, counts and incoming are all null
|
Chris@16
|
1545 return std::pair<int, ActiveTail45*>(returnCount, returnValue);
|
Chris@16
|
1546 }
|
Chris@16
|
1547
|
Chris@16
|
1548 template <class cT, class iT>
|
Chris@16
|
1549 inline iT processEvent_(cT& output, iT inputBegin, iT inputEnd) {
|
Chris@16
|
1550 //std::cout << "processEvent_\n";
|
Chris@16
|
1551 justBefore_ = true;
|
Chris@16
|
1552 //collect up all elements from the tree that are at the y
|
Chris@16
|
1553 //values of events in the input queue
|
Chris@16
|
1554 //create vector of new elements to add into tree
|
Chris@16
|
1555 ActiveTail45* verticalTail = 0;
|
Chris@16
|
1556 std::pair<ActiveTail45*, ActiveTail45*> verticalPair;
|
Chris@16
|
1557 verticalPair.first = 0;
|
Chris@16
|
1558 verticalPair.second = 0;
|
Chris@16
|
1559 int verticalCount = 0;
|
Chris@16
|
1560 iT currentIter = inputBegin;
|
Chris@16
|
1561 std::vector<iterator> elementIters;
|
Chris@16
|
1562 std::vector<std::pair<Vertex45, ActiveTail45*> > elements;
|
Chris@16
|
1563 while(currentIter != inputEnd && currentIter->pt.x() == x_) {
|
Chris@16
|
1564 //std::cout << "loop\n";
|
Chris@16
|
1565 Unit currentY = (*currentIter).pt.y();
|
Chris@16
|
1566 iterator iter = lookUp_(currentY);
|
Chris@16
|
1567 //int counts[4] = {0, 0, 0, 0};
|
Chris@16
|
1568 Vertex45Count counts;
|
Chris@16
|
1569 ActiveTail45* tails[4] = {0, 0, 0, verticalTail};
|
Chris@16
|
1570 //std::cout << "finding elements in tree\n";
|
Chris@16
|
1571 iterator previter = iter;
|
Chris@16
|
1572 if(previter != scanData_.end() &&
|
Chris@16
|
1573 previter->first.evalAtX(x_) >= currentY &&
|
Chris@16
|
1574 previter != scanData_.begin())
|
Chris@16
|
1575 --previter;
|
Chris@16
|
1576 while(iter != scanData_.end() &&
|
Chris@16
|
1577 iter->first.evalAtX(x_) == currentY) {
|
Chris@16
|
1578 //std::cout << "loop2\n";
|
Chris@16
|
1579 elementIters.push_back(iter);
|
Chris@16
|
1580 int index = iter->first.rise + 1;
|
Chris@16
|
1581 //std::cout << index << " " << iter->first.count << "\n";
|
Chris@16
|
1582 counts[index] = iter->first.count;
|
Chris@16
|
1583 tails[index] = iter->second;
|
Chris@16
|
1584 ++iter;
|
Chris@16
|
1585 }
|
Chris@16
|
1586 //int incoming[4] = {0, 0, 0, 0};
|
Chris@16
|
1587 Vertex45Count incoming;
|
Chris@16
|
1588 //std::cout << "aggregating\n";
|
Chris@16
|
1589 do {
|
Chris@16
|
1590 //std::cout << "loop3\n";
|
Chris@16
|
1591 Vertex45Compact currentVertex(*currentIter);
|
Chris@16
|
1592 incoming += currentVertex.count;
|
Chris@16
|
1593 ++currentIter;
|
Chris@16
|
1594 } while(currentIter != inputEnd && currentIter->pt.y() == currentY &&
|
Chris@16
|
1595 currentIter->pt.x() == x_);
|
Chris@16
|
1596 //now counts and tails have the data from the left and
|
Chris@16
|
1597 //incoming has the data from the right at this point
|
Chris@16
|
1598 //cancel out any end points
|
Chris@16
|
1599 //std::cout << counts[0] << " ";
|
Chris@16
|
1600 //std::cout << counts[1] << " ";
|
Chris@16
|
1601 //std::cout << counts[2] << " ";
|
Chris@16
|
1602 //std::cout << counts[3] << "\n";
|
Chris@16
|
1603 //std::cout << incoming[0] << " ";
|
Chris@16
|
1604 //std::cout << incoming[1] << " ";
|
Chris@16
|
1605 //std::cout << incoming[2] << " ";
|
Chris@16
|
1606 //std::cout << incoming[3] << "\n";
|
Chris@16
|
1607 if(verticalTail) {
|
Chris@16
|
1608 counts[3] = -verticalCount;
|
Chris@16
|
1609 }
|
Chris@16
|
1610 incoming[3] *= -1;
|
Chris@16
|
1611 for(unsigned int i = 0; i < 4; ++i) incoming[i] += counts[i];
|
Chris@16
|
1612 //std::cout << "calling processPoint_\n";
|
Chris@16
|
1613 std::pair<int, ActiveTail45*> result = processPoint_(output, elements, verticalPair, previter,
|
Chris@16
|
1614 Point(x_, currentY), counts, tails, incoming);
|
Chris@16
|
1615 verticalCount = result.first;
|
Chris@16
|
1616 verticalTail = result.second;
|
Chris@16
|
1617 if(verticalPair.first != 0 && iter != scanData_.end() &&
|
Chris@16
|
1618 (currentIter == inputEnd || currentIter->pt.x() != x_ ||
|
Chris@16
|
1619 currentIter->pt.y() > (*iter).first.evalAtX(x_))) {
|
Chris@16
|
1620 //splice vertical pair into edge above
|
Chris@16
|
1621 ActiveTail45* tailabove = (*iter).second;
|
Chris@16
|
1622 Point point(x_, (*iter).first.evalAtX(x_));
|
Chris@16
|
1623 verticalPair.second->pushPoint(point);
|
Chris@16
|
1624 ActiveTail45::joinChains(point, tailabove, verticalPair.first, true, output);
|
Chris@16
|
1625 (*iter).second = verticalPair.second;
|
Chris@16
|
1626 verticalPair.first = 0;
|
Chris@16
|
1627 verticalPair.second = 0;
|
Chris@16
|
1628 }
|
Chris@16
|
1629 }
|
Chris@16
|
1630 //std::cout << "erasing\n";
|
Chris@16
|
1631 //erase all elements from the tree
|
Chris@16
|
1632 for(typename std::vector<iterator>::iterator iter = elementIters.begin();
|
Chris@16
|
1633 iter != elementIters.end(); ++iter) {
|
Chris@16
|
1634 //std::cout << "erasing loop\n";
|
Chris@16
|
1635 scanData_.erase(*iter);
|
Chris@16
|
1636 }
|
Chris@16
|
1637 //switch comparison tie breaking policy
|
Chris@16
|
1638 justBefore_ = false;
|
Chris@16
|
1639 //add new elements into tree
|
Chris@16
|
1640 //std::cout << "inserting\n";
|
Chris@16
|
1641 for(typename std::vector<std::pair<Vertex45, ActiveTail45*> >::iterator iter = elements.begin();
|
Chris@16
|
1642 iter != elements.end(); ++iter) {
|
Chris@16
|
1643 //std::cout << "inserting loop\n";
|
Chris@16
|
1644 scanData_.insert(scanData_.end(), *iter);
|
Chris@16
|
1645 }
|
Chris@16
|
1646 //std::cout << "end processEvent\n";
|
Chris@16
|
1647 return currentIter;
|
Chris@16
|
1648 }
|
Chris@16
|
1649
|
Chris@16
|
1650 inline iterator lookUp_(Unit y){
|
Chris@16
|
1651 //if just before then we need to look from 1 not -1
|
Chris@16
|
1652 return scanData_.lower_bound(Vertex45(Point(x_, y), -1+2*justBefore_, 0));
|
Chris@16
|
1653 }
|
Chris@16
|
1654
|
Chris@16
|
1655 };
|
Chris@16
|
1656
|
Chris@16
|
1657 template <typename stream_type>
|
Chris@16
|
1658 static inline bool testPolygon45TilingRect(stream_type& stdcout) {
|
Chris@16
|
1659 stdcout << "testing polygon tiling\n";
|
Chris@16
|
1660 Polygon45Tiling pf;
|
Chris@16
|
1661 std::vector<Polygon45> polys;
|
Chris@16
|
1662 std::vector<Vertex45> data;
|
Chris@16
|
1663 data.push_back(Vertex45(Point(0, 0), 0, 1));
|
Chris@16
|
1664 data.push_back(Vertex45(Point(0, 0), 2, 1));
|
Chris@16
|
1665 data.push_back(Vertex45(Point(0, 10), 2, -1));
|
Chris@16
|
1666 data.push_back(Vertex45(Point(0, 10), 0, -1));
|
Chris@16
|
1667 data.push_back(Vertex45(Point(10, 0), 0, -1));
|
Chris@16
|
1668 data.push_back(Vertex45(Point(10, 0), 2, -1));
|
Chris@16
|
1669 data.push_back(Vertex45(Point(10, 10), 2, 1));
|
Chris@16
|
1670 data.push_back(Vertex45(Point(10, 10), 0, 1));
|
Chris@16
|
1671 polygon_sort(data.begin(), data.end());
|
Chris@16
|
1672 pf.scan(polys, data.begin(), data.end());
|
Chris@16
|
1673 stdcout << "result size: " << polys.size() << "\n";
|
Chris@16
|
1674 for(std::size_t i = 0; i < polys.size(); ++i) {
|
Chris@16
|
1675 stdcout << polys[i] << "\n";
|
Chris@16
|
1676 }
|
Chris@16
|
1677 stdcout << "done testing polygon tiling\n";
|
Chris@16
|
1678 return true;
|
Chris@16
|
1679 }
|
Chris@16
|
1680
|
Chris@16
|
1681 template <typename stream_type>
|
Chris@16
|
1682 static inline bool testPolygon45TilingP1(stream_type& stdcout) {
|
Chris@16
|
1683 stdcout << "testing polygon tiling\n";
|
Chris@16
|
1684 Polygon45Tiling pf;
|
Chris@16
|
1685 std::vector<Polygon45> polys;
|
Chris@16
|
1686 std::vector<Vertex45> data;
|
Chris@16
|
1687 data.push_back(Vertex45(Point(0, 0), 1, 1));
|
Chris@16
|
1688 data.push_back(Vertex45(Point(0, 0), 2, 1));
|
Chris@16
|
1689 data.push_back(Vertex45(Point(0, 10), 2, -1));
|
Chris@16
|
1690 data.push_back(Vertex45(Point(0, 10), 1, -1));
|
Chris@16
|
1691 data.push_back(Vertex45(Point(10, 10), 1, -1));
|
Chris@16
|
1692 data.push_back(Vertex45(Point(10, 10), 2, -1));
|
Chris@16
|
1693 data.push_back(Vertex45(Point(10, 20), 2, 1));
|
Chris@16
|
1694 data.push_back(Vertex45(Point(10, 20), 1, 1));
|
Chris@16
|
1695 polygon_sort(data.begin(), data.end());
|
Chris@16
|
1696 pf.scan(polys, data.begin(), data.end());
|
Chris@16
|
1697 stdcout << "result size: " << polys.size() << "\n";
|
Chris@16
|
1698 for(std::size_t i = 0; i < polys.size(); ++i) {
|
Chris@16
|
1699 stdcout << polys[i] << "\n";
|
Chris@16
|
1700 }
|
Chris@16
|
1701 stdcout << "done testing polygon tiling\n";
|
Chris@16
|
1702 return true;
|
Chris@16
|
1703 }
|
Chris@16
|
1704
|
Chris@16
|
1705 template <typename stream_type>
|
Chris@16
|
1706 static inline bool testPolygon45TilingP2(stream_type& stdcout) {
|
Chris@16
|
1707 stdcout << "testing polygon tiling\n";
|
Chris@16
|
1708 Polygon45Tiling pf;
|
Chris@16
|
1709 std::vector<Polygon45> polys;
|
Chris@16
|
1710 std::vector<Vertex45> data;
|
Chris@16
|
1711 data.push_back(Vertex45(Point(0, 0), 0, 1));
|
Chris@16
|
1712 data.push_back(Vertex45(Point(0, 0), 1, -1));
|
Chris@16
|
1713 data.push_back(Vertex45(Point(10, 0), 0, -1));
|
Chris@16
|
1714 data.push_back(Vertex45(Point(10, 0), 1, 1));
|
Chris@16
|
1715 data.push_back(Vertex45(Point(10, 10), 1, 1));
|
Chris@16
|
1716 data.push_back(Vertex45(Point(10, 10), 0, -1));
|
Chris@16
|
1717 data.push_back(Vertex45(Point(20, 10), 1, -1));
|
Chris@16
|
1718 data.push_back(Vertex45(Point(20, 10), 0, 1));
|
Chris@16
|
1719 polygon_sort(data.begin(), data.end());
|
Chris@16
|
1720 pf.scan(polys, data.begin(), data.end());
|
Chris@16
|
1721 stdcout << "result size: " << polys.size() << "\n";
|
Chris@16
|
1722 for(std::size_t i = 0; i < polys.size(); ++i) {
|
Chris@16
|
1723 stdcout << polys[i] << "\n";
|
Chris@16
|
1724 }
|
Chris@16
|
1725 stdcout << "done testing polygon tiling\n";
|
Chris@16
|
1726 return true;
|
Chris@16
|
1727 }
|
Chris@16
|
1728
|
Chris@16
|
1729 template <typename stream_type>
|
Chris@16
|
1730 static inline bool testPolygon45TilingP3(stream_type& stdcout) {
|
Chris@16
|
1731 stdcout << "testing polygon tiling\n";
|
Chris@16
|
1732 Polygon45Tiling pf;
|
Chris@16
|
1733 std::vector<Polygon45> polys;
|
Chris@16
|
1734 std::vector<Vertex45> data;
|
Chris@16
|
1735 data.push_back(Vertex45(Point(0, 0), 0, 1));
|
Chris@16
|
1736 data.push_back(Vertex45(Point(0, 0), 2, 1));
|
Chris@16
|
1737 data.push_back(Vertex45(Point(0, 10), 2, -1));
|
Chris@16
|
1738 data.push_back(Vertex45(Point(0, 10), 0, -1));
|
Chris@16
|
1739 data.push_back(Vertex45(Point(20, 0), 0, -1));
|
Chris@16
|
1740 data.push_back(Vertex45(Point(20, 0), 2, -1));
|
Chris@16
|
1741 data.push_back(Vertex45(Point(10, 10), 1, -1));
|
Chris@16
|
1742 data.push_back(Vertex45(Point(10, 10), 0, 1));
|
Chris@16
|
1743 data.push_back(Vertex45(Point(20, 20), 1, 1));
|
Chris@16
|
1744 data.push_back(Vertex45(Point(20, 20), 2, 1));
|
Chris@16
|
1745 polygon_sort(data.begin(), data.end());
|
Chris@16
|
1746 pf.scan(polys, data.begin(), data.end());
|
Chris@16
|
1747 stdcout << "result size: " << polys.size() << "\n";
|
Chris@16
|
1748 for(std::size_t i = 0; i < polys.size(); ++i) {
|
Chris@16
|
1749 stdcout << polys[i] << "\n";
|
Chris@16
|
1750 }
|
Chris@16
|
1751 stdcout << "done testing polygon tiling\n";
|
Chris@16
|
1752 return true;
|
Chris@16
|
1753 }
|
Chris@16
|
1754
|
Chris@16
|
1755 template <typename stream_type>
|
Chris@16
|
1756 static inline bool testPolygon45TilingP4(stream_type& stdcout) {
|
Chris@16
|
1757 stdcout << "testing polygon tiling p4\n";
|
Chris@16
|
1758 Polygon45Tiling pf;
|
Chris@16
|
1759 std::vector<Polygon45> polys;
|
Chris@16
|
1760 std::vector<Vertex45> data;
|
Chris@16
|
1761 data.push_back(Vertex45(Point(0, 0), 0, 1));
|
Chris@16
|
1762 data.push_back(Vertex45(Point(0, 0), 2, 1));
|
Chris@16
|
1763 data.push_back(Vertex45(Point(0, 10), 2, -1));
|
Chris@16
|
1764 data.push_back(Vertex45(Point(0, 10), 0, -1));
|
Chris@16
|
1765 data.push_back(Vertex45(Point(10, 0), -1, 1));
|
Chris@16
|
1766 data.push_back(Vertex45(Point(10, 0), 0, -1));
|
Chris@16
|
1767 data.push_back(Vertex45(Point(20, 10), 2, 1));
|
Chris@16
|
1768 data.push_back(Vertex45(Point(20, 10), 0, 1));
|
Chris@16
|
1769 data.push_back(Vertex45(Point(20, -10), -1, -1));
|
Chris@16
|
1770 data.push_back(Vertex45(Point(20, -10), 2, -1));
|
Chris@16
|
1771 polygon_sort(data.begin(), data.end());
|
Chris@16
|
1772 pf.scan(polys, data.begin(), data.end());
|
Chris@16
|
1773 stdcout << "result size: " << polys.size() << "\n";
|
Chris@16
|
1774 for(std::size_t i = 0; i < polys.size(); ++i) {
|
Chris@16
|
1775 stdcout << polys[i] << "\n";
|
Chris@16
|
1776 }
|
Chris@16
|
1777 stdcout << "done testing polygon tiling\n";
|
Chris@16
|
1778 return true;
|
Chris@16
|
1779 }
|
Chris@16
|
1780
|
Chris@16
|
1781 template <typename stream_type>
|
Chris@16
|
1782 static inline bool testPolygon45TilingP5(stream_type& stdcout) {
|
Chris@16
|
1783 stdcout << "testing polygon tiling P5\n";
|
Chris@16
|
1784 Polygon45Tiling pf;
|
Chris@16
|
1785 std::vector<Polygon45> polys;
|
Chris@16
|
1786 std::vector<Vertex45> data;
|
Chris@16
|
1787 data.push_back(Vertex45(Point(0, 0), 0, 1));
|
Chris@16
|
1788 data.push_back(Vertex45(Point(0, 0), 2, 1));
|
Chris@16
|
1789 data.push_back(Vertex45(Point(0, 10), 2, -1));
|
Chris@16
|
1790 data.push_back(Vertex45(Point(0, 10), 0, -1));
|
Chris@16
|
1791 data.push_back(Vertex45(Point(10, 0), 0, -1));
|
Chris@16
|
1792 data.push_back(Vertex45(Point(10, 0), 2, -1));
|
Chris@16
|
1793 data.push_back(Vertex45(Point(10, 10), 2, 1));
|
Chris@16
|
1794 data.push_back(Vertex45(Point(10, 10), 0, 1));
|
Chris@16
|
1795
|
Chris@16
|
1796 data.push_back(Vertex45(Point(1, 1), 0, -1));
|
Chris@16
|
1797 data.push_back(Vertex45(Point(1, 1), 1, 1));
|
Chris@16
|
1798 data.push_back(Vertex45(Point(2, 1), 0, 1));
|
Chris@16
|
1799 data.push_back(Vertex45(Point(2, 1), 1, -1));
|
Chris@16
|
1800 data.push_back(Vertex45(Point(2, 2), 1, -1));
|
Chris@16
|
1801 data.push_back(Vertex45(Point(2, 2), 0, 1));
|
Chris@16
|
1802 data.push_back(Vertex45(Point(3, 2), 1, 1));
|
Chris@16
|
1803 data.push_back(Vertex45(Point(3, 2), 0, -1));
|
Chris@16
|
1804 polygon_sort(data.begin(), data.end());
|
Chris@16
|
1805 pf.scan(polys, data.begin(), data.end());
|
Chris@16
|
1806 stdcout << "result size: " << polys.size() << "\n";
|
Chris@16
|
1807 for(std::size_t i = 0; i < polys.size(); ++i) {
|
Chris@16
|
1808 stdcout << polys[i] << "\n";
|
Chris@16
|
1809 }
|
Chris@16
|
1810 stdcout << "done testing polygon tiling\n";
|
Chris@16
|
1811 return true;
|
Chris@16
|
1812 }
|
Chris@16
|
1813
|
Chris@16
|
1814 template <typename stream_type>
|
Chris@16
|
1815 static inline bool testPolygon45TilingP6(stream_type& stdcout) {
|
Chris@16
|
1816 stdcout << "testing polygon tiling P6\n";
|
Chris@16
|
1817 Polygon45Tiling pf;
|
Chris@16
|
1818 std::vector<Polygon45> polys;
|
Chris@16
|
1819 std::vector<Vertex45> data;
|
Chris@16
|
1820 data.push_back(Vertex45(Point(0, 0), 0, 1));
|
Chris@16
|
1821 data.push_back(Vertex45(Point(0, 0), 2, 1));
|
Chris@16
|
1822 data.push_back(Vertex45(Point(0, 10), 2, -1));
|
Chris@16
|
1823 data.push_back(Vertex45(Point(0, 10), 0, -1));
|
Chris@16
|
1824 data.push_back(Vertex45(Point(10, 0), 0, -1));
|
Chris@16
|
1825 data.push_back(Vertex45(Point(10, 0), 2, -1));
|
Chris@16
|
1826 data.push_back(Vertex45(Point(10, 10), 2, 1));
|
Chris@16
|
1827 data.push_back(Vertex45(Point(10, 10), 0, 1));
|
Chris@16
|
1828
|
Chris@16
|
1829 data.push_back(Vertex45(Point(1, 1), 0, -1));
|
Chris@16
|
1830 data.push_back(Vertex45(Point(1, 1), 2, -1));
|
Chris@16
|
1831 data.push_back(Vertex45(Point(1, 2), 2, 1));
|
Chris@16
|
1832 data.push_back(Vertex45(Point(1, 2), 0, 1));
|
Chris@16
|
1833 data.push_back(Vertex45(Point(2, 1), 0, 1));
|
Chris@16
|
1834 data.push_back(Vertex45(Point(2, 1), 2, 1));
|
Chris@16
|
1835 data.push_back(Vertex45(Point(2, 2), 2, -1));
|
Chris@16
|
1836 data.push_back(Vertex45(Point(2, 2), 0, -1));
|
Chris@16
|
1837
|
Chris@16
|
1838 polygon_sort(data.begin(), data.end());
|
Chris@16
|
1839 pf.scan(polys, data.begin(), data.end());
|
Chris@16
|
1840 stdcout << "result size: " << polys.size() << "\n";
|
Chris@16
|
1841 for(std::size_t i = 0; i < polys.size(); ++i) {
|
Chris@16
|
1842 stdcout << polys[i] << "\n";
|
Chris@16
|
1843 }
|
Chris@16
|
1844 stdcout << "done testing polygon tiling\n";
|
Chris@16
|
1845 return true;
|
Chris@16
|
1846 }
|
Chris@16
|
1847
|
Chris@16
|
1848 template <typename stream_type>
|
Chris@16
|
1849 static inline bool testPolygon45TilingStar1(stream_type& stdcout) {
|
Chris@16
|
1850 stdcout << "testing polygon tiling star1\n";
|
Chris@16
|
1851 Polygon45Tiling pf;
|
Chris@16
|
1852 std::vector<Polygon45> polys;
|
Chris@16
|
1853 std::vector<Vertex45> data;
|
Chris@16
|
1854 // result == 0 8 -1 1
|
Chris@16
|
1855 data.push_back(Vertex45(Point(0, 8), -1, 1));
|
Chris@16
|
1856 // result == 0 8 1 -1
|
Chris@16
|
1857 data.push_back(Vertex45(Point(0, 8), 1, -1));
|
Chris@16
|
1858 // result == 4 0 1 1
|
Chris@16
|
1859 data.push_back(Vertex45(Point(4, 0), 1, 1));
|
Chris@16
|
1860 // result == 4 0 2 1
|
Chris@16
|
1861 data.push_back(Vertex45(Point(4, 0), 2, 1));
|
Chris@16
|
1862 // result == 4 4 2 -1
|
Chris@16
|
1863 data.push_back(Vertex45(Point(4, 4), 2, -1));
|
Chris@16
|
1864 // result == 4 4 -1 -1
|
Chris@16
|
1865 data.push_back(Vertex45(Point(4, 4), -1, -1));
|
Chris@16
|
1866 // result == 4 12 1 1
|
Chris@16
|
1867 data.push_back(Vertex45(Point(4, 12), 1, 1));
|
Chris@16
|
1868 // result == 4 12 2 1
|
Chris@16
|
1869 data.push_back(Vertex45(Point(4, 12), 2, 1));
|
Chris@16
|
1870 // result == 4 16 2 -1
|
Chris@16
|
1871 data.push_back(Vertex45(Point(4, 16), 2, 1));
|
Chris@16
|
1872 // result == 4 16 -1 -1
|
Chris@16
|
1873 data.push_back(Vertex45(Point(4, 16), -1, -1));
|
Chris@16
|
1874 // result == 6 2 1 -1
|
Chris@16
|
1875 data.push_back(Vertex45(Point(6, 2), 1, -1));
|
Chris@16
|
1876 // result == 6 14 -1 1
|
Chris@16
|
1877 data.push_back(Vertex45(Point(6, 14), -1, 1));
|
Chris@16
|
1878 // result == 6 2 -1 1
|
Chris@16
|
1879 data.push_back(Vertex45(Point(6, 2), -1, 1));
|
Chris@16
|
1880 // result == 6 14 1 -1
|
Chris@16
|
1881 data.push_back(Vertex45(Point(6, 14), 1, -1));
|
Chris@16
|
1882 // result == 8 0 -1 -1
|
Chris@16
|
1883 data.push_back(Vertex45(Point(8, 0), -1, -1));
|
Chris@16
|
1884 // result == 8 0 2 -1
|
Chris@16
|
1885 data.push_back(Vertex45(Point(8, 0), 2, -1));
|
Chris@16
|
1886 // result == 8 4 2 1
|
Chris@16
|
1887 data.push_back(Vertex45(Point(8, 4), 2, 1));
|
Chris@16
|
1888 // result == 8 4 1 1
|
Chris@16
|
1889 data.push_back(Vertex45(Point(8, 4), 1, 1));
|
Chris@16
|
1890 // result == 8 12 -1 -1
|
Chris@16
|
1891 data.push_back(Vertex45(Point(8, 12), -1, -1));
|
Chris@16
|
1892 // result == 8 12 2 -1
|
Chris@16
|
1893 data.push_back(Vertex45(Point(8, 12), 2, -1));
|
Chris@16
|
1894 // result == 8 16 2 1
|
Chris@16
|
1895 data.push_back(Vertex45(Point(8, 16), 2, 1));
|
Chris@16
|
1896 // result == 8 16 1 1
|
Chris@16
|
1897 data.push_back(Vertex45(Point(8, 16), 1, 1));
|
Chris@16
|
1898 // result == 12 8 1 -1
|
Chris@16
|
1899 data.push_back(Vertex45(Point(12, 8), 1, -1));
|
Chris@16
|
1900 // result == 12 8 -1 1
|
Chris@16
|
1901 data.push_back(Vertex45(Point(12, 8), -1, 1));
|
Chris@16
|
1902 polygon_sort(data.begin(), data.end());
|
Chris@16
|
1903 pf.scan(polys, data.begin(), data.end());
|
Chris@16
|
1904 stdcout << "result size: " << polys.size() << "\n";
|
Chris@16
|
1905 for(std::size_t i = 0; i < polys.size(); ++i) {
|
Chris@16
|
1906 stdcout << polys[i] << "\n";
|
Chris@16
|
1907 }
|
Chris@16
|
1908 stdcout << "done testing polygon tiling\n";
|
Chris@16
|
1909 return true;
|
Chris@16
|
1910 }
|
Chris@16
|
1911
|
Chris@16
|
1912 template <typename stream_type>
|
Chris@16
|
1913 static inline bool testPolygon45TilingStar2(stream_type& stdcout) {
|
Chris@16
|
1914 stdcout << "testing polygon tiling\n";
|
Chris@16
|
1915 Polygon45Tiling pf;
|
Chris@16
|
1916 std::vector<Polygon45> polys;
|
Chris@16
|
1917
|
Chris@16
|
1918 Scan45 scan45;
|
Chris@16
|
1919 std::vector<Vertex45 > result;
|
Chris@16
|
1920 std::vector<Scan45Vertex> vertices;
|
Chris@16
|
1921 //is a Rectnagle(0, 0, 10, 10);
|
Chris@16
|
1922 Count2 count(1, 0);
|
Chris@16
|
1923 Count2 ncount(-1, 0);
|
Chris@16
|
1924 vertices.push_back(Scan45Vertex(Point(0,4), Scan45Count(Count2(0, 0), count, ncount, Count2(0, 0))));
|
Chris@16
|
1925 vertices.push_back(Scan45Vertex(Point(16,4), Scan45Count(count, ncount, Count2(0, 0), Count2(0, 0))));
|
Chris@16
|
1926 vertices.push_back(Scan45Vertex(Point(8,12), Scan45Count(ncount, Count2(0, 0), count, Count2(0, 0))));
|
Chris@16
|
1927 count = Count2(0, 1);
|
Chris@16
|
1928 ncount = count.invert();
|
Chris@16
|
1929 vertices.push_back(Scan45Vertex(Point(0,8), Scan45Count(count, ncount, Count2(0, 0), Count2(0, 0))));
|
Chris@16
|
1930 vertices.push_back(Scan45Vertex(Point(16,8), Scan45Count(Count2(0, 0), count, ncount, Count2(0, 0))));
|
Chris@16
|
1931 vertices.push_back(Scan45Vertex(Point(8,0), Scan45Count(ncount, Count2(0, 0), count, Count2(0, 0))));
|
Chris@16
|
1932 sortScan45Vector(vertices);
|
Chris@16
|
1933 stdcout << "scanning\n";
|
Chris@16
|
1934 scan45.scan(result, vertices.begin(), vertices.end());
|
Chris@16
|
1935
|
Chris@16
|
1936 polygon_sort(result.begin(), result.end());
|
Chris@16
|
1937 pf.scan(polys, result.begin(), result.end());
|
Chris@16
|
1938 stdcout << "result size: " << polys.size() << "\n";
|
Chris@16
|
1939 for(std::size_t i = 0; i < polys.size(); ++i) {
|
Chris@16
|
1940 stdcout << polys[i] << "\n";
|
Chris@16
|
1941 }
|
Chris@16
|
1942 stdcout << "done testing polygon tiling\n";
|
Chris@16
|
1943 return true;
|
Chris@16
|
1944 }
|
Chris@16
|
1945
|
Chris@16
|
1946 template <typename stream_type>
|
Chris@16
|
1947 static inline bool testPolygon45TilingStarHole1(stream_type& stdcout) {
|
Chris@16
|
1948 stdcout << "testing polygon tiling star hole 1\n";
|
Chris@16
|
1949 Polygon45Tiling pf;
|
Chris@16
|
1950 std::vector<Polygon45> polys;
|
Chris@16
|
1951 std::vector<Vertex45> data;
|
Chris@16
|
1952 // result == 0 8 -1 1
|
Chris@16
|
1953 data.push_back(Vertex45(Point(0, 8), -1, 1));
|
Chris@16
|
1954 // result == 0 8 1 -1
|
Chris@16
|
1955 data.push_back(Vertex45(Point(0, 8), 1, -1));
|
Chris@16
|
1956 // result == 4 0 1 1
|
Chris@16
|
1957 data.push_back(Vertex45(Point(4, 0), 1, 1));
|
Chris@16
|
1958 // result == 4 0 2 1
|
Chris@16
|
1959 data.push_back(Vertex45(Point(4, 0), 2, 1));
|
Chris@16
|
1960 // result == 4 4 2 -1
|
Chris@16
|
1961 data.push_back(Vertex45(Point(4, 4), 2, -1));
|
Chris@16
|
1962 // result == 4 4 -1 -1
|
Chris@16
|
1963 data.push_back(Vertex45(Point(4, 4), -1, -1));
|
Chris@16
|
1964 // result == 4 12 1 1
|
Chris@16
|
1965 data.push_back(Vertex45(Point(4, 12), 1, 1));
|
Chris@16
|
1966 // result == 4 12 2 1
|
Chris@16
|
1967 data.push_back(Vertex45(Point(4, 12), 2, 1));
|
Chris@16
|
1968 // result == 4 16 2 -1
|
Chris@16
|
1969 data.push_back(Vertex45(Point(4, 16), 2, 1));
|
Chris@16
|
1970 // result == 4 16 -1 -1
|
Chris@16
|
1971 data.push_back(Vertex45(Point(4, 16), -1, -1));
|
Chris@16
|
1972 // result == 6 2 1 -1
|
Chris@16
|
1973 data.push_back(Vertex45(Point(6, 2), 1, -1));
|
Chris@16
|
1974 // result == 6 14 -1 1
|
Chris@16
|
1975 data.push_back(Vertex45(Point(6, 14), -1, 1));
|
Chris@16
|
1976 // result == 6 2 -1 1
|
Chris@16
|
1977 data.push_back(Vertex45(Point(6, 2), -1, 1));
|
Chris@16
|
1978 // result == 6 14 1 -1
|
Chris@16
|
1979 data.push_back(Vertex45(Point(6, 14), 1, -1));
|
Chris@16
|
1980 // result == 8 0 -1 -1
|
Chris@16
|
1981 data.push_back(Vertex45(Point(8, 0), -1, -1));
|
Chris@16
|
1982 // result == 8 0 2 -1
|
Chris@16
|
1983 data.push_back(Vertex45(Point(8, 0), 2, -1));
|
Chris@16
|
1984 // result == 8 4 2 1
|
Chris@16
|
1985 data.push_back(Vertex45(Point(8, 4), 2, 1));
|
Chris@16
|
1986 // result == 8 4 1 1
|
Chris@16
|
1987 data.push_back(Vertex45(Point(8, 4), 1, 1));
|
Chris@16
|
1988 // result == 8 12 -1 -1
|
Chris@16
|
1989 data.push_back(Vertex45(Point(8, 12), -1, -1));
|
Chris@16
|
1990 // result == 8 12 2 -1
|
Chris@16
|
1991 data.push_back(Vertex45(Point(8, 12), 2, -1));
|
Chris@16
|
1992 // result == 8 16 2 1
|
Chris@16
|
1993 data.push_back(Vertex45(Point(8, 16), 2, 1));
|
Chris@16
|
1994 // result == 8 16 1 1
|
Chris@16
|
1995 data.push_back(Vertex45(Point(8, 16), 1, 1));
|
Chris@16
|
1996 // result == 12 8 1 -1
|
Chris@16
|
1997 data.push_back(Vertex45(Point(12, 8), 1, -1));
|
Chris@16
|
1998 // result == 12 8 -1 1
|
Chris@16
|
1999 data.push_back(Vertex45(Point(12, 8), -1, 1));
|
Chris@16
|
2000
|
Chris@16
|
2001 data.push_back(Vertex45(Point(6, 4), 1, -1));
|
Chris@16
|
2002 data.push_back(Vertex45(Point(6, 4), 2, -1));
|
Chris@16
|
2003 data.push_back(Vertex45(Point(6, 8), -1, 1));
|
Chris@16
|
2004 data.push_back(Vertex45(Point(6, 8), 2, 1));
|
Chris@16
|
2005 data.push_back(Vertex45(Point(8, 6), -1, -1));
|
Chris@16
|
2006 data.push_back(Vertex45(Point(8, 6), 1, 1));
|
Chris@16
|
2007
|
Chris@16
|
2008 polygon_sort(data.begin(), data.end());
|
Chris@16
|
2009 pf.scan(polys, data.begin(), data.end());
|
Chris@16
|
2010 stdcout << "result size: " << polys.size() << "\n";
|
Chris@16
|
2011 for(std::size_t i = 0; i < polys.size(); ++i) {
|
Chris@16
|
2012 stdcout << polys[i] << "\n";
|
Chris@16
|
2013 }
|
Chris@16
|
2014 stdcout << "done testing polygon tiling\n";
|
Chris@16
|
2015 return true;
|
Chris@16
|
2016 }
|
Chris@16
|
2017
|
Chris@16
|
2018 template <typename stream_type>
|
Chris@16
|
2019 static inline bool testPolygon45TilingStarHole2(stream_type& stdcout) {
|
Chris@16
|
2020 stdcout << "testing polygon tiling star hole 2\n";
|
Chris@16
|
2021 Polygon45Tiling pf;
|
Chris@16
|
2022 std::vector<Polygon45WithHoles> polys;
|
Chris@16
|
2023 std::vector<Vertex45> data;
|
Chris@16
|
2024 // result == 0 8 -1 1
|
Chris@16
|
2025 data.push_back(Vertex45(Point(0, 8), -1, 1));
|
Chris@16
|
2026 // result == 0 8 1 -1
|
Chris@16
|
2027 data.push_back(Vertex45(Point(0, 8), 1, -1));
|
Chris@16
|
2028 // result == 4 0 1 1
|
Chris@16
|
2029 data.push_back(Vertex45(Point(4, 0), 1, 1));
|
Chris@16
|
2030 // result == 4 0 2 1
|
Chris@16
|
2031 data.push_back(Vertex45(Point(4, 0), 2, 1));
|
Chris@16
|
2032 // result == 4 4 2 -1
|
Chris@16
|
2033 data.push_back(Vertex45(Point(4, 4), 2, -1));
|
Chris@16
|
2034 // result == 4 4 -1 -1
|
Chris@16
|
2035 data.push_back(Vertex45(Point(4, 4), -1, -1));
|
Chris@16
|
2036 // result == 4 12 1 1
|
Chris@16
|
2037 data.push_back(Vertex45(Point(4, 12), 1, 1));
|
Chris@16
|
2038 // result == 4 12 2 1
|
Chris@16
|
2039 data.push_back(Vertex45(Point(4, 12), 2, 1));
|
Chris@16
|
2040 // result == 4 16 2 -1
|
Chris@16
|
2041 data.push_back(Vertex45(Point(4, 16), 2, 1));
|
Chris@16
|
2042 // result == 4 16 -1 -1
|
Chris@16
|
2043 data.push_back(Vertex45(Point(4, 16), -1, -1));
|
Chris@16
|
2044 // result == 6 2 1 -1
|
Chris@16
|
2045 data.push_back(Vertex45(Point(6, 2), 1, -1));
|
Chris@16
|
2046 // result == 6 14 -1 1
|
Chris@16
|
2047 data.push_back(Vertex45(Point(6, 14), -1, 1));
|
Chris@16
|
2048 // result == 6 2 -1 1
|
Chris@16
|
2049 data.push_back(Vertex45(Point(6, 2), -1, 1));
|
Chris@16
|
2050 // result == 6 14 1 -1
|
Chris@16
|
2051 data.push_back(Vertex45(Point(6, 14), 1, -1));
|
Chris@16
|
2052 // result == 8 0 -1 -1
|
Chris@16
|
2053 data.push_back(Vertex45(Point(8, 0), -1, -1));
|
Chris@16
|
2054 // result == 8 0 2 -1
|
Chris@16
|
2055 data.push_back(Vertex45(Point(8, 0), 2, -1));
|
Chris@16
|
2056 // result == 8 4 2 1
|
Chris@16
|
2057 data.push_back(Vertex45(Point(8, 4), 2, 1));
|
Chris@16
|
2058 // result == 8 4 1 1
|
Chris@16
|
2059 data.push_back(Vertex45(Point(8, 4), 1, 1));
|
Chris@16
|
2060 // result == 8 12 -1 -1
|
Chris@16
|
2061 data.push_back(Vertex45(Point(8, 12), -1, -1));
|
Chris@16
|
2062 // result == 8 12 2 -1
|
Chris@16
|
2063 data.push_back(Vertex45(Point(8, 12), 2, -1));
|
Chris@16
|
2064 // result == 8 16 2 1
|
Chris@16
|
2065 data.push_back(Vertex45(Point(8, 16), 2, 1));
|
Chris@16
|
2066 // result == 8 16 1 1
|
Chris@16
|
2067 data.push_back(Vertex45(Point(8, 16), 1, 1));
|
Chris@16
|
2068 // result == 12 8 1 -1
|
Chris@16
|
2069 data.push_back(Vertex45(Point(12, 8), 1, -1));
|
Chris@16
|
2070 // result == 12 8 -1 1
|
Chris@16
|
2071 data.push_back(Vertex45(Point(12, 8), -1, 1));
|
Chris@16
|
2072
|
Chris@16
|
2073 data.push_back(Vertex45(Point(6, 4), 1, -1));
|
Chris@16
|
2074 data.push_back(Vertex45(Point(6, 4), 2, -1));
|
Chris@16
|
2075 data.push_back(Vertex45(Point(6, 12), -1, 1));
|
Chris@16
|
2076 data.push_back(Vertex45(Point(6, 12), 2, 1));
|
Chris@16
|
2077 data.push_back(Vertex45(Point(10, 8), -1, -1));
|
Chris@16
|
2078 data.push_back(Vertex45(Point(10, 8), 1, 1));
|
Chris@16
|
2079
|
Chris@16
|
2080 polygon_sort(data.begin(), data.end());
|
Chris@16
|
2081 pf.scan(polys, data.begin(), data.end());
|
Chris@16
|
2082 stdcout << "result size: " << polys.size() << "\n";
|
Chris@16
|
2083 for(std::size_t i = 0; i < polys.size(); ++i) {
|
Chris@16
|
2084 stdcout << polys[i] << "\n";
|
Chris@16
|
2085 }
|
Chris@16
|
2086 stdcout << "done testing polygon tiling\n";
|
Chris@16
|
2087 return true;
|
Chris@16
|
2088 }
|
Chris@16
|
2089
|
Chris@16
|
2090 template <typename stream_type>
|
Chris@16
|
2091 static inline bool testPolygon45Tiling(stream_type& stdcout) {
|
Chris@16
|
2092 stdcout << "testing polygon tiling\n";
|
Chris@16
|
2093 Polygon45Tiling pf;
|
Chris@16
|
2094 std::vector<Polygon45WithHoles> polys;
|
Chris@16
|
2095 std::vector<Vertex45> data;
|
Chris@16
|
2096
|
Chris@16
|
2097 data.push_back(Vertex45(Point(0, 0), 0, 1));
|
Chris@16
|
2098 data.push_back(Vertex45(Point(0, 0), 2, 1));
|
Chris@16
|
2099 data.push_back(Vertex45(Point(0, 100), 2, -1));
|
Chris@16
|
2100 data.push_back(Vertex45(Point(0, 100), 0, -1));
|
Chris@16
|
2101 data.push_back(Vertex45(Point(100, 0), 0, -1));
|
Chris@16
|
2102 data.push_back(Vertex45(Point(100, 0), 2, -1));
|
Chris@16
|
2103 data.push_back(Vertex45(Point(100, 100), 2, 1));
|
Chris@16
|
2104 data.push_back(Vertex45(Point(100, 100), 0, 1));
|
Chris@16
|
2105
|
Chris@16
|
2106 data.push_back(Vertex45(Point(2, 2), 0, -1));
|
Chris@16
|
2107 data.push_back(Vertex45(Point(2, 2), 2, -1));
|
Chris@16
|
2108 data.push_back(Vertex45(Point(2, 10), 2, 1));
|
Chris@16
|
2109 data.push_back(Vertex45(Point(2, 10), 0, 1));
|
Chris@16
|
2110 data.push_back(Vertex45(Point(10, 2), 0, 1));
|
Chris@16
|
2111 data.push_back(Vertex45(Point(10, 2), 2, 1));
|
Chris@16
|
2112 data.push_back(Vertex45(Point(10, 10), 2, -1));
|
Chris@16
|
2113 data.push_back(Vertex45(Point(10, 10), 0, -1));
|
Chris@16
|
2114
|
Chris@16
|
2115 data.push_back(Vertex45(Point(2, 12), 0, -1));
|
Chris@16
|
2116 data.push_back(Vertex45(Point(2, 12), 2, -1));
|
Chris@16
|
2117 data.push_back(Vertex45(Point(2, 22), 2, 1));
|
Chris@16
|
2118 data.push_back(Vertex45(Point(2, 22), 0, 1));
|
Chris@16
|
2119 data.push_back(Vertex45(Point(10, 12), 0, 1));
|
Chris@16
|
2120 data.push_back(Vertex45(Point(10, 12), 2, 1));
|
Chris@16
|
2121 data.push_back(Vertex45(Point(10, 22), 2, -1));
|
Chris@16
|
2122 data.push_back(Vertex45(Point(10, 22), 0, -1));
|
Chris@16
|
2123
|
Chris@16
|
2124 polygon_sort(data.begin(), data.end());
|
Chris@16
|
2125 pf.scan(polys, data.begin(), data.end());
|
Chris@16
|
2126 stdcout << "result size: " << polys.size() << "\n";
|
Chris@16
|
2127 for(std::size_t i = 0; i < polys.size(); ++i) {
|
Chris@16
|
2128 stdcout << polys[i] << "\n";
|
Chris@16
|
2129 }
|
Chris@16
|
2130 stdcout << "done testing polygon tiling\n";
|
Chris@16
|
2131 return true;
|
Chris@16
|
2132 }
|
Chris@16
|
2133 };
|
Chris@16
|
2134
|
Chris@16
|
2135 template <typename Unit>
|
Chris@16
|
2136 class PolyLine45HoleData {
|
Chris@16
|
2137 public:
|
Chris@16
|
2138 typedef typename polygon_45_formation<Unit>::ActiveTail45 ActiveTail45;
|
Chris@16
|
2139 typedef typename ActiveTail45::iterator iterator;
|
Chris@16
|
2140
|
Chris@16
|
2141 typedef polygon_45_concept geometry_type;
|
Chris@16
|
2142 typedef Unit coordinate_type;
|
Chris@16
|
2143 typedef point_data<Unit> Point;
|
Chris@16
|
2144 typedef Point point_type;
|
Chris@16
|
2145 // typedef iterator_points_to_compact<iterator, Point> compact_iterator_type;
|
Chris@16
|
2146 typedef iterator iterator_type;
|
Chris@16
|
2147 typedef typename coordinate_traits<Unit>::area_type area_type;
|
Chris@16
|
2148
|
Chris@16
|
2149 inline PolyLine45HoleData() : p_(0) {}
|
Chris@16
|
2150 inline PolyLine45HoleData(ActiveTail45* p) : p_(p) {}
|
Chris@16
|
2151 //use default copy and assign
|
Chris@16
|
2152 inline iterator begin() const { return p_->getTail()->begin(); }
|
Chris@16
|
2153 inline iterator end() const { return p_->getTail()->end(); }
|
Chris@16
|
2154 inline std::size_t size() const { return 0; }
|
Chris@16
|
2155 template<class iT>
|
Chris@16
|
2156 inline PolyLine45HoleData& set(iT inputBegin, iT inputEnd) {
|
Chris@16
|
2157 return *this;
|
Chris@16
|
2158 }
|
Chris@16
|
2159 private:
|
Chris@16
|
2160 ActiveTail45* p_;
|
Chris@16
|
2161 };
|
Chris@16
|
2162
|
Chris@16
|
2163 template <typename Unit>
|
Chris@16
|
2164 class PolyLine45PolygonData {
|
Chris@16
|
2165 public:
|
Chris@16
|
2166 typedef typename polygon_45_formation<Unit>::ActiveTail45 ActiveTail45;
|
Chris@16
|
2167 typedef typename ActiveTail45::iterator iterator;
|
Chris@16
|
2168 typedef PolyLine45HoleData<Unit> holeType;
|
Chris@16
|
2169
|
Chris@16
|
2170 typedef polygon_45_with_holes_concept geometry_type;
|
Chris@16
|
2171 typedef Unit coordinate_type;
|
Chris@16
|
2172 typedef point_data<Unit> Point;
|
Chris@16
|
2173 typedef Point point_type;
|
Chris@16
|
2174 // typedef iterator_points_to_compact<iterator, Point> compact_iterator_type;
|
Chris@16
|
2175 typedef iterator iterator_type;
|
Chris@16
|
2176 typedef holeType hole_type;
|
Chris@16
|
2177 typedef typename coordinate_traits<Unit>::area_type area_type;
|
Chris@16
|
2178 class iteratorHoles {
|
Chris@16
|
2179 private:
|
Chris@16
|
2180 typename ActiveTail45::iteratorHoles itr_;
|
Chris@16
|
2181 public:
|
Chris@16
|
2182 typedef PolyLine45HoleData<Unit> holeType;
|
Chris@16
|
2183 typedef holeType value_type;
|
Chris@16
|
2184 typedef std::forward_iterator_tag iterator_category;
|
Chris@16
|
2185 typedef std::ptrdiff_t difference_type;
|
Chris@16
|
2186 typedef const value_type* pointer; //immutable
|
Chris@16
|
2187 typedef const value_type& reference; //immutable
|
Chris@16
|
2188 inline iteratorHoles() : itr_() {}
|
Chris@16
|
2189 inline iteratorHoles(typename ActiveTail45::iteratorHoles itr) : itr_(itr) {}
|
Chris@16
|
2190 inline iteratorHoles(const iteratorHoles& that) : itr_(that.itr_) {}
|
Chris@16
|
2191 inline iteratorHoles& operator=(const iteratorHoles& that) {
|
Chris@16
|
2192 itr_ = that.itr_;
|
Chris@16
|
2193 return *this;
|
Chris@16
|
2194 }
|
Chris@16
|
2195 inline bool operator==(const iteratorHoles& that) { return itr_ == that.itr_; }
|
Chris@16
|
2196 inline bool operator!=(const iteratorHoles& that) { return itr_ != that.itr_; }
|
Chris@16
|
2197 inline iteratorHoles& operator++() {
|
Chris@16
|
2198 ++itr_;
|
Chris@16
|
2199 return *this;
|
Chris@16
|
2200 }
|
Chris@16
|
2201 inline const iteratorHoles operator++(int) {
|
Chris@16
|
2202 iteratorHoles tmp = *this;
|
Chris@16
|
2203 ++(*this);
|
Chris@16
|
2204 return tmp;
|
Chris@16
|
2205 }
|
Chris@16
|
2206 inline holeType operator*() {
|
Chris@16
|
2207 return *itr_;
|
Chris@16
|
2208 }
|
Chris@16
|
2209 };
|
Chris@16
|
2210 typedef iteratorHoles iterator_holes_type;
|
Chris@16
|
2211
|
Chris@16
|
2212
|
Chris@16
|
2213 inline PolyLine45PolygonData() : p_(0) {}
|
Chris@16
|
2214 inline PolyLine45PolygonData(ActiveTail45* p) : p_(p) {}
|
Chris@16
|
2215 //use default copy and assign
|
Chris@16
|
2216 inline iterator begin() const { return p_->getTail()->begin(); }
|
Chris@16
|
2217 inline iterator end() const { return p_->getTail()->end(); }
|
Chris@16
|
2218 inline iteratorHoles begin_holes() const { return iteratorHoles(p_->getHoles().begin()); }
|
Chris@16
|
2219 inline iteratorHoles end_holes() const { return iteratorHoles(p_->getHoles().end()); }
|
Chris@16
|
2220 inline ActiveTail45* yield() { return p_; }
|
Chris@16
|
2221 //stub out these four required functions that will not be used but are needed for the interface
|
Chris@16
|
2222 inline std::size_t size_holes() const { return 0; }
|
Chris@16
|
2223 inline std::size_t size() const { return 0; }
|
Chris@16
|
2224 template<class iT>
|
Chris@16
|
2225 inline PolyLine45PolygonData& set(iT inputBegin, iT inputEnd) {
|
Chris@16
|
2226 return *this;
|
Chris@16
|
2227 }
|
Chris@16
|
2228
|
Chris@16
|
2229 // initialize a polygon from x,y values, it is assumed that the first is an x
|
Chris@16
|
2230 // and that the input is a well behaved polygon
|
Chris@16
|
2231 template<class iT>
|
Chris@16
|
2232 inline PolyLine45PolygonData& set_holes(iT inputBegin, iT inputEnd) {
|
Chris@16
|
2233 return *this;
|
Chris@16
|
2234 }
|
Chris@16
|
2235 private:
|
Chris@16
|
2236 ActiveTail45* p_;
|
Chris@16
|
2237 };
|
Chris@16
|
2238
|
Chris@16
|
2239 template <typename T>
|
Chris@16
|
2240 struct PolyLineByConcept<T, polygon_45_with_holes_concept> { typedef PolyLine45PolygonData<T> type; };
|
Chris@16
|
2241 template <typename T>
|
Chris@16
|
2242 struct PolyLineByConcept<T, polygon_with_holes_concept> { typedef PolyLine45PolygonData<T> type; };
|
Chris@16
|
2243 template <typename T>
|
Chris@16
|
2244 struct PolyLineByConcept<T, polygon_45_concept> { typedef PolyLine45HoleData<T> type; };
|
Chris@16
|
2245 template <typename T>
|
Chris@16
|
2246 struct PolyLineByConcept<T, polygon_concept> { typedef PolyLine45HoleData<T> type; };
|
Chris@16
|
2247
|
Chris@16
|
2248 template <typename T>
|
Chris@16
|
2249 struct geometry_concept<PolyLine45PolygonData<T> > { typedef polygon_45_with_holes_concept type; };
|
Chris@16
|
2250 template <typename T>
|
Chris@16
|
2251 struct geometry_concept<PolyLine45HoleData<T> > { typedef polygon_45_concept type; };
|
Chris@16
|
2252
|
Chris@16
|
2253 }
|
Chris@16
|
2254 }
|
Chris@16
|
2255 #endif
|