import numpy import sys from shaperrec import groups from shaperrec import geometric from shaperrec import internal # ************************************************************* # debugging def void(*l): pass def debug_on(*l): sys.stderr.write(' '.join(str(i) for i in l) +'\n') debug = void #debug = debug_on # ************************************************************* # Object manipulation functions def toRemarkableShape( group ): """Test if PathGroup instance 'group' looks like a remarkable shape (ex: Rectangle). if so returns a new shape instance else returns group unchanged""" r = groups.Rectangle.isRectangle( group ) if r : return r return group def resetPrevNextSegment(segs): for i, seg in enumerate(segs[:-1]): s = segs[i+1] seg.next = s s.prev = seg return segs def fitSingleSegment(a): xmin, ymin, w, h = geometric.computeBox(a) inverse = w ', tangents ) if averaged: # average over neighbours avTan = numpy.array(tangents) avTan[:-1] += tangents[1:] avTan[1:] += tangents[:-1] if isClosing: tangents[0]+=tangents[-1] tangents[1]+=tangents[0] avTan *= 1./3 if not isClosing: avTan[0] *=1.5 avTan[-1] *=1.5 return avTan def clusterAngles(array, dAng=0.15): """Cluster together consecutive angles with similar values (within 'dAng'). array : flat array of angles returns [ ..., (indi_0, indi_1),...] where each tuple are indices of cluster i """ N = len(array) closebyAng = numpy.zeros( (N, 4), dtype=int) for i, a in enumerate(array): cb = closebyAng[i] cb[0] =i cb[2]=i cb[3]=i c=i-1 # find number of angles within dAng in nearby positions while c>-1: # indices below i d=geometric.closeAngleAbs(a, array[c]) if d>dAng: break cb[1]+=1 cb[2]=c c-=1 c=i+1 while cdAng: break cb[1]+=1 cb[3]=c c+=1 closebyAng= closebyAng[numpy.argsort(closebyAng[:, 1]) ] clusteredPos = numpy.zeros(N, dtype=int) clusters = [] for cb in reversed(closebyAng): if clusteredPos[cb[0]]==1: continue # try to build a cluster minI = cb[2] while clusteredPos[minI]==1: minI+=1 maxI = cb[3] while clusteredPos[maxI]==1: maxI-=1 for i in range(minI, maxI+1): clusteredPos[i] = 1 clusters.append( (minI, maxI) ) return clusters def adjustAllAngles(paths): for p in paths: if p.isSegment() and p.newAngle is not None: p.adjustToNewAngle() # next translate to fit end points tr = numpy.zeros(2) for p in paths[1:]: if p.isSegment() and p.prev.isSegment(): tr = p.prev.pointN - p.point1 debug(' translating ', p, ' prev is', p.prev, ' ', tr, ) p.translate(tr) def adjustAllDistances(paths): for p in paths: if p.isSegment() and p.newLength is not None: p.adjustToNewDistance() # next translate to fit end points tr = numpy.zeros(2) for p in paths[1:]: if p.isSegment() and p.prev.isSegment(): tr = p.prev.pointN - p.point1 p.translate(tr)