Search code examples
c++qtqt5collisionqpixmap

How to detect collision between two QGraphicsPixmapItems if the pixmaps' edges are transparent?


I have two QGraphicsPixmapItems, the edges of both are transparent and they aren't rectangle shaped. When I try to use QGraphicsItem::collidingItems(), it only checks if their bounding rects are colliding. Is there a way to detect the collision only of the non-transparent parts?


Solution

  • You must set the shape mode to QGraphicsPixmapItem::HeuristicMaskShape:

    QGraphicsPixmapItem::HeuristicMaskShape

    The shape is determine by calling QPixmap::createHeuristicMask(). The performance and memory consumption is similar to MaskShape


    your_item->setShapeMode(QGraphicsPixmapItem::HeuristicMaskShape);
    

    Example:

    main.cpp

    #include <QApplication>
    #include <QGraphicsPixmapItem>
    #include <QGraphicsView>
    
    #include <QDebug>
    
    int main(int argc, char *argv[])
    {
        QApplication a(argc, argv);
        QGraphicsView w;
        QGraphicsScene *scene = new QGraphicsScene;
        w.setScene(scene);
    
        QList<QGraphicsPixmapItem *> items;
    
        for(const QString & filename: {":/character.png", ":/owl.png"}){
            QGraphicsPixmapItem *item = scene->addPixmap(QPixmap(filename));
            item->setShapeMode(QGraphicsPixmapItem::HeuristicMaskShape);
            item->setFlag(QGraphicsItem::ItemIsMovable, true);
            item->setFlag(QGraphicsItem::ItemIsSelectable, true);
            items<<item;
        }
    
        items[1]->setPos(50, 22);
        if(items[0]->collidingItems().isEmpty())
            qDebug()<<"there is no intersection";
        w.show();
        return a.exec();
    }
    

    enter image description here

    output:

    there is no intersection
    

    The complete example can be found in the following link