def calcCurveLength(self): length = 0 for i, (t, pts) in enumerate(self.pen.value): if t == "curveTo": p1, p2, p3 = pts p0 = self.pen.value[i - 1][-1][-1] length += calcCubicArcLength_cached(p0, p1, p2, p3) elif t == "qCurveTo": p1, p2 = pts p0 = self.pen.value[i - 1][-1][-1] length += calcQuadraticArcLength(p0, p1, p2) elif t == "lineTo": pass # todo return length
def _qCurveToOne(self, pt1, pt2): falseCurve = (pt1 == self.currentPt) or (pt1 == pt2) if falseCurve: self._lineTo(pt2) return est = calcQuadraticArcLength(self.currentPt, pt1, pt2) / self.approximateSegmentLength maxSteps = int(round(est)) if maxSteps < 1: self.otherPen.lineTo(pt2) self.currentPt = pt2 return step = 1.0 / maxSteps for factor in range(1, maxSteps + 1): pt = getQuadraticPoint(factor * step, self.currentPt, pt1, pt2) self.otherPen.lineTo(pt) self.currentPt = pt2
def _qCurveToOne(self, pt1, pt2): falseCurve = (pt1 == self.currentPt) or (pt1 == pt2) if falseCurve: self._lineTo(pt2) return est = calcQuadraticArcLength(self.currentPt, pt1, pt2) / self.approximateSegmentLength maxSteps = int(round(est)) if maxSteps < 1: self.currentPt = pt2 return step = 1.0 / maxSteps for factor in range(1, maxSteps + 1): pt = getQuadraticPoint(factor * step, self.currentPt, pt1, pt2) prev_pt = getQuadraticPoint((factor-1) * step, self.currentPt, pt1, pt2) dist = distance(pt, self.point) if self.bestDistance > dist: self.bestDistance = dist self.closest = pt self.orthoPt = self.getOrtho(prev_pt, pt) self.currentPt = pt2
def _print_segments(coords: List[Coordinate], nocolor: bool) -> None: start_coord = None total_distance: float = 0.0 for coord in coords: # keep start coordinate for calculation of final # contour point distances as curve is closed if coord.startpoint: start_coord = coord # nothing to do at the start coordinate continue if coord.oncurve: # we are on the curve, check previous point to see if this # is a line or quadratic curve segment if coord.coord_previous: if coord.coord_previous.oncurve: distance = linear_distance_between_coordinates( (coord.coord_previous.x, coord.coord_previous.y), (coord.x, coord.y), ) line_string = segment_line( coord.coord_previous, coord, distance, nocolor, ) total_distance += distance print(line_string) else: pass if coord.endpoint and start_coord: # add the endpoint to startpoint segment if the endpoint is oncurve # note: this is a forward direction write in contrast to previous # logic which checks backwards distance = linear_distance_between_coordinates( (coord.x, coord.y), (start_coord.x, start_coord.y)) line_string = segment_line(coord, start_coord, distance, nocolor) total_distance += distance print(line_string) # we have an off-curve point else: if coord.endpoint and coord.coord_previous and start_coord: distance = calcQuadraticArcLength( (coord.coord_previous.x, coord.coord_previous.y), (coord.x, coord.y), (start_coord.x, start_coord.y), ) qcurve_string = segment_quadratic_curve( coord.coord_previous, coord, start_coord, distance, nocolor) total_distance += distance print(qcurve_string) elif coord.coord_previous and coord.coord_next: assert coord.coord_previous.oncurve is True assert coord.coord_next.oncurve is True distance = calcQuadraticArcLength( (coord.coord_previous.x, coord.coord_previous.y), (coord.x, coord.y), (coord.coord_next.x, coord.coord_next.y), ) qcurve_string = segment_quadratic_curve( coord.coord_previous, coord, coord.coord_next, distance, nocolor, ) total_distance += distance print(qcurve_string) print( f"{os.linesep} {segment_total_distance(total_distance, nocolor=nocolor)}" )