Welcome! Log In Create A New Profile

Advanced

Calculating the angle of a point in relation to another

Posted by owen 
Re: Calculating the angle of a point in relation to another
February 01, 2012 10:32PM
I can't test it until I get home in the next 2 hours but this is what I have written out so far;
	guVector a, b;
	float theta_x, theta_y, theta_z;
	float dot=0;

	a = (0,0,-1);
	b = player_direction;

	b.y=0; //we doing y

	dot=guVecDotProduct( &a, &b );

	theta_y=acos( dot  / ( sqrt(a.x+a.y+a.z) * sqrt(b.x+b.y+b.z) ) ) *  57.2957795;

	//repeat about for x, z

	GRRLIB_ObjectViewRotate( theta_x, theta_y, theta_z );  //do rotation
Re: Calculating the angle of a point in relation to another
February 02, 2012 12:18PM
Owen, for some extra reference see, GameLogic.cpp under void GameLogic::GunTurretLogic() .. look for comment // Get Direction Vector for the Turret

My lock on stuff looks very close to what your doing above (but keep in mind my maths is very poor so use it as a helper)
Re: Calculating the angle of a point in relation to another
February 02, 2012 03:28PM
Tried it but the wii doesn't seem to like this line of code at all
theta_y=acos( dot  / ( sqrt(a.x+a.y+a.z) * sqrt(b.x+b.y+b.z) ) ) *  57.2957795;
I think its generating so kinda weird number that crashs anything I pass it to :( plus weird graphical artifacts show up on the screen. I'm not sure whats wrong with it.

@titmouse I tried some the roll pitch think that you are doing but doesn't work in 3d. Plus you are manipulating you own matrixs while I am using GRRLIB which accepts degrees instead of radians. I just need a general purpose function that works in 3d and gives me the degree angles that I need to rotate.

here is the code (not working, has some kinda overflow bug)
		guVector a= { 0.0f,0.0f,-1.0f}, b;
		float theta_x=0.0f, theta_y=0.0f, theta_z=0.0f;
		float dot=0.0f;

		b = player_direction;
		b.x=0.0f; //we doing y
		dot=guVecDotProduct( &a, &b );
		theta_x=acos( dot  / ( sqrt(a.x+a.y+a.z) * sqrt(b.x+b.y+b.z) ) ) ;

		b = player_direction;
		b.y=0.0f; //we doing y
		dot=guVecDotProduct( &a, &b );
		theta_y=acos( dot  / ( sqrt(a.x+a.y+a.z) * sqrt(b.x+b.y+b.z) ) ) ;
		
		b = player_direction;
		b.z=0.0f; //we doing y
		dot=guVecDotProduct( &a, &b );
		theta_z=acos( dot  / ( sqrt(a.x+a.y+a.z) * sqrt(b.x+b.y+b.z) ) ) ;	

		player_rotation.x = theta_x;
		player_rotation.y = theta_y;
		player_rotation.z = theta_z;	
Re: Calculating the angle of a point in relation to another
February 02, 2012 09:28PM
Computer_graphics_-_common_problems
I've just cut and paste the sites code and changed to use things like using guVector (may not compile, just an example)
It's the same method as my turret rotation - my link example was rotating a 3D model in space not flat 2D!
void calcPitchAndYaw( guVector* c, guVector* targetP, float* pitchX, float* yawY )
{
  float dX = targetP->x - c->x;                 // horizontal plane
  float dY = targetP->y - c->y;                 // vertical plane
  float dZ = targetP->z - c->z;                 // horizontal plane
  float hypotenuse = sqrt(dX*dX + dZ*dZ);   // distance along horizontal plane
  *pitchX =  RadsToDegs ( atan2(dY, hypotenuse) ) ;           // angle to look up/down
  *yawY   = RadsToDegs ( atan2(dX, dZ) );                   // angle to look left/right
}
Re: Calculating the angle of a point in relation to another
February 03, 2012 09:53PM
@titmouse I don't know my build doesn't seem to like the values I pass to sqrt(). I get no results.

I think I know why none of these methods are working for me. It may not be a problem that can be solved with pure math. I think the model is always facing -z. It does not matter where player_position and player_direction is located, the GRRLIB model is always facing the same direction. The trick now is generating angles that will turn the model in the direction we want it to end up (compensating for the fact that the model is not facing down -z ALL THE TIME). I did not want to use a hack to achieve a solution but at this point it looks like that is what I have to do . I will attempt to hack a solution together over the weekend and let you guys know what I find out.

Thank you all for your help, it is has been informative. I will find space for you names in the credits :)
Re: Calculating the angle of a point in relation to another
February 07, 2012 05:00PM
FINALLY GOT IT TO WORK!

