Пример #1
0
    def draw(self, renderer):
        renderer.open_group("regpolycollection")
        self._transform.freeze()
        self._transOffset.freeze()
        self.update_scalarmappable()
        scales = sqrt(self._sizes * self._dpi.get() / 72.0)

        if self._edgecolors == "None":
            self._edgecolors = self._facecolors

        renderer.draw_regpoly_collection(
            self.clipbox,
            self._offsets,
            self._transOffset,
            self._verts,
            scales,
            self._facecolors,
            self._edgecolors,
            self._linewidths,
            self._antialiaseds,
        )

        self._transform.thaw()
        self._transOffset.thaw()
        renderer.close_group("regpolycollection")
Пример #2
0
def line2d_dist(l, p):
    """
    Distance from line to point
    line is a tuple of coefficients a,b,c 
    """
    a, b, c = l
    x0, y0 = p
    return abs((a * x0 + b * y0 + c) / nx.sqrt(a**2 + b**2))
Пример #3
0
def dist2d(p0, p1):
    """distance between two points"""
    try:
        p = p0 - p1
        return nx.sqrt(sum(p**2))
    except ValueError:
        print p0, p1
        raise
Пример #4
0
def colorbars(epsoutfile):
    x = (arange(50.0)-25)/2.0
    y = (arange(50.0)-25)/2.0
    r = sqrt(x[:,NewAxis]**2+y**2)
    z = 5.0*cos(r)  

    colmap = ColMapper.ColorMapper("yellow-red", exponent=0.55, brightness=0.5)
    lut = colmap.generate_lut()

    c = pyx.canvas.canvas()
    g = pyxgraph(xlimits=(min(x), max(x)), ylimits=(min(y), max(y)),
                 width=6, height=6)
    g.pyxplot("y(x)=sin(x)", style="p")  # FIXME: can't do empty plots!
    g.pyxplotarray(z, colmap=lut)
    c.insert(g)

    minz = minvalue=min(ravel(z))
    maxz = maxvalue=max(ravel(z))

    # --- vertical bars
    dist = 1.2
    for orientation, position in [("vertical", "right"),
                                  ("vertical", "middle"),
                                  ("vertical2", "middle")]:
        cb = pyxcolorbar(lut=lut, frame=g,
                         pos=(dist, 0),
                         orientation = orientation,
                         position = position,
                         minvalue = minz, maxvalue=maxz)
        # add a short note on the style:
        txt = orientation[0]
        if "2" in orientation:
            txt += "2"
        txt += ", "+position[0]            
        cb.pyxlabel( (0.0, 1.3), txt, style=[pyx.text.halign.left])

        c.insert(cb)
        dist = dist + 0.5

    # horizontal ones:
    dist = -0.3
    for orientation, position in [("horizontal", "middle"),
                                  ("horizontal2", "middle")]:
        cb = pyxcolorbar(lut=lut, frame=g, pos=(0.0, dist),
                         orientation = orientation,
                         position = position,
                         minvalue = minz, maxvalue=maxz)
        # add a short note on the style:
        txt = orientation[0]
        if "2" in orientation:
            txt += "2"
        txt += ", "+position[0]            
        cb.pyxlabel( (1.3, 0.5), txt, style=[pyx.text.halign.left])

        c.insert(cb)
        dist = dist - 0.3
    
    pyxsave(c, epsoutfile)
Пример #5
0
 def too_close(self, x,y, lw):
     "if there's a label already nearby, find a better place"
     if self.cl_xy != []:
         dist = [sqrt((x-loc[0]) ** 2 + (y-loc[1]) ** 2) for loc in self.cl_xy]
         for d in dist:
             if d < 1.2*lw:
                 return 1
             else: return 0
     else: return 0
Пример #6
0
 def __init__(self, x, y, dx, dy, width=1.0, **kwargs):
     """Draws an arrow, starting at (x,y), direction and length
     given by (dx,dy) the width of the arrow is scaled by width
     """
     arrow = array([[0.0, 0.1], [0.0, -0.1], [0.8, -0.1], [0.8, -0.3], [1.0, 0.0], [0.8, 0.3], [0.8, 0.1]])
     L = sqrt(dx ** 2 + dy ** 2) or 1  # account for div by zero
     arrow[:, 0] *= L
     arrow[:, 1] *= width
     cx = float(dx) / L
     sx = float(dy) / L
     M = array([[cx, sx], [-sx, cx]])
     verts = matrixmultiply(arrow, M) + [x, y]
     Polygon.__init__(self, [tuple(t) for t in verts], **kwargs)
