def getglyphpath_pt(self, x_pt, y_pt, glyph, size_pt, convertcharcode=False, flex=True): """return an object containing the PyX path, wx_pt and wy_pt for glyph named glyph""" if convertcharcode: if not self.encoding: self._encoding() glyph = self.encoding[glyph] t = self.fontmatrix.scaled(size_pt) tpath = t.translated_pt(x_pt, y_pt) context = T1context(self, flex=flex) p = path() self.updateglyphpath(glyph, p, tpath, context) class glyphpath: def __init__(self, p, wx_pt, wy_pt): self.path = p self.wx_pt = wx_pt self.wy_pt = wy_pt return glyphpath(p, *t.apply_pt(context.wx, context.wy))
class ProteinDomain(Brick): _default_color = cmyk.Purple _offset = (0, -0.5) _path = path( moveto(0, 0), lineto(1, 0), lineto(1, 1), lineto(0, 1), lineto(0, 0), closepath(), moveto(1.4, 0), lineto(2.4, 0), lineto(2.4, 1), lineto(1.4, 1), lineto(1.4, 0), closepath(), moveto(2.8, 0), lineto(4, 0), lineto(4, -0.5), lineto(4+sqrt(3), 0.5), lineto(4, 1.5), lineto(4, 1), lineto(2.8, 1), lineto(2.8, 0), closepath() )
def corner(nx, ny, z, facecolor, edgecolor, trans, xdir, ydir): if xdir: p = path.path(path.moveto(*projector(nx, z, ny)), path.lineto(*projector(nx - 1, z, ny)), path.lineto(*projector(nx - 1, z + 1, ny)), path.lineto(*projector(nx, z + 1, ny)), path.closepath()) c.fill(p, [facecolor, color.transparency(trans)]) if ydir: p = path.path(path.moveto(*projector(nx, z, ny)), path.lineto(*projector(nx, z, ny + 1)), path.lineto(*projector(nx, z + 1, ny + 1)), path.lineto(*projector(nx, z + 1, ny)), path.closepath()) c.fill(p, [facecolor, color.transparency(trans)]) x0, y0 = projector(nx, z, ny) x1, y1 = projector(nx, z + 1, ny) c.stroke(path.line(x0, y0, x1, y1), [edgecolor])
def textpath(self): if self._textpath is None: if self.decode: if self.kerning: data = self.font.metric.resolvekernings( self.glyphnames, self.size_pt) else: data = self.glyphnames else: data = self.charcodes self._textpath = path.path() x_pt = self.x_pt y_pt = self.y_pt for i, value in enumerate(data): if self.kerning and i % 2: if value is not None: x_pt += value else: if i: x_pt += self.spaced_pt glyphpath = self.font.t1file.getglyphpath_pt( x_pt, y_pt, value, self.size_pt, convertcharcode=not self.decode) self._textpath += glyphpath.path x_pt += glyphpath.wx_pt y_pt += glyphpath.wy_pt return self._textpath
def signature(self, deg_max=6, padded=False, has_border=False): """ For a visualization of glyphs, lay out in a 2D grid PNG file. """ self.scale() sig = canvas.canvas([trafo.rotate(90), trafo.mirror(0)]) scale = 1.5 if padded or has_border: sig_margin = 0.2 x = (deg_max + 1) * scale + (1.5 * sig_margin) border_path = path.path(path.moveto(0, 0), path.lineto(0, x), path.lineto(x, x), path.lineto(x, 0), path.closepath()) if padded: border_color = color.cmyk.White if has_border: border_color = color.cmyk.Gray sig.stroke(border_path, [ border_color, trafo.translate(-sig_margin * 2, -sig_margin * 2), style.linewidth(.025) ]) for index in self.glist: if len(index) > 2: c = degree_glyph(index[0], index[1], index[2], (self.mincount, self.maxcount)) else: c = degree_glyph(index[0], index[1], 1, (self.mincount, self.maxcount)) sig.insert(c, [trafo.translate(index[0] * scale, (index[1]) * scale) ]) # text writing requires full latex return sig
def getglyphinfo(self, glyph): warnings.warn("We are about to extract font information for the Type 1 font '%s' from its pfb file. This is bad practice (and it's slow). You should use an afm file instead." % self.name) context = T1context(self) p = path() self.updateglyphpath(glyph, p, trafo.trafo(), context) bbox = p.bbox() return context.wx, context.wy, bbox.llx_pt, bbox.lly_pt, bbox.urx_pt, bbox.ury_pt
def place(self, x, y): x0, y0 = self.coords[0] paths = [path.moveto(x + x0, y + y0)] for point in self.coords[1:]: paths.append(path.lineto(x + point[0], y + point[1])) paths.append(path.closepath()) return (path.path(*paths), self.color, self.stroke_color)
def makebinaries(number, y0): size = 0.4 dist = 0.1 for n in range(32): c.stroke(path.rect(n * size + (n / 8) * dist, y0, size, size)) c.text((n + 0.5) * size + (n / 8) * dist, y0 + 0.07, r"\sffamily %i" % ((number >> 31 - n) & 1), [text.halign.center]) if number >> 31: c.text(32.2 * size + 5 * dist, y0 + 0.07, r"\sffamily = -%i" % ((number ^ 0xffffffff) + 1)) else: c.text(32.2 * size + 5 * dist, y0 + 0.07, r"\sffamily = %i" % number) p = path.path(path.moveto(0.2 * size, size + 0.03), path.lineto(0.2 * size, size + 0.07), path.lineto(3.8 * size, size + 0.07), path.lineto(3.8 * size, size + 0.03)) for n in range(4): c.stroke(p, [trafo.translate(n * (8 * size + dist), y0)]) c.text(n * (8 * size + dist) + 2 * size, size + 0.14 + y0, r"\sffamily %X" % ((number >> ((3 - n) * 8 + 4)) & 15), [text.halign.center]) c.stroke(p, [trafo.translate(n * (8 * size + dist) + 4 * size, y0)]) c.text(n * (8 * size + dist) + 6 * size, size + 0.14 + y0, r"\sffamily %X" % ((number >> ((3 - n) * 8)) & 15), [text.halign.center])
def paint(self, canvas, data, axis, axispos): if self.breaklinesattrs is not None: breaklinesdist_pt = unit.topt(self.breaklinesdist) breaklineslength_pt = unit.topt(self.breaklineslength) breaklinesextent_pt = (0.5*breaklinesdist_pt*math.fabs(self.cos) + 0.5*breaklineslength_pt*math.fabs(self.sin)) if canvas.extent_pt < breaklinesextent_pt: canvas.extent_pt = breaklinesextent_pt for v in [data.subaxes[name].vminover for name in data.names[1:]]: # use a tangent of the basepath (this is independent of the tickdirection) p = axispos.vbasepath(v, None).normpath() breakline = p.tangent(0, length=self.breaklineslength) widthline = p.tangent(0, length=self.breaklinesdist).transformed(trafomodule.rotate(self.breaklinesangle+90, *breakline.atbegin())) # XXX Uiiii tocenter = map(lambda x: 0.5*(x[0]-x[1]), zip(breakline.atbegin(), breakline.atend())) towidth = map(lambda x: 0.5*(x[0]-x[1]), zip(widthline.atbegin(), widthline.atend())) breakline = breakline.transformed(trafomodule.translate(*tocenter).rotated(self.breaklinesangle, *breakline.atbegin())) breakline1 = breakline.transformed(trafomodule.translate(*towidth)) breakline2 = breakline.transformed(trafomodule.translate(-towidth[0], -towidth[1])) canvas.fill(path.path(path.moveto_pt(*breakline1.atbegin_pt()), path.lineto_pt(*breakline1.atend_pt()), path.lineto_pt(*breakline2.atend_pt()), path.lineto_pt(*breakline2.atbegin_pt()), path.closepath()), [color.gray.white]) canvas.stroke(breakline1, self.defaultbreaklinesattrs + self.breaklinesattrs) canvas.stroke(breakline2, self.defaultbreaklinesattrs + self.breaklinesattrs) _title.paint(self, canvas, data, axis, axispos)
def getglyphinfo(self, glyph, flex=True): logger.warning("We are about to extract font information for the Type 1 font '%s' from its pfb file. This is bad practice (and it's slow). You should use an afm file instead." % self.name) context = T1context(self, flex=flex) p = path() self.updateglyphpath(glyph, p, trafo.trafo(), context) bbox = p.bbox() return context.wx, context.wy, bbox.llx_pt, bbox.lly_pt, bbox.urx_pt, bbox.ury_pt
def draw_sector(self, end): """draw the sector""" segment = path.path( path.arc(self.xo, self.yo, self.inner_r, self.start_angle, self.end_angle), path.arcn(self.xo, self.yo, self.sector_width + self.inner_r, self.end_angle, self.start_angle), path.closepath()) self.shape_canvas.fill(segment, [self.sector_color]) # draw a delimiting line between sectors line_color = color.gray(0.15) if end and (self.end_angle - self.start_angle) < 0.25: line_color = color.rgb.red r = self.inner_r + self.sector_width start_radians = self.start_angle * pi / 180.0 end_radians = self.end_angle * pi / 180.0 x0 = self.inner_r * cos(start_radians) + self.xo y0 = self.inner_r * sin(start_radians) + self.yo x1 = r * cos(start_radians) + self.xo y1 = r * sin(start_radians) + self.yo self.shape_canvas.stroke(path.line(x0, y0, x1, y1), [style.linewidth(0.01), line_color]) x0 = self.inner_r * cos(end_radians) + self.xo y0 = self.inner_r * sin(end_radians) + self.yo x1 = r * cos(end_radians) + self.xo y1 = r * sin(end_radians) + self.yo self.shape_canvas.stroke(path.line(x0, y0, x1, y1), [style.linewidth(0.01), line_color])
def makebinaries(number, y0): size = 0.4 dist = 0.1 for n in range(32): c.stroke(path.rect(n*size+(n/8)*dist, y0, size, size)) c.text((n+0.5)*size+(n/8)*dist, y0+0.07, r"\sffamily %i" % ((number >> 31-n) & 1), [text.halign.center]) if number >> 31: c.text(32.2*size+5*dist, y0+0.07, r"\sffamily = -%i" % ((number ^ 0xffffffff)+1)) else: c.text(32.2*size+5*dist, y0+0.07, r"\sffamily = %i" % number) p = path.path(path.moveto(0.2*size, size+0.03), path.lineto(0.2*size, size+0.07), path.lineto(3.8*size, size+0.07), path.lineto(3.8*size, size+0.03)) for n in range(4): c.stroke(p, [trafo.translate(n*(8*size+dist), y0)]) c.text(n*(8*size+dist)+2*size, size+0.14+y0, r"\sffamily %X" % ((number >> ((3-n)*8+4)) & 15), [text.halign.center]) c.stroke(p, [trafo.translate(n*(8*size+dist)+4*size, y0)]) c.text(n*(8*size+dist)+6*size, size+0.14+y0, r"\sffamily %X" % ((number >> ((3-n)*8)) & 15), [text.halign.center])
def paint(self, canvas, data, axis, axispos): if self.breaklinesattrs is not None: breaklinesdist_pt = unit.topt(self.breaklinesdist) breaklineslength_pt = unit.topt(self.breaklineslength) breaklinesextent_pt = (0.5*breaklinesdist_pt*math.fabs(self.cos) + 0.5*breaklineslength_pt*math.fabs(self.sin)) if canvas.extent_pt < breaklinesextent_pt: canvas.extent_pt = breaklinesextent_pt for v in [data.subaxes[name].vminover for name in data.names[1:]]: # use a tangent of the basepath (this is independent of the tickdirection) p = axispos.vbasepath(v, None).normpath() breakline = p.tangent(0, length=self.breaklineslength) widthline = p.tangent(0, length=self.breaklinesdist).transformed(trafomodule.rotate(self.breaklinesangle+90, *breakline.atbegin())) # XXX Uiiii tocenter = map(lambda x: 0.5*(x[0]-x[1]), zip(breakline.atbegin(), breakline.atend())) towidth = map(lambda x: 0.5*(x[0]-x[1]), zip(widthline.atbegin(), widthline.atend())) breakline = breakline.transformed(trafomodule.translate(*tocenter).rotated(self.breaklinesangle, *breakline.atbegin())) breakline1 = breakline.transformed(trafomodule.translate(*towidth)) breakline2 = breakline.transformed(trafomodule.translate(-towidth[0], -towidth[1])) canvas.layer("baseline").fill(path.path(path.moveto_pt(*breakline1.atbegin_pt()), path.lineto_pt(*breakline1.atend_pt()), path.lineto_pt(*breakline2.atend_pt()), path.lineto_pt(*breakline2.atbegin_pt()), path.closepath()), [color.gray.white]) canvas.layer("baseline").stroke(breakline1, self.defaultbreaklinesattrs + self.breaklinesattrs) canvas.layer("baseline").stroke(breakline2, self.defaultbreaklinesattrs + self.breaklinesattrs) _title.paint(self, canvas, data, axis, axispos)
def braid(n, i, t, inverse=False): if not isinstance(t, list): t = [t] t = t + [style.linewidth.Thick, red, style.linecap.round] N = 10 if i is None: items = range(n) else: assert 0<=i<i+1<n items = range(i)+range(i+2, n) for k in items: c.stroke(path.line(0.5*k, 0., 0.5*k, 1.), t) if i is None: return pts0 = [] for j in range(N): theta = pi*j/(N-1) x = 0.5 * 0.5 * (cos(theta)-1.) + 0.5*(i+1) y = 1.*j/(N-1) pts0.append((x, y)) pts1 = [] for j in range(N): theta = pi*j/(N-1) x = 0.5 * 0.5 * (1.-cos(theta)) + 0.5*i y = 1.*j/(N-1) pts1.append((x, y)) if inverse: pts0, pts1 = pts1, pts0 pts = [path.moveto(*pts0[0])] + [path.lineto(*p) for p in pts0[1:]] wiggle = path.path(*pts) c.stroke(wiggle, [deformer.smoothed(2.0)]+t) c.fill(path.circle(0.5*(i+0.5), 0.5, 0.15), t+[white]) pts = [path.moveto(*pts1[0])] + [path.lineto(*p) for p in pts1[1:]] wiggle = path.path(*pts) c.stroke(wiggle, [deformer.smoothed(2.0)]+t)
class Promoter(Brick): _default_color = cmyk.ForestGreen _offset = (0, -0.5) _path = path(moveto(0, 0), lineto(1, 0), lineto(1, 0.75), lineto(3, 0.75), lineto(3, 0.25), lineto(3 + sqrt(3) * 0.75, 1.125), lineto(3, 2.0), lineto(3, 1.5), lineto(1, 1.5), curveto(0.5, 1.5, 0.125, 1.5, 0, 1), lineto(0, 0), closepath())
def dopath(ps, extra=[], fill=[], closepath=True, smooth=0.3): ps = [path.moveto(*ps[0])]+[path.lineto(*p) for p in ps[1:]] if closepath: ps.append(path.closepath()) p = path.path(*ps) if fill: c.fill(p, [deformer.smoothed(smooth)]+extra+fill) c.stroke(p, [deformer.smoothed(smooth)]+extra)
def dopath(ps, extra=[], fill=False, closepath=True): ps = [path.moveto(*ps[0])]+[path.lineto(*p) for p in ps[1:]] if closepath: ps.append(path.closepath()) p = path.path(*ps) if fill: c.fill(p, [deformer.smoothed(0.3)]+extra+[color.rgb.white]) c.stroke(p, [deformer.smoothed(0.3)]+extra)
def polygonal_path(Z, loop=True): pa = path.path( path.moveto(Z[0].real, Z[0].imag), path.multilineto_pt( [ ( unit.topt(z.real), unit.topt(z.imag) ) for z in Z[1:] ] )) if loop: pa.append(path.closepath()) return pa
def client(clientcolor=color.rgb(0.8, 0.5, 0.5)): c = canvas.canvas() r = 0.3 c.fill(path.circle(0, 0, r), [clientcolor]) r = 0.5 p = path.path(path.moveto(-r, 0), path.curveto(-r, r, r, r, r, 0), path.closepath()) c.fill(p, [clientcolor, trafo.translate(0, -1.3 * r)]) return c
def getglyphpathwxwy_pt(self, glyph, size): m = self.fontmatrixpattern.search(self.data1) m11, m12, m21, m22, v1, v2 = map(float, m.groups()[:6]) t = trafo.trafo_pt(matrix=((m11, m12), (m21, m22)), vector=(v1, v2)).scaled(size) context = T1context(self) p = path() self.updateglyphpath(glyph, p, t, context) wx, wy = t.apply_pt(context.wx, context.wy) return p, wx, wy
def corner(nx, ny, z, facecolor, edgecolor, trans, xdir, ydir): if xdir: p = path.path(path.moveto(*projector(nx, z, ny)), path.lineto(*projector(nx-1, z, ny)), path.lineto(*projector(nx-1, z+1, ny)), path.lineto(*projector(nx, z+1, ny)), path.closepath()) c.fill(p, [facecolor, color.transparency(trans)]) if ydir: p = path.path(path.moveto(*projector(nx, z, ny)), path.lineto(*projector(nx, z, ny+1)), path.lineto(*projector(nx, z+1, ny+1)), path.lineto(*projector(nx, z+1, ny)), path.closepath()) c.fill(p, [facecolor, color.transparency(trans)]) x0, y0 = projector(nx, z, ny) x1, y1 = projector(nx, z+1, ny) c.stroke(path.line(x0, y0, x1, y1), [edgecolor])
def server(r, servercolor=color.rgb(0.5, 0.5, 0.8)): c = canvas.canvas() c.fill(path.circle(0, 0, r), [servercolor, trafo.scale(1, 0.5)]) h = 2 * r p = path.path(path.moveto(-r, 0), path.lineto(-r, -h), path.arc(0, -h, r, 180, 0), path.lineto(r, 0), path.arcn(0, 0, r, 0, 180), path.closepath()) c.fill(p, [servercolor, trafo.scale(1, 0.5).translated(0, -0.08 * r)]) return c
def getglyphpathwxwy_pt(self, glyph, size): m = self.fontmatrixpattern.search(self.data1) m11, m12, m21, m22, v1, v2 = map(float, m.groups()[:6]) t = trafo.trafo_pt(matrix=((m11, m12), (m21, m22)), vector=(v1, v2)).scaled(size) context = T1context(self) p = path() self.updateglyphpath(glyph, p, t, context) wx, wy = t.apply_pt(context.wx, context.wy) return p, wx, wy
def read(size, color): size = size * 0.25 cread = canvas.canvas() cread.fill(path.circle(0, 0, 0.35), [color, trafo.scale(size)]) p = path.path(path.moveto(0.8, 0), path.curveto(0.2, 0.5, -0.2, 0.5, -0.8, 0), path.curveto(-0.2, -0.5, 0.2, -0.5, 0.8, 0), path.closepath()) cread.stroke(p, [color, style.linewidth.thick, trafo.scale(size)]) return cread
def ucirc(): x1, y1 = x-dx*r, y-r st_scale = [trafo.scale(x=x1, y=y1, sx=1., sy=sy)] c.fill(path.circle(x1, y1, 0.5*r0), st_scale+[shade0]) c.stroke(path.path(path.arc(x1, y1, 0.5*r0, 180., 0.)), st_scale) x2, y2 = x1-0.5*dx*sy*r0, y1-0.5*sy*r0 c.stroke(path.line(x, y, x2, y2)) c.fill(path.circle(x2, y2, 0.05)) c.text(x2-0.5*r0, y2-0.5*r0, "${c}$", southeast)
def getglyphpathwxwy_pt(self, glyph, size, convertcharcode=False): if convertcharcode: if not self.encoding: self._encoding() glyph = self.encoding[glyph] t = self.fontmatrix.scaled(size) context = T1context(self) p = path() self.updateglyphpath(glyph, p, t, context) wx, wy = t.apply_pt(context.wx, context.wy) return p, wx, wy
def clear(self): """ Deletes the turtle's drawings from the window. This method does not move the turtle or alter its attributes. """ from pyx import path self._window.clear() self._window._addTurtle(self) self._pather = path.path(path.moveto(self.x, self.y)) self._dirty = False
def _fret(self, x, y): p = path.path( path.moveto(x, y), path.lineto(x, y+5*self.fret_height), path.moveto(x+self.fret_width, y), path.lineto(x+self.fret_width, y+5*self.fret_height), ) for i in range(0, 6): p.append(path.moveto(x, y+i*self.fret_height)) p.append(path.lineto(x+self.fret_width, y+i*self.fret_height)) return p
def flush(self): """ Writes the current turtle path and color to the window. PyX drawing only supports one color per path. Therefore, this must be called every time the turtle changes color. """ from pyx import path self._window.stroke(self._pather, self.color) self._pather = path.path(path.moveto(self.x, self.y)) self._dirty = False
def mkpath(x, y, radius=1.): pts = [] pts.append((x+0.07*radius, y+0.05*radius)) pts.append((x+0.5*radius, y+0.3*radius)) pts.append((x+0.5*radius, y-0.3*radius)) pts.append((x+0.07*radius, y-0.05*radius)) pts = [path.moveto(*pts[0])] + [path.lineto(*p) for p in pts[1:]] pts = path.path(*pts) return pts
def draw_pie(c, radius, start, end): pie = path.path(path.moveto(0, 0), path.arc(0, 0, radius, start, end), path.closepath()) hue = (start + end) / (360 * 2) color = pyx.color.hsb(hue, 0.8, 0.8) c.stroke( pie, [style.linewidth(0.01), pyx.color.rgb(1, 1, 1), deco.filled([color])])
def write(size, color): size = size * 0.3 cwrite = canvas.canvas() p = path.path(path.moveto(-0.2, 0.8), path.lineto(0.2, 0.8), path.lineto(0.2, 0), path.lineto(0, -0.2), path.lineto(-0.2, 0), path.lineto(-0.2, 0.8), path.closepath(), path.moveto(0, 0.8), path.lineto(0, 0.05), path.moveto(-0.2, 0), path.arcn(-0.1, 0, 0.1, 180, 20), path.arcn(0.1, 0, 0.1, 160, 0)) cwrite.stroke( p, [color, trafo.scale(size).rotated(-30).translated(0, -0.4 * size)]) return cwrite
def spiral(radius, angle, n, dphi=5): phif = angle + n * 360 npts = abs(phif) // dphi if abs(phif) >= 360: dr = 0.1 * abs(phif) / 360 else: dr = 0 p = path.path(path.moveto(radius - 0.5 * dr, 0)) for nphi in range(1, npts + 1): phi = radians(phif * nphi / npts) r = radius - 0.5 * dr + dr * nphi / npts p.append(path.lineto(r * cos(phi), r * sin(phi))) return p
def file(c, size=1, xoff=0, yoff=0, attrs=[], title=''): w = 3 h = 2.1 fold = 0.6 outline = path.path(path.moveto(0, 0), path.lineto(w, 0), path.lineto(w, h - fold), path.lineto(w - fold, h), path.lineto(0, h), path.closepath()) foldpath = path.path(path.moveto(w - fold, h), path.lineto(w - fold, h - fold), path.lineto(w, h - fold)) c1 = canvas.canvas() c1.stroke(outline, attrs) d = deformer.smoothed(0.2) c1.stroke(d.deform(foldpath), attrs) c1.stroke(path.rect(0.1 * w, 0.3 * h, 0.6 * w, 0.1 * h)) c1.stroke(path.rect(0.1 * w, 0.45 * h, 0.6 * w, 0.1 * h)) c1.stroke(path.rect(0.1 * w, 0.6 * h, 0.6 * w, 0.1 * h)) c1.stroke(path.rect(0.1 * w, 0.75 * h, 0.6 * w, 0.1 * h)) c1.text(0.1, 0.1, r'\sffamily ' + title, [trafo.scale(0.7)]) myattrs = [trafo.translate(xoff, yoff), trafo.scale(size)] myattrs.extend(attrs) c.insert(c1, myattrs)
def tetra(x, y, count=None, subcount=None, rev=1, back=True, front=True, reflect=False): if back: circle(x, y, r, shade) rr = 1.0*r if subcount is not None: ps = [] for i in range(3): theta1 = rev*2*(i+subcount)*pi/3 if i==0: # start of curve x1, y1 = x+rr*sin(theta1), y+rr*cos(theta1) ps.append((x1, y1)) if i==1: x1, y1 = x+0.7*r*sin(theta1), y+0.7*r*cos(theta1) ps.append((x1, y1)) else: x1, y1 = x+0.4*r*sin(theta1), y+0.4*r*cos(theta1) ps.append((x1, y1)) if i==2: # end of curve x1, y1 = x+1.0*rr*sin(theta1), y+1.0*rr*cos(theta1) ps.append((x1, y1)) c.stroke(path.path( path.moveto(*ps[0]), path.lineto(*ps[1]), path.lineto(*ps[2]), path.lineto(*ps[3]), path.lineto(*ps[4])), st_curve+[deformer.smoothed(0.6)]) if front: for theta1 in [0., 2*pi/3, 4*pi/3]: x1, y1 = x+0.5*r*sin(theta1), y+0.5*r*cos(theta1) circle(x1, y1, r0, white) if count is not None: assert 0<=count<=2 s = 0.86*r r1 = 2.4*r0 extra = [] #c.text(x, y, count) if reflect: #count = [0, 1, 2][count] extra.append(trafo.scale(x=x, y=y, sx=-1, sy=1)) extra += [trafo.rotate(-count*120, x=x, y=y)] t = Turtle(x1, y1-r1, -pi/2).right(pi, r1).fwd(s).right(pi, r1).fwd(s) t.stroke(extra) t.stroke(extra+[deco.earrow()])
def draw(self): p = path.path(path.moveto(*self.corners[0]), path.lineto(*self.corners[1]), path.lineto(*self.corners[2]), path.lineto(*self.corners[3]), path.closepath()) fillcolor = color.hsb(2/3*(1-(self.counter-1)/(self.nsquares-1)), 0.2, 1) self.c.stroke(p, [deco.filled([fillcolor])]) x, y = 0.5*(self.corners[0]+self.corners[2]) s = int(np.sum(np.abs(self.corners[1]-self.corners[0]))) self.c.text(x, y, str(s), [text.halign.center, text.valign.middle, text.size(min(s, 5))]) self.counter = self.counter+1
def dopath(ps, extra=[], fill=[], closepath=False, smooth=0.0): if not ps: print "dopath: empty" return ps = [path.moveto(*ps[0])]+[path.lineto(*p) for p in ps[1:]] if closepath: ps.append(path.closepath()) p = path.path(*ps) extra = list(extra) if smooth: extra.append(deformer.smoothed(smooth)) if fill: c.fill(p, extra+fill) c.stroke(p, extra)
def draw(self): p = path.path(path.moveto(*self.corners[0]), path.lineto(*self.corners[1]), path.lineto(*self.corners[2]), path.lineto(*self.corners[3]), path.closepath()) fillcolor = color.hsb( 2 / 3 * (1 - (self.counter - 1) / (self.nsquares - 1)), 0.2, 1) self.c.stroke(p, [deco.filled([fillcolor])]) x, y = 0.5 * (self.corners[0] + self.corners[2]) s = int(np.sum(np.abs(self.corners[1] - self.corners[0]))) self.c.text( x, y, str(s), [text.halign.center, text.valign.middle, text.size(min(s, 5))]) self.counter = self.counter + 1
def filesymbol(size, symbolcolor): wd = size ht = size * 1.414 knick = 0.25 * wd p = path.path(path.moveto(0.5 * wd - knick, 0.5 * ht), path.lineto(0.5 * wd, 0.5 * ht - knick), path.lineto(0.5 * wd, -0.5 * ht), path.lineto(-0.5 * wd, -0.5 * ht), path.lineto(-0.5 * wd, 0.5 * ht), path.lineto(0.5 * wd - knick, 0.5 * ht), path.lineto(0.5 * wd - knick, 0.5 * ht - knick), path.lineto(0.5 * wd, 0.5 * ht - knick)) cf = canvas.canvas() cf.stroke(p, [symbolcolor, style.linewidth.Thick, style.linejoin.round]) return cf
def mkpath(x, y, radius=1.): pts = [ ((x+0.05*radius, y+0.04*radius)), ((x+0.5*radius, y+0.20*radius)), ((x+0.5*radius, y-0.20*radius)), ((x+0.07*radius, y-0.05*radius)), ] pts = [(xx+0.8*yy, yy) for (xx, yy) in pts] pts = [path.moveto(*pts[0])] + [path.lineto(*p) for p in pts[1:]] pts = path.path(*pts) return pts
def frontplane(z, nxmax, mymax, facecolor, edgecolor, trans): p = path.path(path.moveto(*projector(0, z, 0)), path.lineto(*projector(nxmax, z, 0)), path.lineto(*projector(nxmax, z, nymax)), path.lineto(*projector(0, z, nymax)), path.closepath()) c.fill(p, [facecolor, color.transparency(trans)]) c.stroke(p, [edgecolor]) for nx in range(1, nxmax): x0, y0 = projector(nx, z, 0) x1, y1 = projector(nx, z, nymax) c.stroke(path.line(x0, y0, x1, y1), [edgecolor]) for ny in range(1, nymax): x0, y0 = projector(0, z, ny) x1, y1 = projector(nxmax, z, ny) c.stroke(path.line(x0, y0, x1, y1), [edgecolor])
def waning_moon(X, r, cx, cy) : '''draws a waning moon figure, used for moonrise.''' p = path.path(path.moveto(cx, cy+r)) p.append(path.arc(cx, cy, r, 90, -90)) if X>0.5 : R = R_of_S(X-0.5)*r theta = asin(r/R)*180/PI moon_arc_p = path.arc(cx-sqrt(R*R-r*r), cy, R, -theta, theta) else : R = R_of_S(0.5-X)*r theta = asin(r/R)*180/PI moon_arc_p = path.arc(cx+sqrt(R*R-r*r), cy, R, 180-theta, 180+theta) p = path.path.reversed(p) p.append(moon_arc_p) return p
def frontplane(z, nxmax, mymax, facecolor, edgecolor, trans): p = path.path(path.moveto(*projector(0, z, 0)), path.lineto(*projector(nxmax, z, 0)), path.lineto(*projector(nxmax, z, nymax)), path.lineto(*projector(0, z, nymax)), path.closepath()) c.fill(p, [facecolor, color.transparency(trans)]) c.stroke(p, [edgecolor]) for nx in range(1, nxmax): x0, y0 = projector(nx, z, 0) x1, y1 = projector(nx, z, nymax) c.stroke(path.line(x0, y0, x1, y1), [edgecolor]) for ny in range(1, nymax): x0, y0 = projector(0, z, ny) x1, y1 = projector(nxmax, z, ny) c.stroke(path.line(x0, y0, x1, y1), [edgecolor])
def test_pie(radius, start, end): c = canvas.canvas() container = path.rect(-(radius + 1), -(radius + 1), 2 * (radius + 1), 2 * (radius + 1)) c.stroke(container, [style.linewidth(0.001), color.rgb.red]) pie = path.path(path.moveto(0, 0), path.arc(0, 0, radius, start, end), path.closepath()) c.stroke(pie, [ style.linewidth(0.1), pyx.color.rgb(1, 1, 1), deco.filled([color.rgb.red]) ]) c.writeSVGfile("figure")
def event_to_path(event, chart, do_check=True, xoffset=0.0, yoffset=0.0) : '''accepts an array of points representing an event, converts this event to a path''' x, y = to_chart_coord(event[0], chart) p = path.path(path.moveto(x,y)) for e in event[1:] : old_x = x old_y = y x, y = to_chart_coord(e, chart) if (do_check == False or (fabs(old_x - x) < chart.width/2.0 and fabs(old_y - y) < chart.height/2.0)) : p.append(path.lineto(x+xoffset, y+yoffset)) else : p.append(path.moveto(x+xoffset, y+yoffset)) return p
def getglyphpath_pt(self, x_pt, y_pt, glyph, size_pt, convertcharcode=False, flex=True): """return an object containing the PyX path, wx_pt and wy_pt for glyph named glyph""" if convertcharcode: if not self.encoding: self._encoding() glyph = self.encoding[glyph] t = self.fontmatrix.scaled(size_pt) tpath = t.translated_pt(x_pt, y_pt) context = T1context(self, flex=flex) p = path() self.updateglyphpath(glyph, p, tpath, context) class glyphpath: def __init__(self, p, wx_pt, wy_pt): self.path = p self.wx_pt = wx_pt self.wy_pt = wy_pt return glyphpath(p, *t.apply_pt(context.wx, context.wy))
def plot(self, canvas, shape="s"): """Plot this direction on a pyx canvas. The direction will be transformed onto a Lambert equal-area projection and plotted as a square, circle, or triangle (shape parameter: s, c, or t). """ (x, y) = self.project() if shape == "s": canvas.stroke(path.rect(x - 0.1, y - 0.1, 0.2, 0.2)) elif shape == "t": s = 0.15 canvas.stroke(path.path(path.moveto(x, y + s), path.rlineto(-0.866 * s, -1.5 * s), path.rlineto(2 * .866 * s, 0), path.closepath())) elif shape == "c": canvas.stroke(path.circle(x, y, 0.1))
def wiggle(x0, y0, radius, wiggle=0.3, n=1): seed(n) items = [] # theta = 0. theta = 2*pi while theta > 0: r = radius + wiggle*random() p = [x0+r*sin(theta), y0+r*cos(theta)] items.append(p) theta -= 0.3*pi*random() #print items items = [path.moveto(*items[0])] + [path.lineto(*p) for p in items[1:]]\ + [path.lineto(*items[0])] items = path.path(*items) return items
def __init__(self, screen, position=(0, 0), color='red', heading=180, speed=0): """ Creates a new turtle to draw on the given screen. :param screen: window object that turtle will draw on. :type screen: :class:`Window` :param position: initial turtle position (origin is screen center) :type position: 2D ``tuple`` :param color: initial turtle color (default red) :type color: see ``color`` :param heading: initial turtle directions (default 180) :type heading: ``int`` or ``float`` :param speed: initial turtle speed (default 0) :type speed: ``int`` 0..10 """ from .window import Window, is_valid_color, to_valid_color from pyx import path assert type( screen) == Window, "$s is not a Window object" % repr(screen) assert (is_valid_color(color) ), "%s is not a valid color input" % repr(color) self._window = screen screen._addTurtle(self) self._heading = heading self._isdown = True self._speed = speed self._visible = True self._dirty = False self._color = to_valid_color(color) self._x = position[0] self._y = position[1] self._pather = path.path(path.moveto(self.x, self.y))
def interpolated_path(Z, shape=1.0, loop=True): shape /= 6.0 I = range(0, len(Z)-2) if loop: I += [-1] segments = [ ( Z[i] + (Z[i+1]-Z[i-1])*shape, Z[i+1] - (Z[i+2]-Z[i])*shape, Z[i+1] ) for i in I ] pa = path.path( path.moveto(Z[0].real, Z[0].imag), path.multicurveto_pt( [ (unit.topt(W[0].real), unit.topt(W[0].imag), unit.topt(W[1].real), unit.topt(W[1].imag), unit.topt(W[2].real), unit.topt(W[2].imag) ) for W in segments ])) if loop: pa.append(path.closepath()) return pa
def pyx_plotter(self): from pyx import canvas, path, color st = Stats(self.points) if self.plot_range == AUTO: xmax, xmin, ymax, ymin = st.bbox_auto(self.points) else: xmax, xmin, ymax, ymin = st.bbox() wd, ht = xmax - xmin, ymax - ymin sx = self.default_width / wd sy = self.aspect_ratio * self.default_width / ht #print 'WD:', wd, 'HT:', ht, sx, sy clip = canvas.clip(path.rect(sx * xmin, sy * ymin, sx * wd, sy * ht)) c = canvas.canvas([clip]) #c.stroke(path.rect(sx*xmin, sy*ymin, sx*wd, sy*ht)) pth = path.path() first_point = True for p in self.points: if first_point: pth.append(path.moveto(sx * p.x, sy * p.y)) first_point = False else: pth.append(path.lineto(sx * p.x, sy * p.y)) c.stroke(pth) for p in self.points: if st.is_extreme_outlier(p): c.fill(path.circle(sx * p.x, sy * p.y, 0.03), [color.rgb.red]) else: c.fill(path.circle(sx * p.x, sy * p.y, 0.03)) return c
def pyx_plotter(self): from pyx import canvas, path, color st = Stats(self.points) if self.plot_range == AUTO: xmax, xmin, ymax, ymin = st.bbox_auto(self.points) else: xmax, xmin, ymax, ymin = st.bbox() wd, ht = xmax - xmin, ymax - ymin sx = self.default_width / wd sy = self.aspect_ratio * self.default_width / ht #print 'WD:', wd, 'HT:', ht, sx, sy clip = canvas.clip(path.rect(sx * xmin, sy * ymin, sx * wd, sy * ht)) c = canvas.canvas([clip]) #c.stroke(path.rect(sx*xmin, sy*ymin, sx*wd, sy*ht)) pth = path.path() first_point = True for p in self.points: if first_point: pth.append(path.moveto(sx * p.x, sy * p.y)) first_point = False else: pth.append(path.lineto(sx * p.x, sy * p.y)) c.stroke(pth) for p in self.points: if st.is_extreme_outlier(p): c.fill(path.circle(sx * p.x, sy * p.y, 0.03), [color.rgb.red]) else: c.fill(path.circle(sx * p.x, sy * p.y, 0.03)) return c
def textpath(self): if self._textpath is None: if self.decode: if self.kerning: data = self.font.metric.resolvekernings(self.glyphnames, self.size_pt) else: data = self.glyphnames else: data = self.charcodes self._textpath = path.path() x_pt = self.x_pt y_pt = self.y_pt for i, value in enumerate(data): if self.kerning and i % 2: if value is not None: x_pt += value else: if i: x_pt += self.spaced_pt glyphpath = self.font.t1file.getglyphpath_pt(x_pt, y_pt, value, self.size_pt, convertcharcode=not self.decode) self._textpath += glyphpath.path x_pt += glyphpath.wx_pt y_pt += glyphpath.wy_pt return self._textpath
points.insert(idx, (1.5*dx, -2.7*dy)); idx+=1 points.insert(idx, (1.5*dx, -2.*dy)); idx+=1 points.insert(idx, (1.5*dx, -1.4*dy)); idx+=3 # next pair points.insert(idx, (3.7*dx, -1.4*dy)); idx+=1 points.insert(idx, (3.7*dx, -1.6*dy)); idx+=1 points.insert(idx, (1.7*dx, -1.6*dy)); idx+=3 # next pair points.insert(idx, (1.7*dx, -3.3*dy)); # end items = [] for i, p in enumerate(points): if i==0: items.append(path.moveto(*p)) else: items.append(path.lineto(*p)) c.stroke(path.path(*items), [trafo.translate(tx0, ty0), lred, deformer.smoothed(2.0), style.linewidth.THICk, deco.earrow(size=0.3)]) for (s, t) in [(0, 1), (2, 3), (4, 5)]: pair(points0[s], points0[t]) y -= 4.*dy c.text(x, y, r"""When we yank the red line straight we find out what braid moves to do: """, [text.parbox(dw-2*m),]) # Linear order:
def zvgridpath(self, vz): return path.path(path.moveto_pt(*self.vpos_pt(0, 0, vz)), path.lineto_pt(*self.vpos_pt(1, 0, vz)), path.lineto_pt(*self.vpos_pt(1, 1, vz)), path.lineto_pt(*self.vpos_pt(0, 1, vz)), path.closepath())
def yvgridpath(self, vy): return path.path(path.moveto_pt(*self.vpos_pt(0, vy, 0)), path.lineto_pt(*self.vpos_pt(1, vy, 0)), path.lineto_pt(*self.vpos_pt(1, vy, 1)), path.lineto_pt(*self.vpos_pt(0, vy, 1)), path.closepath())
def xvgridpath(self, vx): return path.path(path.moveto_pt(*self.vpos_pt(vx, 0, 0)), path.lineto_pt(*self.vpos_pt(vx, 1, 0)), path.lineto_pt(*self.vpos_pt(vx, 1, 1)), path.lineto_pt(*self.vpos_pt(vx, 0, 1)), path.closepath())
codepointbinary.reverse() size = 0.4 x0 = 0 y0 = 3 dy = 0.07 c.fill(path.rect(x0, y0, 5*size, size), [color.grey(0.5), deco.stroked([color.grey(0.5)])]) c.stroke(path.rect(x0+5*size, y0, 5*size, size)) c.stroke(path.rect(x0+10*size, y0, 6*size, size)) for n in range(len(codepointbinary)): c.text(x0+(n+0.5)*size, y0+dy, r"\sffamily %i" % codepointbinary[n], [text.halign.center]) p = path.path(path.moveto(0.2*size, size+0.03), path.lineto(0.2*size, size+0.07), path.lineto(3.8*size, size+0.07), path.lineto(3.8*size, size+0.03)) for n in range(bits//4): c.stroke(p, [trafo.translate(4*n*size, y0)]) c.text((4*n+2)*size, size+0.14+y0, r"\sffamily %X" % (codepoint >> (bits//4-n-1)*4 & 0x0f), [text.halign.center]) utf8code = 0xC080 \ + (((codepoint >> 6) & 0x1f) << 8) \ + (codepoint & 0x3f) utf8codebinary = [(utf8code & 2**n)/2**n for n in range(bits)] utf8codebinary.reverse() y1 = 2 c.fill(path.rect(x0, y1, 3*size, size),
def last_quarter_moon(r, cx, cy) : p = path.path(path.moveto(cx, cy)) p.append(path.arc(cx, cy, r, 90, -90)) p.append(path.closepath()) return p