def add_frame(self, name, box, style, radius=0): """ name -- The name of the new frame object. box -- The boundary box of the node. style -- The style used to draw the path. radius -- The corner radius of the frame. returns a new frame node. """ r = min( [radius, (abs(box[1] - box[0]) / 2), (abs(box[3] - box[2]) / 2)]) if radius > 0: d = ' '.join( str(x) for x in [ 'M', box[0], (box[2] + r), 'A', r, r, '0 0 1', ( box[0] + r), box[2], 'L', (box[1] - r), box[2], 'A', r, r, '0 0 1', box[1], (box[2] + r), 'L', box[1], ( box[3] - r), 'A', r, r, '0 0 1', (box[1] - r), box[3], 'L', (box[0] + r), box[3], 'A', r, r, '0 0 1', box[0], (box[3] - r), 'Z' ]) else: d = ' '.join( str(x) for x in [ 'M', box[0], box[2], 'L', box[1], box[2], 'L', box[1], box[3], 'L', box[0], box[3], 'Z' ]) elem = PathElement() elem.style = style elem.label = name elem.path = d return elem
def generateLine(self, x1, y1, x2, y2, strokeWidth, stroke, name): line = PathElement() line.path = 'M {} {} L {} {}'.format(x1, y1, x2, y2) line.style = { 'stroke': stroke, 'stroke-width': strokeWidth, 'fill': 'none' } line.label = name return line
def test_path_horizontal_line_stroke_square_cap(self): path = PathElement() path.set_path("M 0 0 " "L 1 0") stroke_half_width = 1.0 path.style = Style("stroke-width:{};stroke:red".format(stroke_half_width * 2)) path.set("stroke-linecap", "square") self.assert_bounding_box_is_equal(path, (-stroke_half_width, 1 + stroke_half_width), (-stroke_half_width, stroke_half_width))
def generateSectorColoredPart(): nSectorPlusOne = nSector + 1 pathPattern = 'm{} {} v {} h {} v {} h {} v {} h {} v {} Z' coloredPart = PathElement() coloredPart.style = { 'stroke': stroke, 'stroke-width': strokeWidth, 'fill': self.sectorColors[nSector] } coloredPart.label = 'colored-part-{}'.format(nSectorPlusOne) coloredPart.path = pathPattern.format( (nColumns / 2 - 2) * xBoxSize, initialY - yBoxSize, -initialY + yBoxSize, xBoxSize, yBoxSize * (nBoxesPerColumn - 5), xBoxSize, yBoxSize, -xBoxSize, yBoxSize * 3) return coloredPart
def generateOutline(): pathPattern = 'm{} {} v {} l {} {} h {} l {} {} v {} Z' outline = PathElement() outline.style = { 'stroke': stroke, 'stroke-width': strokeWidth, 'fill': fillSecure } outline.label = 'outline-{}'.format(nSector + 1) outline.path = pathPattern.format(initialX, initialY, -initialY + yBoxSize, obliqueDistance, -yBoxSize, topDistance, obliqueDistance, yBoxSize, yBoxSize * (nBoxesPerColumn - 1)) return outline
def generateSectorCenterPart(): nSectorPlusOne = nSector + 1 pathPattern = 'm{} {} L {} {} L {} {}' centerColoredPart = PathElement() fill = ('none', self.sectorColors[nSector])[not self.useLaser and self.generateCenter] centerColoredPart.style = { 'stroke': stroke, 'stroke-width': strokeWidth, 'fill': fill } centerColoredPart.label = 'colored-part-{}'.format(nSectorPlusOne) cornerSize = initialX + obliqueDistance centerColoredPart.path = pathPattern.format( cornerSize, 0, 0, -distanceFromBoardCenter, -cornerSize, 0) return centerColoredPart
def plotPath( self, style, yidx=0 ): "Generates path-command-string and returns a path-element." pathstr = "" dataiter = iter(self.data) vals = next(dataiter) values = {'x':vals['x'],'y':vals['y'][yidx]} nextmove = 'M' if values['x'] > self.xmin and values['x'] < self.xmax and values['y'] > self.ymin and values['y'] < self.ymax: pathstr += '{}{},{}'.format( nextmove, self.transformx(values['x']), self.transformy(values['y']) ) nextmove = 'L' prevalues=values while True: try: vals = next(dataiter) values = {'x':vals['x'],'y':vals['y'][yidx]} except StopIteration: break if values['x'] > self.xmin and values['x'] < self.xmax and values['y'] > self.ymin and values['y'] < self.ymax: if nextmove == 'M': interpoint = intersectionPoint(values,prevalues,self.xmin,self.xmax,self.ymin,self.ymax) pathstr += ' {}{},{}'.format( nextmove, self.transformx(interpoint['x']), self.transformy(interpoint['y']) ) nextmove = 'L' pathstr += ' {}{},{}'.format( nextmove, self.transformx(values['x']), self.transformy(values['y']) ) nextmove = 'L' else: if nextmove == 'L': interpoint = intersectionPoint(values,prevalues,self.xmin,self.xmax,self.ymin,self.ymax) pathstr += ' {}{},{}'.format( nextmove, self.transformx(interpoint['x']), self.transformy(interpoint['y']) ) nextmove = 'M' prevalues = values newpath = PathElement(d=pathstr) newpath.style = style return newpath
def generate(self): teeth = self.options.teeth pitch = self.svg.unittouu(str(self.options.pitch) + self.options.unit) angle = self.options.angle # Angle of tangent to tooth at circular pitch wrt radial line. centerdiameter = self.svg.unittouu( str(self.options.centerdiameter) + self.options.unit) # print >>sys.stderr, "Teeth: %s\n" % teeth two_pi = 2.0 * pi # Pitch (circular pitch): Length of the arc from one tooth to the next) # Pitch diameter: Diameter of pitch circle. pitch_diameter = float(teeth) * pitch / pi pitch_radius = pitch_diameter / 2.0 # Base Circle base_diameter = pitch_diameter * cos(radians(angle)) base_radius = base_diameter / 2.0 # Diametrial pitch: Number of teeth per unit length. pitch_diametrial = float(teeth) / pitch_diameter # Addendum: Radial distance from pitch circle to outside circle. addendum = 1.0 / pitch_diametrial # Outer Circle outer_radius = pitch_radius + addendum outer_diameter = outer_radius * 2.0 # Tooth thickness: Tooth width along pitch circle. tooth = (pi * pitch_diameter) / (2.0 * float(teeth)) # Undercut? undercut = (2.0 / (sin(radians(angle))**2)) needs_undercut = teeth < undercut # Clearance: Radial distance between top of tooth on one gear to bottom of gap on another. clearance = 0.0 # Dedendum: Radial distance from pitch circle to root diameter. dedendum = addendum + clearance # Root diameter: Diameter of bottom of tooth spaces. root_radius = pitch_radius - dedendum root_diameter = root_radius * 2.0 half_thick_angle = two_pi / (4.0 * float(teeth)) pitch_to_base_angle = involute_intersect_angle(base_radius, pitch_radius) pitch_to_outer_angle = involute_intersect_angle( base_radius, outer_radius) - pitch_to_base_angle centers = [(x * two_pi / float(teeth)) for x in range(teeth)] points = [] for c in centers: # Angles pitch1 = c - half_thick_angle base1 = pitch1 - pitch_to_base_angle outer1 = pitch1 + pitch_to_outer_angle pitch2 = c + half_thick_angle base2 = pitch2 + pitch_to_base_angle outer2 = pitch2 - pitch_to_outer_angle # Points b1 = point_on_circle(base_radius, base1) p1 = point_on_circle(pitch_radius, pitch1) o1 = point_on_circle(outer_radius, outer1) b2 = point_on_circle(base_radius, base2) p2 = point_on_circle(pitch_radius, pitch2) o2 = point_on_circle(outer_radius, outer2) if root_radius > base_radius: pitch_to_root_angle = pitch_to_base_angle - involute_intersect_angle( base_radius, root_radius) root1 = pitch1 - pitch_to_root_angle root2 = pitch2 + pitch_to_root_angle r1 = point_on_circle(root_radius, root1) r2 = point_on_circle(root_radius, root2) p_tmp = [r1, p1, o1, o2, p2, r2] else: r1 = point_on_circle(root_radius, base1) r2 = point_on_circle(root_radius, base2) p_tmp = [r1, b1, p1, o1, o2, p2, b2, r2] points.extend(p_tmp) path = points_to_svgd(points) # Create SVG Path for gear style = { 'stroke': '#000000', 'fill': 'none', 'stroke-width': str(self.svg.unittouu('1px')) } gear = PathElement() gear.style = style gear.path = path yield gear if centerdiameter > 0.0: arc = PathElement.arc((0, 0), centerdiameter / 2) arc.style = style yield arc