Create a random vector, with a bias toward a specific direction

Started by
4 comments, last by Bacterius 12 years ago
Hi,

I'm trying to create this effect, so that my ants will tend to move away from the central nest if they are not carrying a resource, but tend to move back toward it if they are. My ants are usually controlled by pheramone trails, but they need to be able to act autonomously as well.

Here is my attempt at implementing this: yes, its in javascript.


WorkerAnt.prototype.startRandomDirection = function()
{

// make a new random walk direction with a directional bias
var x = Math.random() * 0.1 + 1
var y = Math.random() * 0.1 + 1;

// create a vector toward the centre of the colony if ant has a resource, and away from it if he doesnt
var dirToNest = Vector2Cache[0];
dirToNest.equalsVectorBetween(this.vPos, Game.World.CentralNest.vPos);

// adjust it by the random amount
dirToNest.X *= x;
dirToNest.Y *= y;

// re-normalise it
dirToNest.normalize();

// invert vector so we are biased to moving back into the nest
if (this.stockType == EnumStockType.None)
{
dirToNest.invert();
}
this.vRoamDir.copyFrom(dirToNest);
}


The code is confounded by the fact that, for performance reasons, I need to avoid creating garbage. This is an ant simulation, with a few thousand ants on screen at once, so ive made a vector class which does all its operations using existing instances.
Don't thank me, thank the moon's gravitation pull! Post in My Journal and help me to not procrastinate!
Advertisement
Do you have an actual question?
Yeah, how do I create a random vector which has a bias toward a certain direction, with the constraints I listed?
Don't thank me, thank the moon's gravitation pull! Post in My Journal and help me to not procrastinate!
You can compute a weighted average of the direction where you are going and a random vector from some distribution. The choice of weights controls how much randomness you'll get in the result. That's probably the easiest solution and it should run pretty fast.
Depending upon the effect required that could work well. Another option is to generate the random vector and then scale it appropriately. For example:
1. Generate a random unit-magnitude vector.
2. Get the dot product of that vector and the normalised bias vector.
3. That should give you a number from -1 to 1. Normalise this to the range you want, e.g. maybe 0.1 in the opposite direction to the bias to 1.0 in the direction of the bias.
4. Multiply the random vector by you normalised scaling factor.

Yes, it's slower. ;)
I needed to do something similar for a BRDF model for my path tracer, I ended up doing this (very similar to jefferytitan's solution):

- calculating a "central" vector which points towards the desired bias
- calculating a random unit vector in the reference sphere
- linearly interpolating the random unit vector with the central vector using a "bias parameter" [eqn]t[/eqn]. If [eqn]t = 0[/eqn], then it's equivalent to just picking a random unit vector, if [eqn]t = 1[/eqn] then the bias is maximal and the central vector is always picked. Values in between give varying amounts of bias.
- normalize the final vector (which will not be of unit length)

Of course, while reasonably fast, it doesn't give a proper bias (it's not cosine weighted) because of the linear interpolation. So it is kind of a hack (and I had to get rid of it eventually because the resulting PDF is nontrivial, but it served me well)

“If I understand the standard right it is legal and safe to do this but the resulting value could be anything.”

This topic is closed to new replies.

Advertisement