Пример #7
0
def array_example1(epsoutfile):
    x = (arange(50.0)-25)/2.0
    y = (arange(50.0)-25)/2.0
    r = sqrt(x[:,NewAxis]**2+y**2)
    z = 5.0*sin(r)  

    g=pyxgraph(xlimits=(min(x), max(x)), ylimits=(min(y), max(y)),
               width=6, height=6, key=False)
    # WARNING: if key is not specified to be False, one gets a weird
    # error ....
    #g.pyxplot("y(x)=sin(x)", style="p")  # FIXME: can't do empty plots!
    g.pyxplotarray(z, colmap=ColMapper.ColorMapper("yellow-red",
                                                exponent=0.55, brightness=0.5))
    g.pyxsave(epsoutfile)
Пример #8
0
    def get_ind_under_point(self, event):
        'get the index of the vertex under point if within epsilon tolerance'
        x, y = zip(*self.poly.verts)

        # display coords
        xt, yt = self.poly.get_transform().numerix_x_y(x, y)
        d = sqrt((xt - event.x)**2 + (yt - event.y)**2)
        indseq = nonzero(equal(d, amin(d)))
        ind = indseq[0]

        if d[ind] >= self.epsilon:
            ind = None

        return ind
Пример #9
0
    def get_ind_under_point(self, event):
        'get the index of the vertex under point if within epsilon tolerance'
        x, y = zip(*self.poly.verts)
        
        # display coords        
        xt, yt = self.poly.get_transform().numerix_x_y(x, y)
        d = sqrt((xt-event.x)**2 + (yt-event.y)**2)
        indseq = nonzero(equal(d, amin(d)))
        ind = indseq[0]

        if d[ind]>=self.epsilon:
            ind = None

        return ind
Пример #10
0
 def __init__(self, x, y, dx, dy, width=1.0, **kwargs):
     """Draws an arrow, starting at (x,y), direction and length
     given by (dx,dy) the width of the arrow is scaled by width
     """
     arrow = array([[0.0, 0.1], [0.0, -0.1], [0.8, -0.1], [0.8, -0.3],
                    [1.0, 0.0], [0.8, 0.3], [0.8, 0.1]])
     L = sqrt(dx**2 + dy**2) or 1  # account for div by zero
     arrow[:, 0] *= L
     arrow[:, 1] *= width
     cx = float(dx) / L
     sx = float(dy) / L
     M = array([[cx, sx], [-sx, cx]])
     verts = matrixmultiply(arrow, M) + [x, y]
     Polygon.__init__(self, [tuple(t) for t in verts], **kwargs)
Пример #11
0
    def locate_label(self, linecontour, labelwidth):
        """find a good place to plot a label (relatively flat
        part of the contour) and the angle of rotation for the
        text object
        """

        nsize = len(linecontour)
        if labelwidth > 1:
            xsize = int(ceil(nsize / labelwidth))
        else:
            xsize = 1
        if xsize == 1:
            ysize = nsize
        else:
            ysize = labelwidth

        XX = resize(asarray(linecontour)[:, 0], (xsize, ysize))
        YY = resize(asarray(linecontour)[:, 1], (xsize, ysize))

        yfirst = YY[:, 0]
        ylast = YY[:, -1]
        xfirst = XX[:, 0]
        xlast = XX[:, -1]
        s = ((reshape(yfirst, (xsize, 1)) - YY) *
             (reshape(xlast, (xsize, 1)) - reshape(xfirst, (xsize, 1))) -
             (reshape(xfirst, (xsize, 1)) - XX) *
             (reshape(ylast, (xsize, 1)) - reshape(yfirst, (xsize, 1))))
        L = sqrt((xlast - xfirst)**2 + (ylast - yfirst)**2)
        dist = add.reduce(([(abs(s)[i] / L[i]) for i in range(xsize)]), -1)
        x, y, ind = self.get_label_coords(dist, XX, YY, ysize, labelwidth)
        #print 'ind, x, y', ind, x, y
        angle = arctan2(ylast - yfirst, xlast - xfirst)
        rotation = angle[ind] * 180 / pi
        if rotation > 90:
            rotation = rotation - 180
        if rotation < -90:
            rotation = 180 + rotation

        # There must be a more efficient way...
        lc = [tuple(l) for l in linecontour]
        dind = lc.index((x, y))
        #print 'dind', dind
        #dind = list(linecontour).index((x,y))

        return x, y, rotation, dind
