Пример #1
0
 def showMoveHelper(self, visible=True):
     """show help text In empty HandBoards"""
     if visible:
         if not self.__moveHelper:
             splitter = QGraphicsRectItem(self)
             hbCenter = self.rect().center()
             splitter.setRect(hbCenter.x() * 0.5, hbCenter.y(), hbCenter.x() * 1, 1)
             helpItems = [splitter]
             for name, yFactor in [(m18n('Move Exposed Tiles Here'), 0.5),
                                     (m18n('Move Concealed Tiles Here'), 1.5)]:
                 helper = QGraphicsSimpleTextItem(name, self)
                 helper.setScale(3)
                 nameRect = QRectF()
                 nameRect.setSize(helper.mapToParent(helper.boundingRect()).boundingRect().size())
                 center = QPointF(hbCenter)
                 center.setY(center.y() * yFactor)
                 helper.setPos(center - nameRect.center())
                 if self.sceneRotation() == 180:
                     rotateCenter(helper, 180)
                 helpItems.append(helper)
             self.__moveHelper = self.scene().createItemGroup(helpItems)
         self.__moveHelper.setVisible(True)
     else:
         if self.__moveHelper:
             self.__moveHelper.setVisible(False)
Пример #2
0
 def decoratePlayer(self, player):
     """show player info on the wall"""
     side = player.front
     sideCenter = side.center()
     name = side.nameLabel
     if player.handBoard:
         player.newHandContent = player.computeNewHand()
         name.setText(' - '.join(
             [player.localName,
              unicode(player.newHandContent.total())]))
     else:
         name.setText(player.localName)
     name.resetTransform()
     if side.rotation() == 180:
         rotateCenter(name, 180)
     nameRect = QRectF()
     nameRect.setSize(
         name.mapToParent(name.boundingRect()).boundingRect().size())
     name.setPos(sideCenter - nameRect.center())
     player.colorizeName()
     side.windTile.setWind(player.wind, self.game.roundsFinished)
     side.windTile.resetTransform()
     side.windTile.setPos(
         sideCenter.x() * 1.63,
         sideCenter.y() - side.windTile.rect().height() / 2.5)
     side.nameLabel.show()
     side.windTile.show()
Пример #3
0
def grab_svg(scene):
    """
    Return a SVG rendering of the scene contents.

    Parameters
    ----------
    scene : :class:`CanvasScene`

    """
    from PyQt4.QtSvg import QSvgGenerator
    svg_buffer = QBuffer()
    gen = QSvgGenerator()
    gen.setOutputDevice(svg_buffer)

    items_rect = scene.itemsBoundingRect().adjusted(-10, -10, 10, 10)

    if items_rect.isNull():
        items_rect = QRectF(0, 0, 10, 10)

    width, height = items_rect.width(), items_rect.height()
    rect_ratio = float(width) / height

    # Keep a fixed aspect ratio.
    aspect_ratio = 1.618
    if rect_ratio > aspect_ratio:
        height = int(height * rect_ratio / aspect_ratio)
    else:
        width = int(width * aspect_ratio / rect_ratio)

    target_rect = QRectF(0, 0, width, height)
    source_rect = QRectF(0, 0, width, height)
    source_rect.moveCenter(items_rect.center())

    gen.setSize(target_rect.size().toSize())
    gen.setViewBox(target_rect)

    painter = QPainter(gen)

    # Draw background.
    painter.setBrush(QBrush(Qt.white))
    painter.drawRect(target_rect)

    # Render the scene
    scene.render(painter, target_rect, source_rect)
    painter.end()

    buffer_str = str(svg_buffer.buffer())
    return unicode(buffer_str.decode("utf-8"))
Пример #4
0
 def drawToolButtonContent(self, option, painter, widget):
     if option.state & QStyle.State_Enabled:
         pixmap = widget.pixmap(QIcon.Normal)
     else:
         pixmap = widget.pixmap(QIcon.Disabled)
     if not pixmap.isNull():
         margin = self._pixel_metrics[QStyle.PM_DefaultFrameWidth] + self._pixel_metrics[QStyle.PM_ButtonMargin]
         if option.features & QStyleOptionToolButton.MenuButtonPopup and option.direction == Qt.LeftToRight:
             right_offset = 1
         else:
             right_offset = 0
         content_rect = QRectF(self.proxy().subControlRect(QStyle.CC_ToolButton, option, QStyle.SC_ToolButton, widget)).adjusted(margin, margin, -margin-right_offset, -margin)
         pixmap_rect  = QRectF(pixmap.rect())
         pixmap_rect.moveCenter(content_rect.center())
         painter.setRenderHint(QPainter.Antialiasing, True)
         painter.setCompositionMode(QPainter.CompositionMode_SourceOver)
         painter.drawPixmap(pixmap_rect.topLeft(), pixmap)