guVector get_rotation_degrees_to_face_target(guVector current, guVector target ) {
	float dx=target.x-current.x;
	float dy=target.y-current.y;
	float dz=target.z-current.z;

	float hyp = sqrt(dx*dx + dz*dz);

	float rx= atan2(dy, hyp);
	float ry= atan2(dx, dz);

	rx= rx * 57.2957795;
	ry= ry * 57.2957795;	
	
	return (guVector){rx, ry, 0};
}

usage

guVector rotation;
	
cp = player_position;
tp = player_direction;

rotation=get_rotation_degrees_to_face_target( cp, tp );

GRRLIB_ObjectViewRotate( rotation.x, rotation.y, rotation.z );  //do rotation

I am going to use it for enemy fighter ships! :)
Re: Calculating the angle of a point in relation to another
February 09, 2012 10:23PM
@Owen: I was trying to solve the problem of first and third person view, and until now I can't find a solution.
The solution proposed by Titmouse and you is not working if the angle is bigger than 180ΒΊ. In this case your solution is doing a mirror of the model.

I've found a solution using matrix calculation and I'll try to explain you below.

First person mode:
When you want to draw you model in first person mode (for instance the front side of a spaceship from the captain point of view) is so easy, you only have to load the view matrix not using the camera proyection matrix:

guMtxIdentity(ObjTransformationMtx);

guMtxIdentity(m);
guMtxScaleApply(m, m, 0.005, 0.005, 0.005);
guMtxConcat(m, ObjTransformationMtx, ObjTransformationMtx);

guMtxIdentity(m);
guMtxTransApply(m, m, 0, -0.1, -0.5);   // move the model a little to front and down to make it visible
guMtxConcat(m, ObjTransformationMtx, ObjTransformationMtx);

GX_LoadPosMtxImm(ObjTransformationMtx, GX_PNMTX0);

guMtxInverse(ObjTransformationMtx, mvi);
guMtxTranspose(mvi, mv);
GX_LoadNrmMtxImm(mv, GX_PNMTX0);
........ Draw yor model .........

Third Person mode:
This view a little more dificult. A possible solution for that is to use a system reference transformation matrix. The idea is to keep the position of the unitary vectors for the Up, Right and Front for your model. If you want to turn right you have to turn right theese vectors also.
To draw the model you only have to calculate first the system reference transformation matrix and concatenate it with your objectview matrix.
Next function give you the correct matrix:

void MtxSisRef(Mtx m, guVector u, guVector v, guVector w){
	m[0][0]=u.x;	m[1][0]=v.x;	m[2][0]=-w.x; 
	m[0][1]=u.y; 	m[1][1]=v.y;	m[2][1]=-w.y; 
	m[0][2]=u.z; 	m[1][2]=v.z; 	m[2][2]=-w.z; 
	m[0][3]=0.0; 	m[1][3]=0.0; 	m[2][3]=0.0; 
}

usage ---> MTxSisRef(Rotmatrix, right, up, front)
Function give you the system reference transform matrix in RotMatrix.

When you want to draw the model you have to concatenate it with you objectviewmatrix:

MtxSisRef(rotm, p, right, up, front);

guMtxIdentity(ObjTransformationMtx);

guMtxConcat(rotm, ObjTransformationMtx, ObjTransformationMtx);

// move to ship position
guMtxIdentity(m);
guMtxTransApply(m, m, position.x, position.y, position.z);
guMtxConcat(m, ObjTransformationMtx, ObjTransformationMtx);

// apply camera proyection matrix
guMtxConcat(_Object3D_view, ObjTransformationMtx, mv);
GX_LoadPosMtxImm(mv, GX_PNMTX0);

guMtxInverse(mv, mvi);
guMtxTranspose(mvi, mv);
GX_LoadNrmMtxImm(mv, GX_PNMTX0);

