PDA

View Full Version : QGraphicsView coordinate system



been_1990
30th October 2010, 22:26
I'm having a real hard time with finding the correct positioning of items in a scene.
1-rotate an item based on the angle of the mouse-to-item position. = Succesfull!
2-create an item, and send it from it's parent position to in direction to the mouse = Problems...

The following code is successful in other platforms such as Adobe Flash:


// When mouse is clicked =

Shot *tiro = new Shot();
double velocity = 10;
double radians = angle * PI / 180; // where angle is successfully defined previously

double velx = velocity * cos(radians);
double vely = velocity * sin(radians);
double x0 = ((redShip->scenePos().x()+redShip->boundingRect().width()/2)+50 ) * cos(radians);
double y0 = ((redShip->scenePos().y()+redShip->boundingRect().width()/2)+50 ) * sin(radians);
double x = x0 + velx ;
double y = y0 + vely ;

tiro->newShot(scene,x0,y0);
tiro->setDirection(x,x);


Shot.cpp:

void Shot::newShot(QGraphicsScene * scene, double x, double y)
{
ball = new QGraphicsEllipseItem(x,x,10,10);

scene->addItem(ball);

}

void Shot::setDirection(double x, double y)
{
dirx = x;
diry = y;
}

//updatePos() is called every second by a QTimer in Shot::Shot()
void Shot::updatePos()
{
x += dirx;
y += diry;
ball->setPos(x,y);
}

The above just creates a shot anywhere in a up-down / left-right diagonal
and sends it following the said diagonal. What am I doing wrong (never Qt's fault...)

wysota
30th October 2010, 22:58
If I understand correctly then your problems are caused by the fact that you are trying to make the missile a child of the cannon (or whatever you have there). The problem is that you are probably handling mouse events in the scene (in scene coordinates) but trying to move the ball in cannon's coordinates. This is of course doable, all you need is to map coordinates from the scene to the item but if you rotate the cannon again (or whatever you have there) the ball will follow the rotation which I don't think is something you want.

To understand Graphics View coordinate system, imagine that the scene is a sheet of paper that has an origin and x and y axis marked on it. Each item is another sheet of paper with its own x and y axis and origin. The origin of the item is pinned to the position of the item on the piece of paper representing its parent. So if you have an item that has its own children, you pin them to the parent item and not to the scene. Now if you start rotating or moving the sheet representing the parent you will notice all children also change their position. It's a good idea to actually take a few pieces of paper (or better yet transparency foils or something that is semi-transparent), a pencil and a couple of pins and repeat all this as an exercise to understand how it all behaves.

been_1990
31st October 2010, 01:12
I watched the ICS video on QGraphicsView and I do understand the relationship between child/parent items.
I traced the new items position and it starts at 0, and that would mean that it is a child of my reference item(the "cannon"). But I don't understand why, if I add it to the scene and not to the item(the "cannon").


void Shot::newShot(QGraphicsScene * scene, double x, double y)
{
ball = new QGraphicsEllipseItem(x,x,10,10);

scene->addItem(ball); // adds new item to the scene, not to the GraphicsItem("cannon")
}

Why does that happen?

EDIT: Another thing I dont understand is this:
5414

between the walls is what the scene is supposed to be, 400x400. But it re-sizes to the whole view and the red cannon instead of being inside the scene, is outside. I set the app to fullscreen.

wysota
31st October 2010, 06:51
I'd say the code should be:

void Shot::newShot(QGraphicsScene * scene, double x, double y)
{
ball = new QGraphicsEllipseItem(-5,-5,10,10);
scene->addItem(ball); // adds new item to the scene, not to the GraphicsItem("cannon")
ball->setPos(x,x);
}

been_1990
31st October 2010, 18:21
Adding "ball->setPos(x,x) " does not change anything.

SixDegrees
31st October 2010, 19:14
First, read this: http://doc.qt.nokia.com/4.5/graphicsview.html It contains a very good discussion on the various coordinate systems employed and how they relate to one another.

Second, statements like


The following code is successful in other platforms such as Adobe Flash

are meaningless at best, disastrous at worst. There are dozens/scores/hundreds of software toolkits out there that perform various graphics tasks, and the way they treat coordinate systems is different in every case. You can't expect to simply plop existing code written using some totally different geometry system into another framework and expect it to work the same. Or to work at all.

You have to understand what you're doing. You can't code by cutting and pasting, at least not until you are thoroughly grounded in the tools you are using.

been_1990
31st October 2010, 23:59
The following code is successful in other platforms such as Adobe Flash
Sorry, the math is successful in other platforms. And their coordinate system is the same as QT, excluding parent-child items relationship.

Seems that what was causing the problem was not related to this positioning code but to another "feature" I had in the program. Thanks for the time, I'm very grateful.

wysota
2nd November 2010, 16:21
Adding "ball->setPos(x,x) " does not change anything.

This is not the only difference between my code and yours.