Пример #5
0
 def decoratePlayer(self, player):
     """show player info on the wall"""
     side = player.front
     sideCenter = side.center()
     name = side.nameLabel
     if player.handBoard:
         player.newHandContent = player.computeNewHand()
         name.setText(' - '.join([player.localName, unicode(player.newHandContent.total())]))
     else:
         name.setText(player.localName)
     name.resetTransform()
     if side.rotation() == 180:
         rotateCenter(name, 180)
     nameRect = QRectF()
     nameRect.setSize(name.mapToParent(name.boundingRect()).boundingRect().size())
     name.setPos(sideCenter - nameRect.center())
     player.colorizeName()
     side.windTile.setWind(player.wind, self.game.roundsFinished)
     side.windTile.resetTransform()
     side.windTile.setPos(sideCenter.x()*1.63, sideCenter.y()-side.windTile.rect().height()/2.5)
     side.nameLabel.show()
     side.windTile.show()
Пример #6
0
    def draw(self, painter, size=None):
        """
        :Arguments:
            painter : QPainter
                Opened painter on which to draw
        """
        bounding_rect = QRectF()
        position = self.position
        transfer_function = self.transfer_function
        font = QFont(self.font)
        text_color = self.text_color
        line_color = self.line_color
        line_thickness = self.line_thickness
        value_range = self.value_range
        if size is None:
            viewport = painter.viewport()  # viewport rectangle
            mat, ok = painter.worldMatrix().inverted()
            if not ok:
                raise ValueError(
                    "Transformation matrix of painter is singular.")
            viewport = mat.mapRect(viewport)
        else:
            viewport = size
# First, prepare the gradient
        w = viewport.width()
        h = viewport.height()
        #print("Size of viewport: {0}x{1}".format(w, h))
        gr = QLinearGradient()
        nb_values = ceil(w / 5.0)
        brush_color = QColor()
        for i in range(int(nb_values)):
            brush_color.setRgbF(*transfer_function.rgba(i / nb_values))
            gr.setColorAt(i / nb_values, brush_color)
# Second, find its position
        metric = QFontMetricsF(font, painter.device())
        font_test = [str(i) * 5 for i in range(10)]
        lim_width = 0
        lim_height = 0
        for t in font_test:
            rect = metric.boundingRect(t)
            lim_width = max(lim_width, rect.width())
            lim_height = max(lim_height, rect.height())
        lim_height *= 3
        length = self.scale_length
        shift_length = (1 - length) / 2
        width = self.scale_width
        shift_width = self.scale_shift_width
        delta_value = value_range[1] - value_range[0]
        if position == "Top":
            scale_rect = QRectF(shift_length * w, shift_width * h, length * w,
                                width * h)
            limit_rect(scale_rect, viewport, lim_width, lim_height)
            gr.setStart(scale_rect.left(), scale_rect.center().y())
            gr.setFinalStop(scale_rect.right(), scale_rect.center().y())
            start_pos = scale_rect.bottomLeft()
            end_pos = scale_rect.bottomRight()
        elif position == "Right":
            scale_rect = QRectF((1 - shift_width - width) * w,
                                shift_length * h, width * w, length * h)
            limit_rect(scale_rect, viewport, lim_width, lim_height)
            gr.setStart(scale_rect.center().x(), scale_rect.bottom())
            gr.setFinalStop(scale_rect.center().x(), scale_rect.top())
            start_pos = scale_rect.bottomLeft()
            end_pos = scale_rect.topLeft()
        elif position == "Bottom":
            scale_rect = QRectF(shift_length * w,
                                (1 - shift_width - width) * h, length * w,
                                width * h)
            limit_rect(scale_rect, viewport, lim_width, lim_height)
            gr.setStart(scale_rect.left(), scale_rect.center().y())
            gr.setFinalStop(scale_rect.right(), scale_rect.center().y())
            start_pos = scale_rect.topLeft()
            end_pos = scale_rect.topRight()
        elif position == "Left":
            scale_rect = QRectF(shift_width * w, shift_length * h, width * w,
                                length * h)
            limit_rect(scale_rect, viewport, lim_width, lim_height)
            gr.setStart(scale_rect.center().x(), scale_rect.bottom())
            gr.setFinalStop(scale_rect.center().x(), scale_rect.top())
            start_pos = scale_rect.bottomRight()
            end_pos = scale_rect.topRight()
        else:
            raise ValueError("Invalid scale position: %s" % position)
        shift_pos = (end_pos - start_pos) / delta_value
        if position in ["Left", "Right"]:
            is_vertical = True
            length = scale_rect.height()
        else:
            is_vertical = False
            length = scale_rect.width()