Пример #12
0
    def locate_label(self, linecontour, labelwidth):
        """find a good place to plot a label (relatively flat
        part of the contour) and the angle of rotation for the
        text object
        """

        nsize= len(linecontour)
        if labelwidth > 1:
            xsize = int(ceil(nsize/labelwidth))
        else:
            xsize = 1
        if xsize == 1:
            ysize = nsize
        else:
            ysize = labelwidth

        XX = resize(asarray(linecontour)[:,0],(xsize, ysize))
        YY = resize(asarray(linecontour)[:,1],(xsize,ysize))

        yfirst = YY[:,0]
        ylast = YY[:,-1]
        xfirst = XX[:,0]
        xlast = XX[:,-1]
        s = ( (reshape(yfirst, (xsize,1))-YY) *
              (reshape(xlast,(xsize,1)) - reshape(xfirst,(xsize,1)))
              - (reshape(xfirst,(xsize,1))-XX)
              * (reshape(ylast,(xsize,1)) - reshape(yfirst,(xsize,1))) )
        L=sqrt((xlast-xfirst)**2+(ylast-yfirst)**2)
        dist = add.reduce(([(abs(s)[i]/L[i]) for i in range(xsize)]),-1)
        x,y,ind = self.get_label_coords(dist, XX, YY, ysize, labelwidth)
        #print 'ind, x, y', ind, x, y
        angle = arctan2(ylast - yfirst, xlast - xfirst)
        rotation = angle[ind]*180/pi
        if rotation > 90:
            rotation = rotation -180
        if rotation < -90:
            rotation = 180 + rotation

        # There must be a more efficient way...
        lc = [tuple(l) for l in linecontour]
        dind = lc.index((x,y))
        #print 'dind', dind
        #dind = list(linecontour).index((x,y))

        return x,y, rotation, dind
Пример #13
0
    def draw(self, renderer):
        renderer.open_group('regpolycollection')
        self._transform.freeze()
        self._transOffset.freeze()
        self.update_scalarmappable()
        scales = sqrt(self._sizes * self._dpi.get() / 72.0)

        if self._edgecolors == 'None':
            self._edgecolors = self._facecolors

        renderer.draw_regpoly_collection(self.clipbox, self._offsets,
                                         self._transOffset, self._verts,
                                         scales, self._facecolors,
                                         self._edgecolors, self._linewidths,
                                         self._antialiaseds)

        self._transform.thaw()
        self._transOffset.thaw()
        renderer.close_group('regpolycollection')
Пример #14
0
def array_example3(epsoutfile):
    x = (arange(200.0) - 100) / 10.0
    y = (arange(200.0) - 100) / 10.0
    r = sqrt(x[:, NewAxis] ** 2 + y ** 2)
    z = 5.0 * cos(r)

    colmap1 = ColMapper.ColorMapper("red")
    colmap1.exponent = 0.9
    colmap1.invert = True

    colmap2 = ColMapper.ColorMapper("green")
    colmap2.exponent = 0.9

    colmap3 = ColMapper.ColorMapper("green")
    colmap3.invert = True
    colmap3.exponent = 0.9

    colmap4 = ColMapper.ColorMapper("blue")
    colmap4.exponent = 0.9

    colmap = ColMapper.SegmentedColorMapping(
        [(-5.0, -2.5, colmap1), (-2.5, 0.0, colmap2), (0.0, 2.5, colmap3), (2.5, 5.0, colmap4)], -5.0, 5.0
    )

    #     colmap = ColMapper.example_SegmentedColorMapping(min(ravel(z)),max(ravel(z)))
    lut = colmap.generate_lut()

    pilbitmap = ColMapper.Array2PIL(z, lut=lut)

    c = pyx.canvas.canvas()
    g = pyxgraph(xlimits=(min(x), max(x)), ylimits=(min(y), max(y)), width=6, height=6, key=False)
    g.pyxplot("y(x)=sin(x)+20", style="p")  # FIXME: can't do empty plots!

    g.pyxbitmap(pilbitmap)

    c.insert(g)

    cb = pyxcolorbar(lut=lut, frame=g, pos=(1.1, 0.0), minvalue=min(ravel(z)), maxvalue=max(ravel(z)))
    c.insert(cb)

    pyxsave(c, epsoutfile)
