Calculating the angle of a point in relation to another
January 12, 2012 02:57PM
So I'm started coding up a simple 3d racing game and I am trying to figure out how to turn.

I have 2 vectors;

float player_position[3] = {0,0,0};
float player_direction[3] = {0,0,1000};

I want to change the player_direction vector by an angle example 60 degrees to the right or left of its current position. Whats the simplest way to calculate the new point in c?



Edited 1 time(s). Last edit at 01/12/2012 05:20PM by owen.
Re: Calculating the angle of a point in relation to another
January 12, 2012 05:13PM
Step 1 - Created a rotated matrix based on the angle.
Step 2 - Multiply the directional vector by the matrix to get the new direction.
Mtx m;
guVector orig_direction = player_direction;
guMtxRotDeg(m, "y", 60); // rotate around y axis by 60 degrees
guVecMultiply(m, &orig_direction, &player_direction);
I only peeked at gu.h for reference, this might not actually work properly.

It might be better if you kept player_direction normalized, then when you use it to update player_position you can scale by the current velocity * time.
Re: Calculating the angle of a point in relation to another
January 12, 2012 05:46PM
the guVector is basically a float[3]. I haven't thought about momentum or velocity as yet. I could keep the direction normalized but it would mean having to mess around with the Mtx functions.

Why are you doing; orig_direction = player_direction? The way I planned is to have the player_direction change relative to the player_position. As in the player_direction is a point rotated around the player_position (center) by 60 degrees.
Re: Calculating the angle of a point in relation to another
January 12, 2012 06:23PM
If you wanna do the calculations manually the easiest way is using two easy formulaes. I suppose the vector rotates on the Y axis.

z' = z*cos(angle)-x*sin(angle)

x' = z*sin(angle)+x*cos(angle)

Please take in account that sin and cos functions works in radians. Due to it you have to use DegToRad function.
Re: Calculating the angle of a point in relation to another
January 12, 2012 06:50PM
@wilco2009 I convert the degrees to rads. Yes the vector rotates on the Y axis but I don't understand your formula. Is it the same thing as doing;

