PDA

View Full Version : QGraphicsPixmapItem collision detection



sophister
4th July 2010, 05:26
I add two QGraphicsPixmapItem objects in a QGraphicsScene, and I want to detect the collision between them. The picture's format is PNG. But when collision happens, the system use the outer rectangle to detect it, not the inner outline of the items.
Question is, how can I detect the collision according to the inner outline of the picture, not the outer rectangle of the picture.

Thanks in advance!

JohannesMunk
4th July 2010, 16:00
Hi!

You need to subclass and reimplement either of



QGraphicsItem::collidesWithItem(const QGraphicsItem * other, Qt::ItemSelectionMode mode)
QGraphicsItem::shape()


whichever is faster in your case.

Johannes

sophister
4th July 2010, 18:38
Hi!

You need to subclass and reimplement either of



QGraphicsItem::collidesWithItem(const QGraphicsItem * other, Qt::ItemSelectionMode mode)
QGraphicsItem::shape()


whichever is faster in your case.

Johannes

Thanks!!

But I thought QGraphicsPixmapItem has done that for me.
The sub-attack demo in Qt4.6 just use this class to detect collision, not having reimplemented both methods.

JohannesMunk
4th July 2010, 18:40
That's right. But the default implementation obviously returns the outer rectangle. If you want something different, here is the place to change it.

Joh

sophister
4th July 2010, 19:40
That's right. But the default implementation obviously returns the outer rectangle. If you want something different, here is the place to change it.

Joh

Maybe that's the problem: I do not know how to reimplement the two methods, because I have no idea how to get the inner outline of the PNG picture and return it as QPainterPath, any idea?

JohannesMunk
4th July 2010, 19:51
That's an entirely different question! And I have no simple answer ready for you.

What exactly do you mean with inner outline? Is your PNG partly transparent?

Joh

JohannesMunk
4th July 2010, 20:33
I just found this:

http://doc.trolltech.com/latest/qgraphicspixmapitem.html#shapemode-enum.html

So if you set the transparency right, that should work!

Excerpt of the source code of how this is implemented internally :->


void updateShape()
{
shape = QPainterPath();
switch (shapeMode) {
case QGraphicsPixmapItem::MaskShape: {
QBitmap mask = pixmap.mask();
if (!mask.isNull()) {
shape = qt_regionToPath(QRegion(mask).translated(offset.to Point()));
break;
}
// FALL THROUGH
}
case QGraphicsPixmapItem::BoundingRectShape:
shape.addRect(QRectF(offset.x(), offset.y(), pixmap.width(), pixmap.height()));
break;
case QGraphicsPixmapItem::HeuristicMaskShape:
#ifndef QT_NO_IMAGE_HEURISTIC_MASK
shape = qt_regionToPath(QRegion(pixmap.createHeuristicMask ()).translated(offset.toPoint()));
#else
shape.addRect(QRectF(offset.x(), offset.y(), pixmap.width(), pixmap.height()));
#endif
break;
}
}


Joh

sophister
4th July 2010, 20:36
That's an entirely different question! And I have no simple answer ready for you.

What exactly do you mean with inner outline? Is your PNG partly transparent?

Joh

yes, the PNG pictures are partly transparent in the edges. Does Qt provide any method to get the inner outline. I thought QPixmap or some other iamge-operating class should have that kind method.