View Full Version : Help with a visual effect
SkripT
4th May 2006, 17:33
Hi, I want to know what's the simple way to obain this visual effect: a rectangle (for example) that rotates 180 degrees from the Y axis:
Coordinate system
|Y
|
|
|
|_________________ X
/
/
/
/ Z
All I want is to emulate the effect of a page (of a book) turning around :cool:
I think that I could use openGL but I don't hve much experinece with it, maybe it can be easily achieved with QPainter :confused:
Thanks in advance.
If you have a point (x, y, z) and you rotate it around Y axis by a degrees, you'll get (x', y', z') where:
x' = x cos a + z sin a,
y' = y,
z' = -x sin a + z cos a.
Second thing you will need is a projection. In this case it probably will be enough if you use:
xp = x - z
yp = y + z
(where xp, and yp are the painter coordinates).
The algorithm:
translate the painter so that the (0, 0) point is in the middle of the top edge of the book,
x1 = width/2, y1 = 0, z1 = 0, (upper corner of the page)
x2 = width/2, y2 = height, z2 = 0, (lower corner of the page)
for a = 0, 1, ..., 180:
calculate new x1, y1, z1, x2, y2 and z2
draw a (0, 0)--(x1-z1, y1-z1)--(x2-z2, y2-z2)--(0, height) rectangle
Note that in fact x1 == x2, z1 == z2 and both y1 and y2 are constant.
SkripT
4th May 2006, 18:35
Thanks a lot jacek, good knowledge of maths ;)
EDIT: taking a look at this alogrithm carefully, I think that it will paint the rectangle with the correct size in each degree, the problem is that I want to paint an image (texture) on this rectangle and I want that it "deforms" with each degree. Is it still possible with QPainter?
I want that it "deforms" with each degree. Is it still possible with QPainter?
Try QPainter::setMatrix() or QImage::transform().
wysota
4th May 2006, 20:12
Wouldn't it be enough to transform the painter matrix to do it all?
Hmm... Looks like QMatrix is just 2x2 in size...
Looks like QMatrix is just 2x2 in size...
No, it's 3x3, but the last column is [0;0;1]. Anyway, it will be enough, since you only have to shear and scale the painter (or image).
SkripT
4th May 2006, 23:19
Thanks a lot jacek and wysota for your replies. My question is: so, using QMatrix is enought to do all the rotations/shear/scale that I need applied on the image or the rectangle to simulate the effect that I need? QMatrix seems to work only in 2D and this effect has a 3D component I think....
QMatrix is enought to do all the rotations/shear/scale that I need applied on the image or the rectangle to simulate the effect that I need?
Theoretically, yes. ;)
QMatrix seems to work only in 2D and this effect has a 3D component I think....
Do you have a 3D monitor?
SkripT
5th May 2006, 00:11
Theoretically, yes. ;)
Do you have a 3D monitor?
Not, but now I know what to request for christmas :p .
I will try with QMatrix it and I comment the results ;)
SkripT
5th May 2006, 09:01
Hi again, I've been reading carefully and testing what the docs explains from QMatrix class and I don't know how could I use it to obtain the effect that I want :( . I know that I should call QMatrix::shear and QMatrix::scale in some way because, as the docs says, "...Rotation is achieved by carefully setting both the shearing factors and the scaling factors" but I don't know how :confused:
It's clear that I'm not a math expert... ;) Could you please guide me a little bit in how could I configure the QMatrix to get the respective "transformated" rectangle for each angle rotated? Thanks again.
wysota
5th May 2006, 09:11
Try those:
http://www.inversereality.org/tutorials/graphics programming/3dwmatrices.html
http://gpwiki.org/index.php/3D:Matrix_Math
SkripT
5th May 2006, 09:28
Thanks a lot wysota. Now I know that to rotate from the Y-axis, I have to use the following matrix:
Matrix:
cosa 0 -sina 0
0 1 0 0
sina 0 cosa 0
0 0 0 1
Now the problem is that QMatrix works with 3x3 matrixs :eek: How can I transfrom this matrix in terms of QMatrix?
wysota
5th May 2006, 09:34
Jacek has always been much better at maths (especially matrices) than me, so he'll probably correct me but I think using ( cosa, -sina, sina, cosa) could do the trick. Try it, maybe it works, but you should wait for Jacek's reply anyway.
SkripT
5th May 2006, 09:37
Ok thanks anyway wysota. I think that, as I comented, QMatrix uses only 3x3 matrix because they work in 2D...
wysota
5th May 2006, 09:40
Yes, but you should be able to achieve the same result with a smaller matrix. The equation will just be more complicated (or use more than one QMatrix).
SkripT
5th May 2006, 10:03
Hi again, I attach the code that I use, trying as wysota comments. The problem is that the rotation is done in 2D, so if I try to rotate an image 90º from the Y axis, the result is not a vertical line or even a null image :confused:
#include <QtGui>
#include <math.h>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QImage imatge("../test.jpg");
double radians = 90 * 3.14159265 / 180; //rotation of 90º
imatge = imatge.transformed(QMatrix(cos(radians),-sin(radians),sin(radians),cos(radians),0,0));
imatge.save("../transformated.jpg", "jpg");
return 0;
}
I think that's not as easy as that code :crying:
Let's see... you need a matrix that for given angle a will transform the (0, 0)--(width/2, 0)--(width/2, height)--(0, heigth) rectangle into (0, 0)--(x1-z1, y1+z1)--(x2-z2, y2+z2)--(0, height).
QMatrix works like this:
x' = m11*x + m21*y + dx
y' = m22*y + m12*x + dy
Since we need to map (0,0) to (0,0), dx = dy = 0.
(0, height) must be mapped to (0, height), so:
0 = m11*0 + m21*height + 0
height = m22*height + m12*0 + 0,
thus:
m21 = 0 and m22 = 1.
(width/2, 0) must be mapped to (x1-z1, y1+z1), where x1, y1, z1 are coordinates of a (width/2,0,0) point rotated around Y axis by a degrees, so:
x1 = width/2 cos a
y1 = 0
z1 = -width/2 sin a
x1 - z1 = width/2 ( sin a + cos a )
y1 + z1 = -width/2 sin a
width/2 (sin a + cos a ) = m11 * width/2
-width/2 sin a = 0 + m12* width/2
which gives us: m11 = sin a + cos a and m12 = - sin a
Whole matrix:
/ sin a + cos a - sin a 0 \
| 0 1 0 |
\ 0 0 1 /
SkripT
5th May 2006, 12:01
Wow jacek, you're a machine in maths :) Now it give better results, but the rotation in 90º is not a "slim" image :confused:. Here's the code:
#include <QtGui>
#include <math.h>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QImage imatge("../proba.jpg");
double radians = 90 * 3.14159265 / 180;
imatge = imatge.transformed(QMatrix(sin(radians)+cos(radian s),-sin(radians),0,1,0,0));
imatge.save("../transformada.jpg", "jpg");
return 0;
}
With this you'll get a better result:
/ 0.5 sin a + cos a - 0.5 sin a 0 \
| 0 1 0 |
\ 0 0 1 /
SkripT
5th May 2006, 14:19
Really good example jacek, thanks a lot :)
SkripT
5th May 2006, 15:55
In honor of jacek, look what I have achieved using his code :cool: I've noticed some strange issues:
1) In my computer it goes very slow. I think that's some issue with QPainter....
2) The movement in the right side is not simetric with the left side :confused: . The matrix should work "equally" with both sides, isn't it?
PD: copy the images where the exe file is
PD2: tune the speed with the value passed to QTimer::start
1) In my computer it goes very slow. I think that's some issue with QPainter....
You scale a big image very often --- it must cost. You could try OpenGL or you can record that animation and just replay it.
The movement in the right side is not simetric with the left side :confused: . The matrix should work "equally" with both sides, isn't it?
No it shouldn't, it's because of a simple projection that I used here. If you use a bit more complex one it might look better.
Well SkripT, i have been reading this discussion right from the start...i have a suggestion though, have you tried using OpenGL for achieving the effect you want? it doesn't require much extensive GL knowledge...infact you can use the inbuilt rotate function, put it in a for loop and rotate the image by say 2 degs per loop execution to give you the effect of the moving page!! you as it is know the co-ordinates, just pass them...and opengl will take care of the rest! and ya, it won't slow your system....It'll move as a breeeeeeeeze!!!
;)
Nupul
SkripT
7th May 2006, 18:06
Thanks for the suggestion Nupul. In the beggining, I thought that QPainter was enough to achieve the effect but seems that it's a bit slow :rolleyes: . Next step: OpenGL but that's a new story... ;)
Thanks for the suggestion Nupul. In the beggining, I thought that QPainter was enough to achieve the effect but seems that it's a bit slow :rolleyes: . Next step: OpenGL but that's a new story... ;)
Let's say a new chapter to your story....so you can keep 'flipping the pages' to see your progress :D
SkripT
7th May 2006, 19:15
Let's say a new chapter to your story....so you can keep 'flipping the pages' to see your progress :D
:D good joke Nupul
Powered by vBulletin® Version 4.2.5 Copyright © 2024 vBulletin Solutions Inc. All rights reserved.