1 Attachment(s)
How to reflect QGraphicsItem?
I have a task to reflect one or more QGraphicsItems relatively to a line. And this operation should be performed correctly again and again to the mirrored items.
I've read a lot about QTransform and affine transformations and realized that I need 1) rotate; 2) scale (1;-1) 3) translate..somewhere
that's what I have now:
Code:
double x1 = line->line().x1();
double y1 = line->line().y1();
double x2 = line->line().x2();
double y2 = line->line().y2();
double angle = atan((y2 - y1)/(x2 - x1));
group->rotate(angle*180/acos(-1.0));
group->scale(1,-1);
group->rotate(-angle*180/acos(-1.0));
item->setTransform (group->transform(),true);
destroyItemGroup(group);
removeItem(line);
delete line;
curItem = NULL;
This is steps 1-2 as I don't know how to translate items correctly regardless of their pos() and previous mirror operations. At least the resulting angle of mirrored item seems to be right, but not after the second reflection :confused:
"curItem" holds the line of the mirror (it's temporal and is erased after the operation), "group" of items to be reflected is created elsewhere.
Thanks in advance for all your help. I attached the whole project (Qt 4.3.2, Visual Studio 2005 .vcproj, but without a .pro, sorry)
Re: How to reflect QGraphicsItem?
Will have to see into ur prob,,,, seems interesting.
Meanwhile you can have a look at this :)
Re: How to reflect QGraphicsItem?
The link has no deal with my question
Re: How to reflect QGraphicsItem?
As far as I understand mirroring without taking a piece of paper and experimenting with calculations, mirroring is equal to scaling with a scale of (1, -1) or (-1, 1) where the scale axis (x or y) matches the mirror line. Therefore all you need to do can be summarized by three points:
1. transform the coordinate space so that one of its axis matches the line of the mirror
2. scale relative to the chosen axis
3. transform the coordinate space back to its original state
Remember that you want to move the coordinate space and not the item, so you should probably invert all the matrices if you want to apply them to the item and not the world.
I suggest you start by creating a custom widget derived from QWidget that will consist of a shape (even hardcoded), a mirror line (hardcoded) and a paint event that will transform the painter and draw the mirrored shape. This will let you verify my assumptions and should allow you to do the reverse mapping you need with the graphics view architecture.
Re: How to reflect QGraphicsItem?
Thanks but I need reflecting not only relatively to an axis, but to ANY line, given by 2 points.
Re: How to reflect QGraphicsItem?
See points 1. and 3. of my previous post.
Re: How to reflect QGraphicsItem?
I still keep on failing with this task...
In the constructor of the scene I've placed 2 lines
Code:
pen.setWidth(2);
pen.setColor(Qt::black);
line->setPen(pen);
addItem(line);
addItem(line);
they'll be axises. Also i track mouse coordinates
Code:
QPoint p
= mouseEvent
->scenePos
().
toPoint();
QMainWindow* parent
= qobject_cast<QMainWindow
*>
(view
->parentWidget
());
parent
->statusBar
()->showMessage
(QString::number(p.
x())+" ; "+QString::number(p.
y()));
why when I just create simple line with dots (10,10) and (60,10) and then call
item->translate(0, 20);
it moves to the position (10,50) and (60,50) ?!
Well, that's not essential for me at this moment...
After hours of mind torturing I've written this:
Code:
double x1 = line->line().x1();
double y1 = line->line().y1();
double x2 = line->line().x2();
double y2 = line->line().y2();
double angle = atan((y2 - y1)/(x2 - x1));
{
QTransform tozero;
tozero.translate(-x1/2, -y1/2);
tozero.rotateRadians(angle);
QTransform mirror;
mirror.scale(1, -1);
QTransform back;
back.rotateRadians(-angle);
back.translate(x1/2, y1/2);
item->setTransform(tozero*mirror*back,true);
}
It works perfectly relativly to any line that is paralle to 0x, but if it's not the item flies away =( help me plz!
Re: How to reflect QGraphicsItem?
So why not try my approach? :)
Re: How to reflect QGraphicsItem?
wysota
as far as I understand, it IS your approach :)
Re: How to reflect QGraphicsItem?
Certainly not. I told you to transform the viewport and not the item. I really suggest leaving graphics view aside now and finding proper transformations using QPainter - it should be much simpler. Then you can adjust the code for the graphics view architecture. Currently you are just guessing.
Re: How to reflect QGraphicsItem?
hmm but why should I transform the viewport? o_O I can have many items in the viewport and not all of them must be mirrored, but only the selected ones.
And how the "QPainter decision" can be simpler...then I'll have to convert it to the "GVF decision". I almost have this decision, it almost works, I'm sure the trouble is very tiny, but I can't see it ((
anyway thanks for your attention...
Re: How to reflect QGraphicsItem?
Yes, you are right - almost.
Re: How to reflect QGraphicsItem?
So if you clearly see my error, why don't just tell it? :( and get one more "thanks"
u see I'm not of the ones who ask to do everything for them, I did my best!
Re: How to reflect QGraphicsItem?
I don't see your error. I suggest you experiment with a simpler world, but you know better, so stick to your approach.
Re: How to reflect QGraphicsItem?
even if a man with such a long operational experience as you have (as I suggest) doesn't see the error...how wil I see it? it's my 1st program in Qt.
Re: How to reflect QGraphicsItem?
Maybe because I didn't look for it.