Collision: calculating reflection angle
-
I'm making a simple game, and I'm using QGraphicsView to display graphics. The game is very similar to pinball, so there's a ball, which is supposed to bounce off from obstacles and walls. I'm having difficulties in calculating the reflection angle when the ball collides with other items. As far as I know, qt only supports detecting when collisions happen, but there is no simple way to gain any additional information, for example the normal of the surface, which is required to calculate the reflection angle. Here's the advance function of the ball, which is executed once every 0.1 seconds:
@
void Ball::advance(int step)
{
if (step == 0)
{
return;
}QList<QGraphicsItem*> colliders = collidingItems(); if (!colliders.empty()) { QGraphicsItem* obstacle = colliders.first(); //Here I calculate the angle of the tangent. This function doesn't have // an implementation yet, and that actually is what I'm asking. qreal tangent = atan(getTangentAngleFactor(obstacle)); qreal speed = sqrt(dx_*dx_+dy_*dy_); //This is the direction of the ball before collision. dy_ is multiplied by // -1, because in QGraphicsView y-axis grows downwards. qreal angle = atan(-dy_/dx_); //Calculate the reflection angle qreal reflection = 2*tangent-angle; dx_ = speed*cos(reflection); dy_ = -speed*sin(reflection); } setPos(pos().x() + dx_, pos().y() + dy_); //The ball has a downwards acceleration dy_ = dy_ + 0.1;
}
@
Basically the only problem is, that I don't know the tangent, normal, or even the collision point. I'd be very grateful, if someone could help me with this problem, as I've spent quite much time trying to sort it out.
-
Take a look at QgraphicsItem::itemChanged
Reimplement this function, store all the information you need and you can compute everything -
I think it will be easier to use a 2D physics engine like "Box2D":http://box2d.org/
There a lot of implementations/examples in Qt ("qml-box2d":https://github.com/bjorn/qml-box2d or my "qbox2d":https://github.com/Code-ReaQtor/qbox2d) or take a look at this "blog":http://blog.qt.digia.com/blog/2010/02/26/qt-box2d-is-easy/ -
Thank you for the advice. I'd definitely use box2d, but this is a course project and I'm not sure if we're allowed to use external libraries. I checked itemChanged() function, but I still don't understand, how it can be used to detect the collision point/tangent/normal.
-
For anybody else who intends to use Box2D with Qt:
The V-Play Game Engine SDK offers easy-to-use QML components for Box2D physics and collision detection.
It might be worth a look if you want to develop cross-platform 2D games with Qt.Cheers,
GT