angle=DegToRad(60);
player_direction.y = player_direction.y;
player_direction.z' = player_position.z*cos(angle)-player_position.x*sin(angle);
player_direction.x' = player_position.z*sin(angle)+player_position.x*cos(angle);
Re: Calculating the angle of a point in relation to another
January 12, 2012 06:51PM
Quote
owen
the guVector is basically a float[3]. I haven't thought about momentum or velocity as yet. I could keep the direction normalized but it would mean having to mess around with the Mtx functions.
You had player_direction.z set to 1000, I thought that implied the velocity.
Vectors and matrices go hand in hand, especially since libogc has special asm functions to manipulate them using paired single instructions. Doing things manually (like wilco2009's example above) will be slower.
Quote

Why are you doing; orig_direction = player_direction? The way I planned is to have the player_direction change relative to the player_position. As in the player_direction is a point rotated around the player_position (center) by 60 degrees.
guVecMultiply expects different arguments for the source (IN) and destination (OUT) vectors so it gets copied to a temp vector.
Using a vector to represent a point is a bit strange. You can't rotate around a point, only around a vector/axis. To do what you want to do you'd have to subtract player_position from player_direction (so player_direction was based around 0,0,0), rotate it then translate back to player_position.
Re: Calculating the angle of a point in relation to another
January 12, 2012 07:02PM
@tueidj sorry about that player_direction is a point in space which the player position is constantly moving towards. yeah its very "hackish" but its the only way I know how to do it now. I'm not on competent with the matrix programming as yet. Unless you have some simple functions that I can drop into my code without forcing me to enter the matrix revolution.
Re: Calculating the angle of a point in relation to another
January 12, 2012 08:36PM
@owen - As tueidj says, to rotate a position point has not sense. The rotation have to be applied to the direction vector, and then to increment position vector based on the direction vector.

angle=DegToRad(60);
player_direction.y = player_direction.y;
player_direction.z = player_direction.z*cos(angle)-player_direction.x*sin(angle);
player_direction.x = player_direction.z*sin(angle)+player_direction.x*cos(angle);

when you move your position you can use direction vector to increment it:

player.position.x += player.direction.x;
player.position.y += player.direction.y;
player.position.z += player.direction.z;

As tueidj says, matrix calculation is much faster because you uses the graphic coprocessor to do it, but probabily manual calculation is more easy and comprensible to you.
Re: Calculating the angle of a point in relation to another
January 12, 2012 10:08PM
@wilco2009 At the moment when I turn I do not move the position vector. I simply want to move the direction vector to another location which is a few degrees to the right or left on the perimeter surrounding the player_position. I think its more of a 2 dimensional rotation but I don't know a simple way to calculate the new point.



Edited 1 time(s). Last edit at 01/12/2012 10:21PM by owen.
Re: Calculating the angle of a point in relation to another
January 12, 2012 10:32PM
OK, If I understand you have a player postion (camera vector) and you need to calculate the lookat vector. Isn't it?

If it is correct the process is the following:

- You need to keep the direction vector as an unitary vector. For instance you can start looking at front (0,0,1)
- If you want to rotate the view direction you have to turn the direction vector a certain angle:
angle=DegToRad(60);
player_direction.y = player_direction.y;
player_direction.z = player_direction.z*cos(angle)-player_direction.x*sin(angle);
player_direction.x = player_direction.z*sin(angle)+player_direction.x*cos(angle);
- Then you have to calculate the lookup vector combining the position vector and the direction vector, and using a distance value to look more far.
lookup.x = player_direction.x*distance + player_position.x;
lookup.y = player_direction.y*distance + player_position.y;
lookup.z = player_direction.z*distance + player_position.z;
- Finally you can use GRRLIB_Camera3dSettings to setup the view:
GRRLIB_Camera3dSettings (player_position.x, player_position.y, player_position.z, 0, 1, 0, lookup.x, lookup.y, lookup.z);
Re: Calculating the angle of a point in relation to another
January 12, 2012 10:55PM
@wilco2009 yeah its basically a look at vector for the player. I will try the code you posted and see what happens. thanx.
Re: Calculating the angle of a point in relation to another
January 13, 2012 03:09AM
@tueidj you mtx transformation seems to be rotating around itself and I don't know how to merge the player position into the equation.

@wilco2009 doesn't really work. It produces the same point everytime an angle is passed to the function. And if I try to increase the angle from 30 to 360 it rotates around player position in a figure 8.
Re: Calculating the angle of a point in relation to another
January 13, 2012 08:55AM
To combine the tueidj's ecuation with the position vector you have to use player_position as origin of coordinates before to rotate "player_direction".
Due to it you have to move player_direction in the following way:

player_direction' = player_direction - player_position.

then rotate and then move again in oposite direction:

player_direction'' = player_direction' + player_position.

In matrix operations you can use MtxApplyTrans to move the vector.

Mtx m,m1;
guVector orig_direction = player_direction;
guMtxIdentity(m);
guMtxApplyTrans (&m, &m1, -player_position.x, -player_position.y, -player_position.z)
guMtxRotDeg(m1, "y", 60); // rotate around y axis by 60 degrees
guMtxApplyTrans (&m1, &m, player_position.x, player_position.y, player_position.z)
guVecMultiply(m, &orig_direction, &player_direction);

By other hand, I'll check my "manual" previous code in the Wii, because I don't know why doestn't work properly.



Edited 4 time(s). Last edit at 01/13/2012 01:21PM by wilco2009.
Re: Calculating the angle of a point in relation to another
January 13, 2012 05:32PM
@wilco2009 this version works as expected but it only works if player_position is (0,0,0). If I change the player position the player_direction flies off in one direction. I really don't know why. The player_direction should be rotating around the center point ( player_position ) no matter where it is located.

here is the function so far;

guVector rotate_to_angle( float angle, guVector player_direction, guVector player_position ) {
	guVector lookup;
	float distance=1000;  
	angle=DegToRad(angle);

	Mtx m,m1;
	guVector orig_direction = player_direction;
	guMtxIdentity(m);
	guMtxApplyTrans (&m, &m1, -player_position.x, -player_position.y, -player_position.z);
	guMtxRotDeg(m1, 'y', angle); // rotate around y axis by 60 degrees
	guMtxApplyTrans (&m1, &m, player_position.x, player_position.y, player_position.z);
	guVecMultiply(m, &orig_direction, &player_direction);

	return player_direction;
}



Edited 1 time(s). Last edit at 01/13/2012 05:39PM by owen.
Re: Calculating the angle of a point in relation to another
January 13, 2012 08:37PM
guMtxRotDeg doesn't modify a matrix, it creates a new one. It will need to be concat'd with m1 before applying the second translation (I can't paste code atm, hopefully wilco2009 will sort it out...)
Re: Calculating the angle of a point in relation to another
January 13, 2012 08:48PM
Bellow you can find a tested code:

	Mtx m,om;
	guMtxIdentity(m);
	guMtxApplyTrans (m, m, -player_position.x, -player_position.y, -player_position.z);
    guMtxConcat(m, om, om);

	guMtxRotDeg(m, 'y', angle); // rotate around y axis by 60 degrees
	guVecMultiply(m, &orig_direction, &player_direction);
    guMtxConcat(m, om, om);

	guMtxIdentity(m);
	guMtxApplyTrans (m, m, player_position.x, player_position.y, player_position.z);
    guMtxConcat(m, om, om);

In my previous post I've some errors.
1. you have to use the array directly as parameter (without "&")
2 To combine translation and rotation I have to concatenate both matrix

Please, check it now.

NOTE: If you wanna move the player in the view direction you can calculate the diference between player_direction and player_position and normalize the result. Then you can increment your player_position by a fraction of the result vector.



Edited 4 time(s). Last edit at 01/13/2012 09:07PM by wilco2009.
Re: Calculating the angle of a point in relation to another
January 13, 2012 09:10PM
Thank you, I will test it in 1 hour when I get home.
Re: Calculating the angle of a point in relation to another
January 13, 2012 11:18PM
@wilco2009 the player_direction is now rotating around (0,0,0) and the player position has no effect on it. :(
Re: Calculating the angle of a point in relation to another
January 14, 2012 12:50PM
Sorry again. I solved another little bug. guVecMultiply have to be used at the end to apply the matrix result:

Mtx m,om;
guMtxIdentity(m);
guMtxApplyTrans (m, om, -player_position.x, -player_position.y, -player_position.z);

guMtxRotDeg(m, 'y', angle); // rotate around y axis by 60 degrees
guMtxConcat(m, om, om);

guMtxIdentity(m);
guMtxApplyTrans (m, m, player_position.x, player_position.y, player_position.z);
guMtxConcat(m, om, om);

guVecMultiply(om, &orig_direction, &player_direction);

GRRLIB_Camera3dSettings(player_position.x,player_position.y,player_position.z, 0,1,0, player_direction.x,player_direction.y,player_direction.z);

By other hand, as I tell you in a previous post, you can move your point of view with the following code:

guVecSub(&player_direction,&player_position,&normdir);
guVecNormalize(&normdir);
guVecScale(&normdir, &stepdir, 0.1);

if(WPAD_ButtonsHeld(0) & WPAD_BUTTON_UP) guVecAdd(&player_position, &stepdir, &player_position);
if(WPAD_ButtonsHeld(0) & WPAD_BUTTON_DOWN) guVecSub(&player_position, &stepdir, &player_position);

You can find a complete example download this: [www.megaupload.com]



Edited 2 time(s). Last edit at 01/14/2012 01:05PM by wilco2009.
Re: Calculating the angle of a point in relation to another
January 14, 2012 04:18PM
@wilco2009 Ahha! It works now, surprisingly and confusingly well. Thanx for your help. This matrix stuff is like magic. I had already had a way to move my point of view but your matrix version has less lines of code.
I know I will have problems when I try to add the other stuff like momentum, gravity and the wheels of the car but I am worrying about those things as yet. I will probably use it to make a car game where you knock down cones in a parking lot (like this; [www.youtube.com] ).


if( button_left_held || button_2_held ) {
	guVecAdd(&player_position, &stepdir, &player_position);
	guVecAdd(&player_direction, &stepdir, &player_direction);	//i am moving the direction away from the position so they never meet
}

if( button_right_held || button_1_held ) {
	guVecSub(&player_position, &stepdir, &player_position);
	guVecSub(&player_direction, &stepdir, &player_direction);
}


if( button_up_held || button_down_held) {
	guVector np;
	
	angle=100;
	if( button_down_held ) angle=-100;
	
	np = rotate_to_angle( angle, (guVector){player_direction[0], player_direction[1], player_direction[2]}, (guVector){player_position[0], player_position[1], player_position[2]} );  //function wilco's matrix code
	player_direction[0]=np.x;
	player_direction[1]=np.y; player_direction[2]=np.z;
	
		
	guVecSub(&player_direction,&player_position,&normdir);
	guVecNormalize(&normdir);
	guVecScale(&normdir, &stepdir, 10);
	
	//angle+=10;
	//if(angle >= 360) angle=1;
}



Edited 1 time(s). Last edit at 01/14/2012 04:19PM by owen.
Sorry, only registered users may post in this forum.

Click here to login