.NET Forum / Languages / Managed C++ / November 2005
Graphic transforms
|
|
Thread rating:  |
Peter Oliphant - 24 Oct 2005 22:39 GMT I'm working with Graphics transforms (i.e., RotateTranform, TranslateTransform and ScaleTransform ). Are these applied to the WORLD (graphics container) before drawing into that world (graphics container)? That is, if I apply a Rotation of 90 degrees clockwise then the old x-axis is now the new y-axis and the old y-axis is now the new x-axis (sign-reversed due to the fact that the y-axis of a screen increases the lower on the display).
I ask because I couldn't figure out what the 'rotation point' for each object I draw, then it occured to me I'm probably rotating-translating-scaling the world instead. If I'm correct, doubling the x-scale will HALVE the x-dimensions of the graphic objects being drawn. This is in contrast to the scale transform being applied to the object itself, which would result in it doubling the object in x-size...
Thus, if tranforms are applied to the world (graphics container), I should apply the reverse operations I want to have as an affect of the object (e.g., translate in the opposite direction, lower scale to increase object size, rotate counterclockwise to rotate object clockwise, etc.)...
Have I got this right? : )
[==P==]
Olaf Baeyens - 25 Oct 2005 13:27 GMT > I'm working with Graphics transforms (i.e., RotateTranform, > TranslateTransform and ScaleTransform ). Are these applied to the WORLD [quoted text clipped - 3 lines] > (sign-reversed due to the fact that the y-axis of a screen increases the > lower on the display). I have the impression that it is the first time you work with this type of functionality. Did you ever program in DirectX or OpenGL? If not, then you have a steep learning curve to understand this all.
(This based on my OpenGL adventures)
First of all, check out "affine space" in google, that is a good starting point.
Second you must understand that every translate and rotate will create a new coordinate system relative towards the previous one. Also understand that a rotate and then a translate will have a different result compared to a translate first and then rotate.
Technically, you could say that your camera is alway in coordinate 0,0,0 and a rotation of 0,0,0. so your Y will be always right and the Y always up when you give draw commands. This is because you are working in local coordinates. And when you finally have drawn you scene then the camera rotation and translation will shift your scene away from the camera giving the impression that there is a camera.
Now, it is up to choose what coordinate system you want to use, first rotate then translate or first translate and then rotate. Whatever you do, stick to it for all objects you wish to paint. Do not mix it or you will get grey hair as I got it. ;-)
Another thing that you must separate, you will have multiple matrixes, that you can set to the identify matrix. One for the model view and one for the projection view. The projection view is for warping the scene like perspective but not used for camera movement. So camera movement must be done on the model matrix, not projection matrix (I got confused in this one). The same for lights, use the model view matrix.
If you want to work only in absolute coordinates, then always initialize the model matrix to the identify before applying EVERY the translate-rotate. If you want to use relative coordinates, then set the identify matrix BEFORE you start the sequence of rotate-translate-rotate-translate sequence. It is you choice what system you want to use.
Note: it is maybe a steep learning curve but it is worth putting the energy into it. :-) The good news is, if you work in 2D, then it is simple, but once you start in 3D then the rotation migth give you a lot of headaches.
Good luck.
Peter Oliphant - 25 Oct 2005 16:50 GMT Actually, I know this stuuf pretty well (I've been a game designer/programmer for over 3 decades). But conventions can change, and I was just interested in 'what' was being transformed and how the transforms 'responded' to parameters. It would be perfectly reasonable to have transforms applied to the object in contrast to the world, but both paradigm work. Now I know its the 'transform world' paradigm in this case.
I'm somewhat familiar with how to manipulate a graphic object: you translate it to (0,0), scale and rotate(the order here doesn't matter IF scale is consistent in both x and y directions), and then translate, followed by the final inverse translation from (0,0) (the last two translation order also doesn't matter). And in fact I already have my code working in this regard.
And, while writing code, I found out the convention is a little 'mixed'. While rotate and translate do work as inverses from the pov of the object (e.g., if you want to move the object in a direction move the world in the opposite direction), I was surprised to find out that 'scale' is odd, in that to double the object size you double the scale of the world.
It works now, so thanks! : )
[==P==]
>> I'm working with Graphics transforms (i.e., RotateTranform, >> TranslateTransform and ScaleTransform ). Are these applied to the WORLD [quoted text clipped - 63 lines] > > Good luck. Olaf Baeyens - 26 Oct 2005 08:38 GMT > Actually, I know this stuuf pretty well (I've been a game > designer/programmer for over 3 decades). Oops my mistake, now I know somone that I can ask question to when I have this probem. :-)
> And, while writing code, I found out the convention is a little 'mixed'. > While rotate and translate do work as inverses from the pov of the object > (e.g., if you want to move the object in a direction move the world in the > opposite direction), I was surprised to find out that 'scale' is odd, in > that to double the object size you double the scale of the world. You mean you double the local scale so your object gets drawn 2 times as much? It is hard to imagine that the rest of the world suddenly doubles too.
Of course if you scale up by 2, then your camera movement will also scaled with 2. So somehow you must push the model matrix before the scale of the object on the stack and pop it back again for the camera translation. Or am I missing something here?
Now I am very curious. :-)
Peter Oliphant - 26 Oct 2005 16:46 GMT > Of course if you scale up by 2, then your camera movement will also scaled > with 2. [quoted text clipped - 4 lines] > > Now I am very curious. :-) This is the idea. One thinks of rotation as happening 'naturally' about a certain point of an object. For example, one thinks of rotating a square about its center point. Lets call this the rotation point of an object, and measure it as relative to the upper left hand corner of the smallest rectangel that can contain it (i.e., relative to what the .NET Framework thinks is its Left and Top points), and call this [rotate_dx, rotate_dy].
Similarly, if one is scaling in an x of y direction separately, one thinks of this as happening when the object is in a certain 'rotational orientation'. For example, we think of a square 'naturally' as its sides being parallel to the x-axis and y-axis.
Thus, the first thing to do is to decide what the natural orientation for an object is, and build it this way as your model. Then pick a rotation point for it.
Ok, here we go. Say the object is to be placed at location (x,y) with rotation r and scale_x and scale_y. First perform a translation of the object so its rotation point is at (0,0). That is, move the world (-x,-y) and then (-rotate_dx, -rotate_dy). We'll call this translate transform T = (-x-rotate_x, -y-rotate_dy).
Now, as far as other transforms are concerned, the object is located at the world origin. Now we must scale before we rotate, since we can scale independently on both x and y directions, and our model is the correct orientation. So we now apply scaling.
We can now apply rotate since scaling does not move the rotation point (thats why we put it at world (0,0) since multiplying by anything still results in (0,0)).
We can now move the object back to its original position, so we applt the INVERSE of what we defined before as T. Thus, we translate by ( x+rotate_x, y+rotate_y ). Note that since this is done after the scaling the camera position is NOT scaled along with the object!!! Finally, we can apply any additional translation in order to move the object from last position.
Thus the full transform function is as follows:
transform = T(-x-rotate_dx,-y-rotate_dy) S(scale_x,scale_y) R(r) T(x+rotate_dx, y+rotate_dy) T(dx, Tdy)
applied from left to right, with:
T = translate R = rotate S = scale
And there you have it! The trick is moving it to the wrod origin before scaling and rotating to ease the computations, and to scale before rotating since scaling can be performed on two axes.
Is that what you were asking? : )
[==P==]
>> Actually, I know this stuuf pretty well (I've been a game >> designer/programmer for over 3 decades). [quoted text clipped - 21 lines] > > Now I am very curious. :-) Olaf Baeyens - 27 Oct 2005 11:18 GMT > This is the idea. One thinks of rotation as happening 'naturally' about a > certain point of an object...... [quoted text clipped - 15 lines] > > Is that what you were asking? : ) I believe you just killed the newsgroup with this quantum mechanics like explanation. :-) A lot of people here will need counseling here I guess. :-)
But you are right in your explanation.
But you forget that every object has another rotation called orientation. ;-) First is the rotation and translation regarding of your parent starting coordinate. Second the orientation rotation on it's own axis (assuming that you do not have an offset)
I am happy that GDI+ has DirectX and OpenGL like transforming functionality. I missed that in GDI a lot.
I noticed that in the Windows vista they have created a very simple DirectX engine usable in .NET, so I guess that 3D visualization will become much more easy to implement. But nevertheless, translation/rotation/scaling is confusing for any newbie trying it.
Peter Oliphant - 02 Nov 2005 19:17 GMT I found out (the hard way) that my explanation was too simplified. I now am aware it's a bit more complex than I previously thought.
For example. Translation. If you translate before you rotate then the rotation is not about the desired rotation point. Further, one should scale before rotating since scaling is on two different axis, and if rotation is applied first then scaling the x-axis will be in the direction of the ROTATED x-axis.
So. one must apply scale, then rotate, then translation. Before these operations the object's rotation point must be translated to the origin (so that rotation is, indeed, about this point), and after all is done translated back the reverse vector that moved it to the origin.
Now, since translation must happen after both rotation and scaling, to translate with respect to the original (screen) coordinate system the translation must be adjusted accordingly. Thus, it must be rotated and scaled as such:
adjusted_trans_x = ((trans_x * cos) - (trans_y * sin)) / scale_x adjusted_trans_y = ((trans_y * cos) + (trans_x * sin)) / scale_y
Sooooo, one must 'bite the bullet' with respect to translation, which is ironic since without rotation and scaling translation is typically the most computationally simple, but with it the most computationally complex! : )
[==P==]
>> This is the idea. One thinks of rotation as happening 'naturally' about a >> certain point of an object...... [quoted text clipped - 40 lines] > But nevertheless, translation/rotation/scaling is confusing for any newbie > trying it.
Free MagazinesGet these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...
|
|
|