The only additional thing you need is to obtain the camera proyection matrix (_Object3D_view). Because you are using GRRLIB it is not visible. Due to it we have to use a little hack.

We will use to new functions instead GRRLIB_Camera3dSettings and GRRLIB_3dMode:

void Object3D_Camera3dSettings(f32 posx, f32 posy, f32 posz,
    f32 upx, f32 upy, f32 upz,
    f32 lookx, f32 looky, f32 lookz) {

   _Object3D_cam.x=posx;
   _Object3D_cam.y=posy;
   _Object3D_cam.z=posz;

   _Object3D_up.x=upx;
   _Object3D_up.y=upy;
   _Object3D_up.z=upz;

   _Object3D_look.x=lookx;
   _Object3D_look.y=looky;
   _Object3D_look.z=lookz;
   GRRLIB_Camera3dSettings(posx, posy, posz, upx, upy, upz, lookx, looky, lookz);
}

void Object3D_3dMode(f32 minDist, f32 maxDist, f32 fov, bool texturemode, bool normalmode) {
    guLookAt(_Object3D_view, &_Object3D_cam, &_Object3D_up, &_Object3D_look);
	GRRLIB_3dMode(minDist,maxDist,fov,texturemode,normalmode);
}


In both cases you need two functions to turn your system reference:

void Turn_y(f32 ang){
Mtx m;

	guMtxRotAxisDeg(m, &player_up, ang);
	guVecMultiply(m, &player_right, &player_right);
	guVecCross(&player_up, &player_right, &player_front);
	guVecScale(&player_front, &player_front, -1);

	guVecScale(&player_front, &lookat, 100.0f);
	guMtxIdentity(m);
	guMtxTrans(m, player_position.x, player_position.y, player_position.z);
	guVecMultiply(m, &lookat, &lookat);

}

void Turn_x(f32 ang){
Mtx m;

	guMtxRotAxisDeg(m, &player_right, ang);
	guVecMultiply(m, &player_up, &player_up);
	guVecCross(&player_up, &player_right, &player_front);
	guVecScale(&player_front, &player_front, -1);

	guVecScale(&player_front, &lookat, 100.0f);
	guMtxIdentity(m);
	guMtxTrans(m, player_position.x, player_position.y, player_position.z);
	guVecMultiply(m, &lookat, &lookat);
}



