Advertisement

can't get wander algorithm to work

Started by January 24, 2009 10:10 AM
1 comment, last by weewun 15 years, 10 months ago
hi, iv been trying to get a basic wander algorithm to work (see here for the one im trying to use: http://www.red3d.com/cwr/steer/Wander.html ) but when i try to impliment it, i just get the sprite wandering in a circle and i cant figure out why :( the code iv created to do this is shown below. if anyone can see where im going wrong please help :P cheers



void agent::wander()
{
	
	/////////////
	//	for the wander algorithm, i am using the 'wander steering behavior' 
	//	described here: http://www.red3d.com/cwr/steer/Wander.html
	//	this involves getting a point on a circle projected in front of
	//	the object and moving this around the circle each fram. with this
	//	a steering vector is found which is then used to 'steer' the object
	/////////////


	//find circle center
	vector2d  circleCenter;
	circleCenter.set(theSprite.position.getX() + (theSprite.direction.getX() * rootTwoStrength),
					 theSprite.position.getY() + (theSprite.direction.getY() * rootTwoStrength));

	//rotate wDirection a random amount
	float Ang = wRate - (2 * (wRate/(rand()%10 + 1 ))); // +1 so no division by 0
	
	if(Ang < 0) Ang += 360;
	Ang *= PI / 180.0 ;

	wDirection.normalise();

	wDirection.setX(  (wDirection.getX() * cos(Ang)) - (wDirection.getY() * sin(Ang)));
	wDirection.setY(  (wDirection.getY() * cos(Ang)) + (wDirection.getX() * sin(Ang)));
	
	
	
	//find point on circle that steering vector will be created from
	vector2d steeringPosition;
	steeringPosition.set(circleCenter.getX() + wDirection.getX() * wStrength, circleCenter.getY() + wDirection.getY() * wStrength);

	//find steering vector
	vector2d steeringVector;
	steeringVector.set(	steeringPosition.getX() - theSprite.position.getX(),
						steeringPosition.getY() - theSprite.position.getY());

	steeringVector.normalise();

	//adjust direction vector depending on steering vector
	theSprite.direction.set((theSprite.direction.getX() + steeringVector.getX() ) /2,
							(theSprite.direction.getY() + steeringVector.getY() ) /2);

	

	theSprite.direction.normalise(); //just incase

	theSprite.actualPosition.move(	theSprite.direction.getX() * velocity, 
									theSprite.direction.getY() * velocity);
	


}




Have you actually traced through the code in debug mode and watched your values change? If you haven't, I'm not entirely sure that we should.

Just curious. Usually something simple like this is a dumb mathematical error and, therefore, jumps out at you if you watch it happen.

Dave Mark - President and Lead Designer of Intrinsic Algorithm LLC
Professional consultant on game AI, mathematical modeling, simulation modeling
Co-founder and 10 year advisor of the GDC AI Summit
Author of the book, Behavioral Mathematics for Game AI
Blogs I write:
IA News - What's happening at IA | IA on AI - AI news and notes | Post-Play'em - Observations on AI of games I play

"Reducing the world to mathematical equations!"

Advertisement
Yes, i had already spent many hours staring at the debug screen to try and find out what the problem was, i was more interested in whether or not the theory behind how i was trying to do it was correct - sorry if it appeared otherwise.

After spending many more hours on this, i found the main reason (granted, there were a couple other errors i had to fix due to just being dumb) for the sprite just move in a circle.

the line:
deltaAng = wRate - (2 * ( wRate / ((rand()%10) + 1) ) )


i was using to generate a random angular displacement tended to favour more positive numbers in the long run (although it did produce negative numbers frequently too which is why it took me a while to see the error) so i have settled for a non-random size of angular displacement and just choose a set +ve or -ve one at random and it seems to work fine. if anyone is interested in(granted, a slopp version as i have just finished it with alot of experimentation ) what i have incase its useful to anyone in the future is:

void agent::wander(){		/////////////	//	for the wander algorithm, i am using the 'wander steering behavior' 	//	described here: http://www.red3d.com/cwr/steer/Wander.html	//	this involves getting a point on a circle projected in front of	//	the object and moving this around the circle each fram. with this	//	a steering vector is found which is then used to 'steer' the object	/////////////	//find circle center	circleCenter.set(theSprite.actualPosition.getX() + (theSprite.direction.getX() *  rootTwoStrength),					 theSprite.actualPosition.getY() + (theSprite.direction.getY() *  rootTwoStrength));	//rotate wDirection a random amount	if(rand()%2 == 0)		deltaAng = -wRate;	else deltaAng = wRate;	if(deltaAng < 0) deltaAng += 360;	deltaAng *= PI / 180.0 ;		float angle = atan2( wDirection.getY(), wDirection.getX() ); //the current angle of the wDirection	deltaAng += angle;	wDirection.normalise();	wDirection.setX(cos(deltaAng));	wDirection.setY(sin(deltaAng));				//find point on circle that steering vector will be created from		steeringPosition.set(circleCenter.getX() + (wDirection.getX() * wStrength), circleCenter.getY() + (wDirection.getY() * wStrength));	//find steering vector		steeringVector.set(	steeringPosition.getX() - theSprite.actualPosition.getX(),						steeringPosition.getY() - theSprite.actualPosition.getY());	steeringVector.normalise();	//adjust direction vector depending on steering vector	theSprite.direction.set(theSprite.direction.getX() + (steeringVector.getX()  /50),							theSprite.direction.getY() + (steeringVector.getY()  /50));		theSprite.direction.normalise(); //just incase	theSprite.actualPosition.move(	theSprite.direction.getX() * velocity, 									theSprite.direction.getY() * velocity);}

This topic is closed to new replies.

Advertisement