예제 #1
0
def lineIntersects(l1, l2):
    (p1, p2) = l1.points[0], l1.points[-1]
    (p3, p4) = l2.points[0], l2.points[-1]
    (x1, y1), (x2, y2), (x3, y3), (x4, y4) = p1, p2, p3, p4
    nx = (x1 * y2 - y1 * x2) * (x3 - x4) - (x1 - x2) * (x3 * y4 - y3 * x4)
    ny = (x1 * y2 - y1 * x2) * (y3 - y4) - (y1 - y2) * (x3 * y4 - y3 * x4)
    d = (x1 - x2) * (y3 - y4) - (y1 - y2) * (x3 - x4)

    if d == 0:
        return []

    ip = (nx / d, ny / d)

    parameters = []
    for (start, end, t_start) in ((p1, p2, l1._t1), (p3, p4, l2._t1)):
        lineLen = dist(start, end)
        lenFromStart = dist(ip, start)
        t = lenFromStart / lineLen
        # check the intersection is not before the start, nor after the end
        lenFromEnd = dist(ip, end)
        if not isclose(lineLen + lenFromStart, lenFromEnd) and 0 < t < 1:
            parameters.append(t_start + t)

    if len(parameters) == 2:
        return parameters
    else:
        return []
예제 #2
0
def rebuildContour(_poly, recog, pthash, pvhash, resolution):
    def _pthash(p):
        k = tuple(p)
        if k not in pthash:
            return None
        return pthash[k]

    j0 = 0
    while (j0 < len(_poly) and _pthash(_poly[j0])):
        j0 += 1

    poly = _poly[j0:] + _poly[:j0 + 1]
    j = 0
    ans = []

    while j < len(poly):
        n = j + 1
        while n < len(poly) and _pthash(poly[n]):
            n += 1
        if n < len(poly):
            pv = ordinalSegPts(poly, j, n, pthash, pvhash)
            if pv:
                seg = recog[pv[0]][pv[1]][pv[2]]
                z1 = bezpt(poly[j], resolution)
                z4 = bezpt(poly[n], resolution)
                if (dist(z1, seg.points[0]) < 1 / resolution
                        and dist(z4, seg.points[3]) < 1 / resolution):
                    ans.append(Bezier(z1, seg.points[1], seg.points[2], z4))
                elif (dist(z1, seg.points[3]) < 1 / resolution
                      and dist(z4, seg.points[0]) < 1 / resolution):
                    ans.append(Bezier(z1, seg.points[2], seg.points[1], z4))
                else:
                    t1 = seg.project(z1).t
                    t4 = seg.project(z4).t
                    if t1 < t4:
                        sseg = seg.split(t1, t4)
                        ans.append(
                            Bezier(z1, sseg.points[1], sseg.points[2], z4))
                    elif t1 > t4:
                        sseg = seg.split(t4, t1)
                        ans.append(
                            Bezier(z1, sseg.points[2], sseg.points[1], z4))
            else:
                m = j
                while m < n:
                    p1, p2 = poly[m], poly[m + 1]
                    if (abs(p1[0] - p2[0]) >= resolution
                            or abs(p1[1] - p2[1]) >= resolution):
                        b1 = bezpt(p1, resolution)
                        b2 = bezpt(p2, resolution)
                        ans.append(Bezier(b1, b1, b2, b2))
                    m += 1
        j = n
    return ans
예제 #3
0
    def project(self, point):
        # step 1: coarse check
        LUT = self.getLUT()
        l = len(LUT) - 1
        mdist, mpos = utils.closest(LUT, point)
        if mpos == 0 or mpos == l:
            t = mpos / l
            pt = self.compute(t)
            return Bezier._ProjectedPoint(pt.x, pt.y, t, mdist)

        # step 2: fine check
        t1 = (mpos - 1) / l
        t2 = (mpos + 1) / l
        step = 0.1 / l
        mdist += 1
        t = t1
        ft = t
        while t < t2 + step:
            p = self.compute(t)
            d = utils.dist(point, p)
            if d < mdist:
                mdist = d
                ft = t
            t += step
        p = self.compute(ft)
        return Bezier._ProjectedPoint(p.x, p.y, ft, mdist)
예제 #4
0
def splitContour(contour, irec, ERROR):
    z0 = contour[0].get(0)
    jc = 0
    tlast = 0
    ans = []

    for j in range(len(irec)):
        t = irec[j] - jc
        pt = contour[jc].get(t)
        if t >= 1 or dist(pt, z0) >= ERROR * 2:
            ans.append(contour[jc].split(tlast, t))
            z0 = pt
            if t < 1:
                tlast = t
            else:
                tlast = 0
                jc += 1
        else:
            if tlast >= 1:
                tlast = 0
                jc += 1

    return ans