• 12
• 9
• 9
• 13
• 10

# Varying a 3D vector by a random amount

This topic is 2944 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

Hi. Im implementing a search function for a character. Im using the method outlined in AI Wisdom 2: Hunting down the player in a convincing manner. You start just getting a direction vector to the players location. The next part is to alter this vector by a random variance within a defined angle Q. Can anyone help me with how i would go about altering the vector by Q? Cheers

##### Share on other sites
Here's one way to do it:

1. Compute the vector from the entity position to the player position

2. Compute a random angle in the range [-Q/2, Q/2]

3. Rotate the direction vector about the entity's up vector (or world up vector) by the specified angle

##### Share on other sites
Define "random variance". Do you want a cone of possible vectors which are separated by at most Q degrees? Or variation only in one axis? Or something else?

##### Share on other sites
Here is the way I randomize a vector in the field of view of a given direction with limits to the min and max angle between the given vector and the randomized vector:
1. Randomize a vector in a unit box.
2. if the vector is outside the unit sphere go back to step 1.
3. Normalize the vector.
4. If the vector is in the requested area then we are done.
5. Transform the vector to the requested area.

Here is my code in C++. It uses a linear transformation instead of a rotation matrix for efficiency.

void RandVecInArea(CVector3f& vRand, CVector3f& vDir,		   float fMin, float fMax){	do{		vRand.Set(Rand(-1, 1), Rand(-1, 1), Rand(-1, 1));	}while(vRand.Length2() > 1);	vRand.Normalize();	float fCosTi((-1)*(vRand*vDir));	float fTi(acos(fCosTi));	float fTt(0), fTmp(PI - fTi);	if(fMin <= fTmp && fTmp <= fMax) return;  //vRand is in the specified area	else if(fTmp < fMin) fTt = fMin + (1 - (PI - fTi)/fMin)*(fMax - fMin);	else fTt = fMin + (fTi/(PI - fMax))*(fMax - fMin);	fTmp = sin(fTt)/sin(fTi);	vRand = (cos(fTt) - fTmp*fCosTi)*vDir - fTmp*vRand;}