# Get the ticks
        ticks = self.selectValues(length, is_vertical, painter)
        if len(ticks) == 0:
            return
        ticks_str, ticks_extra = self._tick2str(ticks)
        # Figure the shifts
        dist_to_bar = self.text_to_bar
        max_width = 0
        max_height = 0
        for t in ticks_str:
            rect = metric.boundingRect(t)
            max_width = max(rect.width(), max_width)
            max_height = max(rect.height(), max_height)
        if position == "Left":
            shift_left = dist_to_bar
            shift_top = None
        elif position == "Right":
            shift_left = -dist_to_bar - max_width
            shift_top = None
        elif position == "Top":
            shift_left = None
            shift_top = dist_to_bar
        else:
            shift_left = None
            shift_top = -dist_to_bar - max_height
        painter.save()
        painter.translate(viewport.topLeft())
        #print("viewport.topLeft() = {0}x{1}".format(viewport.left(), viewport.top()))
        painter.setBrush(gr)
        line_pen = QPen(line_color)
        line_pen.setWidth(line_thickness)
        painter.setPen(line_pen)
        painter.drawRect(scale_rect)
        bounding_rect |= scale_rect
        #print("Scale rect: +{0}+{1}x{2}x{3}".format(scale_rect.left(),
        #scale_rect.top(), scale_rect.width(), scale_rect.height()))
        painter.setFont(font)
        painter.setPen(text_color)
        for ts, t in zip(ticks_str, ticks):
            r = metric.boundingRect(ts)
            pos = start_pos + shift_pos * (t - value_range[0])
            if shift_left is None:
                pos.setX(pos.x() - r.width() / 2)
            else:
                pos.setX(pos.x() + shift_left)
            if shift_top is None:
                pos.setY(pos.y() - r.height() / 2)
            else:
                pos.setY(pos.y() + shift_top)
            r.moveTo(pos)
            real_rect = painter.drawText(
                r, Qt.TextDontClip | Qt.AlignVCenter | Qt.AlignHCenter, ts)
            bounding_rect |= real_rect
        if ticks_extra is not None or self.unit:
            unit = self.unit
            exp_width = width = space_width = 0
            exp_txt = ""
            r = exp_r = unit_r = QRectF()
            exp_font = None
            if ticks_extra is not None:
                exp_txt = u"×10"
                r = metric.boundingRect(exp_txt)
                exp_font = QFont(font)
                exp_size = self.exp_size
                if exp_font.pixelSize() != -1:
                    exp_font.setPixelSize(exp_size * exp_font.pixelSize())
                else:
                    exp_font.setPointSizeF(exp_size * exp_font.pointSizeF())
                exp_metric = QFontMetricsF(exp_font, painter.device())
                exp_r = exp_metric.boundingRect(ticks_extra)
            if unit:
                unit_r = metric.boundingRect(unit)
            total_width = r.width() + exp_r.width() + unit_r.width()
            total_height = max(r.height(),
                               unit_r.height()) + exp_r.height() / 2
            pos = scale_rect.topRight()
            log_debug("top right of scale bar = (%g,%g)" % (pos.x(), pos.y()))
            log_debug("Size of image = (%d,%d)" % (w, h))
            log_debug("Size of text = (%g,%g)" % (total_width, total_height))
            if position == "Bottom":
                pos.setY(pos.y() + scale_rect.height() + dist_to_bar)
                pos.setX(pos.x() - total_width)
            elif position == "Top":
                pos.setY(pos.y() - dist_to_bar - total_height)
                pos.setX(pos.x() - total_width)
            else:  # position == "left" or "right"
                pos.setX(pos.x() - (scale_rect.width() + total_width) / 2)
                if pos.x() < 0:
                    pos.setX(dist_to_bar)
                elif pos.x() + total_width + dist_to_bar > w:
                    pos.setX(w - total_width - dist_to_bar)
                pos.setY(pos.y() - dist_to_bar - total_height)
            log_debug("Display unit at position: (%g,%g)" % (pos.x(), pos.y()))

            if ticks_extra is not None:
                r.moveTo(pos)
                real_rect = painter.drawText(
                    r, Qt.TextDontClip | Qt.AlignVCenter | Qt.AlignHCenter,
                    exp_txt)
                bounding_rect |= real_rect
                pos.setX(pos.x() + r.width())
                pos.setY(pos.y() - metric.ascent() / 2)
                exp_r.moveTo(pos)
                painter.setFont(exp_font)
                real_rect = painter.drawText(
                    exp_r, Qt.TextDontClip | Qt.AlignVCenter | Qt.AlignHCenter,
                    ticks_extra)
                bounding_rect |= real_rect
                pos.setY(pos.y() + metric.ascent() / 2)
            if unit:
                pos.setX(pos.x() + space_width + exp_r.width())
                unit_r.moveTo(pos)
                painter.setFont(font)
                real_rect = painter.drawText(
                    unit_r,
                    Qt.TextDontClip | Qt.AlignVCenter | Qt.AlignHCenter, unit)
                bounding_rect |= real_rect
        # Draw the ticks now
        painter.setPen(line_pen)
        tick_size = self.tick_size
        if is_vertical:
            width = scale_rect.width() * tick_size
        else:
            width = scale_rect.height() * tick_size
        pen_width = painter.pen().widthF()
        if pen_width == 0:
            pen_width = 1.0
        for t in ticks:
            pos1 = start_pos + shift_pos * (t - value_range[0])
            pos2 = QPointF(pos1)
            if is_vertical:
                pos1.setX(scale_rect.left() + pen_width)
                pos2.setX(pos1.x() + width - pen_width)
                painter.drawLine(pos1, pos2)
                pos1.setX(scale_rect.right() - pen_width)
                pos2.setX(pos1.x() - width + pen_width)
                painter.drawLine(pos1, pos2)
            else:
                pos1.setY(scale_rect.top() + pen_width)
                pos2.setY(pos1.y() + width - pen_width)
                painter.drawLine(pos1, pos2)
                pos1.setY(scale_rect.bottom() - pen_width)
                pos2.setY(pos1.y() - width + pen_width)
                painter.drawLine(pos1, pos2)
        painter.restore()
        bounding_rect = bounding_rect.adjusted(-pen_width, -pen_width,
                                               pen_width, pen_width)
        return bounding_rect
