Vector Math Help

Started by
7 comments, last by Cornstalks 14 years, 12 months ago
Hello, I'm posting for the first time on GameDev. I've heard it's a great place to find game programming help, so I had a question. I'm trying to work on a function involving a lot of vector math and I'm not sure how to do it. Let's say I've got two vectors A and B. A has the initial position of Apos, and B has the initial position of Bpos. If A also has a velocity of Avel quantified by it's speed and direction, and B has a set speed Bspeed, but no direction. I want to write a function to calculate the direction that the B vector would have to be to intersect with A. It would also have to be a function of time. Think of it as a sniper trying to shoot a moving target by leading the target. I want to write a function to calculate the direction and time to fire a bullet given a target's movement speed and direction and knowing how fast the bullet travels. Thanks in advance for the help. :)
http://www.startpause.com
Advertisement
Just so you know, you don't actually have two vectors. You've got three. A and B aren't vectors themselves. There are the vectors Apos, Avel, and Bpos. You also have the magnitude of Bspeed. Here's how I would go about solving this:

Imagine there is a ball starting at position Apos moving with velocity Avel. If you draw a circle such that the circle's center is at Bpos and the ball lies on the circle's perimeter, you know how far away the ball is from Bpos (it's the radius of the cirlce). You know how long it will take to travel that distance at the speed of Bspeed. You also know where on the circle's perimeter the ball is, so you can find the direction that simply points from the circle's center (Bpos) to the ball's current location.

Does that help? I want to help you, but I also think you'll get the most out of it if you're able to solve it yourself. Feel free to ask any questions. Also know that this is just one way to do it; it's not necessarily the only way to do it.
[size=2][ I was ninja'd 71 times before I stopped counting a long time ago ] [ f.k.a. MikeTacular ] [ My Blog ] [ SWFer: Gaplessly looped MP3s in your Flash games ]
Your visual aid is in fact very helpful, and it puts the problem into a lot of perspective.

Unfortunately I'm still haven't trouble. Let me discuss what I've tried to do for the past couple hours:

So, let's say r is the radius of this circle, and p1 represents the point on the circle where the ball lies. So then let's say t represents the time it takes to travel from Bpos to p1, and furthermore, also the time it takes for the ball to travel from Apos to p1. And of course Bdir is the direction of B.

Also, I'm going to call ABv the vector created between Apos and Bpos.

So we want to solve for t and Bdir.

Ok, so I'm going to go through my thought process.

t = r/Bspd
[Adir]/t = Avel

theta = arccos(A.B/|A||B|)
so theta = arccos(ABv.Apos/|ABv||Apos|)
r = distance AB * sin theta

so t = (distance AB * sin theta)/Bspd

Now, I know that a velocity vector is direction/time. Since we know t,

Avel * t = [Adir]
Avel * (distance AB * sin theta)/Bspd = [Adir]

Actually, I'm not sure I understand exactly how to use the Velocity vector. I understand that Bspd is the magnitude...

Anyway, I thought also that maybe the Bdir could be calculated from taking a horizontal vector from Bpos, and taking a dot product between that and Bpos and calculating the angle of it from there.

Anyway, I'm not sure if I'm on the right track or what, but more help would be greatly appreciated. :)
http://www.startpause.com
This is not an easy problem, to intercept a projectile with another one. You'd have to set there equations of motion equal to each other and figure out the missing info.

Or there's an iterative approach.

Lets say you have a function targetPath() which takes a parameter dt. targetPath() returns the position of the target after dt from it's intial position. so targetPath(0) is where the target is now, and targetPath(1) is where the target will be in 1 second. myFlightTime() takes a parameter target which then returns the time required to reach the target.

const float distThreshold = missileRadius; //interception accuracyfloat flightTime = 0;Vector target = targetPath(0);Vector error;for (;;){ //compute flight time and new target location flightTime = myFlightTime(target); Vector targetFuture = targetPath(flightTime); //determine error error = targetFuture - target; if (error.Length() < distThreshold) break; //keep searching target = targetFuture;}//shoot at "target", and you'll intercept with "error" accuracy// (assuming these functions will converge :P)
Hmm, I understand the logic of it, but I can't imagine that this is a very efficient way to do it... right?
http://www.startpause.com
The trajectory of the target (modeled as a point) would be
rA(t) := pA + t * vA
where it is assumed to move on a straight line.

Similarly, the trajectory of the bullet would be
rB(t) := pB + ( t - T ) * vB, T>=0, |vB| == vB
where T denotes the time when shooting as mentioned in the OP.

A perfect hit would be given if
rA(t) == rB(t)

Now, in 3D you have 4 equations
rA,x(t) == rB,x(t)
rA,y(t) == rB,y(t)
rA,z(t) == rB,z(t)
|vB| == vB
but 5 variables
vB,x, vB,y, vB,z, t, T
and hence cannot solve uniquely.

Fortunately this seems me no problem since you can choose T for whatever you like. For simplicity we can choose it as "now" (T==0), so that with the abbreviation
pAB := pA - pB
the equation gives
pAB = t * ( vB - vA )

Splitting this into the 3 scalar equations, so that
vB,x = ...
vB,y = ...
vB,z = ...
are given, they can be inserted into the 4th equation
vB,x2 + vB,y2 + vB,z2 = vB2

Without self having done so, it seems me that this is a quadratic equation of t (after expanding with t2 on both sides), and hence can be solved with the p,q-formula to a t1 and t2, from which presumbly only 1 value is positive. The negative value, however, requires a negative vB, what is valid due to the square but nevertheless is nonsense for the given use case.

Now that a single, specific t is determinded, rA(t) can be computed by setting that t in, and since rA(t)==rB(t) also vB can be computed.


Hopefully I made no mistake ... ;)
Hmm, I'm not sure I completely understand...
http://www.startpause.com
Ok I finally got it!! :)

Both ways (that were discussed in this forum) too. I haven't written the functions for them yet, but I have a step-by-step method written out on paper similar to what you wrote haegarr. :)

Thank you very much everyone, especially MikeTacular, your circle method is brilliant. The first time I figured it out, I was working through haegarr's method, but then I thought about it more with your method and it's so much easier!

Thanks again everyone.

I'll post the function later when I'm done with it, haha.
http://www.startpause.com
Quote:Original post by AnujSuper9
Ok I finally got it!! :)

Both ways (that were discussed in this forum) too. I haven't written the functions for them yet, but I have a step-by-step method written out on paper similar to what you wrote haegarr. :)

Thank you very much everyone, especially MikeTacular, your circle method is brilliant. The first time I figured it out, I was working through haegarr's method, but then I thought about it more with your method and it's so much easier!

Thanks again everyone.

I'll post the function later when I'm done with it, haha.

That's the kind of post I love to see! I'll be looking forward to reading your future post. And I'd be happy to help if you run into any troubles along the way.
[size=2][ I was ninja'd 71 times before I stopped counting a long time ago ] [ f.k.a. MikeTacular ] [ My Blog ] [ SWFer: Gaplessly looped MP3s in your Flash games ]

This topic is closed to new replies.

Advertisement