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 []
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
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)
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