예제 #1
0
def _pointInHole(polygon, level = 2):
    sl = geomap.scanPoly(polygon)
    for y in range(sl.startIndex(), sl.endIndex()):
        inside = 0
        x = 0
        for seg in sl[y]:
            if inside and x < seg.begin:
                return Vector2(x, y)
            x = seg.end
            inside += seg.direction

    result = geomap.centroid(polygon)
    if polygon.contains(result):
        return result

    result = []
    bbox = polygon.boundingBox()
    midPoint = (bbox.begin() + bbox.end())/2
    xRange = numpy.arange(bbox.begin()[0], bbox.end()[0], 1.0/level)
    for y in numpy.arange(bbox.begin()[1], bbox.end()[1], 1.0/level):
        for x in xRange:
            p = Vector2(x, y)
            if polygon.contains(p):
                result.append((squaredNorm(p-midPoint), p))
    if not result:
        return _pointInHole(polygon, level+1)
    result.sort()
    return result[0][1]
예제 #2
0
def offset(freemanCodes, pointIndex, closed = True):
    if closed:
        pointIndex = pointIndex % len(freemanCodes)

    dsl, ofs = geomap.tangentDSL(freemanCodes, pointIndex, closed)
    if not ofs:
        return Vector2(0, 0)

    fc1 = freemanCodes[pointIndex - ofs]
    count = len(freemanCodes)
    for crackIndex in range(pointIndex - ofs + 1, pointIndex + ofs):
        fc2 = freemanCodes[crackIndex % count]
        if fc2 != fc1:
            break

    q = quadrant(fc1, fc2)
    alpha = (2.*dsl.pos+dsl.b-1)/(2*dsl.b)
    if q == 0:
        return Vector2( alpha, -alpha)
    elif q == 1:
        return Vector2(-alpha, -alpha)
    elif q == 2:
        return Vector2(-alpha,  alpha)
    else:
        return Vector2( alpha,  alpha)
예제 #3
0
파일: koch.py 프로젝트: hmeine/geomap
def kochCurve(level=5):
    result = Polygon()
    p0 = Vector2(-0.5, -math.sqrt(1. / 12))
    result.append(p0)
    p1 = p0 + Vector2(_kochCos, _kochSin)
    result.append(p1)
    p2 = p1 + Vector2(_kochCos, -_kochSin)
    result.append(p2)
    result.append(p0)
    for i in range(level):
        result = _kochIteration(result)
    return result
예제 #4
0
파일: koch.py 프로젝트: hmeine/geomap
def _kochIteration(poly):
    result = Polygon()
    for i in range(len(poly) - 1):
        segment = poly[i + 1] - poly[i]
        smaller = segment / 3
        left = Vector2(smaller[0] * _kochCos - smaller[1] * _kochSin,
                       smaller[0] * _kochSin + smaller[1] * _kochCos)
        right = Vector2(smaller[0] * _kochCos + smaller[1] * _kochSin,
                        -smaller[0] * _kochSin + smaller[1] * _kochCos)
        p1 = poly[i] + smaller
        p2 = p1 + left
        p3 = p2 + right
        result.append(poly[i])
        result.append(p1)
        result.append(p2)
        result.append(p3)
    result.append(result[0])
    return result
예제 #5
0
def rectifiedJunctionNodePosition(chords):
    """Defition of node position for junction triangles from rectified
    CAT article.  Not as good as the original definition for
    triangles, but works for other polygons, too."""
    totalWeights = 0.0
    result = Vector2(0, 0)
    for chord in chords:
        weight = chord.edge().length()
        result += middlePoint(chord) * weight
        totalWeights += weight
    return result / totalWeights
예제 #6
0
def offset2(freemanCodes, pointIndex, closed = True):
    """My own derivation of the necessary offset(), perpendicular to
    the tangent - gives different, but nearly indistinguishable
    results.  The RMSE of the points' radii in the circle example from
    __main__ is 0.4 percent lower, so this is the default / used in
    euclideanPath. ;-)"""

    if closed:
        pointIndex = pointIndex % len(freemanCodes)

    dsl, ofs = crackEdgeTangent(freemanCodes, pointIndex, closed)

    cp = Rational(2*dsl.pos+dsl.width()-1, 2*(sq(dsl.a) + sq(dsl.b)))
    return Vector2(float(dsl.a*cp), float(-dsl.b*cp))
