Advertisement

Rotation

Started by December 19, 2002 11:30 AM
8 comments, last by Greg K 22 years, 2 months ago
I want to rotate a point around another point. The point I am rotating is target, and the point I am rotating around is pos. Here is the code I am using.

rotate( float zRot, float yRot)
{
	float dist;
	
	// Get the vector
	target.x -= pos.x;
	target.y -= pos.y;
	target.z -= pos.z;

	// Get the distance
	dist = sqrt(target.x * target.x + target.y * target.y + target.z * target.z);

    zRot += atan (target.x/target.y);
	yRot += acos (target.z/dist);
	
	if( zRot > (2*D3DX_PI) ) zRot -= (2*D3DX_PI);
	if( yRot > (2*D3DX_PI) ) yRot -= (2*D3DX_PI);

	if( zRot < 0.0f ) zRot += (2*D3DX_PI);
	if( yRot < 0.0f ) yRot += (2*D3DX_PI);
	
	target.x = sin(yRot)*cos(zRot)*dist + pos.x;
    target.y = sin(yRot)*sin(zRot)*dist + pos.y;
    target.z = cos(yRot)*dist + pos.z;

}
 
Needless to say that something is wrong with it. The problem is, I don''t know what. The program runs and the Z component seems to be fine but the x/y jumps all over the place. -Greg Koreman
Well, first use atan2 to get the angle in the right quadrant or do it manually. The domain of atan is (-pi/2,pi/2). The domain of atan2 is [0, 2pi). Second use a transform matrix You z and y rotation seems to be around the origin, not the point being rotated around, i.e. sqrt(t.t) should be sqrt((t-p).(t-p)) where t is target and p is pos. You need spherical coordinates relative to pos, not the origin. The conversion back to rectangular coordinates looks correct as near as I can tell.

Without using linear algebra you will quickly get buried in the math in 3D. Linear algebra, matrices, lets you deal with it at a much higher level. Basically one variable, matrix, represents an entire series of rotations about various axes, translations and scaling. It is possible, but not practical without it.
Keys to success: Ability, ambition and opportunity.
Advertisement
Um, make that range, or is it domain, no it''s range. Oh, geez, I get so confused over some simple subjects sometimes
Keys to success: Ability, ambition and opportunity.
Domain is the possible set of input values for a function. The domain of sqrt(x) over the reals is x >= 0. The range of the function is the possible output values of the function. Range of sinx = [-1,1] over the reals, sqrt(x) = [0, infinity), etc. For the arctan function, it has an infinite domain and finite range of (-pi/2, pi/2) over the reals. Note that to actually get the values of +-pi/2, you need to take the limits as x approaches +-infinity.

Brendan
Brendan"Mathematics is the Queen of the Sciences, and Arithmetic the Queen of Mathematics" -Gauss
Ok, I decided to use matrices and the D3DX functions. This is where it got me.


  D3DXMATRIX mat;D3DXMatrixRotationYawPitchRoll(&mat, yaw, pitch, 0);D3DXVec3Subtract(⌖, ⌖, &pos);D3DXVec3TransformCoord( ⌖, ⌖, &mat);D3DXVec3Add(⌖, ⌖, &pos);  


Unfortunatly this doesn''t work. Does anyone know why? (yaw and pitch are floats sent in to the function)
-Greg

target.x = sin(yRot)*cos(zRot)*dist + pos.x;
target.y = sin(yRot)*sin(zRot)*dist + pos.y;
target.z = cos(yRot)*dist + pos.z;


what you''re doing here is not rotating target but the point (0,0,1) first around the y axis and then around the z axis, then scaling the result to the length of the distance between target and pos, and translating it to pos....
everything is O.K. except that you rotate (0,0,1) instead of (target - pos) (and no scaling is necessary then).
I''d suggest computing matrices for z and y rotation:
z:
cos(zRot) sin(zRot) 0
-sin(zRot) cos(zRot) 0
0 0 1

y:
cos(yRot) 0 sin(yRot)
0 1 0
-sin(yRot) 0 cos(yRot)

and multiplying them... you''d get something like this:


target.x = cos(yRot)*cos(zRot)*target.x + sin(zRot)*target.y + sin(yRot)*cos(zRot)*target.z + pos.x;
target.y = -cos(yRot)*sin(zRot)*target.x + cos(zRot)*target.y - sin(yRot)*sin(zRot)*target.z + pos.y;
target.z = -sin(yRot)*target.x + cos(yRot))*target.z + pos.z;



GA
Visit our homepage: www.rarebyte.de.stGA
Advertisement
I have my doubts that you can use the same variable as two differant parameters. I think you might get by with:


  D3DXMATRIX mat;D3DXMatrixIdentity(&mat);D3DXMatrixTranslation(&mat, -pos.x, -pos.y, -pos.z);D3DXMatrixRotationYawRollPitch(&mat, yaw, roll, 0);D3DXMatrixTranslation(&mat, pos.x, pos.y, pos.z);Dd3DVec3TransformCoord(&result, ⌖, &mat);  


That would certainly make the functions handy, but I don''t know that it actually works. The documentation is rather abbreviated. About the only guidance is that the matrix parameter is [in/out], but it says that for the identity matrix. So what does that mean? That it returns any matrix passed in? You may have to create each of the matrices and use D3DXMatrixMultiply which will make it a real pain in the ass. Since D3DXMatrixMultiply takes three parameters instead of two I don''t have a lot of faith that it isn''t a real pain. The only suggestion I could make is to create your own functions that copies the matrix, creates the transform and multiplies the two matrices returning the result in the original matrix. It seems incredible that there would not be functions to do that so I really have trouble believing those functions don''t already do that.
Keys to success: Ability, ambition and opportunity.
i forgot something... to store the target vector temporarily...:


ttarget = target;

target.x = cos(yRot)*cos(zRot)*ttarget.x + sin(zRot)*ttarget.y + sin(yRot)*cos(zRot)*ttarget.z + pos.x;
target.y = -cos(yRot)*sin(zRot)*ttarget.x + cos(zRot)*ttarget.y - sin(yRot)*sin(zRot)*ttarget.z + pos.y;
target.z = -sin(yRot)*ttarget.x + cos(yRot))*ttarget.z + pos.z;
Visit our homepage: www.rarebyte.de.stGA
I am not sure what do you want. How can rotate a point around another point? You can rotate a point around a vector. But if you want to rotate a point around a point, there are many possibilities. Because there is a plane in which every line passes the point (pos) match the requirement. Can you give more detailed information.

Kidd
I was rotating a point around another point which I made into the origin. I have two angles, one for Z rotation and one for elevation. I think I figured out how to do it though.
-Greg

This topic is closed to new replies.

Advertisement