Пример #7
0
 def rebuild( self ):
     """
     Rebuilds the data for this scene to draw with.
     """
     global XChartWidgetItem
     if ( XChartWidgetItem is None ):
         from projexui.widgets.xchartwidget.xchartwidgetitem \
         import XChartWidgetItem
     
     self._buildData = {}
     
     # build the grid location
     x      = 8
     y      = 8
     w      = self.sceneRect().width()
     h      = self.sceneRect().height()
     hpad   = self.horizontalPadding()
     vpad   = self.verticalPadding()
     hmax   = self.horizontalRuler().maxNotchSize(Qt.Horizontal)
     
     left_offset   = hpad + self.verticalRuler().maxNotchSize(Qt.Vertical)
     right_offset  = left_offset + hpad
     top_offset    = vpad
     bottom_offset = top_offset + vpad + hmax
     
     left    = x + left_offset
     right   = w - right_offset
     top     = y + top_offset
     bottom  = h - bottom_offset
     
     rect = QRectF()
     rect.setLeft(left)
     rect.setRight(right)
     rect.setBottom(bottom)
     rect.setTop(top)
     
     self._buildData['grid_rect'] = rect
     
     # rebuild the ruler data
     self.rebuildGrid()
     self._dirty = False
     
     # rebuild all the items
     padding  = self.horizontalPadding() + self.verticalPadding()
     grid     = self.sceneRect()
     filt     = lambda x: isinstance(x, XChartWidgetItem)
     items    = filter(filt, self.items())
     height   = float(grid.height())
     if height == 0:
         ratio = 1
     else:
         ratio = grid.width() / height
     count    = len(items)
     
     if ( not count ):
         return
     
     if ( ratio >= 1 ):
         radius   = (grid.height() - padding * 2) / 2.0
         x        = rect.center().x()
         y        = rect.center().y()
         dx       = radius * 2.5
         dy       = 0
     else:
         radius   = (grid.width() - padding * 2) / 2.0
         x        = rect.center().x()
         y        = rect.center().y()
         dx       = 0
         dy       = radius * 2.5
     
     for item in items:
         item.setPieCenter(QPointF(x, y))
         item.setRadius(radius)
         item.rebuild()
         
         x += dx
         y += dy
     
     if ( self._trackerItem and self._trackerItem() ):
         self._trackerItem().rebuild(self._buildData['grid_rect'])
