Jump to content
  • Advertisement
Sign in to follow this  
jonzy_x86

Translate V Cos/Sin on X/Y Plane

This topic is 3627 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi, This is one of my first posts on this board, it's with regards to OpenGL, but could be applied to DirectX too so I am writing it here... I am developing a 3D game with a point and click interface (similar to that of Populous or Command Conquer). So in my 3D world my camera is looking down the Z axis, at the ground. The units are viewed from above, the X axis moves units east and west and the Y axis moves units north and south. Now, my question is about translation. Consider this... Unit 1 is at location 0,0,0. Without using any opengl translations, I move this unit along the X axis some arbitrary value with the cos() function, and also along the Y axis with the sin() function. The precise sin and cos values are not important right now, let's say the unit is 10.0 units south east of 0,0 on the X,Y plane. This is all good, but now consider using OpenGL rotates and translation. Unit 2 is at 0,0,0 and I rotate by 45o clockwise, then translate along the X axis 10.0 units, my unit 2 is now in the same place as Unit 1, *however*, the X and Y values of Unit 1 and 2 are different. Is there any way to calculate the X/Y location using the OpenGL rotate and translate method? Any help would be much appreciated. Thanks Paul

Share this post


Link to post
Share on other sites
Advertisement
I'm a little confused so sorry if I'm not of much help. My understanding is that both objects are in the same position on screen but with different X, and Y values. I assume this is unexpected behavior and you are trying to figure out a way to calculate X and Y such that Unit 2's X and Y values are equivalent to Unit 1.

If this is the case, I'm guessing the actual problem is that you're multiplying scale, rotations, and translations in the incorrect order in openGL. Scale * rotate * translate != translate * rotate * scale. Unfortunately, I forget the correct order in openGL but I'm sure a quick google search can help you. I also wouldn't be surprised if openGL has a function call that will produce the matrix you are looking for without creating the individual matrices and multiplying them.

I assume there is no direct need to retrieve position from openGL because you will be storing that information in the object itself.

I also question why you talk about moving along the X axis using a cos() function. Are you calculating x position using r * cos( theta ) and y by r * sin( theta )? If so, why?

Hope I'm not completely off base.

Share this post


Link to post
Share on other sites
Hi Peter,

Thanks for the reply. I'll try to explain it again as it was late last night :)

The x/y values of the object are stored in a struct...

struct Object
{
float fX;
float fY;
flaot fZ; // Not used here
};

If all value are at 0,0,0 and ignoring the sin/cos values. If I move the unit east along the x-axis and south along the y-axis, it is south-east of the origin. Let's say it is 10 units away at this point and x is something like 7.5 and y maybe -7.5.

All good - Object1.x = 7.5 Object1.y = -7.5

But, with a second object at the origin, using opengl...

Object2.x = 10.0f; // (or maybe 7.5 - not sure)
glLoadIdentity();
glRotatef(45.0f,0.0f,0.0f,1.0f); // Rotate clockwise
glTranslatef(Object2.x,0.0f,0.0f); // Object now at southeast of origin
Done();

Now, object2.y = 0 but both objects are (roughly) in the same place on the screen.

Thanks

Share this post


Link to post
Share on other sites
Revert the order of rotation and translation, like so:

Object2.x = 10.0f; // (or maybe 7.5 - not sure)
glLoadIdentity();
glTranslatef(Object2.x,0.0f,0.0f); // Object now at southeast of origin
glRotatef(45.0f,0.0f,0.0f,1.0f); // Rotate clockwise
Done();


Remember that, with the above order, the object is rotated into a 45° orientation, and then translated to a new position. With your original order, the object is translated to a new position and then rotated. But, due to being far from the origin (and the rotation ever happens around the origin 0), the rotation also changes the position.

Share this post


Link to post
Share on other sites
Heagarr,

Thanks for correcting the code, but I think my point is being missed.

The problem is still that even though both objects are at the same position (on the screen co-ordinates), only Object 1 has a value of both x and y at the end of the movement, whereas Object2 only has an x value.

