PDA

View Full Version : position vectors



KaKa
17th March 2007, 11:51
I noticed that we define positions using vectors in pixels.
However, I don't know when the vectors are referring to the absolute position relative to the computer window; when the vectors are referring to the position relative to the parent widgets; or when the vectors are referring to the position relative to itself. And I really find it hard to calculate and measure positions.
Any summaries or good methods out there?

Thanks very much!

wysota
17th March 2007, 12:09
I noticed that we define positions using vectors in pixels.
Not in pixels. The unit depends on transformations used.


However, I don't know when the vectors are referring to the absolute position relative to the computer window; when the vectors are referring to the position relative to the parent widgets; or when the vectors are referring to the position relative to itself. And I really find it hard to calculate and measure positions.
Any summaries or good methods out there?

Unless the documentation states otherwise, positions are calculated using local coordinate system. For instance QWidget::pos() keeps the position relative to the parent widget, just like the docs say. But in most cases you don't have to look into the docs as the interpretation is obvious/logical.

KaKa
17th March 2007, 17:59
hmm...I understand things slowly.

I will use an example to proceed my question. For this function, whose definition is as follows in the documentation:


"void QPainter::drawText ( int x, int y, const QString & text )

This is an overloaded member function, provided for convenience.

Draws the given text at position (x, y), using the painter's currently defined text direction."

I really don't know what is the unit for x or y.

and the tutorial was using

painter.drawText(200, 200,
tr("Angle = ") + QString::number(currentAngle));
How does it know, the rectangle should be 200*200 relative to the widget as it didn't define the widget's size?

You have kindly told me that
The unit depends on transformations used.
But how would I know what transformation is used?

wysota
17th March 2007, 18:27
"void QPainter::drawText ( int x, int y, const QString & text )

This is an overloaded member function, provided for convenience.

Draws the given text at position (x, y), using the painter's currently defined text direction."

I really don't know what is the unit for x or y.
Logical unit of the painter.


How does it know, the rectangle should be 200*200 relative to the widget as it didn't define the widget's size?
I don't know what kind of answer you expect here... The person who wrote the code wanted the text to start at that position.


You have kindly told me that
The unit depends on transformations used.
But how would I know what transformation is used?
Well... in general you shouldn't care if you didn't set it. But if you have to know, then retrieve the painter matrix and/or window rect and viewport rect.

I have an idea - please take a look at the analog clock example bundled with Qt. It describes how the painter is transformed to achieve the desired effect. Of course the appropriate section of the docs (http://doc.trolltech.com/latest/coordsys.html) is a good place to read as well.

KaKa
18th March 2007, 09:27
I still don't understand though...

Say that programmer chose the position 200, 200 to put his/her text, but as in the code there was no place defining how large the whole wedigt is. I mean if the wedgit is defined by X*X, then if we don't know what this X is, then how would we know wehre exactly 200, 200 is in this X*X area?

From the clock example, I sort of got the conclusion that the whole wedgit is defined as 100%*100%, and therefore, the logic unit is based on the portion according to the whole length. However, When I saw that 200, how can it be 200%?

Then I noticed that it as if the logic unit was derived from hight(), width() divided by some factor. ---But I don't want to do it all the time.

So basically, I just don't know when I want to put say a dot at certain position, how to count its logical unit (x,y)?

Hope that makes my question more clear.

wysota
18th March 2007, 11:39
Say that programmer chose the position 200, 200 to put his/her text, but as in the code there was no place defining how large the whole wedigt is. I mean if the wedgit is defined by X*X, then if we don't know what this X is, then how would we know wehre exactly 200, 200 is in this X*X area?
It's plain maths. Each "window" has a coordinate system with an origin that is initially located in the upper left corner of the viewport with axis pointing right and down and the correlation between a physical unit and a logical unit is 1:1 - meaning that a point (200,200) is located 200 pixels to the right and 200 pixels down from the upper left corner of the viewport. This is the most often used configuration. But now you have two independent options:
1. Make "logical" and "physical" units different - this is called viewport-window transformation. In this case you tell Qt to use a linear transformation defined by two rectangles - a physical (viewport) rectangle (measured in device units - in case of widgets those are pixels) and a logical (window) rectangle measured in logical units - for example if you set a window of (0, 0, 100, 100) you'll get a logical unit equal to percentage of the width x percentage of the height of the physical device. Thanks to that transformation you don't have to recalculate everything every time the size of the physical device (widget) changes as Qt will do that for you behind the scenes.

2. Apply a 2d transformation matrix to the painter (since Qt 4.3 you can also apply a 3d transformation matrix so now you can do full 3d transformations on a 2d canvas). This allows you to scale, rotate, translate or shear the painter - that's what the analog clock example uses - it translates the painter so that the origin is in the centre of the widget and then rotate the painter and draw a vertical line always in the same logical position. As the painter is rotated, physical coordinates related to the same logical coordinates become different. Take a look at the link I suggested in my previous post - it has nice pictures to explain the whole thing.


From the clock example, I sort of got the conclusion that the whole wedgit is defined as 100%*100%, and therefore, the logic unit is based on the portion according to the whole length. However, When I saw that 200, how can it be 200%?
It's not percentage. It depends on what you set the window rectangle to.

Let's make an example... Let's take a widget that is 400 x 200 pixels (so it has an initial viewport of (0, 0, 400, 200) and initial window of (0, 0, 400, 200)) and let's apply a window-viewport transformation by changing the logical unit. Calling QWidget::setWindow(-10, -10, 20, 20) sets the logical coordinate system to a rectangle that maps PHYSICAL(0, 0) to LOGICAL(-10, -10) and PHYSICAL(0+400, 0+200) to LOGICAL(-10+20, -10+20). This gives us:

PX = PXmin + PXwid*(LX-LXmin)/LXwid
PY = PYmin + PYhei*(LY-LYmin)/LYhei

with:
PXmin = 0, PXwid = 400, PYmin = 0, PYhei = 200
LXmin = -10, LXwid = 20, LYmin = -10, LYhei = 20

calculating for L(X,Y) = (4,4):
PX = 0 + 400 * (4+10) / 20 = 280
PY = 0 + 200 * (4+10) / 20 = 140

So a point LOGICAL(4,4) maps to PHYSICAL(280,140)
If you resize the widget to (200,200), PXwid and PYhei will change to (200,200) and again calculating for L(X,Y) = (4,4):
PX = 0+200*(4+10) / 20 = 140
PY = 0+200*(4+10) / 20 = 140

so this time the same logical point LOGICAL(4,4) maps to PHYSICAL(140,140).


Then I noticed that it as if the logic unit was derived from hight(), width() divided by some factor. ---But I don't want to do it all the time.
You don't have to, just don't touch the initial transformation and you'll have the logical unit identical to the physical one.


So basically, I just don't know when I want to put say a dot at certain position, how to count its logical unit (x,y)?

Don't calculate anything, just don't apply any transformations.

KaKa
18th March 2007, 16:06
Thanks so much for the detailed answer! This really helps!!! :)