Пример #15
0
def array_example2(epsoutfile):
    x = (arange(50.0)-25)/2.0
    y = (arange(50.0)-25)/2.0
    r = sqrt(x[:,NewAxis]**2+y**2)
    z = 5.0*cos(r)  

    colmap = ColMapper.ColorMapper("yellow-red", exponent=0.55, brightness=0.5)
    lut = colmap.generate_lut()

    c = pyx.canvas.canvas()
    g = pyxgraph(xlimits=(min(x), max(x)), ylimits=(min(y), max(y)),
                 width=6, height=6)
    g.pyxplot("y(x)=sin(x)", style="p")  # FIXME: can't do empty plots!
    g.pyxplotarray(z, colmap=lut)
    c.insert(g)

    cb = pyxcolorbar(lut=lut, frame=g, pos=(1.1,0.0),
                     minvalue=min(ravel(z)), maxvalue=max(ravel(z)))
    c.insert(cb)
    
    pyxsave(c, epsoutfile)
Пример #16
0
    def draw(self, renderer):
        if not self.get_visible(): return
        renderer.open_group('regpolycollection')
        self._transform.freeze()
        self._transOffset.freeze()
        self.update_scalarmappable()
        self._update_verts()
        scales = sqrt(asarray(self._sizes) * self._dpi.get() / 72.0)

        if is_string_like(self._edgecolors) and self._edgecolors[:2] == 'No':
            #self._edgecolors = self._facecolors
            self._linewidths = (0, )


#        print 'in draw(), self._offsets = %s' % (`self._offsets`)
        renderer.draw_regpoly_collection(self.clipbox, self._offsets,
                                         self._transOffset, self._verts,
                                         scales, self._facecolors,
                                         self._edgecolors, self._linewidths,
                                         self._antialiaseds)

        self._transform.thaw()
        self._transOffset.thaw()
        renderer.close_group('regpolycollection')
Пример #17
0
def pyxarrow(canvas, xystart, xyend, length=None, arrowstyle=None,
             graphcoords=False):
    """
       xystart=(,)
       xyend=(,)
       are coordinates from [0.0, 1.0]
       relative to the canvas (or graph) area
       (values outside of this range are also allowed).
       If length is not None
       the direction is specified by xystart,xyend
    """
    if arrowstyle == None:
        arrowstyle = [pyx.style.linewidth.THIck, pyx.deco.earrow.Large]