Edited 5 time(s). Last edit at 02/10/2012 07:55PM by wilco2009.
Re: Calculating the angle of a point in relation to another
February 10, 2012 03:51PM
good tips from wilco2009
Owen, small speed up for you... (I've left the return by value as is)

Code snip...
guVector get_rotation_degrees_to_face_target(guVector* pCurrent, guVector* pTarget ) {
	float dx = pTarget->x - pCurrent->x;
	float dy = pTarget->y - pCurrent->y;
	float dz = pTarget->z - pCurrent->z;
... rest the same
example calling code..
	guVector p1 = {20, 20, 20};
	guVector p2 = {-33, -33, -33};
	guVector vec = get_rotation_degrees_to_face_target(&p1, &p2);

	printf ("%f %f %f",vec.x,vec.y,vec.z );
Re: Calculating the angle of a point in relation to another
February 10, 2012 05:11PM
That won't really change anything, if you look at the compiler's output you'll find it already passes the input and output vectors using pointers.
Re: Calculating the angle of a point in relation to another
February 10, 2012 09:52PM
Array & functions yes - but structures using pointers for you? (just checked guVector is a struct), new one on me! that would break C.

Is it in some way marked as an array, hidden away somewhere - I've yet to see this How does it do this???



Edited 1 time(s). Last edit at 02/10/2012 10:09PM by Titmouse.
Re: Calculating the angle of a point in relation to another
February 10, 2012 10:10PM
@wilco2009 That is advanced stuff! I hope you are still working on that example program.

@titmouse here is the current vector point rotation function based on wilco's code. try this function to see if it works for you;
guVector rotate_vec_to_angle( guVector position_vec, guVector center_vec, float rot_deg_x, float rot_deg_y, float rot_deg_z ) {
	guVector orig_direction = position_vec;

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

	guMtxRotDeg(m, 'x', rot_deg_x); // rotate around y axis
	guMtxConcat(m, om, om);
	guMtxRotDeg(m, 'y', rot_deg_y); // rotate around x axis
	guMtxConcat(m, om, om);
	guMtxRotDeg(m, 'z', rot_deg_z); // rotate around z axis
	guMtxConcat(m, om, om);

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

	guVecMultiply(om, &orig_direction, &position_vec);

	return position_vec;
}
Re: Calculating the angle of a point in relation to another
February 11, 2012 01:37PM
Owen, same thing as my example code post to this thread on January 28, 2012 12:10PM (I optimized a little and has things like scaling too)
But yes it looks like it should work fine.
Please note: You will need to read up on gimbal lock - this method will fail if you use it the wrong way!!!
Re: Calculating the angle of a point in relation to another
February 11, 2012 02:18PM
@titmouse yeah I know about gimbal lock but its a matrix operation shouldn't it work fine? I am just going to be spinning asteroids so it may not be much of a problem for me if it gimbal locks. (collision detection will be the next problem, probably should start another thread)



Edited 1 time(s). Last edit at 02/11/2012 02:19PM by owen.
Re: Calculating the angle of a point in relation to another
February 11, 2012 02:21PM
wilco2009 – do you have any open projects (i.e. shared Google code) with these techniques. (your wii brew link is blocked)
Things like guVecScale(&player_front, &player_front, -1); // to flip, is something I would not thought of doing, obvious now I've seen it!
Infact I've never though about changing things like the up,left vectors, to alow for 360 rotation without issues!
Re: Calculating the angle of a point in relation to another
February 11, 2012 02:27PM
Owen, for a asteroids you only need to spin arround two axis. (think you know that)
What you have looks spot on - just leave one spin axis as zero.
Re: Calculating the angle of a point in relation to another
February 11, 2012 02:37PM
Quote
Titmouse
wilco2009 – do you have any open projects (i.e. shared Google code) with these techniques. (your wii brew link is blocked)
Things like guVecScale(&player_front, &player_front, -1); // to flip, is something I would not thought of doing, obvious now I've seen it!
Infact I've never though about changing things like the up,left vectors, to alow for 360 rotation without issues!

have you seen his tutorial 11? its like a freespace, source included. you have to translate the page though; [wii.scenebeta.com] video of it; [www.youtube.com]
Re: Calculating the angle of a point in relation to another
February 11, 2012 04:46PM
Quote
Titmouse
Array & functions yes - but structures using pointers for you? (just checked guVector is a struct), new one on me! that would break C.

Is it in some way marked as an array, hidden away somewhere - I've yet to see this How does it do this???
C is only a language specification, it has nothing to do with how the ABI is defined. A struct is simply a fixed size array that is allowed to have different sized elements. If it's declared const or the function doesn't modify it there's no need to create a temporary copy.
Re: Calculating the angle of a point in relation to another
February 11, 2012 05:27PM
Quote
Titmouse
wilco2009 – do you have any open projects (i.e. shared Google code) with these techniques. (your wii brew link is blocked)
Things like guVecScale(&player_front, &player_front, -1); // to flip, is something I would not thought of doing, obvious now I've seen it!
Infact I've never though about changing things like the up,left vectors, to alow for 360 rotation without issues!
As Owen says you can take a look to the 11th part of my course. The only thing it is in Spanish.
I haven't any active source in google code.
I'm developing improvements in the source code of the course. My idea is to make a space war shooter.
I could share my code with you, no problem for that.
Re: Calculating the angle of a point in relation to another
February 13, 2012 12:33AM
wilco2009 - I'll keep a look out for your space shooter in the near future, must admit I'm starting a 3D shooter myself, based kind of on the 3D intro scene from my Bolt Thrower game.
I'm just pondering on using quaternions (I think rather than say changing Up, Right and Front ) since I'll have all types of camera views, gimbal lock in general will be an issue for me.

Yes I would indeed like to see your working code - drop me a line at titmouse001@gmail.com
Re: Calculating the angle of a point in relation to another
February 13, 2012 12:43AM
tueidj - I see, thanks for the info.

Sorry Owen, hitting your thread a bit hard now wth off subject matters ;)
Sorry, only registered users may post in this forum.

Click here to login