精确检测两个图形项之间的碰撞
Precise detection of collision between two graphical items
我有两个图形项目,RectItem
和 CurveItem
。我需要精确检测这两个项目之间的碰撞。我为展位项目实施了 shape()
方法。当我从场景 self.collidingItems(self.rect_item, mode=Qt.IntersectsItemShape
中移动其中一项时,我验证是否检测到碰撞。
我通过在场景中移动项目来碰撞它们,但仅在 CurveItem
的顶部检测到碰撞。我不明白我哪里弄错了。
代码:
class RectItem(QGraphicsRectItem):
def __init__(self, x, y, w, h):
super().__init__(x, y, w, h)
self.setFlag(QGraphicsItem.ItemIsMovable)
self.setPen(QPen(Qt.cyan))
def shape(self):
path = QPainterPath()
path.addRect(self.boundingRect())
return path
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 QRectF()
def shape(self):
return self.path
def _setupPath(self):
path = QPainterPath()
path.moveTo(0, 0)
path.cubicTo(99, 0, 50, 50, 99, 99)
path.cubicTo(0, 99, 50, 50, 0, 0)
return path
class Scene(QGraphicsScene):
def __init__(self):
super().__init__()
self.curve_item = CurveItem()
self.rect_item = RectItem(-50, -50, 25, 25)
self.addItem(self.curve_item)
self.addItem(self.rect_item)
def mouseMoveEvent(self, e):
print(self.collidingItems(self.rect_item, mode=Qt.IntersectsItemShape))
super().mouseMoveEvent(e)
尽管您不会使用 boundingRect()
来检测碰撞,但您必须 return 一个 QRect
,这是覆盖 shape
的最小尺寸,为此我们可以使用QPainterPath
的boundingRect()
方法,而且不需要覆盖QGraphicsRectItem
.
的形状
class RectItem(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()
path.moveTo(0, 0)
path.cubicTo(99, 0, 50, 50, 99, 99)
path.cubicTo(0, 99, 50, 50, 0, 0)
return path
class Scene(QGraphicsScene):
def __init__(self):
super().__init__()
self.curve_item = CurveItem()
self.rect_item = RectItem(-50, -50, 25, 25)
self.addItem(self.curve_item)
self.addItem(self.rect_item)
def mouseMoveEvent(self, e):
print(self.collidingItems(self.rect_item, mode=Qt.IntersectsItemShape))
super().mouseMoveEvent(e)
我有两个图形项目,RectItem
和 CurveItem
。我需要精确检测这两个项目之间的碰撞。我为展位项目实施了 shape()
方法。当我从场景 self.collidingItems(self.rect_item, mode=Qt.IntersectsItemShape
中移动其中一项时,我验证是否检测到碰撞。
我通过在场景中移动项目来碰撞它们,但仅在 CurveItem
的顶部检测到碰撞。我不明白我哪里弄错了。
代码:
class RectItem(QGraphicsRectItem):
def __init__(self, x, y, w, h):
super().__init__(x, y, w, h)
self.setFlag(QGraphicsItem.ItemIsMovable)
self.setPen(QPen(Qt.cyan))
def shape(self):
path = QPainterPath()
path.addRect(self.boundingRect())
return path
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 QRectF()
def shape(self):
return self.path
def _setupPath(self):
path = QPainterPath()
path.moveTo(0, 0)
path.cubicTo(99, 0, 50, 50, 99, 99)
path.cubicTo(0, 99, 50, 50, 0, 0)
return path
class Scene(QGraphicsScene):
def __init__(self):
super().__init__()
self.curve_item = CurveItem()
self.rect_item = RectItem(-50, -50, 25, 25)
self.addItem(self.curve_item)
self.addItem(self.rect_item)
def mouseMoveEvent(self, e):
print(self.collidingItems(self.rect_item, mode=Qt.IntersectsItemShape))
super().mouseMoveEvent(e)
尽管您不会使用 boundingRect()
来检测碰撞,但您必须 return 一个 QRect
,这是覆盖 shape
的最小尺寸,为此我们可以使用QPainterPath
的boundingRect()
方法,而且不需要覆盖QGraphicsRectItem
.
class RectItem(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()
path.moveTo(0, 0)
path.cubicTo(99, 0, 50, 50, 99, 99)
path.cubicTo(0, 99, 50, 50, 0, 0)
return path
class Scene(QGraphicsScene):
def __init__(self):
super().__init__()
self.curve_item = CurveItem()
self.rect_item = RectItem(-50, -50, 25, 25)
self.addItem(self.curve_item)
self.addItem(self.rect_item)
def mouseMoveEvent(self, e):
print(self.collidingItems(self.rect_item, mode=Qt.IntersectsItemShape))
super().mouseMoveEvent(e)