예제 #7
0
def circumCircle(p1, p2, p3):
    """circumCircle(p1, p2, p3) -> (Vector2, float)

    Returns the center and radius of the circumcircle of the given
    three points."""

    p1sm = squaredNorm(p1)
    x1 = p1[0]
    y1 = p1[1]
    p2sm = squaredNorm(p2)
    x2 = p2[0]
    y2 = p2[1]
    p3sm = squaredNorm(p3)
    x3 = p3[0]
    y3 = p3[1]
    a = numpy.linalg.det(
        numpy.array([[x1, y1, 1],
                     [x2, y2, 1],
                     [x3, y3, 1]]))
    d = numpy.linalg.det(
        -numpy.array([[p1sm, y1, 1],
                      [p2sm, y2, 1],
                      [p3sm, y3, 1]]))
    e = numpy.linalg.det(
        numpy.array([[p1sm, x1, 1],
                     [p2sm, x2, 1],
                     [p3sm, x3, 1]]))
    f = numpy.linalg.det(
        -numpy.array([[p1sm, x1, y1],
                      [p2sm, x2, y2],
                      [p3sm, x3, y3]]))
    circumCenter = Vector2(-d/(2*a), -e/(2*a))

    denom = 4*math.sq(a) - f/a

    circumRadius2 = (math.sq(d) + math.sq(e)) / (4*math.sq(a)) - f/a

    if circumRadius2 > 0:
        circumRadius = math.sqrt(circumRadius2)
    else:
        lengths = [(p2-p1).magnitude(),
                   (p3-p2).magnitude(),
                   (p1-p3).magnitude()]
        lengths.sort()
        circumRadius = (lengths[1] + lengths[2]) / 4.0
        sys.stderr.write("circumcircle: side lengths^2 are %s -> improvised radius = %s\n"
                         % (lengths, circumRadius))

    return circumCenter, circumRadius
예제 #8
0
def pruneByMorphologicalSignificance(skel, ratio = 0.1):
    for edge in skel.edgeIter():
        edge.setFlag(IS_BARB, False)

        if edge.startNode().hasDegree(1):
            edge.setFlag(IS_BARB, True)

            endSide = edge.endSide[0]-edge.endSide[1]
            minDist = ratio * numpy.linalg.norm(endSide)

            endNormal = Vector2(endSide[1], -endSide[0])
            endNormal /= numpy.linalg.norm(endNormal)

            for p in edge:
                if abs(dot(p - edge[-1], endNormal)) > minDist:
                    edge.setFlag(IS_BARB, False)
                    break

            if edge.flag(IS_BARB):
                continue # no need to test other side

        if edge.endNode().hasDegree(1):
            edge.setFlag(IS_BARB, True)

            startSide = edge.startSide[0]-edge.startSide[1]
            minDist = ratio * max(1.0, numpy.linalg.norm(startSide))

            startNormal = Vector2(startSide[1], -startSide[0])
            startNormal /= numpy.linalg.norm(startNormal)

            for p in edge:
                if abs(dot(p - edge[0], startNormal)) > minDist:
                    edge.setFlag(IS_BARB, False)
                    break

    return _pruneBarbsInternal(skel)
예제 #9
0
    import Gnuplot
    def gpLine(points, with_ = "lines", **kwargs):
        return Gnuplot.Data(points, with_ = with_, **kwargs)

    g = Gnuplot.Gnuplot()
    g("set size ratio -1")

    ep = [p + offset(fc, i) for i, p in enumerate(list(crackPoly)[:-1])]
    ep.append(ep[0])
    ep2 = [p + offset2(fc, i) for i, p in enumerate(list(crackPoly)[:-1])]
    ep2.append(ep2[0])
    g.plot(gpLine(crackPoly), gpLine(ep), gpLine(ep2))

    g2 = Gnuplot.Gnuplot()
    g2.plot([norm(p-Vector2(25,25))-20 for p in ep],
            [norm(p-Vector2(25,25))-20 for p in ep2])

#     tangents = [tangentDSL(fc, i, True)[0] for i in range(len(fc))]
#     g.plot(gpLine(tangentList(ep, 1), "lp"),
#            gpLine([atan2(t.b, t.a)+math.pi/2 for t in tangents], "lp"))

#     e = DSLExperiment(True)
#     for code in [1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1]:
#         if not e(code):
#             break
#         print "code %s -> %s" % (code, e.dsl)

#     index = 43
#     print "debugging %d:" % index
#     dsl, ofs = tangentDSL(fc, index, True)
예제 #10
0
파일: testmap.py 프로젝트: hmeine/geomap
#         print "%d edges were deleted (e.g. at image border)." % (
#             len(map.deleted), )
#     if hasattr(map, "unsortable") and map.unsortable:
#         print "%d unsortable groups of edges occured." % (
#             len(map.unsortable), )
#     if hasattr(map, "unembeddableContours") and map.unembeddableContours:
#         print "%d outer contours could not be embedded into " \
#               "their surrounding faces!" % (len(map.unembeddableContours), )

# --------------------------------------------------------------------

print "- creating empty GeoMap..."
tm = geomap.GeoMap([], [], Size2D(256, 256))

points = geomap.Vector2Array([
    Vector2(232.20846246994, 81.488755298170375),
    Vector2(228.16750125077627, 81.481533365106415),
    Vector2(224.94552025882538, 81.580691309124461)
])

n1 = tm.addNode(points[0])
n2 = tm.addNode(points[-1])
print "- endnodes %d and %d created." % (n1.label(), n2.label())

print "- adding edge..."
edge = tm.addEdge(n1, n2, points)

print "- testing DartPointIter..."
dart = tm.dart(-edge.label())
for i, p in enumerate(dart):
    assert p == dart[i]