Обнаружение столкновения между прямоугольником и элементом с изогнутой формой - PullRequest
0 голосов
/ 30 апреля 2018

Мне нужно точно определить столкновение между элементом прямоугольника и другим элементом, который имеет кривую Безье. В настоящий момент столкновение обнаруживается правильно, когда я сталкиваюсь с прямоугольником нижней части формы кривой Безье. Но когда я перемещаю прямоугольник внутри кривой формы Безье, также обнаруживается столкновение, хотя эти элементы не сталкиваются. Я хочу получить точное столкновение между этими двумя предметами. Я не понимаю, где я допустил ошибку.

enter image description here

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)

1 Ответ

0 голосов
/ 30 апреля 2018

Чтобы увидеть, в чем причина проблемы, мы можем поместить QBrush для рисования содержимого CurveItem и получить следующее:

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

enter image description here

Почему это происходит?

QPainterPath соединяет конечную и начальную точки, если фигура не является закрытой, поэтому она генерирует фигуру с содержимым , и это приводит к тому, что при перемещении прямоугольника по линии она сигнализирует о том, что она пересекается .

Какое решение?

Вернитесь по тому же пути к начальной точке, соединяя, таким образом, новую последнюю строку с начальной без генерации содержимого .

В следующем коде есть решение:

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
...