【问题标题】:Detecting collision between rectangle and item with bezier curve shape用贝塞尔曲线形状检测矩形和项目之间的碰撞
【发布时间】:2018-10-10 18:15:13
【问题描述】:

我需要精确检测矩形项目与另一个具有贝塞尔曲线形状的项目之间的碰撞。目前,当我将矩形与贝塞尔曲线形状的底部碰撞时,正确检测到碰撞。但是当我在贝塞尔曲线形状内移动矩形时,也会检测到碰撞,尽管这些项目没有碰撞。我想获得这两个项目之间的精确碰撞。我不明白我在哪里做错了。

class RectangleItem(QGraphicsRectItem):
    def __init__(self, *args):
        super().__init__(*args)
        self.setFlag(QGraphicsItem.ItemIsMovable)
        self.setPen(QPen(Qt.cyan))


class CurveItem(QGraphicsItem):
    def __init__(self):
        super().__init__()
        self.path = self._setupPath()

    def paint(self, painter, styles, widget=None):
        painter.drawPath(self.path)

    def boundingRect(self):
        return self.path.boundingRect()

    def shape(self):
        return self.path

    def _setupPath(self):
        path = QPainterPath()

        p1 = QPointF(0, 100)
        p2 = QPointF(400, 100)
        c = QPointF(200, 800)

        path.moveTo(p1)
        path.quadTo(c, p2)
        return path


class Scene(QGraphicsScene):
    def __init__(self):
        super().__init__()

        self.curve_item = CurveItem()
        self.addItem(self.curve_item)

        self.rectangle_item = RectangleItem(0, 0, 50, 50)
        self.addItem(self.rectangle_item)

    def mouseMoveEvent(self, e):
        print(self.collidingItems(self.curve_item))
        super().mouseMoveEvent(e)

【问题讨论】:

    标签: python pyqt pyqt4 pyqt5 qgraphicsitem


    【解决方案1】:

    为了观察问题的原因,我们可以放置一个 QBrush 来绘制 CurveItem 内容,我们得到以下结果:

    def paint(self, painter, styles, widget=None):
        painter.setBrush(QBrush(QColor("green")))
        painter.drawPath(self.path)
    

    为什么会这样?

    QPainterPath 如果图形未闭合,则将最终点和初始点连接起来,因此它会生成一个带有 content 的图形,这会导致当您将矩形移动到线上时,它会发出信号表明它是相交。

    解决办法是什么?

    通过相同的路径返回到起点,从而将新的最后一行与初始行连接起来,而不生成 内容

    解决方法如下:

    class CurveItem(QGraphicsItem):
        def __init__(self):
            super().__init__()
            self.path = self._setupPath()
    
        def paint(self, painter, styles, widget):
            painter.drawPath(self.path)
    
        def boundingRect(self):
            return self.path.boundingRect()
    
        def shape(self):
            return self.path
    
        def _setupPath(self):
            path = QPainterPath()
    
            p1 = QPointF(0, 100)
            p2 = QPointF(400, 100)
            c = QPointF(200, 800)
    
            path.moveTo(p1)
            path.quadTo(c, p2)
    
            # back
            path.quadTo(c, p1)
            return path
    

    【讨论】:

    • 很好的解释。谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-01-26
    • 2017-10-30
    • 1970-01-01
    • 1970-01-01
    • 2014-05-05
    • 2011-08-17
    • 1970-01-01
    相关资源
    最近更新 更多