def process_ver_scanline(self, scanline): if DEBUG_POLYGONEXTRACTOR3: prev = None for p in scanline: if p.dir == 0: self.cont.fill("red") else: self.cont.fill("blue") self.cont.AddDot(p[0], p[1]) self.cont.fill("black") self.cont.AddText(p[0], p[1], str(p.id)) if prev: self.cont.AddLine(prev[0], prev[1], p[0], p[1]) prev = p if DEBUG_POLYGONEXTRACTOR: last = 0 inside = False s = "" for point in scanline: next_y = point[1] if inside: s += "*" * int(next_y - last) else: s += " " * int(next_y - last) last = next_y inside = not inside print(s) if DEBUG_POLYGONEXTRACTOR: print("active paths: "), for path in self.curr_path_list: print("%d(%g,%g)" % (path.id, path.points[-1][0], path.points[-1][1])), print() print("prev points: "), for point in self.prev_line: print("(%g,%g)" % (point[0], point[1])), print() print("active points: "), for point in scanline: print("%d(%g,%g)" % (point.id, point[0], point[1])), print() prev_point = Iterator(self.prev_line) curr_point = Iterator(scanline) curr_path = Iterator(self.curr_path_list) winding = 0 while (prev_point.remains() > 0) or (curr_point.remains() > 0): if DEBUG_POLYGONEXTRACTOR: print("num_prev=%d, num_curr=%d" % (prev_point.remains(), curr_point.remains())) if (prev_point.remains() == 0) and (curr_point.remains() >= 2): c0 = next(curr_point) c1 = next(curr_point) # new path starts p0 = Path() p0.winding = winding + 1 if DEBUG_POLYGONEXTRACTOR: print("new path %d(%g,%g)" % (p0.id, c0[0], c0[1])) p0.append(c0) self.curr_path_list.append(p0) p1 = Path() p1.winding = winding if DEBUG_POLYGONEXTRACTOR: print("new path %d(%g,%g)" % (p1.id, c1[0], c1[1])) p1.append(c1) self.curr_path_list.append(p1) p0.top_join = p1 p1.top_join = p0 continue if (prev_point.remains() >= 2) and (curr_point.remains() == 0): # old path ends p0 = curr_path.takeNext() if DEBUG_POLYGONEXTRACTOR: print("end path %d" % p0.id) self.all_path_list.append(p0) next(prev_point) p1 = curr_path.takeNext() if DEBUG_POLYGONEXTRACTOR: print("end path %d" % p1.id) self.all_path_list.append(p1) next(prev_point) p0.bot_join = p1 p1.bot_join = p0 continue if (prev_point.remains() >= 2) and (curr_point.remains() >= 2): p0 = prev_point.peek(0) p1 = prev_point.peek(1) c0 = curr_point.peek(0) c1 = curr_point.peek(1) if DEBUG_POLYGONEXTRACTOR: print("overlap test: p0=%g p1=%g" % (p0[0], p1[0])) print("overlap test: c0=%g c1=%g" % (c0[0], c1[0])) if c1[1] < p0[1]: # new segment is completely to the left # new path starts s0 = Path() if DEBUG_POLYGONEXTRACTOR: print("new path %d(%g,%g) w=%d" % (s0.id, c0[0], c0[1], winding + 1)) s0.append(c0) curr_path.insert(s0) s1 = Path() s0.winding = winding + 1 s1.winding = winding if DEBUG_POLYGONEXTRACTOR: print("new path %d(%g,%g) w=%d" % (s1.id, c1[0], c1[1], winding)) s1.append(c1) curr_path.insert(s1) next(curr_point) next(curr_point) s0.top_join = s1 s1.top_join = s0 elif c0[1] > p1[1]: # new segment is completely to the right # old path ends s0 = curr_path.takeNext() if DEBUG_POLYGONEXTRACTOR: print("end path %d" % s0.id) self.all_path_list.append(s0) next(prev_point) s1 = curr_path.takeNext() if DEBUG_POLYGONEXTRACTOR: print("end path %d" % s1.id) self.all_path_list.append(s1) next(prev_point) s0.bot_join = s1 s1.bot_join = s0 winding = s1.winding else: # new segment is overlapping left_path = next(curr_path) right_path = curr_path.peek() left_point = c0 right_point = c1 winding = left_path.winding next(curr_point) next(prev_point) overlap_p = True overlap_c = True while overlap_c or overlap_p: overlap_p = False overlap_c = False # check for path joins if prev_point.remains() >= 2: p2 = prev_point.peek(1) if DEBUG_POLYGONEXTRACTOR: print("join test: p0=%g p1=%g p2=%g" % (p0[0], p1[0], p2[0])) print("join test: c0=%g c1=%g" % (c0[0], c1[0])) if p2[1] <= c1[1]: overlap_p = True if self.policy == PolygonExtractor.CONTOUR: s0 = curr_path.takeNext() s1 = curr_path.takeNext() if curr_path.remains() >= 1: right_path = curr_path.peek() self.all_path_list.append(s0) self.all_path_list.append(s1) if DEBUG_POLYGONEXTRACTOR: print("path %d joins %d" % (s0.id, s1.id)) s0.bot_join = s1 s1.bot_join = s0 elif self.policy == PolygonExtractor.MONOTONE: s0 = curr_path.takeNext() left_path.bot_join = s0 s0.bot_join = left_path if DEBUG_POLYGONEXTRACTOR: print("path %d joins %d" % (left_path.id, s0.id)) curr_path.remove(left_path) self.all_path_list.append(left_path) self.all_path_list.append(s0) s1 = next(curr_path) left_path = s1 right_path = curr_path.peek() next(prev_point) next(prev_point) winding = s1.winding p0 = p2 if prev_point.remains() >= 1: p1 = prev_point.peek(0) else: overlap_p = False # check for path splits if curr_point.remains() >= 2: c2 = curr_point.peek(1) if DEBUG_POLYGONEXTRACTOR: print("split test: p0=%g p1=%g" % (p0[0], p1[0])) print("split test: c0=%g c1=%g c2=%g" % (c0[0], c1[0], c2[0])) if c2[1] <= p1[1]: overlap_c = True s0 = Path() s1 = Path() s0.winding = winding + 1 s1.winding = winding s0.top_join = s1 s1.top_join = s0 if DEBUG_POLYGONEXTRACTOR: print( "region split into %d and %d (w=%d)" % (s0.id, s1.id, winding + 1)) next(curr_point) c0 = next(curr_point) if self.policy == PolygonExtractor.CONTOUR: s0.append(c1) curr_path.insert(s0) s1.append(c2) curr_path.insert(s1) elif self.policy == PolygonExtractor.MONOTONE: s0.append(left_point) s1.append(c1) curr_path.insertBefore(s0) curr_path.insertBefore(s1) left_point = c2 if curr_point.remains() >= 1: c1 = curr_point.peek(0) right_point = c1 else: overlap_c = False if DEBUG_POLYGONEXTRACTOR: print("add to path %d(%g,%g)" % (left_path.id, left_point[0], left_point[1])) left_path.append(left_point) right_path.append(right_point) if right_path == curr_path.peek(): next(curr_path) if DEBUG_POLYGONEXTRACTOR: print("add to path %d(%g,%g)" % (right_path.id, right_point[0], right_point[1])) winding = right_path.winding next(prev_point) next(curr_point) if DEBUG_POLYGONEXTRACTOR: output = "active paths: " for path in self.curr_path_list: output += "%d(%g,%g,w=%d)" % (path.id, path.points[-1][0], path.points[-1][1], path.winding) print(output) self.prev_line = scanline
def process_ver_scanline(self, scanline): if DEBUG_POLYGONEXTRACTOR3: prev = None for p in scanline: if p.dir == 0: self.cont.fill("red") else: self.cont.fill("blue") self.cont.AddDot(p.x, p.y) self.cont.fill("black") self.cont.AddText(p.x, p.y, str(p.id)) if prev: self.cont.AddLine(prev.x, prev.y, p.x, p.y) prev = p if DEBUG_POLYGONEXTRACTOR: last = 0 inside = False s = "" for point in scanline: next_y = point.y if inside: s += "*" * int(next_y - last) else: s += " " * int(next_y - last) last = next_y inside = not inside print s if DEBUG_POLYGONEXTRACTOR: print "active paths: ", for path in self.curr_path_list: print "%d(%g,%g)" \ % (path.id, path.points[-1].x, path.points[-1].y), print print "prev points: ", for point in self.prev_line: print "(%g,%g)" % (point.x, point.y), print print "active points: ", for point in scanline: print "%d(%g,%g)" % (point.id, point.x, point.y), print prev_point = Iterator(self.prev_line) curr_point = Iterator(scanline) curr_path = Iterator(self.curr_path_list) winding = 0 while (prev_point.remains() > 0) or (curr_point.remains() > 0): if DEBUG_POLYGONEXTRACTOR: print "num_prev=%d, num_curr=%d" \ % (prev_point.remains(), curr_point.remains()) if (prev_point.remains() == 0) and (curr_point.remains() >= 2): c0 = curr_point.next() c1 = curr_point.next() # new path starts p0 = Path() p0.winding = winding + 1 if DEBUG_POLYGONEXTRACTOR: print "new path %d(%g,%g)" % (p0.id, c0.x, c0.y) p0.append(c0) self.curr_path_list.append(p0) p1 = Path() p1.winding = winding if DEBUG_POLYGONEXTRACTOR: print "new path %d(%g,%g)" % (p1.id, c1.x, c1.y) p1.append(c1) self.curr_path_list.append(p1) p0.top_join = p1 p1.top_join = p0 continue if (prev_point.remains() >= 2) and (curr_point.remains() == 0): #old path ends p0 = curr_path.takeNext() if DEBUG_POLYGONEXTRACTOR: print "end path %d" % p0.id self.all_path_list.append(p0) prev_point.next() p1 = curr_path.takeNext() if DEBUG_POLYGONEXTRACTOR: print "end path %d" % p1.id self.all_path_list.append(p1) prev_point.next() p0.bot_join = p1 p1.bot_join = p0 continue if (prev_point.remains() >= 2) and (curr_point.remains() >= 2): p0 = prev_point.peek(0) p1 = prev_point.peek(1) c0 = curr_point.peek(0) c1 = curr_point.peek(1) if DEBUG_POLYGONEXTRACTOR: print "overlap test: p0=%g p1=%g" % (p0.x, p1.x) print "overlap test: c0=%g c1=%g" % (c0.x, c1.x) if c1.y < p0.y: # new segment is completely to the left # new path starts s0 = Path() if DEBUG_POLYGONEXTRACTOR: print "new path %d(%g,%g) w=%d" \ % (s0.id, c0.x, c0.y, winding + 1) s0.append(c0) curr_path.insert(s0) s1 = Path() s0.winding = winding + 1 s1.winding = winding if DEBUG_POLYGONEXTRACTOR: print "new path %d(%g,%g) w=%d" \ % (s1.id, c1.x, c1.y, winding) s1.append(c1) curr_path.insert(s1) curr_point.next() curr_point.next() s0.top_join = s1 s1.top_join = s0 elif c0.y > p1.y: # new segment is completely to the right # old path ends s0 = curr_path.takeNext() if DEBUG_POLYGONEXTRACTOR: print "end path %d" % s0.id self.all_path_list.append(s0) prev_point.next() s1 = curr_path.takeNext() if DEBUG_POLYGONEXTRACTOR: print "end path %d" % s1.id self.all_path_list.append(s1) prev_point.next() s0.bot_join = s1 s1.bot_join = s0 winding = s1.winding else: # new segment is overlapping left_path = curr_path.next() right_path = curr_path.peek() left_point = c0 right_point = c1 winding = left_path.winding curr_point.next() prev_point.next() overlap_p = True overlap_c = True while overlap_c or overlap_p: overlap_p = False overlap_c = False # check for path joins if prev_point.remains() >= 2: p2 = prev_point.peek(1) if DEBUG_POLYGONEXTRACTOR: print "join test: p0=%g p1=%g p2=%g" \ % (p0.x, p1.x, p2.x) print "join test: c0=%g c1=%g" % (c0.x, c1.x) if p2.y <= c1.y: overlap_p = True if self.policy == PolygonExtractor.CONTOUR: s0 = curr_path.takeNext() s1 = curr_path.takeNext() if curr_path.remains() >= 1: right_path = curr_path.peek() self.all_path_list.append(s0) self.all_path_list.append(s1) if DEBUG_POLYGONEXTRACTOR: print "path %d joins %d" \ % (s0.id, s1.id) s0.bot_join = s1 s1.bot_join = s0 elif self.policy == PolygonExtractor.MONOTONE: s0 = curr_path.takeNext() left_path.bot_join = s0 s0.bot_join = left_path if DEBUG_POLYGONEXTRACTOR: print "path %d joins %d" \ % (left_path.id, s0.id) curr_path.remove(left_path) self.all_path_list.append(left_path) self.all_path_list.append(s0) s1 = curr_path.next() left_path = s1 right_path = curr_path.peek() prev_point.next() prev_point.next() winding = s1.winding p0 = p2 if prev_point.remains() >= 1: p1 = prev_point.peek(0) else: overlap_p = False # check for path splits if curr_point.remains()>=2: c2 = curr_point.peek(1) if DEBUG_POLYGONEXTRACTOR: print "split test: p0=%g p1=%g" % (p0.x, p1.x) print "split test: c0=%g c1=%g c2=%g" \ % (c0.x, c1.x, c2.x) if c2.y <= p1.y: overlap_c = True s0 = Path() s1 = Path() s0.winding = winding + 1 s1.winding = winding s0.top_join = s1 s1.top_join = s0 if DEBUG_POLYGONEXTRACTOR: print "region split into %d and %d (w=%d)" \ % (s0.id, s1.id, winding + 1) curr_point.next() c0 = curr_point.next() if self.policy == PolygonExtractor.CONTOUR: s0.append(c1) curr_path.insert(s0) s1.append(c2) curr_path.insert(s1) elif self.policy == PolygonExtractor.MONOTONE: s0.append(left_point) s1.append(c1) curr_path.insertBefore(s0) curr_path.insertBefore(s1) left_point = c2 if curr_point.remains() >= 1: c1 = curr_point.peek(0) right_point = c1 else: overlap_c = False if DEBUG_POLYGONEXTRACTOR: print "add to path %d(%g,%g)" \ % (left_path.id, left_point.x, left_point.y) left_path.append(left_point) right_path.append(right_point) if right_path == curr_path.peek(): curr_path.next() if DEBUG_POLYGONEXTRACTOR: print "add to path %d(%g,%g)" \ % (right_path.id, right_point.x, right_point.y) winding = right_path.winding prev_point.next() curr_point.next() if DEBUG_POLYGONEXTRACTOR: print "active paths: ", for path in self.curr_path_list: print "%d(%g,%g,w=%d)" % (path.id, path.points[-1].x, path.points[-1].y, path.winding), print self.prev_line = scanline
def process_hor_scanline(self, scanline): if DEBUG_POLYGONEXTRACTOR: last = 0 inside = False s = "" for point in scanline: next_x = point.x if inside: s += "*" * int(next_x - last) else: s += " " * int(next_x - last) last = next_x inside = not inside print s if DEBUG_POLYGONEXTRACTOR: print "active paths: ", for path in self.curr_path_list: print "%d(%g,%g)" \ % (path.id, path.points[-1].x, path.points[-1].y), print print "prev points: ", for point in self.prev_line: print "(%g,%g)" % (point.x, point.y), print print "active points: ", for point in scanline: print "%d(%g,%g)" % (point.id, point.x, point.y), print prev_point = Iterator(self.prev_line) curr_point = Iterator(scanline) curr_path = Iterator(self.curr_path_list) winding = 0 while (prev_point.remains() > 0) or (curr_point.remains() > 0): if DEBUG_POLYGONEXTRACTOR: print "num_prev=%d, num_curr=%d" \ % (prev_point.remains(), curr_point.remains()) if (prev_point.remains() == 0) and (curr_point.remains() >= 2): c0 = curr_point.next() c1 = curr_point.next() # new path starts p0 = Path() p0.winding = winding + 1 if DEBUG_POLYGONEXTRACTOR: print "new path %d(%g,%g)" % (p0.id, c0.x, c0.y) p0.append(c0) self.curr_path_list.append(p0) p1 = Path() p1.winding = winding if DEBUG_POLYGONEXTRACTOR: print "new path %d(%g,%g)" % (p1.id, c1.x, c1.y) p1.append(c1) self.curr_path_list.append(p1) p0.top_join = p1 p1.top_join = p0 continue if (prev_point.remains() >= 2) and (curr_point.remains() == 0): #old path ends p0 = curr_path.takeNext() if DEBUG_POLYGONEXTRACTOR: print "end path %d" % p0.id self.all_path_list.append(p0) prev_point.next() p1 = curr_path.takeNext() if DEBUG_POLYGONEXTRACTOR: print "end path %d" % p1.id self.all_path_list.append(p1) prev_point.next() p0.bot_join = p1 p1.bot_join = p0 continue if (prev_point.remains() >= 2) and (curr_point.remains() >= 2): p0 = prev_point.peek(0) p1 = prev_point.peek(1) c0 = curr_point.peek(0) c1 = curr_point.peek(1) if DEBUG_POLYGONEXTRACTOR: print "overlap test: p0=%g p1=%g" % (p0.x, p1.x) print "overlap test: c0=%g c1=%g" % (c0.x, c1.x) if c1.x < p0.x: # new segment is completely to the left # new path starts s0 = Path() if DEBUG_POLYGONEXTRACTOR: print "new path %d(%g,%g) w=%d" \ % (s0.id, c0.x, c0.y, winding + 1) s0.append(c0) curr_path.insert(s0) s1 = Path() s0.winding = winding + 1 s1.winding = winding if DEBUG_POLYGONEXTRACTOR: print "new path %d(%g,%g) w=%d" \ % (s1.id, c1.x, c1.y, winding) s1.append(c1) curr_path.insert(s1) curr_point.next() curr_point.next() s0.top_join = s1 s1.top_join = s0 elif c0.x > p1.x: # new segment is completely to the right # old path ends s0 = curr_path.takeNext() if DEBUG_POLYGONEXTRACTOR: print "end path %d" % s0.id self.all_path_list.append(s0) prev_point.next() s1 = curr_path.takeNext() if DEBUG_POLYGONEXTRACTOR: print "end path %d" % s1.id self.all_path_list.append(s1) prev_point.next() s0.bot_join = s1 s1.bot_join = s0 winding = s1.winding else: # new segment is overlapping left_path = curr_path.next() right_path = curr_path.peek() left_point = c0 right_point = c1 winding = left_path.winding curr_point.next() prev_point.next() overlap_p = True overlap_c = True while overlap_c or overlap_p: overlap_p = False overlap_c = False # check for path joins if prev_point.remains() >= 2: p2 = prev_point.peek(1) if DEBUG_POLYGONEXTRACTOR: print "join test: p0=%g p1=%g p2=%g" \ % (p0.x, p1.x, p2.x) print "join test: c0=%g c1=%g" % (c0.x, c1.x) if p2.x <= c1.x: overlap_p = True if self.policy == PolygonExtractor.CONTOUR: s0 = curr_path.takeNext() s1 = curr_path.takeNext() if curr_path.remains() >= 1: right_path = curr_path.peek() self.all_path_list.append(s0) self.all_path_list.append(s1) if DEBUG_POLYGONEXTRACTOR: print "path %d joins %d" \ % (s0.id, s1.id) s0.bot_join = s1 s1.bot_join = s0 elif self.policy == PolygonExtractor.MONOTONE: s0 = curr_path.takeNext() left_path.bot_join = s0 s0.bot_join = left_path if DEBUG_POLYGONEXTRACTOR: print "path %d joins %d" \ % (left_path.id, s0.id) curr_path.remove(left_path) self.all_path_list.append(left_path) self.all_path_list.append(s0) s1 = curr_path.next() left_path = s1 right_path = curr_path.peek() prev_point.next() prev_point.next() winding = s1.winding p0 = p2 if prev_point.remains() >= 1: p1 = prev_point.peek(0) else: overlap_p = False # check for path splits if curr_point.remains() >= 2: c2 = curr_point.peek(1) if DEBUG_POLYGONEXTRACTOR: print "split test: p0=%g p1=%g" % (p0.x, p1.x) print "split test: c0=%g c1=%g c2=%g" \ % (c0.x, c1.x, c2.x) if c2.x <= p1.x: overlap_c = True s0 = Path() s1 = Path() s0.winding = winding + 1 s1.winding = winding s0.top_join = s1 s1.top_join = s0 if DEBUG_POLYGONEXTRACTOR: print "region split into %d and %d (w=%d)" \ % (s0.id, s1.id, winding + 1) curr_point.next() c0 = curr_point.next() if self.policy == PolygonExtractor.CONTOUR: s0.append(c1) curr_path.insert(s0) s1.append(c2) curr_path.insert(s1) elif self.policy == PolygonExtractor.MONOTONE: s0.append(left_point) s1.append(c1) curr_path.insertBefore(s0) curr_path.insertBefore(s1) left_point = c2 if curr_point.remains() >= 1: c1 = curr_point.peek(0) right_point = c1 else: overlap_c = False if DEBUG_POLYGONEXTRACTOR: print "add to path %d(%g,%g)" \ % (left_path.id, left_point.x, left_point.y) left_path.append(left_point) right_path.append(right_point) if right_path == curr_path.peek(): curr_path.next() if DEBUG_POLYGONEXTRACTOR: print "add to path %d(%g,%g)" \ % (right_path.id, right_point.x, right_point.y) winding = right_path.winding prev_point.next() curr_point.next() if DEBUG_POLYGONEXTRACTOR: print "active paths: ", for path in self.curr_path_list: print "%d(%g,%g,w=%d)" % (path.id, path.points[-1].x, path.points[-1].y, path.winding), print self.prev_line = scanline