def transform_side(sides, targets, angle_offset=0): def angle(point1, point2): diff = point1 - point2 if diff.real == 0: return 90.0 return atan(diff.imag / diff.real) * 180.0 / pi # change this so that it has two targets transformed_side = Path(*sides) source_angle = angle(transformed_side.end, transformed_side.start) - \ angle(targets[0], targets[1]) transformed_side = transformed_side.rotated(-source_angle + angle_offset) source = transformed_side.end if angle_offset == 0 else transformed_side.start diff = targets[1] - source transformed_side = transformed_side.translated(diff) draw_marker(targets[0], rgb(0, 200, 200)) draw_marker(targets[1], rgb(0, 255, 255)) transformed_diff = abs(transformed_side.start - transformed_side.end) targets_diff = abs(targets[0] - targets[1]) if transformed_diff < targets_diff: transformed_side.insert( 0, Line(start=targets[0], end=transformed_side.start)) elif transformed_diff > targets_diff: # pop elements off until the transformed diff is smaller while transformed_diff > targets_diff: transformed_side.pop(0) transformed_diff = abs(transformed_side.start - transformed_side.end) print("path", transformed_side) print("path is longer", transformed_diff - targets_diff) return transformed_side
def test_stack_paths2(): blo = Path(*[ Line(start=0, end=100), Line(start=100, end=100 + 100j), Line(start=100 + 100j, end=100j), Line(start=100j, end=0) ]) all_paths = [blo, blo.translated(110)] attributes = [{"fill": "black"}, {"fill": "black"}] all_paths_new, attributes_new = stack_paths(all_paths, attributes) assert all_paths == all_paths_new assert attributes_new == attributes
def test_generate_pattern_colors(fill): dig = Digitizer() diff = 110 blo = Path(*[Line(start=0, end=100), Line(start=100, end=100 + 100j), Line(start=100 + 100j, end=100j), Line(start=100j, end=0)]) dig.all_paths = [blo, blo.translated(diff)] dig.attributes = [{"fill": "black"}, {"fill": "red"}] dig.scale = 1.0 dig.fill = fill dig.generate_pattern() print([(i, block.stitches[0].tags) for i, block in enumerate(dig.pattern.blocks)]) assert len(dig.pattern.thread_colors) == 2 assert len(dig.pattern.blocks[0].stitches) > 0 assert "JUMP" in dig.pattern.blocks[0].stitches[0].tags assert "STITCH" in dig.pattern.blocks[1].stitches[0].tags assert "TRIM" in dig.pattern.blocks[2].stitches[0].tags assert "COLOR" in dig.pattern.blocks[3].stitches[0].tags assert "STITCH" in dig.pattern.blocks[4].stitches[0].tags assert "END" in dig.pattern.blocks[5].stitches[0].tags assert len(dig.pattern.blocks[4].stitches) > 0
def calc_path_freetype_decompose(self, fontsize: float) -> Path: ''' ''' outline: freetype.Outline = self.face.glyph.outline def move_to(a, ctx): ctx.append("M {},{}".format(a.x, a.y)) def line_to(a, ctx): ctx.append("L {},{}".format(a.x, a.y)) def conic_to(a, b, ctx): ctx.append("Q {},{} {},{}".format(a.x, a.y, b.x, b.y)) def cubic_to(a, b, c, ctx): ctx.append("C {},{} {},{} {},{}".format(a.x, a.y, b.x, b.y, c.x, c.y)) ctx: List[str] = [] outline.decompose(ctx, move_to=move_to, line_to=line_to, conic_to=conic_to, cubic_to=cubic_to) path_str = " ".join(ctx) # build a Path instance path = parse_path(path_str) # this path is not at the right position - it has to be scaled, shifted and flipped yflip = self.yflip_value if yflip == None: yflip = self.bbox.yMax xshift = self.xshift_value if xshift == None: xshift = self.bbox.xMin # extra scaling scaling = fontsize / self.CHAR_SIZE # let's go path = path.translated(-xshift) # flipping means a special transformation ... matrix(1,0, 0,-1, 0,7.5857) apath = Path() tf = np.identity(3) tf[1][1] = -1 for seg in path: aseg = xxpath.transform(seg, tf) apath.append(aseg) # and the companion translation path = apath.translated(yflip * 1j) # finally path = path.scaled(scaling, scaling) self.path = path return self.path