It's probably trivial, the only reason I want to know is because I need to track all objects positions from the origin and this won't be possible using method 2.

Share this post


Link to post
Share on other sites
With this set-up

Object2.x = 10.0f; // (or maybe 7.5 - not sure)
glLoadIdentity();
glRotatef(45.0f,0.0f,0.0f,1.0f); // Rotate clockwise
glTranslatef(Object2.x,0.0f,0.0f); // Object now at southeast of origin
Done();




the object will be placed approx. at x=7 and y=7, because
x := 10 * cos( 45° ) - 0 * sin( 45° )
y := 10 * sin( 45° ) + 0 * cos( 45° )

OpenGL (a) rotates counterclockwise, and (b) the later transformation is applied to the object in a more local manner. That means that the above transformation first translates the object to (10,0) and then rotates around (0,0) by 45° counterclockwise. Hence the above code does not match what you describe in the OP, neither works it like expected here
Quote:
Unit 2 is at 0,0,0 and I rotate by 45o clockwise, then translate along the X axis 10.0 units

nor here
Quote:
my unit 2 is now in the same place as Unit 1

(because object 1 is assumed to be at (7.5,-7.5) and not (7,7)). Well, at least if I've done it right...


Just a moment: Perhaps you expect OpenGL to alter the 2nd Object structure? No, it doesn't. The glTranslate and glRotate and so on are temporary and affect the geometry only for rendering. You have to store and compute the movement of the objects yourself, and then to set-up OpenGL's render transformation each frame accordingly to the current self stored data.


If this still doesn't match your problem, please consider to give us more details.

Share this post


Link to post
Share on other sites
Ahh, you want to find the values of x and y after the transform. What you do is multiply the transform matrix with a position vector (or is it the other way around?) and get a vector with the resulting position.

Final position = (Transformation matrix) x (original position)

I'm not sure OpenGL has built-in functionality for this (DX does, at least D3DX), otherwise you might want to use some form of math library to do this or just google for some optimized sample code.

Share this post


Link to post
Share on other sites
Haegar I believe is hitting the nail on the head for the problem you are experiencing.

In a perfect world, you want all rotations of your object to occur around it's center of mass and all translations to occur in the world coordinate system and not your local coordinate system. I believe you are describing either a problem of translating along your local coordinate system or rotating around a point that is not your object's center of mass.

See this picture for examples:



In the top example, you rotate the box and begin moving along it's X axis which is rotated to no longer be aligned with the world. In the second case you translate your object but then are still rotating around the origin of the world so your object will actually be rotating along the circle that I drew. I believe case #2 is what you are experiencing.

In effect, what you are seeing is incorrect graphics behavior and your objects should not actually be in the same position. If an object has a Y value of 0 it should be along the X axis of the world, never in the same position as an object that has a position of X = 7.5, Y = 7.5

Share this post


Link to post
Share on other sites
Quote:
Original post by DvDmanDT
Ahh, you want to find the values of x and y after the transform. What you do is multiply the transform matrix with a position vector (or is it the other way around?) and get a vector with the resulting position.


Yes!!! That's it!

Quote:
Final position = (Transformation matrix) x (original position)

I'm not sure OpenGL has built-in functionality for this (DX does, at least D3DX), otherwise you might want to use some form of math library to do this or just google for some optimized sample code.


Hmmm... Transform matrix * original position when original position is 0,0,0 will result in a zero matrix. But I think that you may be onto something there.

I don't think there is an OpenGL function as you say, but there must be a mathematical solution to it.

Share this post


Link to post
Share on other sites
Hmm. I still question why you need to get screen coordinates from openGL. Is this for picking? Collision detection?
Quote:
Original post by jonzy_x86
Hmmm... Transform matrix * original position when original position is 0,0,0 will result in a zero matrix.
This is incorrect in most cases. Your transform matrix is going to be a 4x4 matrix whereas your original position will be a 4x1 or 1x4 matrix equivalent to (0,0,0,1) in your example. Your result will be a 4x1 or 1x4 matrix with values (X,Y,Z,1) if everything worked out correctly.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!