Пример #8
0
    def rebuild(self):
        """
        Rebuilds the data for this scene to draw with.
        """
        global XChartWidgetItem
        if (XChartWidgetItem is None):
            from projexui.widgets.xchartwidget.xchartwidgetitem \
            import XChartWidgetItem

        self._buildData = {}

        # build the grid location
        x = 8
        y = 8
        w = self.sceneRect().width()
        h = self.sceneRect().height()
        hpad = self.horizontalPadding()
        vpad = self.verticalPadding()
        hmax = self.horizontalRuler().maxNotchSize(Qt.Horizontal)

        left_offset = hpad + self.verticalRuler().maxNotchSize(Qt.Vertical)
        right_offset = left_offset + hpad
        top_offset = vpad
        bottom_offset = top_offset + vpad + hmax

        left = x + left_offset
        right = w - right_offset
        top = y + top_offset
        bottom = h - bottom_offset

        rect = QRectF()
        rect.setLeft(left)
        rect.setRight(right)
        rect.setBottom(bottom)
        rect.setTop(top)

        self._buildData['grid_rect'] = rect

        # rebuild the ruler data
        self.rebuildGrid()
        self._dirty = False

        # rebuild all the items
        padding = self.horizontalPadding() + self.verticalPadding()
        grid = self.sceneRect()
        filt = lambda x: isinstance(x, XChartWidgetItem)
        items = filter(filt, self.items())
        height = float(grid.height())
        if height == 0:
            ratio = 1
        else:
            ratio = grid.width() / height
        count = len(items)

        if (not count):
            return

        if (ratio >= 1):
            radius = (grid.height() - padding * 2) / 2.0
            x = rect.center().x()
            y = rect.center().y()
            dx = radius * 2.5
            dy = 0
        else:
            radius = (grid.width() - padding * 2) / 2.0
            x = rect.center().x()
            y = rect.center().y()
            dx = 0
            dy = radius * 2.5

        for item in items:
            item.setPieCenter(QPointF(x, y))
            item.setRadius(radius)
            item.rebuild()

            x += dx
            y += dy

        if (self._trackerItem and self._trackerItem()):
            self._trackerItem().rebuild(self._buildData['grid_rect'])
Пример #9
0
def alignImages(data, alignment_data, translation, rotation):
    """
    Align the images in data using the points found in alignment_data.

    Arguments:
      - data, TrackingData: data set to align
      - alignment_data, TrackingData: data set used for the alignment
      - translation, (str|int): type of translation. Valid values are:
         * "Bounding-box centre"
         * "Barycentre"
         * Any point if in alignment_data
      - rotation, (str,int,int): type of rotation. The first value is the rotation type. For now, it has to be
      "TwoPoint". The two other values are the points id used for the rotation. """
    # First, check the alignment data is valid
    #pts = alignment_data[alignment_data.images_name[0]].points()
    a = scipy.zeros(len(data), dtype=float)
    if rotation is not None:
        assert len(rotation) == 3
        assert rotation[0] == "TwoPoint"
        r1 = rotation[1]
        r2 = rotation[2]
        for d in alignment_data:
            if not r1 in d:
                raise AlgoException("Image %s doesn't contain point %d." % (d._current_image, r1))
            if not r2 in d:
                raise AlgoException("Image %s doesn't contain point %d." % (d._current_image, r2))
        # Then, compute the rotation
        vecs = scipy.zeros((len(data), 2), dtype=float)
        for i, d in enumerate(alignment_data):
            v = d[r2] - d[r1]
            vecs[i, :] = (v.x(), v.y())
        a = scipy.arctan2(vecs[:, 1], vecs[:, 0])
        a = a[0] - a
    # At last, compute the translation using the reference
    refs = scipy.zeros((len(data), 2), dtype=float)
    if translation == "Bounding-box centre":
        for i, d in enumerate(alignment_data):
            mat, _ = d.matrix().inverted()
            p1 = None
            rect = QRectF()
            for p in d.positions():
                p = mat.map(p)
                if p1 is None:
                    p1 = p
                else:
                    rect |= QRectF(p1, p).normalized()
            mid_pos = rect.center()
            refs[i, :] = (mid_pos.x(), mid_pos.y())
    elif translation == "Barycentre":
        for i, d in enumerate(alignment_data):
            mat, _ = d.matrix().inverted()
            mid_pos = mat.map(sum(d.positions(), QPointF())/len(d))
            refs[i, :] = (mid_pos.x(), mid_pos.y())
    else:
        for i, d in enumerate(alignment_data):
            mat, _ = d.matrix().inverted()
            if not translation in d:
                s = "Error, point %d is not in image %s. Cannot use it to align images."
                raise AlgoException(s % (translation, d.image_name))
            pos = mat.map(d[translation])
            refs[i, :] = (pos.x(), pos.y())
    moved_refs = refs*cos(a)[:, newaxis] + c_[-refs[:, 1], refs[:, 0]]*sin(a)[:, newaxis]
    moved_refs = moved_refs[0, :] - moved_refs
    a *= 180/math.pi
    return moved_refs, a
