Sign in to follow this  

Potential Function Chasing - Rotation

This topic is 4301 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. I am attempting to use Lenard-Jones potential function to do chasing/obstacle avoidance AI for a space game. The potential functions give me a nice steering vector that makes my AI ships follow the player or avoid obstacles quite well. The problem I have is that I can't seem to make my rotation work with this steering vector. The ships fly sideways and don't ever seem to point the way they are moving. I've tried several methods to try and make my AI ships turn in the direction of the steering vector but I've had no luck so far. My potential function chase function:
//This potential function is based on the potential functions chapter in the
//AI for game developers O'Reilly book.
void SpaceObject::ChaseObject(SpaceObject *object)
{
	D3DXVECTOR3 r = pos - (*object).pos;
	D3DXVECTOR3 u = r;

	D3DXVec3Normalize(&u,&u);

	double U,n,m,d;

	n = 2;
	m = 3;
	d = D3DXVec3Length(&r)/70;
	U = -object->pAttraction/pow(d,n) + object->pRepulsion/pow(d,m);

	u = U *u;
	if(D3DXVec3Length(&u) > acceleration)
	{
		D3DXVec3Normalize(&u,&u);
		u = u * acceleration;
	}

	//Turn towards the desired direction
	TurnToPos(object->pos + u);

	//This probably shouldn't be like this, since then the ship can
	//fly sideways and other not good directions
	velocity += u;
	//Make sure the velocity isn't greater than the max speed
	if(D3DXVec3Length(&velocity) > maxSpeed)
	{
		//Reduce the speed to the max
		D3DXVec3Normalize(&velocity,&velocity);
		velocity *= maxSpeed;
	}
}

And here is the code for my turning function which doesn't work:
void SpaceObject::TurnToPos(const D3DXVECTOR3 &dPos)
{
	D3DXVECTOR3 u,r;
	int dir = 0; //direction to turn
	int tolerance = 0.001; //turning tolerance

	//Get the global difference coordinates
	r = dPos - pos;

	//Convert the global coordinates to local coordinates
	u.x = r.x*cos(-rotation)+r.y*sin(-rotation);
	u.y = -r.x*sin(-rotation)+r.y*cos(-rotation);
	u.z = 0; //never a z-component

	//Normalize the local coordinates
	D3DXVec3Normalize(&u,&u);

	//If x is negative move to the left
	//If x is positive move to the right
	if(u.x < -tolerance)
		dir = -1;
	else if(u.x > tolerance)
		dir = 1;

	//Turn the ship
	Rotate(dir);
}

Any help is greatly appreciated! Thank you Gundark

Share this post


Link to post
Share on other sites
The Rotate(dir) function rotates the ship either left or right, depending on the dir parameter. -1 rotates the ship left, 1 rotates the ship right.

Here is the source code for the function:

void SpaceObject::Rotate(int dir)
{
if(dir != -1 && dir != 1) //only accept 1 and -1
return;
//Change the ships rotation
double tmp = turningspeed * dir;
rotation += tmp;
if(rotation > 2*D3DX_PI)
rotation -= 2*D3DX_PI;
if(rotation < 0)
rotation += 2*D3DX_PI;
}

Share this post


Link to post
Share on other sites
Hey, I fixed my own problem! The problem was that what I considered to be 0 degrees was actually 90 degrees off of what the formulas I was using were expecting to be 0 degrees.

So the solution was to add 90 degrees to the rotation when calculating local coordinates.

Thanks for all the people that looked at this posts and my code, and uh... sorry to bother you!

Gundark

Share this post


Link to post
Share on other sites
Not to thread rip but I just wanted to pass along some ideas of how to refactor code for faster compile and run. I changed tolerance to const in the example but if you intend to adjust it during gameplay then it would be a non-const member var.

void SpaceObject::TurnToPos(const D3DXVECTOR3 &dPos)
{
const int tolerance = 0.001; //turning tolerance | const is initialized at compile time.

//Get the global difference coordinates
D3DXVECTOR3 r( dPos - pos ); // instanciate vs assign.
D3DXVECTOR3 u;

//Convert the global coordinates to local coordinates
u.x = r.x*cos(-rotation)+r.y*sin(-rotation);
u.y = -r.x*sin(-rotation)+r.y*cos(-rotation);
u.z = 0; //never a z-component

//Normalize the local coordinates
D3DXVec3Normalize(&u,&u);

//If x is negative move to the left
//If x is positive move to the right
int dir = (u.x < -tolerance) ? -1 : 1; // declare and assign in one line

//Turn the ship
Rotate(dir);
}

Note variable declaration in the middle of a function is the same to the compiler and early declaration. It only affects scope as the stack space is reserved with the function and held until the function exits. These techniques also reduce optimization cycles by reducing the amount of instance tracking that the optmizer has to look at.

Share this post


Link to post
Share on other sites

This topic is 4301 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.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this