Predator/Prey Math Question

Hope no one minds if I take a shot at asking this on the Unity forums even though it’s not a Unity specific question.

I have the math down fine. Predator intercepts prey:

function Intercept(target : GameObject) : Vector3
{
	var closingVelocity : float = Vector3.Distance(target.rigidbody.velocity, rb.velocity);
	var closingDistance : float = Vector3.Distance(target.transform.position, tf.position);
	var timeToClose : float = closingDistance/closingVelocity;
	var predictedPosition : Vector3 = target.transform.position + target.rigidbody.velocity*timeToClose;
	
	// catch this exception - player is ahead of ball
	if (Vector3.Dot(target.rigidbody.velocity.normalized, rb.velocity.normalized) > 0.0  Vector3.Dot((target.transform.position - tf.position).normalized, rb.velocity.normalized) < 0.0)
		predictedPosition = target.transform.position;
		
	predictedPosition.y = tf.position.y;		
			
	return predictedPosition;
}

But this algorithm does not take into account the predator’s initial velocity or acceleration. It still works though, it just calculates the predictedPosition as if the predator can accelerate to maxSpeed instantly and turn on a dime. Once the predator has reached maxSpeed and is on course to intercept the calculation is correct.

Any thoughts on how I can recode this intercept formula to take the predator’s initial velocity and acceleration into account so that the predictedPosition is absolutely accurate throughout the pursuit?

I’ve been googling all over the web and can’t find anything.

Thanks as always for any help.

Mitch

How are you defining the character’s rate of turn (are you turning it using a torque that has a maximum value, say)?

Thanks Andeeee for responding. As you know from previous posts - you are my favorite math guru! :smile:

Here is my Locomotion() method. I have a constant acceleration applied to both the magnitude and direction of the velocity vector.

function Locomotion(targetPosition : Vector3, speed : float, acceleration : float) : void
{
	if (isGrounded)
	{				
		var previousVelocity : Vector3 = rb.velocity;
		previousVelocity.y = 0.0;

		var seekVelocity : Vector3 = Seek(targetPosition, speed);
		seekVelocity.y = 0.0;
				
		var moveVelocity : Vector3;
		
		var velocityDifferential : float = (seekVelocity - previousVelocity).magnitude;
		if (velocityDifferential < acceleration)
			moveVelocity = seekVelocity;
		else
	  		moveVelocity = (1 - (acceleration/velocityDifferential))*previousVelocity + (acceleration/velocityDifferential)*seekVelocity;

		if (moveVelocity != Vector3.zero)
			tf.rotation = Quaternion.LookRotation(moveVelocity);

		rb.AddForce(moveVelocity - previousVelocity, ForceMode.VelocityChange);
		
		tf.eulerAngles.x = 0.0;
		tf.eulerAngles.z = 0.0;	
	}
}

Does this info give you enough info to go on?

Thanks Andeeee.

Mitch

this can be quite a complex task as far as i can tell. depending on how complex your final product will be, you should consider using an approximation such as to first slowly turn around to something close to the final direction (for example using your existing method to determine the ‘predictedPosition’) and then calculate the exact position using only straight paths.

hope you get what i mean even though my english vocabulary is too limited for this kind of stuff. feel free to ask though.

Yes, approximating is a possibility. I’m kinda hoping someone can point me in the right direction for an exact calculation.

Think of the prey as a rolling ball in a vacuum. No friction, no air resistance. The ball has a constant velocity.

The predator is traveling at some other velocity. maxAcceleration defines the rate by which the predator can change its velocity and maxSpeed is the maximum velocity.magnitude.

There seems to be a mathematical relationship here that can exactly determine when and where the predator can intercept the prey.

Oh, but what is it?

there’s a pretty easy function, but it doesn’t take into consideration any turns, meaning your predator will turn in the right direction immediately.

the general approach would be for the predator

p1(t) = currentPosition + maxVelocity * (t-deltaT) + 0.5deltaTmaxAcceleration

where deltaT is the time it takes for the predator to accelerate to full speed

deltaT = (maxVelocity - currentVelocity)/maxAcceleration

the function for the prey would be

p2(t) = currentPreyPosition + t*preyVelocity

it is the same t in both functions, if p1 = p2, that means they are in the same spot

currentPosition + maxVelocity * (t-deltaT) + 0.5deltaTdeltaTmaxAcceleration = currentPreyPosition + tpreyVelocity

which results in (note: this is what you would probably use in your code, all the above is just an explanation)

t = (currentPosition - currentPreyPosition + 0.5maxAccelerationdeltaTdeltaT - maxVelocitydeltaT)/(preyVelocity - maxVelocity)

now just substitute the t in either p1 or p2 (hint: p2 is easier) and you get the position you are looking for as result

anyone please correct me if i made any mistakes, been out of school for a while now (and i just woke up :wink: )

Thanks for this snippet of math. I’ll try it out and see where I get. I have one question though - how do I determine maxVelocity. maxSpeed (float) is a constant. But maxVelocity – what is the direction of the vector?

Thanks. Mitch

Well, I’m a little confused by a few things:

deltaT = (maxVelocity - currentVelocity)/maxAcceleration

deltaT is a float, but (maxVelocity - currentVelocity)/maxAcceleration is a vector value.

Also:

t = (currentPosition - currentPreyPosition + 0.5maxAccelerationdeltaTdeltaT - maxVelocitydeltaT)/(preyVelocity - maxVelocity)

You have vectors and floats being added and subtracted. No can do. Wish I was better at math so I could infer what you were getting at. Anyway, I do appreciate the effort to help. Thanks.

Mitch

i should make sure to have a coffee before i post something in here next time :wink:

deltaT is easy, you can just use (maxSpeed - currentVelocity.magnitude)/maxAcceleration

maxVelocity will be a bit more of a problem since the direction of that vector is p2 - p1 + preyVelocity*t

so
maxVelocity = (preyPosition - currentPosition + preyVelocity*t).normalized * maxSpeed

this will be a bit more complicated than i anticipated and unfortunately i don’t really have the time to find a solution for this right now

hopefully someone else can help you out with this, there are definately a few people in these forums that know this kind of stuff alot better than i do, but you could probably ask this kind of question in a math-related forum somewhere else too

Again, thanks for trying.

I have been searching math forums for a few weeks. I thought I was on to something with Pursuit Curves, but that is not exactly this issue.

I will probably post something in a math forum as my next step. Thanks.

(Hoping Andeeee will weigh in on this :wink: )