Пример #10
0
    def draw(self, painter, size = None):
        """
        :Arguments:
            painter : QPainter
                Opened painter on which to draw
        """
        bounding_rect = QRectF()
        position = self.position
        transfer_function = self.transfer_function
        font = QFont(self.font)
        text_color = self.text_color
        line_color = self.line_color
        line_thickness = self.line_thickness
        value_range = self.value_range
        if size is None:
            viewport = painter.viewport() # viewport rectangle
            mat, ok = painter.worldMatrix().inverted()
            if not ok:
                raise ValueError("Transformation matrix of painter is singular.")
            viewport = mat.mapRect(viewport)
        else:
            viewport = size
# First, prepare the gradient
        w = viewport.width()
        h = viewport.height()
        #print("Size of viewport: {0}x{1}".format(w, h))
        gr = QLinearGradient()
        nb_values = ceil(w/5.0)
        brush_color = QColor()
        for i in range(int(nb_values)):
            brush_color.setRgbF(*transfer_function.rgba(i/nb_values))
            gr.setColorAt(i/nb_values, brush_color)
# Second, find its position
        metric = QFontMetricsF(font, painter.device())
        font_test = [ str(i)*5 for i in range(10) ]
        lim_width = 0
        lim_height = 0
        for t in font_test:
            rect = metric.boundingRect(t)
            lim_width  = max(lim_width,  rect.width())
            lim_height = max(lim_height, rect.height())
        lim_height *= 3
        length = self.scale_length
        shift_length = (1-length)/2
        width = self.scale_width
        shift_width = self.scale_shift_width
        delta_value = value_range[1]-value_range[0]
        if position == "Top":
            scale_rect = QRectF(shift_length*w, shift_width*h, length*w, width*h)
            limit_rect(scale_rect, viewport, lim_width, lim_height)
            gr.setStart(scale_rect.left(), scale_rect.center().y())
            gr.setFinalStop(scale_rect.right(), scale_rect.center().y())
            start_pos = scale_rect.bottomLeft()
            end_pos = scale_rect.bottomRight()
        elif position == "Right":
            scale_rect = QRectF((1-shift_width-width)*w, shift_length*h, width*w, length*h)
            limit_rect(scale_rect, viewport, lim_width, lim_height)
            gr.setStart(scale_rect.center().x(), scale_rect.bottom())
            gr.setFinalStop(scale_rect.center().x(), scale_rect.top())
            start_pos = scale_rect.bottomLeft()
            end_pos = scale_rect.topLeft()
        elif position == "Bottom":
            scale_rect = QRectF(shift_length*w, (1-shift_width-width)*h, length*w, width*h)
            limit_rect(scale_rect, viewport, lim_width, lim_height)
            gr.setStart(scale_rect.left(), scale_rect.center().y())
            gr.setFinalStop(scale_rect.right(), scale_rect.center().y())
            start_pos = scale_rect.topLeft()
            end_pos = scale_rect.topRight()
        elif position == "Left":
            scale_rect = QRectF(shift_width*w, shift_length*h, width*w, length*h)
            limit_rect(scale_rect, viewport, lim_width, lim_height)
            gr.setStart(scale_rect.center().x(), scale_rect.bottom())
            gr.setFinalStop(scale_rect.center().x(), scale_rect.top())
            start_pos = scale_rect.bottomRight()
            end_pos = scale_rect.topRight()
        else:
            raise ValueError("Invalid scale position: %s" % position)
        shift_pos = (end_pos-start_pos)/delta_value
        if position in ["Left", "Right"]:
            is_vertical = True
            length = scale_rect.height()
        else:
            is_vertical = False
            length = scale_rect.width()
# Get the ticks
        ticks = self.selectValues(length, is_vertical, painter)
        if len(ticks) == 0:
            return
        ticks_str, ticks_extra = self._tick2str(ticks)
