def doCompute(self, drawer, landmark, figure, **args): (lowerLeft, lowerRight), (width, height) = math2d.boundingBox(landmark) scale = pow(pow(width, 2) + pow(height, 2), 0.5) scaleFactor = scale * 0.1 polygon = math2d.boxToPolygon( (lowerLeft - scaleFactor, lowerRight - scaleFactor), (width + 2 * scaleFactor, height + 2 * scaleFactor)) out = {} figureSteps = list( math2d.stepAlongLine(figure, math2d.length(figure) / 100.0)) out["endPointsInLandmarkBoundingBox"] = 0 for p in figureSteps[90:]: if math2d.isInteriorPoint(polygon, p): out["endPointsInLandmarkBoundingBox"] += 1 drawer.drawPoint("endPointsInLandmarkBoundingBox", p) drawer.drawLine("endPointsInLandmarkBoundingBox", math2d.polygonToLine(polygon)) out["startPointsInLandmarkBoundingBox"] = 0 for p in figureSteps[:10]: if math2d.isInteriorPoint(polygon, p): out["startPointsInLandmarkBoundingBox"] += 1 drawer.drawPoint("startPointsInLandmarkBoundingBox", p) drawer.drawLine("startPointsInLandmarkBoundingBox", math2d.polygonToLine(polygon)) return out
def makePlots(self): X, Y = math2d.points_to_xy(math2d.polygonToLine(self.polygon)) plot, = self.axes.plot(X, Y, 'ro-', animated=True, scalex=False, scaley=False) return [plot]
def averageParallel(self, drawer, landmark, figure): total = 0.0 count = 0.0 d_f = math2d.length(figure)/100 steps = list(math2d.stepAlongLine(figure, d_f)) for f1, f2 in zip(steps, steps[1:]): g1 = math2d.closestPointOnLine(math2d.polygonToLine(landmark), f1) g2 = math2d.closestPointOnLine(math2d.polygonToLine(landmark), f2) drawer.drawLine('averageParallel', [f1,g1]) try: angle = math2d.angleBetweenLines([f1, f2], [g1, g2]) except math2d.VerticalSegmentError: continue total += angle count += 1 if count == 0: return math.pi/4 else: return total / count
def doCompute(self, drawer, landmark, figure, **args): (x0,y0), (width, height) = math2d.boundingBox(landmark) #point, dims = (x0 + width, y0), (width, height) #translatedBox = math2d.boxToPolygon(point, dims) translatedBox = math2d.boxToPolygon((x0,y0),(width, height)) drawer.drawRect("intersectBoundingBox", translatedBox[0], translatedBox[2]) if math2d.clip(figure, math2d.polygonToLine(translatedBox)) != []: return {"intersectBoundingBox":1} else: return {"intersectBoundingBox":0}
def findSubsetOfFigure(landmark, figure): bestScore = None bestPath = figure d_f = math2d.length(figure)/100 for subpath in math2d.slideWindowAlongPath(figure, d_f, fractionSize=0.6): totalDist = 0.0 count = 0 for f1 in [x for x in math2d.stepAlongLine(figure, d_f)]: g1 = math2d.closestPointOnLine(math2d.polygonToLine(landmark), f1) totalDist += math2d.dist(f1, g1) count += 1 mean = totalDist / count if bestScore == None or mean <= bestScore: bestScore = mean bestPath = subpath clippedFigure = bestPath
def computeAxes1(landmarkGeom, figureGeom): if math2d.length(figureGeom) == 0: raise InsaneExample("Degenertie figure.") landmarkAsLine = math2d.polygonToLine(landmarkGeom) l = math2d.length(landmarkAsLine) resolution = 100 fLength = math2d.length(figureGeom) def score(xArr): axis = [ math2d.pointOnLine(landmarkAsLine, xArr[0] % l), math2d.pointOnLine(landmarkAsLine, xArr[1] % l) ] score = 0.0 for p1, p2 in zip( math2d.stepAlongLine(figureGeom, fLength / resolution), math2d.stepAlongLine(axis, math2d.length(axis) / resolution)): score += math2d.squaredist(p1, p2) return score #plot2d.plotLine(landmarkGeom, "r+-") #plot2d.plotLine(figureGeom, "r+-") guessMajor, guessMinor = computeAxes2(landmarkGeom, figureGeom) if guessMinor == None: return None, None guess = [ math2d.distAlongLine(landmarkAsLine, guessMinor[0]), math2d.distAlongLine(landmarkAsLine, guessMinor[1]) ] #xopt = optimize.fmin(score, guess) xopt, retval = optimize.anneal(score, guess) #pylab.show() #print "opt", xopt p1 = math2d.pointOnLine(landmarkAsLine, xopt[0] % l) p2 = math2d.pointOnLine(landmarkAsLine, xopt[1] % l) minor = [p1, p2] major = math2d.perpendicular(minor) return major, minor
def draw(self): print "drawing" for r in self.plots: r.remove() self.plots = [] colorMap = {"figure":"blue", "ground":"red"} for k, geometry in self.geometry.iteritems(): if k == "ground": geometry = math2d.polygonToLine(geometry) X, Y = na.transpose(geometry) line, = self.axes.plot(X, Y, color=colorMap[k], linewidth=1.5) self.plots.append(line) selectedFeature = self.featureModel.selectedData() if selectedFeature != None: for drawCommand in selectedFeature.drawCommands: print drawCommand method = eval("self.drawer.%s" % drawCommand["name"]) self.plots.extend(method(*drawCommand["args"])) mpl.draw()
def geometryAsLine(self, offset): return math2d.polygonToLine(self.geometry(offset))
def computeAxes2(landmarkGeom, figureGeom): if math2d.length(figureGeom) == 0: raise InsaneExample("Degenerate figure.") # three algorithms # 1. connect endpoints and extend # 2. fit line with regression # 3. get a line with my fancy optimization (minimize area and distance) #intersectPoints = math2d.intersectLines(math2d.polygonToLine(landmarkGeom), # figureGeom) #m, b = math2d.fitLine(figureGeom) #intersectPoints = math2d.intersectPolygonAnalytic(landmarkGeom, m, b) endPointSegment = [figureGeom[0], figureGeom[-1]] if not math2d.isVertical(endPointSegment) and not math2d.isDegenerate( endPointSegment): m, b = math2d.lineEquation(endPointSegment) intersectPoints = math2d.intersectPolygonAnalytic(landmarkGeom, m, b) else: gYs = [p[1] for p in landmarkGeom] mungedFigAxis = [(figureGeom[0][0], min(gYs) - 1), (figureGeom[0][0], max(gYs) + 1)] intersectPoints = math2d.intersectLines( math2d.polygonToLine(landmarkGeom), mungedFigAxis) #m, b = math2d.fitLine(figureGeom) #intersectPoints = math2d.intersectPolygonAnalytic(landmarkGeom, m, b) if len(intersectPoints) == 0: if math2d.isInteriorPoint(landmarkGeom, figureGeom[0]): minor = [ math2d.closestPointOnPolygon(landmarkGeom, figureGeom[0]), math2d.closestPointOnPolygon(landmarkGeom, figureGeom[-1]) ] else: return None, None elif (len(intersectPoints) == 1 or (intersectPoints[0] == intersectPoints[1])): if math2d.isInteriorPoint(landmarkGeom, figureGeom[0]): minorStart = math2d.closestPointOnPolygon(landmarkGeom, figureGeom[0]) else: minorStart = intersectPoints[0] minorEnd = math2d.closestPointOnPolygon(landmarkGeom, figureGeom[-1]) minor = [minorStart, minorEnd] else: # ignoring figure after first two intersect points minor = [intersectPoints[0], intersectPoints[1]] D = tklib_get_distance(na.transpose(intersectPoints), [0, 0]) i_st = na.argmin(D) i_end = na.argmax(D) minor = [intersectPoints[i_st], intersectPoints[i_end]] try: major = math2d.perpendicular(minor) intersectPoint = math2d.intersectSegment(major, minor) except: print "minor", minor print "figure", figureGeom raise if intersectPoint == None: # if math2d.sorta_eq(math2d.length(figureGeom), 0): # degenerate case - start and end at the same point. # can happen for zero length tracks. # But other tracks too - still happens when you test zero length. raise InsaneExample("No axes" + ` [major, minor, intersectPoint] `) else: return major, minor