Отображение boundingRect () на родительский элемент и пересечение дает неожиданные результаты для обработки столкновений - PullRequest
0 голосов
/ 16 сентября 2018

Вот как я обрабатываю столкновение двух графических элементов. Он вызывается в mouseMoveEvent и itemChange. Вот так:

void GraphicsItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
{
    auto delta = event->pos() - event->lastPos();
    auto new_pos = handleCollisions(pos() + delta);
    setPos(new_pos);
}

Функция new_pos такова, что я могу вызвать ее в itemChange и вернуть ее в качестве значения. Однако эта версия обработки столкновений оставляет new_pos без изменений. Вместо этого мы перемещаем элементы, которые сталкиваются с этим (как мы перемещаем этот с помощью мыши). Я пытаюсь взять пересечение двух вовлеченных ограничивающих линий и сдвинуть другое на более короткое измерение пересечения прямоугольников. Результатом, который является неожиданным, является то, что прямоугольники движутся не только на это небольшое количество, а вместо этого по всей ширине (или высоте) любого из boundingRects () (они имеют одинаковый размер). Я объяснил это тем, что приведенный ниже код, который вычисляет пересечение ограничивающих сторон в пространстве позиции родителя (где pos (), setPos () относительно), неверен.

Так как мне это сделать?

Вот картинка того, что я хочу: enter image description here

QPointF GraphicsItem::handleCollisions(const QPointF& new_pos) const {
    auto collisions = collidingItems();
    auto rect = mapToParent(boundingRect().translated(new_pos - pos())).boundingRect();
    for(int k=0; k < collisions.count(); k++)
    {
        auto item = collisions[k];
        if (item->parentItem() == parentItem()) {
            auto rect1 = mapToParent(item->boundingRect()).boundingRect();
            rect1 = rect1.intersected(rect);
            qDebug() << (rect1.width());
            qDebug() << (rect1.height());
            auto v = rect1.center() - rect.center();
            if (v.x() >= 0) {
                if (v.y() >= 0) {
                    if (rect1.width() <= rect1.height())
                        item->setPos(item->pos() + QPointF(-rect1.width(), 0));
                    else
                        item->setPos(item->pos() + QPointF(0, -rect1.height()));
                }
                else {
                    if (rect1.width() <= rect1.height())
                        item->setPos(item->pos() + QPointF(rect1.width(), 0));
                    else
                        item->setPos(item->pos() + QPointF(0, rect1.height()));
                }
            }
            else {
                if (v.y() >= 0) {
                    if (rect1.width() <= rect1.height())
                        item->setPos(item->pos() + QPointF(rect1.width(), 0));
                    else
                        item->setPos(item->pos() + QPointF(0, -rect1.height()));
                }
                else {
                    if (rect1.width() <= rect1.height())
                        item->setPos(item->pos() + QPointF(rect1.width(), 0));
                    else
                        item->setPos(item->pos() + QPointF(0, rect1.height()));
                }
            }
        }
    }
    return new_pos;     // return this position unchanged
}

1 Ответ

0 голосов
/ 16 сентября 2018

Я нашел его.

item->mapToParent(...)

вместо

mapToParent(...)

должен вызываться в цикле.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...