コード例 #1
0
ファイル: graphics.py プロジェクト: cdd1969/pygwa
    def paint(self, painter, option, widget=None):
        if (self.p1 == self.p2):
            return

        myPen = self.pen()
        myPen.setColor(self.myColor)
        arrowSize = self.myArrowHeadSize
        painter.setPen(myPen)
        painter.setBrush(self.myColor)

        line = QtCore.QLineF(self.p1, self.p2)

        angle = math.acos(line.dx() / line.length())
        if line.dy() >= 0:
            angle = (math.pi * 2.0) - angle

        arrowP1 = line.p2() - QtCore.QPointF(
            math.sin(angle + math.pi / 3.0) * arrowSize,
            math.cos(angle + math.pi / 3) * arrowSize)
        arrowP2 = line.p2() - QtCore.QPointF(
            math.sin(angle + math.pi - math.pi / 3.0) * arrowSize,
            math.cos(angle + math.pi - math.pi / 3.0) * arrowSize)

        self.arrowHead.clear()
        for point in [line.p2(), arrowP1, arrowP2]:
            self.arrowHead.append(point)

        painter.drawLine(line)
        painter.drawPolygon(self.arrowHead)
コード例 #2
0
ファイル: interact.py プロジェクト: gesellkammer/sndtrck
 def paint(self, p, opt, widget, **args):
     p.setPen(self.pen)
     line = self._line
     if line is None:
         br = self.boundingRect()
         self._line = line = QtCore.QLineF(0.0, br.bottom(), 0.0, br.top())
     p.drawLine(line)
コード例 #3
0
    def transformAngle(self, relativeItem=None):
        """Return the rotation produced by this item's transform (this assumes there is no shear in the transform)
        If relativeItem is given, then the angle is determined relative to that item.
        """
        if relativeItem is None:
            relativeItem = self.parentItem()

        tr = self.itemTransform(relativeItem)
        if isinstance(tr, tuple):  ## difference between pyside and pyqt
            tr = tr[0]
        #vec = tr.map(Point(1,0)) - tr.map(Point(0,0))
        vec = tr.map(QtCore.QLineF(0, 0, 1, 0))
        #return Point(vec).angle(Point(1,0))
        return vec.angleTo(
            QtCore.QLineF(vec.p1(),
                          vec.p1() + QtCore.QPointF(1, 0)))
コード例 #4
0
 def pixelHeight(self):
     ## deprecated
     vt = self.deviceTransform()
     if vt is None:
         return 0
     vt = fn.invertQTransform(vt)
     return vt.map(QtCore.QLineF(0, 0, 0, 1)).length()
コード例 #5
0
ファイル: graphics.py プロジェクト: cdd1969/pygwa
 def updatePosition(self):
     line = QtCore.QLineF(self.p1, self.p2)
     self.setLine(line)
コード例 #6
0
    def pixelVectors(self, direction=None):
        """Return vectors in local coordinates representing the width and height of a view pixel.
        If direction is specified, then return vectors parallel and orthogonal to it.
        
        Return (None, None) if pixel size is not yet defined (usually because the item has not yet been displayed)
        or if pixel size is below floating-point precision limit.
        """

        ## This is an expensive function that gets called very frequently.
        ## We have two levels of cache to try speeding things up.

        dt = self.deviceTransform()
        if dt is None:
            return None, None

        ## Ignore translation. If the translation is much larger than the scale
        ## (such as when looking at unix timestamps), we can get floating-point errors.
        dt.setMatrix(dt.m11(), dt.m12(), 0, dt.m21(), dt.m22(), 0, 0, 0, 1)

        ## check local cache
        if direction is None and dt == self._pixelVectorCache[0]:
            return tuple(map(Point,
                             self._pixelVectorCache[1]))  ## return a *copy*

        ## check global cache
        #key = (dt.m11(), dt.m21(), dt.m31(), dt.m12(), dt.m22(), dt.m32(), dt.m31(), dt.m32())
        key = (dt.m11(), dt.m21(), dt.m12(), dt.m22())
        pv = self._pixelVectorGlobalCache.get(key, None)
        if direction is None and pv is not None:
            self._pixelVectorCache = [dt, pv]
            return tuple(map(Point, pv))  ## return a *copy*

        if direction is None:
            direction = QtCore.QPointF(1, 0)
        if direction.manhattanLength() == 0:
            raise Exception("Cannot compute pixel length for 0-length vector.")

        ## attempt to re-scale direction vector to fit within the precision of the coordinate system
        ## Here's the problem: we need to map the vector 'direction' from the item to the device, via transform 'dt'.
        ## In some extreme cases, this mapping can fail unless the length of 'direction' is cleverly chosen.
        ## Example:
        ##   dt = [ 1, 0,    2
        ##          0, 2, 1e20
        ##          0, 0,    1 ]
        ## Then we map the origin (0,0) and direction (0,1) and get:
        ##    o' = 2,1e20
        ##    d' = 2,1e20  <-- should be 1e20+2, but this can't be represented with a 32-bit float
        ##
        ##    |o' - d'|  == 0    <-- this is the problem.

        ## Perhaps the easiest solution is to exclude the transformation column from dt. Does this cause any other problems?

        #if direction.x() == 0:
        #r = abs(dt.m32())/(abs(dt.m12()) + abs(dt.m22()))
        ##r = 1.0/(abs(dt.m12()) + abs(dt.m22()))
        #elif direction.y() == 0:
        #r = abs(dt.m31())/(abs(dt.m11()) + abs(dt.m21()))
        ##r = 1.0/(abs(dt.m11()) + abs(dt.m21()))
        #else:
        #r = ((abs(dt.m32())/(abs(dt.m12()) + abs(dt.m22()))) * (abs(dt.m31())/(abs(dt.m11()) + abs(dt.m21()))))**0.5
        #if r == 0:
        #r = 1.  ## shouldn't need to do this; probably means the math above is wrong?
        #directionr = direction * r
        directionr = direction

        ## map direction vector onto device
        #viewDir = Point(dt.map(directionr) - dt.map(Point(0,0)))
        #mdirection = dt.map(directionr)
        dirLine = QtCore.QLineF(QtCore.QPointF(0, 0), directionr)
        viewDir = dt.map(dirLine)
        if viewDir.length() == 0:
            return None, None  ##  pixel size cannot be represented on this scale

        ## get unit vector and orthogonal vector (length of pixel)
        #orthoDir = Point(viewDir[1], -viewDir[0])  ## orthogonal to line in pixel-space
        try:
            normView = viewDir.unitVector()
            #normView = viewDir.norm()  ## direction of one pixel orthogonal to line
            normOrtho = normView.normalVector()
            #normOrtho = orthoDir.norm()
        except:
            raise Exception("Invalid direction %s" % directionr)

        ## map back to item
        dti = fn.invertQTransform(dt)
        #pv = Point(dti.map(normView)-dti.map(Point(0,0))), Point(dti.map(normOrtho)-dti.map(Point(0,0)))
        pv = Point(dti.map(normView).p2()), Point(dti.map(normOrtho).p2())
        self._pixelVectorCache[1] = pv
        self._pixelVectorCache[0] = dt
        self._pixelVectorGlobalCache[key] = pv
        return self._pixelVectorCache[1]