# Figure the shifts
        dist_to_bar = self.text_to_bar
        max_width = 0
        max_height = 0
        for t in ticks_str:
            rect = metric.boundingRect(t)
            max_width = max(rect.width(), max_width)
            max_height = max(rect.height(), max_height)
        if position == "Left":
            shift_left = dist_to_bar
            shift_top = None
        elif position == "Right":
            shift_left = -dist_to_bar-max_width
            shift_top = None
        elif position == "Top":
            shift_left = None
            shift_top = dist_to_bar
        else:
            shift_left = None
            shift_top = -dist_to_bar-max_height
        painter.save()
        painter.translate(viewport.topLeft())
        #print("viewport.topLeft() = {0}x{1}".format(viewport.left(), viewport.top()))
        painter.setBrush(gr)
        line_pen = QPen(line_color)
        line_pen.setWidth(line_thickness)
        painter.setPen(line_pen)
        painter.drawRect(scale_rect)
        bounding_rect |= scale_rect
        #print("Scale rect: +{0}+{1}x{2}x{3}".format(scale_rect.left(),
            #scale_rect.top(), scale_rect.width(), scale_rect.height()))
        painter.setFont(font)
        painter.setPen(text_color)
        for ts,t in zip(ticks_str, ticks):
            r = metric.boundingRect(ts)
            pos = start_pos+shift_pos*(t-value_range[0])
            if shift_left is None:
                pos.setX( pos.x() - r.width()/2 )
            else:
                pos.setX( pos.x() + shift_left )
            if shift_top is None:
                pos.setY( pos.y() - r.height()/2)
            else:
                pos.setY( pos.y() + shift_top )
            r.moveTo(pos)
            real_rect = painter.drawText(r, Qt.TextDontClip | Qt.AlignVCenter | Qt.AlignHCenter, ts)
            bounding_rect |= real_rect
        if ticks_extra is not None or self.unit:
            unit = self.unit
            exp_width = width = space_width = 0
            exp_txt = ""
            r = exp_r = unit_r = QRectF()
            exp_font = None
            if ticks_extra is not None:
                exp_txt = u"×10"
                r = metric.boundingRect(exp_txt)
                exp_font = QFont(font)
                exp_size = self.exp_size
                if exp_font.pixelSize() != -1:
                    exp_font.setPixelSize(exp_size*exp_font.pixelSize())
                else:
                    exp_font.setPointSizeF(exp_size*exp_font.pointSizeF())
                exp_metric = QFontMetricsF(exp_font, painter.device())
                exp_r = exp_metric.boundingRect(ticks_extra)
            if unit:
                unit_r = metric.boundingRect(unit)
            total_width = r.width()+exp_r.width()+unit_r.width()
            total_height = max(r.height(),unit_r.height())+exp_r.height()/2
            pos = scale_rect.topRight()
            log_debug("top right of scale bar = (%g,%g)" % (pos.x(), pos.y()))
            log_debug("Size of image = (%d,%d)" % (w,h))
            log_debug("Size of text = (%g,%g)" % (total_width, total_height))
            if position == "Bottom":
                pos.setY(pos.y() + scale_rect.height() + dist_to_bar)
                pos.setX(pos.x() - total_width)
            elif position == "Top":
                pos.setY(pos.y() - dist_to_bar - total_height)
                pos.setX(pos.x() - total_width)
            else: # position == "left" or "right"
                pos.setX(pos.x() - (scale_rect.width() + total_width)/2)
                if pos.x() < 0:
                    pos.setX(dist_to_bar)
                elif pos.x()+total_width+dist_to_bar > w:
                    pos.setX(w - total_width - dist_to_bar)
                pos.setY(pos.y() - dist_to_bar - total_height)
            log_debug("Display unit at position: (%g,%g)" % (pos.x(), pos.y()))

            if ticks_extra is not None:
                r.moveTo(pos)
                real_rect = painter.drawText(r, Qt.TextDontClip | Qt.AlignVCenter | Qt.AlignHCenter, exp_txt)
                bounding_rect |= real_rect
                pos.setX( pos.x() + r.width() )
                pos.setY( pos.y() - metric.ascent()/2 )
                exp_r.moveTo(pos)
                painter.setFont(exp_font)
                real_rect = painter.drawText(exp_r, Qt.TextDontClip | Qt.AlignVCenter | Qt.AlignHCenter, ticks_extra)
                bounding_rect |= real_rect
                pos.setY(pos.y() + metric.ascent()/2)
            if unit:
                pos.setX(pos.x() + space_width + exp_r.width())
                unit_r.moveTo(pos)
                painter.setFont(font)
                real_rect = painter.drawText(unit_r, Qt.TextDontClip | Qt.AlignVCenter | Qt.AlignHCenter, unit)
                bounding_rect |= real_rect
        # Draw the ticks now
        painter.setPen(line_pen)
        tick_size = self.tick_size
        if is_vertical:
            width = scale_rect.width()*tick_size
        else:
            width = scale_rect.height()*tick_size
        pen_width = painter.pen().widthF()
        if pen_width == 0:
            pen_width = 1.0
        for t in ticks:
            pos1 = start_pos + shift_pos*(t-value_range[0])
            pos2 = QPointF(pos1)
            if is_vertical:
                pos1.setX(scale_rect.left() + pen_width)
                pos2.setX(pos1.x() + width - pen_width)
                painter.drawLine(pos1, pos2)
                pos1.setX(scale_rect.right() - pen_width)
                pos2.setX(pos1.x() - width + pen_width)
                painter.drawLine(pos1, pos2)
            else:
                pos1.setY(scale_rect.top() + pen_width)
                pos2.setY(pos1.y() + width - pen_width)
                painter.drawLine(pos1, pos2)
                pos1.setY(scale_rect.bottom() - pen_width)
                pos2.setY(pos1.y() - width + pen_width)
                painter.drawLine(pos1, pos2)
        painter.restore()
        bounding_rect = bounding_rect.adjusted(-pen_width, -pen_width, pen_width, pen_width)
        return bounding_rect
