def __init__(self, size=1, color=1, line_width=1, line_color=1, shape=1, labels=False, *args, **kwargs): if size > 10: print >> sys.stderr, 'WARNING: Node size > 10: ' + \ 'will be set to 10' DataSet.__init__(self, *args, **kwargs) for aNode in self.data: self.parent.node_xy[aNode] = self.data[aNode][0:2] if self.type == 'xysize': if aNode not in self.parent.node_sz: self.parent.node_sz[aNode] = self.data[aNode][2] else: if aNode not in self.parent.node_sz: self.parent.node_sz[aNode] = size try: if labels: self.data = [values + (label, ) for label, values in self.data.items()] else: self.data = [values for label,values in self.data.items()] except: raise TypeError( 'data for a NodeSet must be a dictionary' ) self.symbol.configure(size=size, fill_color=color, linewidth=line_width, color=line_color, shape=shape) self.line.linestyle = 0 if labels: self.avalue.onoff='on'
def __init__(self, size=1, color=1, ignore_missing=False, *args, **kwargs): DataSet.__init__(self, *args, **kwargs) theData = [] try: for n1, n2, in self.data: try: x1, y1 = self.parent.node_xy[n1] x2, y2 = self.parent.node_xy[n2] theData.append((x1, y1)) theData.append((x2, y2)) except KeyError: if ignore_missing: print >> sys.stderr, 'WARNING: ignoring link %s-%s' % ( n1, n2 ) else: raise KeyError( 'nodes should be added to the network first' ) self.data = theData except: raise TypeError( 'data must be a list of node pairs' ) self.symbol.shape = 0 self.line.configure(type=4, linestyle=1, linewidth=size, color=color)
def __init__(self, color, *args, **kwargs): DataSet.__init__(self, *args, **kwargs) # shading and line self.symbol.configure(shape=0, fill_color=color, color=color) self.line.configure(type=1, linestyle=1, color=color) self.fill.configure(type=2, color=color, pattern=1) self.baseline.type = 3
def __init__(self, color, outline_color=1, *args, **kwargs): DataSet.__init__(self, *args, **kwargs) if len(self.data) != 2: raise TypeError, 'Data for SolidOutlinedRectangle MUST contain 2 points' x0 = self.data[0][0] x1 = self.data[1][0] y0 = min(self.data[0][1], self.data[1][1]) y1 = max(self.data[0][1], self.data[1][1]) self.data = [(x0, y1), (x1, y1), (x1, y0), (x0, y0), (x0,y1)] self.symbol.configure(shape=0) self.line.configure(linewidth=0, color=outline_color) self.fill.configure(type=2, rule=0, color=color) self.baseline.configure(type=1)
def __init__(self, color, outline_color=1, *args, **kwargs): DataSet.__init__(self, *args, **kwargs) if len(self.data) != 2: raise TypeError, 'Data for SolidOutlinedRectangle MUST contain 2 points' x0 = self.data[0][0] x1 = self.data[1][0] y0 = min(self.data[0][1], self.data[1][1]) y1 = max(self.data[0][1], self.data[1][1]) self.data = [(x0, y1), (x1, y1), (x1, y0), (x0, y0), (x0, y1)] self.symbol.configure(shape=0) self.line.configure(linewidth=0, color=outline_color) self.fill.configure(type=2, rule=0, color=color) self.baseline.configure(type=1)
def __init__(self, size=1, color=1, line_width=1, line_color=1, shape=1, labels=False, *args, **kwargs): if size > 10: print >> sys.stderr, 'WARNING: Node size > 10: ' + \ 'will be set to 10' DataSet.__init__(self, *args, **kwargs) for aNode in self.data: self.parent.node_xy[aNode] = self.data[aNode][0:2] if self.type == 'xysize': if aNode not in self.parent.node_sz: self.parent.node_sz[aNode] = self.data[aNode][2] else: if aNode not in self.parent.node_sz: self.parent.node_sz[aNode] = size try: if labels: self.data = [ values + (label, ) for label, values in self.data.iteritems() ] else: self.data = [values for label, values in self.data.iteritems()] except: raise TypeError, 'data for a NodeSet must be a dictionary' self.symbol.configure(size=size, fill_color=color, linewidth=line_width, color=line_color, shape=shape) self.line.linestyle = 0 if labels: self.avalue.onoff = 'on'
def __init__(self, size=1, color=1, ignore_missing=False, *args, **kwargs): DataSet.__init__(self, *args, **kwargs) theData = [] try: for n1, n2, in self.data: try: x1, y1 = self.parent.node_xy[n1] x2, y2 = self.parent.node_xy[n2] theData.append((x1, y1)) theData.append((x2, y2)) except KeyError: if ignore_missing: print >> sys.stderr, 'WARNING: ignoring link %s-%s' % ( n1, n2) else: raise KeyError, \ 'nodes should be added to the network first' self.data = theData except: raise TypeError, 'data must be a list of node pairs' self.symbol.shape = 0 self.line.configure(type=4, linestyle=1, linewidth=size, color=color)
def __init__(self, size=1, color=1, avoid_crossing_nodes=True, put_arrows=True, curvature=.6, arrow_position=0.75, *args, **kwargs): # -- Preferences (Fixed manual tweaks - not arguments) ----- # radius buffer percentage for determining where the circle # of a node ends. To avoid links curving around but still # touching the nodes node_border_buffer_percentage = 0.08 # The threshold percentage of points in a link that are under the target # and the source. If this much or more are covered, the links try to bend # themselves, so that more of them are visible. bad_cover_percentage = 0.29 # ---------------------- DataSet.__init__(self, *args, **kwargs) if arrow_position > 1.0: arrow_position = 1.0 elif arrow_position < 0.0: arrow_position = 0.0 newData = [] # -- loop over each link -- # for n1, n2, in self.data: curveData = [] xi, yi = self.parent.node_xy[n1] xf, yf = self.parent.node_xy[n2] source = n1 target = n2 # Quadratic Bezier curve curve = Bezier(xi, yi, xf, yf, curvature=curvature) wxmin, wymin, wxmax, wymax = kwargs['parent'].get_world() vxmin, vymin, vxmax, vymax = kwargs['parent'].get_view() # compute the scaling factor between items in the world space and in the view space # asuming that one uses circular node symbols # if the view space is not square, there are potential issues ratio = min((wxmax - wxmin) / (vxmax - vxmin), (wymax - wymin) / (vymax - vymin)) def point_under_node(x, y, node, buffer_perc=0.00): """given a point and a node label, checks if point is under the node symbol""" # get node info x0, y0 = self.parent.node_xy[node] r = (self.parent.node_sz[node] / 100.) * ratio * (1 + buffer_perc) # check if point is under the node (within the circle) if (x - x0)**2 + (y - y0)**2 <= r**2: return True else: return False if avoid_crossing_nodes: #################################################################### # Now check if the curve is under any other node # # but the source and the target. If it is, change curvature, # # check again: # # CURVE AROUND NODES IN YOUR WAY # while True: giveup = False recheck = False increment = 0.3 for x, y in curve.points(1000)[1:-1]: for n in self.parent.node_xy: if n in (source, target): # we won't try to curve around these continue # check if point is under the node (within the circle) if point_under_node( x, y, n, buffer_perc=node_border_buffer_percentage): # point is indeed under it. curve away and recheck. recheck = True if 0 < curve.curvature < 10: curve.change_curvature(curve.curvature + increment) elif curve.curvature > 10: curve.change_curvature(-.4) elif -10 < curve.curvature <= 0: curve.change_curvature(curve.curvature - increment) elif curve.curvature < -10: curve.change_curvature(5) giveup = True #print n1,n2, 'under', n, '-> new curvature', curve.curvature break # the loop over nodes to check coverage if recheck or giveup: break # the loop over points of link if recheck and not giveup: continue # the while loop (check coverage again) else: #end of cheking without breaks. Passed the test. break # the while loop # # # # ######------------ -------####### # Check if all the curve is under source and target nodes # # If so, curve it away and back in (give it a high curvature): # # FLARE OUT IF SOURCE AND TARGET COVER YOU # while True: covered = 0 for x, y in curve.points(40)[1:-1]: for n in (source, target): # check if point (x,y) is in the node if point_under_node(x, y, n): covered += 1 if covered / (2 * 38.) >= bad_cover_percentage: # bad_cover_percentage or more is covered # bend a little to show more of yourself # do this again and again until either # the coverage is less than the threshold # or you curved a lot but still couldn't get away # ( threshold to give up: |curvature| = 15 ) if 0 < curve.curvature <= 5: curve.change_curvature(curve.curvature + .4) elif curve.curvature > 5: curve.change_curvature(-1.4) elif 0 >= curve.curvature > -15: curve.change_curvature(curve.curvature - .4) elif curve.curvature < -15: break # give up #print n1,n2, 'cover %.1f %%' % (100*covered/(2*38.)), ' -> new curvature', curve.curvature else: # break # # # ################################################################## # This is a linkset, so every point except the # first and the last ones must appear twice # (one segment is plotted, the next ignored) curveData.append((xi, yi)) for x, y in curve.points(120)[1:-1]: curveData.append((x, y)) curveData.append((x, y)) curveData.append((xf, yf)) if put_arrows: ################################################################## # PUT AN ARROWHEAD ON THE LINK # # # # Find the position of the arrow # the range of visible points def visible_points(node1, node2): # scan all points on the curve starting from # center of second node, going back, stop when # you found the fist point NOT under the node. # (the edge of it). node1 and node2 are instances # of start & end nodes. domain = [] # Otherwise, scan for when we get out # from under node 1: node_1_out = len(curveData) - 2 for i in range(1, len(curveData) - 1, 2): x, y = curveData[i] if not point_under_node(x, y, node1): # We broke out from under node 1. # Check if we are already under node 2. node_1_out = i break # If we are already under node 2, nothing is # visible go backwards, say the visible # part is the intersection of nodes! if point_under_node(x, y, node2): if node_1_out == 1: domain = [curveData[0], curveData[1]] for i in range(node_1_out, 1, -2): domain.insert(0, curveData[i]) x, y = curveData[i] if not point_under_node(x, y, node2): if len(domain) == 1: domain.insert(0, curveData[i - 1]) return domain # end of for, we are back at start return domain # But if we are not there yet, scan forwards until you find it node_2_out = len(curveData) - 2 for i in range(node_1_out, len(curveData) - 1, 2): x, y = curveData[i] if point_under_node(x, y, node2): node_2_out = i if len(domain) == 1: domain.append(0, curveData[i + 1]) return domain else: domain.append(curveData[i]) # In case we couldn't fill domain, there aren't any visibles left, # say all is visible if domain == []: domain.append(curveData[0]) for i in range(1, len(curveData) - 1, 2): domain.append(curveData[i]) domain.append(curveData[-1]) # you found it, return it return domain # Find your arrow position domain = visible_points(source, target) i = int(arrow_position * len(domain)) - 1 if i < 1: i = 1 start, end = domain[i - 1], domain[i] self.parent.add_drawing_object(DrawLine, loctype="world", onoff="on", start=start, end=end, linestyle=1, linewidth=size, color=color, arrow=2, arrow_type=1, arrow_length=0.85, arrow_layout=(0.8, 0.8)) # # # # ################################################################## #---------------# # #Write the i j of links (for debugging) # self.parent.add_drawing_object(DrawText, # char_size = .8, # text = '%s %s' % (n1,n2), # loctype="world", # onoff="on", # x = start[0], # y=start[1], # color=color) #---------------# # put the calculated link into the collective data for the linkset. newData.extend(curveData) # -- end of loop over each link -- # # Configure the whole linkset self.data = newData self.symbol.shape = 0 self.line.configure(type=4, linestyle=1, linewidth=size, color=color)
def __init__(self, color, pixelsize=None, square_pixels=True, *args, **kwargs): DataSet.__init__(self, *args, **kwargs) # Sort print >> sys.stderr, "Sorting data." pixeldata = sorted(self.data, key=lambda (x,y): (y,x)) # Determine pixel size if pixelsize is not None: step_x = step_y = pixelsize / 2. else: print >> sys.stderr, "Acquiring pixel size." pixelsizes_x, pixelsizes_y = set(), set() for i in range(len(pixeldata)-1): x0,y0 = pixeldata[i] x1,y1 = pixeldata[i+1] dy = round(y1-y0, 12) dx = round(x1-x0, 12) if dy != 0: pixelsizes_y.add(dy) elif dx != 0: pixelsizes_x.add(dx) if len(pixelsizes_x) > 0 and len(pixelsizes_y) > 0: step_x = min(pixelsizes_x)/2. step_y = min(pixelsizes_y)/2. elif len(pixelsizes_x) == 0 and len(pixelsizes_y) > 0: step_y = min(pixelsizes_y)/2. step_x = step_y elif len(pixelsizes_x) > 0 and len(pixelsizes_y) == 0: step_x = min(pixelsizes_x)/2. step_y = step_x else: step_x = step_y = 0.5 if square_pixels: step_x = step_y = min([step_x, step_y]) # Now we have pixel locations. Draw around the outer pixels, # ignore holes in the middle. print >> sys.stderr, "Tracing the outline of the shape from given pixels." self.data = [] # ---Bottom---------- x,y = pixeldata[0] # first pixel, bottom left xp = x - step_x yp = y - step_y self.data.append((xp,yp)) current_y = round(y,12) # rightmost pixel of first row, bottom right for x,y in pixeldata: if round(y,12) != current_y: # last pixel, bottom right xp = last_x + step_x yp = last_y - step_y self.data.append((xp,yp)) break last_x, last_y = x,y # in case there was only one row and you missed this if round(y,12) == current_y: # still current_y after iteration, we missed it! xp = last_x + step_x yp = last_y - step_y self.data.append((xp,yp)) # ---Right side (scan up, line by line)------ groove_flag = False for x,y in pixeldata: if round(y,12) != current_y: # Last pixel of a row # Finish last groove if you started one if groove_flag: # last pixel, bottom right xp = last_x + step_x yp = last_y - step_y self.data.append((xp,yp)) groove_flag = False # Are we starting a new groove? if round(x,12) != round(last_x,12): # yes, a new groove encountered # last pixel, top right xp = last_x + step_x yp = last_y + step_y self.data.append((xp,yp)) groove_flag = True current_y = round(y,12) last_x, last_y = x,y # in case there was a groove you didn't finish because # we ran out of rows, do it now if groove_flag: # last pixel, bottom right xp = last_x + step_x yp = last_y - step_y self.data.append((xp,yp)) groove_flag = False # ---Top------- x,y = pixeldata[-1] # final pixel, top right xp = x + step_x yp = y + step_y self.data.append((xp,yp)) current_y = round(y,12) # leftmost pixel of highest row, top left for x,y in reversed(pixeldata): if round(y,12) != current_y: # last pixel, top left xp = last_x - step_x yp = last_y + step_y self.data.append((xp,yp)) break last_x, last_y = x,y # in case there was only one row and you missed this if round(y,12) == current_y: # still current_y after iteration, we missed it! xp = last_x - step_x yp = last_y + step_y self.data.append((xp,yp)) # --- Left side (scan backwards [down])------ groove_flag = False for x,y in reversed(pixeldata): if round(y,12) != current_y: # Last pixel of a row # Finish last groove if you started one if groove_flag: # last pixel, top left xp = last_x - step_x yp = last_y + step_y self.data.append((xp,yp)) groove_flag = False # Are we starting a new groove? if round(x,12) != round(last_x,12): # yes, a new groove encountered # last pixel, bottom left xp = last_x - step_x yp = last_y - step_y self.data.append((xp,yp)) groove_flag = True current_y = round(y,12) last_x, last_y = x,y # in case there was a groove you didn't finish because # we ran out of rows, do it now if groove_flag: # last pixel, top left xp = last_x - step_x yp = last_y + step_y self.data.append((xp,yp)) groove_flag = False # --- Complete the shape by repeating the first ever point --- self.data.append(self.data[0]) print >> sys.stderr, "Tracing complete." self.symbol.configure(shape=0) self.line.configure(linewidth=0, color=color) self.fill.configure(type=2, rule=0, color=color) self.baseline.configure(type=1)
def __init__(self, size=1, color=1, avoid_crossing_nodes=True, put_arrows=True, curvature = .6, arrow_position = 0.75, *args, **kwargs): # -- Preferences (Fixed manual tweaks - not arguments) ----- # radius buffer percentage for determining where the circle # of a node ends. To avoid links curving around but still # touching the nodes node_border_buffer_percentage = 0.08 # The threshold percentage of points in a link that are under the target # and the source. If this much or more are covered, the links try to bend # themselves, so that more of them are visible. bad_cover_percentage = 0.29 # ---------------------- DataSet.__init__(self, *args, **kwargs) if arrow_position > 1.0: arrow_position = 1.0 elif arrow_position < 0.0: arrow_position = 0.0 newData = [] # -- loop over each link -- # for n1, n2, in self.data: curveData = [] xi, yi = self.parent.node_xy[n1] xf, yf = self.parent.node_xy[n2] source = n1 target = n2 # Quadratic Bezier curve curve = Bezier(xi,yi,xf,yf, curvature=curvature) wxmin,wymin,wxmax,wymax = kwargs['parent'].get_world() vxmin,vymin,vxmax,vymax = kwargs['parent'].get_view() # compute the scaling factor between items in the world space and in the view space # asuming that one uses circular node symbols # if the view space is not square, there are potential issues ratio = min((wxmax - wxmin)/(vxmax - vxmin),(wymax - wymin)/(vymax - vymin)) def point_under_node(x,y,node, buffer_perc=0.00): """given a point and a node label, checks if point is under the node symbol""" # get node info x0, y0 = self.parent.node_xy[node] r = (self.parent.node_sz[node]/100.) * ratio * (1 + buffer_perc) # check if point is under the node (within the circle) if (x-x0)**2+(y-y0)**2 <= r**2: return True else: return False if avoid_crossing_nodes: #################################################################### # Now check if the curve is under any other node # # but the source and the target. If it is, change curvature, # # check again: # # CURVE AROUND NODES IN YOUR WAY # while True: giveup = False recheck = False increment = 0.3 for x,y in curve.points(1000)[1:-1]: for n in self.parent.node_xy: if n in (source, target): # we won't try to curve around these continue # check if point is under the node (within the circle) if point_under_node(x,y,n, buffer_perc = node_border_buffer_percentage): # point is indeed under it. curve away and recheck. recheck = True if 0 < curve.curvature < 10: curve.change_curvature(curve.curvature + increment) elif curve.curvature > 10: curve.change_curvature(-.4) elif -10 < curve.curvature <= 0: curve.change_curvature(curve.curvature - increment) elif curve.curvature < -10: curve.change_curvature(5) giveup = True #print n1,n2, 'under', n, '-> new curvature', curve.curvature break # the loop over nodes to check coverage if recheck or giveup: break # the loop over points of link if recheck and not giveup: continue # the while loop (check coverage again) else: #end of cheking without breaks. Passed the test. break # the while loop # # # # ######------------ -------####### # Check if all the curve is under source and target nodes # # If so, curve it away and back in (give it a high curvature): # # FLARE OUT IF SOURCE AND TARGET COVER YOU # while True: covered = 0 for x,y in curve.points(40)[1:-1]: for n in (source, target): # check if point (x,y) is in the node if point_under_node(x,y,n): covered += 1 if covered/(2*38.) >= bad_cover_percentage: # bad_cover_percentage or more is covered # bend a little to show more of yourself # do this again and again until either # the coverage is less than the threshold # or you curved a lot but still couldn't get away # ( threshold to give up: |curvature| = 15 ) if 0 < curve.curvature <= 5: curve.change_curvature(curve.curvature + .4) elif curve.curvature > 5: curve.change_curvature(-1.4) elif 0 >= curve.curvature > -15: curve.change_curvature(curve.curvature - .4) elif curve.curvature < -15: break # give up #print n1,n2, 'cover %.1f %%' % (100*covered/(2*38.)), ' -> new curvature', curve.curvature else: # break # # # ################################################################## # This is a linkset, so every point except the # first and the last ones must appear twice # (one segment is plotted, the next ignored) curveData.append((xi, yi)) for x,y in curve.points(120)[1:-1]: curveData.append((x, y)) curveData.append((x, y)) curveData.append((xf, yf)) if put_arrows: ################################################################## # PUT AN ARROWHEAD ON THE LINK # # # # Find the position of the arrow # the range of visible points def visible_points(node1, node2): # scan all points on the curve starting from # center of second node, going back, stop when # you found the fist point NOT under the node. # (the edge of it). node1 and node2 are instances # of start & end nodes. domain = [] # Otherwise, scan for when we get out # from under node 1: node_1_out = len(curveData)-2 for i in range(1, len(curveData)-1, 2): x,y = curveData[i] if not point_under_node(x,y,node1): # We broke out from under node 1. # Check if we are already under node 2. node_1_out = i break # If we are already under node 2, nothing is # visible go backwards, say the visible # part is the intersection of nodes! if point_under_node(x,y,node2): if node_1_out == 1: domain=[curveData[0],curveData[1]] for i in range(node_1_out, 1, -2): domain.insert(0, curveData[i]) x,y = curveData[i] if not point_under_node(x,y,node2): if len(domain) == 1: domain.insert(0, curveData[i-1]) return domain # end of for, we are back at start return domain # But if we are not there yet, scan forwards until you find it node_2_out = len(curveData)-2 for i in range(node_1_out, len(curveData)-1, 2): x,y = curveData[i] if point_under_node(x,y,node2): node_2_out = i if len(domain) == 1: domain.append(0, curveData[i+1]) return domain else: domain.append(curveData[i]) # In case we couldn't fill domain, there aren't any visibles left, # say all is visible if domain == []: domain.append(curveData[0]) for i in range (1, len(curveData)-1, 2): domain.append(curveData[i]) domain.append(curveData[-1]) # you found it, return it return domain # Find your arrow position domain = visible_points(source, target) i = int(arrow_position * len(domain)) -1 if i < 1: i = 1 start, end = domain[i-1], domain[i] self.parent.add_drawing_object(DrawLine, loctype="world", onoff="on", start=start, end=end, linestyle=1, linewidth=size, color=color, arrow=2, arrow_type=1, arrow_length = 0.85, arrow_layout=(0.8,0.8)) # # # # ################################################################## #---------------# # #Write the i j of links (for debugging) # self.parent.add_drawing_object(DrawText, # char_size = .8, # text = '%s %s' % (n1,n2), # loctype="world", # onoff="on", # x = start[0], # y=start[1], # color=color) #---------------# # put the calculated link into the collective data for the linkset. newData.extend(curveData) # -- end of loop over each link -- # # Configure the whole linkset self.data = newData self.symbol.shape = 0 self.line.configure(type=4, linestyle=1, linewidth=size, color=color)
def __init__(self, color, *args, **kwargs): DataSet.__init__(self, *args, **kwargs) # line only (no symbols) self.symbol.configure(shape=0, fill_color=color, color=color) self.line.configure(type=1, linestyle=1, color=color)
def __init__(self, color, *args, **kwargs): DataSet.__init__(self, *args, **kwargs) # make symbols circles of uniform color (with no line) self.symbol.configure(shape=1, fill_color=color, color=color) self.line.configure(type=0, linestyle=0, color=color)
def __init__(self, color, pixelsize=None, square_pixels=True, *args, **kwargs): DataSet.__init__(self, *args, **kwargs) # Sort print >> sys.stderr, "Sorting data." pixeldata = sorted(self.data, key=lambda (x, y): (y, x)) # Determine pixel size if pixelsize is not None: step_x = step_y = pixelsize / 2. else: print >> sys.stderr, "Acquiring pixel size." pixelsizes_x, pixelsizes_y = set(), set() for i in range(len(pixeldata) - 1): x0, y0 = pixeldata[i] x1, y1 = pixeldata[i + 1] dy = round(y1 - y0, 12) dx = round(x1 - x0, 12) if dy != 0: pixelsizes_y.add(dy) elif dx != 0: pixelsizes_x.add(dx) if len(pixelsizes_x) > 0 and len(pixelsizes_y) > 0: step_x = min(pixelsizes_x) / 2. step_y = min(pixelsizes_y) / 2. elif len(pixelsizes_x) == 0 and len(pixelsizes_y) > 0: step_y = min(pixelsizes_y) / 2. step_x = step_y elif len(pixelsizes_x) > 0 and len(pixelsizes_y) == 0: step_x = min(pixelsizes_x) / 2. step_y = step_x else: step_x = step_y = 0.5 if square_pixels: step_x = step_y = min([step_x, step_y]) # Now we have pixel locations. Draw around the outer pixels, # ignore holes in the middle. print >> sys.stderr, "Tracing the outline of the shape from given pixels." self.data = [] # ---Bottom---------- x, y = pixeldata[0] # first pixel, bottom left xp = x - step_x yp = y - step_y self.data.append((xp, yp)) current_y = round(y, 12) # rightmost pixel of first row, bottom right for x, y in pixeldata: if round(y, 12) != current_y: # last pixel, bottom right xp = last_x + step_x yp = last_y - step_y self.data.append((xp, yp)) break last_x, last_y = x, y # in case there was only one row and you missed this if round(y, 12) == current_y: # still current_y after iteration, we missed it! xp = last_x + step_x yp = last_y - step_y self.data.append((xp, yp)) # ---Right side (scan up, line by line)------ groove_flag = False for x, y in pixeldata: if round(y, 12) != current_y: # Last pixel of a row # Finish last groove if you started one if groove_flag: # last pixel, bottom right xp = last_x + step_x yp = last_y - step_y self.data.append((xp, yp)) groove_flag = False # Are we starting a new groove? if round(x, 12) != round(last_x, 12): # yes, a new groove encountered # last pixel, top right xp = last_x + step_x yp = last_y + step_y self.data.append((xp, yp)) groove_flag = True current_y = round(y, 12) last_x, last_y = x, y # in case there was a groove you didn't finish because # we ran out of rows, do it now if groove_flag: # last pixel, bottom right xp = last_x + step_x yp = last_y - step_y self.data.append((xp, yp)) groove_flag = False # ---Top------- x, y = pixeldata[-1] # final pixel, top right xp = x + step_x yp = y + step_y self.data.append((xp, yp)) current_y = round(y, 12) # leftmost pixel of highest row, top left for x, y in reversed(pixeldata): if round(y, 12) != current_y: # last pixel, top left xp = last_x - step_x yp = last_y + step_y self.data.append((xp, yp)) break last_x, last_y = x, y # in case there was only one row and you missed this if round(y, 12) == current_y: # still current_y after iteration, we missed it! xp = last_x - step_x yp = last_y + step_y self.data.append((xp, yp)) # --- Left side (scan backwards [down])------ groove_flag = False for x, y in reversed(pixeldata): if round(y, 12) != current_y: # Last pixel of a row # Finish last groove if you started one if groove_flag: # last pixel, top left xp = last_x - step_x yp = last_y + step_y self.data.append((xp, yp)) groove_flag = False # Are we starting a new groove? if round(x, 12) != round(last_x, 12): # yes, a new groove encountered # last pixel, bottom left xp = last_x - step_x yp = last_y - step_y self.data.append((xp, yp)) groove_flag = True current_y = round(y, 12) last_x, last_y = x, y # in case there was a groove you didn't finish because # we ran out of rows, do it now if groove_flag: # last pixel, top left xp = last_x - step_x yp = last_y + step_y self.data.append((xp, yp)) groove_flag = False # --- Complete the shape by repeating the first ever point --- self.data.append(self.data[0]) print >> sys.stderr, "Tracing complete." self.symbol.configure(shape=0) self.line.configure(linewidth=0, color=color) self.fill.configure(type=2, rule=0, color=color) self.baseline.configure(type=1)
def __init__(self, color, *args, **kwargs): DataSet.__init__(self, *args, **kwargs) # make right stairs dataset (no symbols) self.symbol.configure(shape=1, fill_color=color, color=1) self.line.configure(type=0, linestyle=0, color=color)