#    print "canvas.xpos",canvas.xpos
#    print "canvas.ypos",canvas.ypos
#    print "canvas.width",canvas.width
#    print "canvas.height",canvas.height
    
    if graphcoords == True:
        # canvas.pos only works after dolayout!
        xmin = canvas.axes["x"].axis.min
        xmax = canvas.axes["x"].axis.max
        ymin = canvas.axes["y"].axis.min
        ymax = canvas.axes["y"].axis.max

        if xmin == None or ymin == None or xmax == None or ymax == None:
            #if not canvas.did(canvas.dolayout):
            #    canvas.dolayout()
            #    print "forced dolayout here"
            x0, y0 = canvas.pos(xystart[0], xystart[1])
            x1, y1 = canvas.pos(xyend[0], xyend[1])
        else:
           
            def convertxy(position):
                """Convert from [0.0, 1.0] coordinates to canvas coordinates """
                return ( (position[0]-xmin)/(xmax-xmin),
                         (position[1]-ymin)/(ymax-ymin)  )
                         
            def convertxy_logx(position):
                """Convert from [0.0, 1.0] coordinates to canvas coordinates 
                   on a logarithmic scale in x-direction"""
                return ( (log(position[0])-log(xmin))/(log(xmax)-log(xmin)),
                         (position[1]-ymin)/(ymax-ymin)  )
                         
            def convertxy_logy(position):
                """Convert from [0.0, 1.0] coordinates to canvas coordinates 
                   on a logarithmic scale in y-direction"""
                return ( (position[0]-xmin)/(xmax-xmin),
                         (log(position[1])-log(ymin))/(log(ymax)-log(ymin))  )
                         
            def convertxy_loglog(position):
                """Convert from [0.0, 1.0] coordinates to canvas coordinates 
                   on a logarithmic scale in x- and y-direction"""
                return ( (log(position[0])-log(xmin))/(log(xmax)-log(xmin)),
                         (log(position[1])-log(ymin))/(log(ymax)-log(ymin))  )

            if canvas.xaxistype == "linear" and canvas.yaxistype == "linear":
                xystart_normalized = convertxy(xystart)
                xyend_normalized = convertxy(xyend)
            elif canvas.xaxistype == "log" and canvas.yaxistype == "linear":
                xystart_normalized = convertxy_logx(xystart)
                xyend_normalized = convertxy_logx(xyend)
            elif canvas.xaxistype == "linear" and canvas.yaxistype == "log":
                xystart_normalized = convertxy_logy(xystart)
                xyend_normalized = convertxy_logy(xyend)
            elif canvas.xaxistype == "log" and canvas.yaxistype == "log":
                xystart_normalized = convertxy_loglog(xystart)
                xyend_normalized = convertxy_loglog(xyend)
            else:
                xystart_normalized = convertxy(xystart)
                xyend_normalized = convertxy(xyend)

            x0 = canvas.xpos+xystart_normalized[0]*canvas.width
            x1 = canvas.xpos+xyend_normalized[0]*canvas.width
            y0 = canvas.ypos+xystart_normalized[1]*canvas.height
            y1 = canvas.ypos+xyend_normalized[1]*canvas.height
    else:
        x0 = canvas.xpos+xystart[0]*canvas.width
        x1 = canvas.xpos+xyend[0]*canvas.width
        y0 = canvas.ypos+xystart[1]*canvas.height
        y1 = canvas.ypos+xyend[1]*canvas.height
        
        
    if length != None:
        dx = xyend[0]-xystart[0]
        dy = xyend[1]-xystart[1]
        norm = sqrt(dx**2+dy**2)
        dx, dy = length*dx/norm, length*dy/norm

        x1 = canvas.xpos+xyend[0]*canvas.width+dx*canvas.width
        y1 = canvas.xpos+xyend[1]*canvas.height+dy*canvas.height

    path = pyx.path.path(pyx.path.moveto(x0, y0), pyx.path.lineto(x1, y1))
    canvas.stroke(path, arrowstyle)
Пример #18
0
    def update_coords(self, renderer):
        """Computes the actual x,y coordinates for
        text based on the input x,y and the
        dashlength. Since the rotation is with respect
        to the actual canvas's coordinates we need to
        map back and forth.
        """
        dashx, dashy = self.get_position()
        dashlength = self.get_dashlength()
        # Shortcircuit this process if we don't have a dash
        if dashlength == 0.0:
            self._x, self._y = dashx, dashy
            return

        dashrotation = self.get_dashrotation()
        dashdirection = self.get_dashdirection()
        dashpad = self.get_dashpad()
        dashpush = self.get_dashpush()

        angle = get_rotation(dashrotation)
        theta = pi * (angle / 180.0 + dashdirection - 1)
        cos_theta, sin_theta = cos(theta), sin(theta)

        transform = self.get_transform()

        # Compute the dash end points
        # The 'c' prefix is for canvas coordinates
        cxy = array(transform.xy_tup((dashx, dashy)))
        cd = array([cos_theta, sin_theta])
        c1 = cxy + dashpush * cd
        c2 = cxy + (dashpush + dashlength) * cd

        (x1, y1) = transform.inverse_xy_tup(tuple(c1))
        (x2, y2) = transform.inverse_xy_tup(tuple(c2))
        self.dashline.set_data((x1, x2), (y1, y2))

        # We now need to extend this vector out to
        # the center of the text area.
        # The basic problem here is that we're "rotating"
        # two separate objects but want it to appear as
        # if they're rotated together.
        # This is made non-trivial because of the
        # interaction between text rotation and alignment -
        # text alignment is based on the bbox after rotation.
        # We reset/force both alignments to 'center'
        # so we can do something relatively reasonable.
        # There's probably a better way to do this by
        # embedding all this in the object's transformations,
        # but I don't grok the transformation stuff
        # well enough yet.
        we = Text.get_window_extent(self, renderer=renderer)
        w, h = we.width(), we.height()
        # Watch for zeros
        if sin_theta == 0.0:
            dx = w
            dy = 0.0
        elif cos_theta == 0.0:
            dx = 0.0
            dy = h
        else:
            tan_theta = sin_theta / cos_theta
            dx = w
            dy = w * tan_theta
            if dy > h or dy < -h:
                dy = h
                dx = h / tan_theta
        cwd = array([dx, dy]) / 2
        cwd *= 1 + dashpad / sqrt(dot(cwd, cwd))
        cw = c2 + (dashdirection * 2 - 1) * cwd

        self._x, self._y = transform.inverse_xy_tup(tuple(cw))

        # Now set the window extent
        # I'm not at all sure this is the right way to do this.
        we = Text.get_window_extent(self, renderer=renderer)
        self._twd_window_extent = we.deepcopy()
        self._twd_window_extent.update(((c1[0], c1[1]), ), False)

        # Finally, make text align center
        Text.set_horizontalalignment(self, 'center')
        Text.set_verticalalignment(self, 'center')