Пример #11
0
def alignImages(data, alignment_data, translation, rotation):
    """
    Align the images in data using the points found in alignment_data.

    Arguments:
      - data, TrackingData: data set to align
      - alignment_data, TrackingData: data set used for the alignment
      - translation, (str|int): type of translation. Valid values are:
         * "Bounding-box centre"
         * "Barycentre"
         * Any point if in alignment_data
      - rotation, (str,int,int): type of rotation. The first value is the rotation type. For now, it has to be
      "TwoPoint". The two other values are the points id used for the rotation. """
    # First, check the alignment data is valid
    #pts = alignment_data[alignment_data.images_name[0]].points()
    a = scipy.zeros(len(data), dtype=float)
    if rotation is not None:
        assert len(rotation) == 3
        assert rotation[0] == "TwoPoint"
        r1 = rotation[1]
        r2 = rotation[2]
        for d in alignment_data:
            if not r1 in d:
                raise AlgoException("Image %s doesn't contain point %d." %
                                    (d._current_image, r1))
            if not r2 in d:
                raise AlgoException("Image %s doesn't contain point %d." %
                                    (d._current_image, r2))
        # Then, compute the rotation
        vecs = scipy.zeros((len(data), 2), dtype=float)
        for i, d in enumerate(alignment_data):
            v = d[r2] - d[r1]
            vecs[i, :] = (v.x(), v.y())
        a = scipy.arctan2(vecs[:, 1], vecs[:, 0])
        a = a[0] - a
    # At last, compute the translation using the reference
    refs = scipy.zeros((len(data), 2), dtype=float)
    if translation == "Bounding-box centre":
        for i, d in enumerate(alignment_data):
            mat, _ = d.matrix().inverted()
            p1 = None
            rect = QRectF()
            for p in d.positions():
                p = mat.map(p)
                if p1 is None:
                    p1 = p
                else:
                    rect |= QRectF(p1, p).normalized()
            mid_pos = rect.center()
            refs[i, :] = (mid_pos.x(), mid_pos.y())
    elif translation == "Barycentre":
        for i, d in enumerate(alignment_data):
            mat, _ = d.matrix().inverted()
            mid_pos = mat.map(sum(d.positions(), QPointF()) / len(d))
            refs[i, :] = (mid_pos.x(), mid_pos.y())
    else:
        for i, d in enumerate(alignment_data):
            mat, _ = d.matrix().inverted()
            if not translation in d:
                s = "Error, point %d is not in image %s. Cannot use it to align images."
                raise AlgoException(s % (translation, d.image_name))
            pos = mat.map(d[translation])
            refs[i, :] = (pos.x(), pos.y())
    moved_refs = refs * cos(a)[:, newaxis] + c_[-refs[:, 1], refs[:, 0]] * sin(
        a)[:, newaxis]
    moved_refs = moved_refs[0, :] - moved_refs
    a *= 180 / math.pi
    return moved_refs, a