def saveSVG(self, fn): pathsCK = self.paths['ck'] pathsLL0 = self.paths['ll0'] def getSegment(path): return CubicBezier(complex(path['p0'][0], path['p0'][1]), complex(path['c0'][0], path['c0'][1]), complex(path['c1'][0], path['c1'][1]), complex(path['p1'][0], path['p1'][1])) # C/K ck = Path(getSegment(pathsCK[0]), getSegment(pathsCK[1]), getSegment(pathsCK[2]), getSegment(pathsCK[3])) # L/L0 ll0 = Path(getSegment(pathsLL0[0])) paths = [ck, ll0] pathAttributes = { "stroke-width": self.width, "stroke": "#000", "fill": "#fff" } svg_attributes = {"viewBox": "0 0 600 600", "x": "0px", "y": "0px"} attributes = [pathAttributes, pathAttributes] wsvg(paths, attributes=attributes, svg_attributes=svg_attributes, filename=fn)
def test_jump_reduction(): paths = [] rect_width = 100 rect_height = rect_width / 2 for i in range(3): y_offset = rect_width*i*1j corners = [rect_height, rect_width+rect_height, rect_width+rect_height + rect_height*1j, rect_height*1j+ rect_height] corners = [c+y_offset for c in corners] lines = [Line(start=corners[j], end=corners[(j+1) % len(corners)]) for j in range(len(corners))] _path = Path(*lines) _path = _path.rotated(i*20) paths += list(_path) max_y = max([p.start.imag for p in paths]+[p.end.imag for p in paths]) max_x = max([p.start.real for p in paths]+[p.end.real for p in paths]) filename = "test_jump_reduction.svg" viewbox = [0, -rect_height, max_x+2*rect_height, max_y+2*rect_height] dwg = Drawing(filename, width="10cm", viewBox=" ".join([str(b) for b in viewbox])) dwg.add(dwg.path(d=Path(*paths).d())) dwg.save() dig = Digitizer() dig.filecontents = open(filename, "r").read() dig.svg_to_pattern() pattern_to_svg(dig.pattern, join(filename + ".svg"))
def fill_trap(self, paths, color="gray"): side = shorter_side(paths) shapes = [[Path(*paths), "none", "black"], [Path(*paths[side:side + 3]), color, "none"]] side2 = side + 2 shapes = self.fill_shape(side, side2, paths, shapes) write_debug("fill", shapes) return side, side2
def fill_triangle(self, paths, color="green"): triangle_sides = [ paths[0], paths[1], Line(start=paths[2].start, end=paths[0].start) ] shapes = [[Path(*paths), "none", "black"], [Path(*triangle_sides), color, "none"]] lengths = [p.length() for p in triangle_sides] side1 = argmax(lengths) lengths[side1] = 0 side2 = argmax(lengths) shapes = self.fill_shape(side1, side2, triangle_sides, shapes) write_debug("fill", shapes)
def augment(path_nested, num): path_list = [] path = Path() for p in path_nested: for segment in p: path.append(segment) end_points_list = [] for segment in path: s = segment.bpoints()[0] e = segment.bpoints()[-1] end_points_list.append((s.real, s.imag)) end_points_list.append((e.real, e.imag)) end_points = np.array(end_points_list) hull_points = end_points[ConvexHull(end_points).vertices] idx_xmin, idx_ymin = np.argmin(hull_points, axis=0) idx_xmax, idx_ymax = np.argmax(hull_points, axis=0) x_range = 0.15 * (hull_points[idx_xmax][0] - hull_points[idx_xmin][0]) y_range = 0.15 * (hull_points[idx_ymax][1] - hull_points[idx_ymin][1]) idx_min_max = np.unique([idx_xmin, idx_ymin, idx_xmax, idx_ymax]) for _ in range(num): # global deformation p = hull_points q = hull_points.copy() for idx in idx_min_max: x, y = p[idx] q[idx] = (x + random.gauss(0, x_range), y + y_range * random.gauss(0, y_range)) path_deformed = Path() for segment in path: points = [] for v in segment.bpoints(): real, imag = moving_least_square_with_rigid_transformation( p, q, np.array([v.real, v.imag]), max(x_range, y_range)) point_xformed = complex(real, imag) points.append(point_xformed) if len(segment.bpoints()) == 2: line = Line(points[0], points[1]) path_deformed.append(line) else: cubic_bezier = CubicBezier(points[0], points[1], points[2], points[3]) path_deformed.append(cubic_bezier) path_list.append(path_deformed) return path_list
def pattern_to_svg(pattern, filename): if isinstance(filename, str) or isinstance(filename, unicode): output_file = open(filename, "wb") else: output_file = filename paths = [] colors = [] scale_factor = 0.1 # scale from cm to mm from pes for block in pattern.blocks: block_paths = [] last_stitch = None for stitch in block.stitches: if "JUMP" in stitch.tags: last_stitch = stitch continue if last_stitch is None: last_stitch = stitch continue block_paths.append( Line(start=last_stitch.complex * scale_factor, end=stitch.complex * scale_factor)) last_stitch = stitch if len(block_paths) > 0: colors.append(block.tuple_color) paths.append(Path(*block_paths)) dims = overall_bbox(paths) mindim = max(dims[1] - dims[0], dims[3] - dims[2]) print("in pattern to svg, overallbbox", overall_bbox(paths)) if len(paths) == 0: print("warning: pattern did not generate stitches") return wsvg(paths, colors, filename=output_file, mindim=mindim)
def save_points_as_svg_handler(points, size, image_number): # filename like file:///home/gdshen/Pictures/00000.jpg filename = os.path.join(project_path, svg_dir, image_number + '.svg') paths = [] for i in range(size): start_point_x = points.property(i).property('startPoint').property( 'X').toInt() start_point_y = points.property(i).property('startPoint').property( 'Y').toInt() control_point_x = points.property(i).property( 'controlPoint').property('X').toInt() control_point_y = points.property(i).property( 'controlPoint').property('Y').toInt() target_point_x = points.property(i).property( 'targetPoint').property('X').toInt() target_point_y = points.property(i).property( 'targetPoint').property('Y').toInt() print(start_point_x, start_point_y, control_point_x, control_point_y, target_point_x, target_point_y) paths.append( Path( QuadraticBezier(complex(start_point_x, start_point_y), complex(control_point_x, control_point_y), complex(target_point_x, target_point_y)))) wsvg(paths=paths, filename=filename)
def initialize(self): current_grid = defaultdict(dict) # simplify paths to lines poly_paths = [] for path in self.paths: if path.length() > MINIMUM_STITCH_LENGTH: num_segments = ceil(path.length() / MINIMUM_STITCH_LENGTH) for seg_i in range(int(num_segments)): poly_paths.append(Line(start=path.point(seg_i/num_segments), end=path.point((seg_i+1)/num_segments))) else: poly_paths.append(Line(start=path.start, end=path.end)) bbox = overall_bbox(self.paths) curr_x = int(bbox[0]/MINIMUM_STITCH_LENGTH)*MINIMUM_STITCH_LENGTH total_tests = int(bbox[1]-bbox[0])*int(bbox[3]-bbox[2])/(MINIMUM_STITCH_LENGTH*MINIMUM_STITCH_LENGTH) while curr_x < bbox[1]: curr_y = int(bbox[2]/MINIMUM_STITCH_LENGTH)*MINIMUM_STITCH_LENGTH while curr_y < bbox[3]: test_line = Line(start=curr_x + curr_y * 1j, end=curr_x + MINIMUM_STITCH_LENGTH + ( curr_y + MINIMUM_STITCH_LENGTH) * 1j) start = time() is_contained = path1_is_contained_in_path2(test_line, Path(*poly_paths)) end = time() if is_contained: current_grid[curr_x][curr_y] = False curr_y += MINIMUM_STITCH_LENGTH curr_x += MINIMUM_STITCH_LENGTH self.current_grid = current_grid
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 cross_stitch_to_pattern(self, _image): # this doesn't work well for images with more than 2-3 colors max_dimension = max(_image.size) pixel_ratio = int(max_dimension * MINIMUM_STITCH_LENGTH / (4 * 25.4)) if pixel_ratio != 0: _image = _image.resize( (_image.size[0] / pixel_ratio, _image.size[1] / pixel_ratio)) pixels = posturize(_image) paths = [] attrs = [] for color in pixels: for pixel in pixels[color]: rgb = "#%02x%02x%02x" % (pixel[2][0], pixel[2][1], pixel[2][2]) x = pixel[0] y = pixel[1] attrs.append({"fill": "none", "stroke": rgb}) paths.append( Path( Line(start=x + 1j * y, end=x + 0.5 * MINIMUM_STITCH_LENGTH + 1j * (y + MINIMUM_STITCH_LENGTH)))) debug_paths = [[path, attrs[i]["fill"], attrs[i]["stroke"]] for i, path in enumerate(paths)] write_debug("png", debug_paths) self.all_paths = paths self.attributes = attrs self.scale = 1.0 self.generate_pattern()
def generate(self, u, v, w): seg1 = self.getSegment(self.c, self.k, 0, u) seg2 = self.getSegment(self.c, self.k, 1, u) seg3 = self.getSegment(self.c, self.k, 2, u) seg4 = self.getSegment(self.c, self.k, 3, u) ck = Path(seg1, seg2, seg3, seg4) ll0 = Path( CubicBezier(self.lerp(self.l['start'], self.l0['start'], v), self.lerp(self.l['c1'], self.l0['c1'], v), self.lerp(self.l['c2'], self.l0['c2'], v), self.lerp(self.l['end'], self.l0['end'], v))) self.paths = [ck, ll0] self.width = w
def extract_text_font(root, metadata_file): glyphcodes = get_text_names_to_codes(metadata_file) # (2) Output bounding box svg for glyph in glyphs: if glyph.attrib["glyph-name"] not in glyphcodes: continue # set glyph id g_element = ET.SubElement(root, "g") name = glyph.attrib["glyph-name"] glyph_code = glyphcodes[name] #glyph_code = name.split("uni")[-1] g_element.set("c", glyph_code) g_element.set("n", name) # set bounding box values if present if "d" in glyph.attrib: path = Path(glyph.attrib["d"]) xmin, xmax, ymin, ymax = path.bbox() g_element.set("x", str(round(xmin, 2))) g_element.set("y", str(round(ymin, 2))) g_element.set("w", str(round(xmax - xmin, 2))) g_element.set("h", str(round(ymax - ymin, 2))) else: g_element.set("x", str(0.0)) g_element.set("y", str(0.0)) g_element.set("w", str(0.0)) g_element.set("h", str(0.0)) # set set horiz-av-x horiz_adv_x = glyph.attrib[ "horiz-adv-x"] if "horiz-adv-x" in glyph.attrib else "" if horiz_adv_x: g_element.set("h-a-x", horiz_adv_x) return root
def path_difference_shapely(path1, path2): try: poly1 = path_to_poly(path1) except (IndexError, ValueError) as e: return path1 if not poly1.is_valid or not path2.closed: # output the shape to a debug file # write_debug("invalid1", [[shape_to_path(poly1), "black", "none"]]) return path1 poly2 = path_to_poly(path2) if not poly2.is_valid: # output the shape to a debug file # write_debug("invalid2", [[shape_to_path(poly2), "black", "none"]]) return path1 diff_poly = poly1.difference(poly2) if isinstance(diff_poly, Polygon): new_path = shape_to_path(diff_poly) elif isinstance(diff_poly, GeometryCollection) or isinstance( diff_poly, MultiPolygon): new_path = [] for shape in diff_poly: # line objects have a length but no area new_path += shape_to_path(shape) else: print("not sure what to do with type:", type(diff_poly)) # make a new path from these points return Path(*new_path)
def snap(self, tree, threshold): def process(points): for i, p in enumerate(points): best, _, dist = tree.nearest_neighbor([p.real, p.imag]) if dist < threshold: points[i] = complex(best[0], best[1]) return points path = parse_path(self['d']) newPath = Path() for seg in path: points = process([seg.start, seg.end]) if isinstance(seg, Line): newSeg = Line(*points) newPath.append(newSeg) elif isinstance(seg, CubicBezier): newSeg = CubicBezier(points[0], seg.control1, seg.control2, points[1]) newPath.append(newSeg) self['d'] = newPath.d() return self
def transform_path(transform, path): if isinstance(path, str): return transform_path_string(transform, path) # if not a string, it's probably a Path object segments = path._segments for segment in segments: if isinstance(segment, CubicBezier): segment.start = transform_point(segment.start, matrix=transform, format="complex") segment.end = transform_point(segment.end, matrix=transform, format="complex") segment.control1 = transform_point(segment.control1, matrix=transform, format="complex") segment.control2 = transform_point(segment.control2, matrix=transform, format="complex") elif isinstance(segment, Line): segment.start = transform_point(segment.start, matrix=transform, format="complex") segment.end = transform_point(segment.end, matrix=transform, format="complex") else: raise ValueError("not sure how to handle {}".format(type(segment))) return Path(*segments)
def flip_path(upside_down_path): path = [] _, _, min_y, max_y = upside_down_path.bbox() offset = max_y + min_y for segment in upside_down_path._segments: if type(segment) is Line: path.append( Line(complex(segment.start.real, -segment.start.imag + offset), complex(segment.end.real, -segment.end.imag + offset))) elif type(segment) is Arc: path.append( Arc(complex(segment.start.real, -segment.start.imag + offset), segment.radius, abs(180 - segment.rotation), segment.large_arc, not segment.sweep, complex(segment.end.real, -segment.end.imag + offset))) elif type(segment) is QuadraticBezier: path.append( QuadraticBezier( complex(segment.start.real, -segment.start.imag + offset), complex(segment.control.real, -segment.control.imag + offset), complex(segment.end.real, -segment.end.imag + offset))) else: raise ValueError(f"Unknown type: {type(segment)}") return Path(*path)
def d(self, useSandT=False, use_closed_attrib=False, rel=False): """Returns a path d-string for the path object. For an explanation of useSandT and use_closed_attrib, see the compatibility notes in the README.""" segments = [s._segment for s in self._segments] path = Path(*segments) return path.d(useSandT, use_closed_attrib, rel)
def test_generate_straight_stroke(): dig = Digitizer() paths = [Path(*[Line(start=0, end=100), Line(start=100, end=100 + 100j), Line(start=100 + 100j, end=100j), Line(start=100j, end=0)])] dig.stroke_color = (0, 0, 0) dig.scale = 1.0 dig.generate_straight_stroke(paths) assert len(dig.stitches) > len(paths)
def generateInBetweens(poseA, poseB, steps): inv = Inventory() # make pairs pairs = [] for key in ORDER: if key in poseA.inv and key in poseB.inv: partA = poseA.inv[key] partB = poseB.inv[key] if len(partA) != 1 or len(partB) != 1: print('Too many parts {0} - A: {1} B: {2}'.format( key, partA.keys(), partB.keys())) continue pairs.append((key, partA.values()[0], partB.values()[0])) # If there are 3 steps, there are 4 gaps between start and finish # |------1------2------3------| gaps = steps + 1 # process pairs for key, a, b in pairs: pathA = parse_path(a['d']) pathB = parse_path(b['d']) if len(pathA) != len(pathB): print('Unmatched segments {0} - A: {1} B: {2}'.format( key, pathA, pathB)) continue for step in range(1, gaps): newPath = Path() for i in range(len(pathA)): segA = pathA[i] segB = pathB[i] if isinstance(segA, Line): points = _deltaPoints([segA.start, segA.end], [segB.start, segB.end], step, gaps) newPath.append(Line(*points)) elif isinstance(segA, CubicBezier): points = _deltaPoints( [segA.start, segA.control1, segA.control2, segA.end], [segB.start, segB.control1, segB.control2, segB.end], step, gaps) newPath.append(CubicBezier(*points)) newPart = Part(newPath.d()) newPart['x'] = int(_delta(a['x'], b['x'], step, gaps)) newPart['y'] = int(_delta(a['y'], b['y'], step, gaps)) newPart['z'] = int(_delta(a['z'], b['z'], step, gaps)) inv.addPart(key, newPart) print(key, step, newPart) return inv
def test_fill_scan(): dig = Digitizer() dig.fill_color = (0, 0, 0) paths = Path(*[Line(start=0, end=100), Line(start=100, end=100+100j), Line(start=100+100j, end=100j), Line(start=100j, end=0)]) dig.scale = 1.0 dig.fill = True dig.fill_scan(paths) assert len(dig.stitches) > 0
def test_scan_lines(): paths = Path(*[ Line(start=0, end=100), Line(start=100, end=100 + 100j), Line(start=100 + 100j, end=100j), Line(start=100j, end=0) ]) lines = scan_lines(paths) assert len(lines) > 0
def _remove_zero_length_lines(cls, paths): new_paths = [] for path in paths: pp = list(filter(lambda x: x.start != x.end, path)) newpath = Path() for p in pp: newpath.append(p) new_paths.append(newpath) return new_paths
def glyphToPaths(g, yMul=-1): paths = [] contours = [] yOffs = -font.info.unitsPerEm # decompose components if len(g.components): font.newGlyph('__svgsync') ng = font['__svgsync'] ng.width = g.width ng.appendGlyph(g) ng.decompose() g = ng for c in g: curve = False points = c.points path = Path() currentPos = 0j controlPoints = [] for x in range(len(points)): p = points[x] # print 'p#' + str(x) + '.type = ' + repr(p.type) if p.type == 'move': currentPos = vec2(p.x, (p.y + yOffs) * yMul) elif p.type == 'offcurve': controlPoints.append(p) elif p.type == 'curve': pos = vec2(p.x, (p.y + yOffs) * yMul) if len(controlPoints) == 2: cp1, cp2 = controlPoints path.append(CubicBezier( currentPos, vec2(cp1.x, (cp1.y + yOffs) * yMul), vec2(cp2.x, (cp2.y + yOffs) * yMul), pos)) else: if len(controlPoints) != 1: raise Exception('unexpected number of control points for curve') cp = controlPoints[0] path.append(QuadraticBezier(currentPos, vec2(cp.x, (cp.y + yOffs) * yMul), pos)) currentPos = pos controlPoints = [] elif p.type == 'line': pos = vec2(p.x, (p.y + yOffs) * yMul) path.append(Line(currentPos, pos)) currentPos = pos paths.append(path) if font.has_key('__svgsync'): font.removeGlyph('__svgsync') return paths
def test_generate_pattern(fill): dig = Digitizer() dig.all_paths = [Path(*[Line(start=0, end=100), Line(start=100, end=100+100j), Line(start=100+100j, end=100j), Line(start=100j, end=0)])] dig.attributes = [{"fill": "black"}] dig.scale = 1.0 dig.fill = fill dig.generate_pattern() assert len(dig.pattern.blocks) > 0 assert len(dig.pattern.blocks[0].stitches) > 0
def get_path(points): acc = [] start = complex(*points[0]) points = points[1:] + points[:1] for p in points: end = complex(*p) line = Line(start, end) acc.append(line) start = end return Path(*acc)
def extract_smufl_font(root, metadata_file): glyphnames = get_supported_glyph_codes() metadata = get_json_content(metadata_file) glyph_anchors = metadata[ "glyphsWithAnchors"] if "glyphsWithAnchors" in metadata else "" # extract alternate glyphs and append them if any alternate_glyphs = get_alternate_glyphs(glyphnames, metadata) if bool(alternate_glyphs): glyphnames.update(alternate_glyphs) # (1) Create xml file for each glyph write_xml_glyphs(glyphnames) # (2) Output bounding box svg for glyph in glyphs: # set glyph id glyph_code = glyph.attrib["glyph-name"][-4:] if glyph_code not in glyphnames: continue g_element = ET.SubElement(root, "g") g_element.set("c", glyph_code) # set bounding box values if present if "d" in glyph.attrib: path = Path(glyph.attrib["d"]) xmin, xmax, ymin, ymax = path.bbox() g_element.set("x", str(round(xmin, 2))) g_element.set("y", str(round(ymin, 2))) g_element.set("w", str(round(xmax - xmin, 2))) g_element.set("h", str(round(ymax - ymin, 2))) else: g_element.set("x", str(0.0)) g_element.set("y", str(0.0)) g_element.set("w", str(0.0)) g_element.set("h", str(0.0)) # set set horiz-av-x if "horiz-adv-x" in glyph.attrib: g_element.set("h-a-x", glyph.get("horiz-adv-x")) if not float(g_element.get("w")): g_element.set("w", glyph.get("horiz-adv-x")) # add glyph anchors if present for current glyph current_glyphname = glyphnames[ glyph_code] if glyph_code in glyphnames else "" if current_glyphname: g_element.set("n", current_glyphname) if current_glyphname in glyph_anchors: for key, value in glyph_anchors[current_glyphname].items(): a_element = ET.SubElement(g_element, "a") a_element.set("n", key) a_element.set("x", str(round(value[0], 2))) a_element.set("y", str(round(value[1], 2))) return root
def trace_image(filecontents): output = StringIO() output.write(filecontents) _image = Image.open(output) pixels = posturize(_image) output_paths = [] attributes = [] for color in pixels: data = zeros(_image.size, uint32) for pixel in pixels[color]: data[pixel[0], pixel[1]] = 1 # Create a bitmap from the array bmp = potrace.Bitmap(data) # Trace the bitmap to a path path = bmp.trace() # Iterate over path curves for curve in path: svg_paths = [] start_point = curve.start_point true_start = curve.start_point for segment in curve: if true_start is None: true_start = segment.start_point if start_point is None: start_point = segment.start_point if isinstance(segment, BezierSegment): svg_paths.append( CubicBezier( start=start_point[1] + 1j * start_point[0], control1=segment.c1[1] + segment.c1[0] * 1j, control2=segment.c2[1] + segment.c2[0] * 1j, end=segment.end_point[1] + 1j * segment.end_point[0])) elif isinstance(segment, CornerSegment): svg_paths.append( Line(start=start_point[1] + 1j * start_point[0], end=segment.c[1] + segment.c[0] * 1j)) svg_paths.append( Line(start=segment.c[1] + segment.c[0] * 1j, end=segment.end_point[1] + 1j * segment.end_point[0])) else: print("not sure what to do with: ", segment) start_point = segment.end_point # is the path closed? if true_start == start_point: output_paths.append(Path(*svg_paths)) color = pixel[2] rgb = "#%02x%02x%02x" % (color[0], color[1], color[2]) fill = rgb attributes.append({"fill": fill, "stroke": rgb}) true_start = None start_point = None svg_paths = [] return output_paths, attributes
def svgbox( pixelid, crosshatch, value, numlines ): lines = int( (255-value)/(256/numlines) ) vertical_lines = 0 horizontal_lines = lines if (crosshatch): horizontal_lines = ceil( lines / 2) vertical_lines = lines - horizontal_lines paths = [] move = [] origin = [pixelid[0]*((config.boxsize[0]/config.meters_per_step)/config.svg_pixel_size ), pixelid[1]*((config.boxsize[1]/config.meters_per_step)/config.svg_pixel_size ) ] current_loc = origin.copy() for y in range(0,horizontal_lines): if (y == 0): move = [0,(((config.boxsize[1]/config.meters_per_step)/config.svg_pixel_size )/horizontal_lines)/2] current_loc = [ current_loc[0] + move[0], current_loc[1] + move[1] ] else: move = [0,(((config.boxsize[1]/config.meters_per_step)/config.svg_pixel_size )/horizontal_lines)] current_loc = [ current_loc[0] + move[0], current_loc[1] + move[1] ] if (y % 2 == 0): move = [(config.boxsize[0]/config.meters_per_step)/config.svg_pixel_size,0] else: move = [(-config.boxsize[0]/config.meters_per_step)/config.svg_pixel_size,0] paths.append( Path( Line( complex(current_loc[0], current_loc[1]), complex(current_loc[0] + move[0], current_loc[1] + move[1] ) ) ) ) current_loc = [ current_loc[0] + move[0], current_loc[1] + move[1] ] current_loc = origin.copy() if (crosshatch): for y in range(0,vertical_lines): if (y == 0): move = [(((config.boxsize[0]/config.meters_per_step)/config.svg_pixel_size) /vertical_lines)/2,0] current_loc = [ current_loc[0] + move[0], current_loc[1] + move[1] ] else: move = [((config.boxsize[0]/config.meters_per_step) /config.svg_pixel_size )/vertical_lines,0] current_loc = [ current_loc[0] + move[0], current_loc[1] + move[1] ] if (y % 2 == 0): move = [0,((config.boxsize[1]/config.meters_per_step) /config.svg_pixel_size )] else: move = [0,((-config.boxsize[1]/config.meters_per_step) /config.svg_pixel_size )] paths.append( Path( Line( complex(current_loc[0], current_loc[1]), complex(current_loc[0] + move[0], current_loc[1] + move[1] ) ) ) ) current_loc = [ current_loc[0] + move[0], current_loc[1] + move[1] ] current_loc = origin.copy() return paths
def __init__(self, *segments, **kw): byA_FrozenClass.__init__(self) self._segments = Path() for p in segments: assert isinstance(p, byA_Line) or isinstance(p, byA_CubicBezier) if isinstance(p, byA_Line): self.insert(-1, p) if isinstance(p, byA_CubicBezier): self.insert(-1, p) if 'closed' in kw: self._segments.closed = kw['closed'] # DEPRECATED self._freeze("byA_Path")
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