Пример #19
0
    def update_coords(self, renderer):
        """Computes the actual x,y coordinates for
        self._mytext based on the input x,y and the
        dashlength. Since the rotation is with respect
        to the actual canvas's coordinates we need to
        map back and forth.
        """
        (x, y) = self.get_position()
        dashlength = self.get_dashlength()

        # Shortcircuit this process if we don't have a dash
        if dashlength == 0.0:
            self._mytext.set_position((x, y))
            return

        dashrotation = self.get_dashrotation()
        dashdirection = self.get_dashdirection()
        dashpad = self.get_dashpad()
        dashpush = self.get_dashpush()
        transform = self.get_transform()

        angle = get_rotation(dashrotation)
        theta = pi*(angle/180.0+dashdirection-1)
        cos_theta, sin_theta = cos(theta), sin(theta)

        # Compute the dash end points
        # The 'c' prefix is for canvas coordinates
        cxy = array(transform.xy_tup((x, y)))
        cd = array([cos_theta, sin_theta])
        c1 = cxy+dashpush*cd
        c2 = cxy+(dashpush+dashlength)*cd
        (x1, y1) = transform.inverse_xy_tup(tuple(c1))
        (x2, y2) = transform.inverse_xy_tup(tuple(c2))
        self.dashline.set_data((x1, x2), (y1, y2))

        # We now need to extend this vector out to
        # the center of the text area.
        # The basic problem here is that we're "rotating"
        # two separate objects but want it to appear as
        # if they're rotated together.
        # This is made non-trivial because of the
        # interaction between text rotation and alignment -
        # text alignment is based on the bbox after rotation.
        # We reset/force both alignments to 'center'
        # so we can do something relatively reasonable.
        # There's probably a better way to do this by
        # embedding all this in the object's transformations,
        # but I don't grok the transformation stuff
        # well enough yet.
        we = self._mytext.get_window_extent(renderer=renderer)
        w, h = we.width(), we.height()
        # Watch for zeros
        if sin_theta == 0.0:
            dx = w
            dy = 0.0
        elif cos_theta == 0.0:
            dx = 0.0
            dy = h
        else:
            tan_theta = sin_theta/cos_theta
            dx = w
            dy = w*tan_theta
            if dy > h or dy < -h:
                dy = h
                dx = h/tan_theta
        cwd = array([dx, dy])/2
        cwd *= 1+dashpad/sqrt(dot(cwd,cwd))
        cw = c2+(dashdirection*2-1)*cwd
        self._mytext.set_position(transform.inverse_xy_tup(tuple(cw)))

        # Now set the window extent
        # I'm not at all sure this is the right way to do this.
        we = self._mytext.get_window_extent(renderer=renderer)
        self._window_extent = we.deepcopy()
        self._window_extent.update(((c1[0], c1[1]),), False)

        # Finally, make text align center
        self._mytext.set_horizontalalignment('center')
        self._mytext.set_verticalalignment('center')
Пример #20
0
    def __init__(
        self,
        x,
        y,
        dx,
        dy,
        width=0.001,
        length_includes_head=False,
        head_width=None,
        head_length=None,
        shape="full",
        overhang=0,
        head_starts_at_zero=False,
        **kwargs
    ):
        """Returns a new Arrow.

        length_includes_head: True if head is counted in calculating the length.

        shape: ['full', 'left', 'right']

        overhang: distance that the arrow is swept back (0 overhang means
        triangular shape).

        head_starts_at_zero: if True, the head starts being drawn at coordinate
        0 instead of ending at coordinate 0.
        """
        if head_width is None:
            head_width = 3 * width
        if head_length is None:
            head_length = 1.5 * head_width

        distance = sqrt(dx ** 2 + dy ** 2)
        if length_includes_head:
            length = distance
        else:
            length = distance + head_length
        if not length:
            verts = []  # display nothing if empty
        else:
            # start by drawing horizontal arrow, point at (0,0)
            hw, hl, hs, lw = head_width, head_length, overhang, width
            left_half_arrow = array(
                [
                    [0.0, 0.0],  # tip
                    [-hl, -hw / 2.0],  # leftmost
                    [-hl * (1 - hs), -lw / 2.0],  # meets stem
                    [-length, -lw / 2.0],  # bottom left
                    [-length, 0],
                ]
            )
            # if we're not including the head, shift up by head length
            if not length_includes_head:
                left_half_arrow += [head_length, 0]
            # if the head starts at 0, shift up by another head length
            if head_starts_at_zero:
                left_half_arrow += [head_length / 2.0, 0]
            # figure out the shape, and complete accordingly
            if shape == "left":
                coords = left_half_arrow
            else:
                right_half_arrow = left_half_arrow * [1, -1]
                if shape == "right":
                    coords = right_half_arrow
                elif shape == "full":
                    coords = concatenate([left_half_arrow, right_half_arrow[::-1]])
                else:
                    raise ValueError, "Got unknown shape: %s" % shape
            cx = float(dx) / distance
            sx = float(dy) / distance
            M = array([[cx, sx], [-sx, cx]])
            verts = matrixmultiply(coords, M) + (x + dx, y + dy)

        Polygon.__init__(self, map(tuple, verts), **kwargs)
Пример #21
0
    def __init__(self, x, y, dx, dy, width=0.001, length_includes_head=False, \
        head_width=None, head_length=None, shape='full', overhang=0, \
        head_starts_at_zero=False,**kwargs):
        """Returns a new Arrow.

        length_includes_head: True if head is counted in calculating the length.

        shape: ['full', 'left', 'right']

        overhang: distance that the arrow is swept back (0 overhang means
        triangular shape).

        head_starts_at_zero: if True, the head starts being drawn at coordinate
        0 instead of ending at coordinate 0.
        """
        if head_width is None:
            head_width = 3 * width
        if head_length is None:
            head_length = 1.5 * head_width

        distance = sqrt(dx**2 + dy**2)
        if length_includes_head:
            length = distance
        else:
            length = distance + head_length
        if not length:
            verts = []  #display nothing if empty
        else:
            #start by drawing horizontal arrow, point at (0,0)
            hw, hl, hs, lw = head_width, head_length, overhang, width
            left_half_arrow = array([
                [0.0, 0.0],  #tip
                [-hl, -hw / 2.0],  #leftmost
                [-hl * (1 - hs), -lw / 2.0],  #meets stem
                [-length, -lw / 2.0],  #bottom left
                [-length, 0],
            ])
            #if we're not including the head, shift up by head length
            if not length_includes_head:
                left_half_arrow += [head_length, 0]
            #if the head starts at 0, shift up by another head length
            if head_starts_at_zero:
                left_half_arrow += [head_length / 2.0, 0]
            #figure out the shape, and complete accordingly
            if shape == 'left':
                coords = left_half_arrow
            else:
                right_half_arrow = left_half_arrow * [1, -1]
                if shape == 'right':
                    coords = right_half_arrow
                elif shape == 'full':
                    coords = concatenate(
                        [left_half_arrow, right_half_arrow[::-1]])
                else:
                    raise ValueError, "Got unknown shape: %s" % shape
            cx = float(dx) / distance
            sx = float(dy) / distance
            M = array([[cx, sx], [-sx, cx]])
            verts = matrixmultiply(coords, M) + (x + dx, y + dy)

        Polygon.__init__(self, map(tuple, verts), **kwargs)
Пример #22
0
def mod(v):
    """3d vector length"""
    return nx.sqrt(v[0]**2 + v[1]**2 + v[2]**2)