math3dpositioncoordinatesprediction# How to find the interception coordinates of a moving target in 3D space?

Assuming I have a spaceship (`source`

); And an asteroid (`target`

) is somewhere near it.

I know, in 3D space (XYZ vectors):

- My ship's
*position*(`sourcePos`

) and*velocity*(`sourceVel`

). - The asteroid's
*position*(`targetPos`

) and*velocity*(`targetVel`

).

(eg. `sourcePos`

= [30, 20, 10]; `sourceVel`

= [30, 20, 10]; `targetPos`

= [600, 400, 200]; `targetVel`

= [300, 200, 100]`)

I also know that:

- The ship's
*velocity*is*constant*. - The asteroid's
*velocity*is*constant*. - My ship's projectile
*speed*(`projSpd`

) is*constant*. - My ship's projectile
*trajectory*, after being shot, is*linear*(*/straight*).

(eg. `projSpd`

= 2000.00)

How can I calculate the interception coordinates I need to shoot at in order to hit the asteroid?

Notes:

This question is based on this Yahoo - Answers page.

I also searched for similar problems on Google and here on SO, but most of the answers are for 2D-space, and, of the few for 3D, neither the explanation nor the pseudo-codes explain what is doing what and/or why, so I couldn't really understand enough to apply them on my code successfully. Here are some of the pages I visited:

Danik Games Devlog, Blitz3D Forums thread, UnityAnswers, StackOverflow #1, StackOverflow #2

I really can't figure out the maths / execution-flow on the linked pages as they are, unless someone dissects it (further) into what is doing what, and why;

Provides a properly-commented pseudo-code for me to follow;

Or at least points me to links that actually explain how the equations work instead of just throwing even more random numbers and unfollowable equations in my already-confused psyche.

Solution

I find the easiest approach to these kind of problems to make sense of them first, and have a basic high school level of maths will help too.

Solving this problem is essentially solving 2 equations with 2 variables which are unknown to you:

- The vector you want to find for your projectile (
`V`

) - The time of impact (
`t`

)

The variables you know are:

- The target's position (
`P0`

) - The target's vector (
`V0`

) - The target's speed (
`s0`

) - The projectile's origin (
`P1`

) - The projectile's speed (
`s1`

)

Okay, so the 1st equation is basic. The impact point is the same for both the target and the projectile. It is equal to the starting point of both objects + a certain length along the line of both their vectors. This length is denoted by their respective speeds, and the time of impact. Here's the equation:

```
P0 + (t * s0 * V0) = P1 + (t * s1 * V)
```

Notice that there are two missing variables here - `V`

& `t`

, and so we won't be able to solve this equation right now. On to the 2nd equation.

The 2nd equation is also quite intuitive. The point of impact's distance from the origin of the projectile is equal to the speed of the projectile multiplied by the time passed:

We'll take a mathematical expression of the point of impact from the 1st equation:

```
P0 + (t * s0 * V0) <-- point of impact
```

The point of origin is `P1`

The distance between these two must be equal to the speed of the projectile multiplied by the time passed `(distance = speed * time)`

.

The formula for distance is: `(x0 - x1)^2 + (y0 - y1)^2 = distance^2`

, and so the equation will look like this:

```
((P0.x + s0 * t * V0.x) - P1.x)^2 + ((P0.y + s0 * t * V0.y) - P1.y)^2 = (s1 * t)^2
```

(You can easily expand this for 3 dimensions)

Notice that here, you have an equation with only ONE unknown variable: `t`

!. We can discover here what `t`

is, then place it in the previous equation and find the vector `V`

.

Let me solve you some pain by opening up this formula for you (if you really want to, you can do this yourself).

```
a = (s0 * V0.x * V0.x) + (s0 * V0.y * V0.y) - (s1 * s1)
b = 2 * ((P0.x * s0 * V0.x) + (P0.y * s0 * V0.y) - (P1.x * s0 * V0.x) - (P1.y * s0 * V0.y))
c = (P0.x * P0.x) + (P0.y * P0.y) + (P1.x * P1.x) + (P1.y * P1.y) - (2 * P1.x * P0.x) - (2 * P1.y * P0.y)
t1 = (-b + sqrt((b * b) - (4 * a * c))) / (2 * a)
t2 = (-b - sqrt((b * b) - (4 * a * c))) / (2 * a)
```

Now, notice - we will get 2 values for `t`

here.

One or both may be negative or an invalid number. Obviously, since `t`

denotes time, and time can't be invalid or negative, you'll need to discard these values of `t`

.

It could very well be that both `t`

's are NaN or negative (in which case, the projectile cannot hit the target since it's faster and out of range). It could also be that both `t`

's are valid and positive, in which case you'll want to choose the smaller of the two (since it's preferable to hit the target sooner rather than later).

```
t = smallestWhichIsntNegativeOrNan(t1, t2)
```

Now that we've found the time of impact, let's find out what the direction the projectile should fly is. Back to our 1st equation:

```
P0 + (t * s0 * V0) = P1 + (t * s1 * V)
```

Now, `t`

is no longer a missing variable, so we can solve this quite easily. Just tidy up the equation to isolate `V`

:

```
V = (P0 - P1 + (t * s0 * V0)) / (t * s1)
V.x = (P0.x - P1.x + (t * s0 * V0.x)) / (t * s1)
V.y = (P0.y - P1.y + (t * s0 * V0.y)) / (t * s1)
```

And that's it, you're done!
Assign the vector `V`

to the projectile and it will go to where the target will be rather than where it is now.

I really like this problem since it takes math equations we learnt in high school where everyone said "why are learning this?? we'll never use it in our lives!!", and gives them a pretty awesome and practical application.

I hope this helps you, or anyone else who's trying to solve this.

- Finding the string length of a integer in .NET
- Constraining a number to a looping range. Is there a more elegant function?
- Why is the counter decrementing correctly but the countdown is not?
- Math question in regards to functions in the form (1) / ( b ^ c )
- Denormalizing thetas after a linear regression with gradient descent
- How to calculate percentage when old value is ZERO
- Intuitive Understanding of GCD algorithm
- What's the simplest way to extend a numpy array in 2 dimensions?
- Why do I divide Z by W in a perspective projection in OpenGL?
- How to calculate with googol or even larger numbers in java?
- How to check for NaN values
- How does this bitwise operation check for a power of 2?
- how to make this function periodic in MATLAB?
- How do I determine the number of digits of an integer in C?
- How to determine if a large integer is a power of 3 in Python?
- Fastest prime test for small-ish numbers
- Automatically simplify redundant arithmetic relations
- Python polynomial pow
- Rounding to even in C#
- Count ones in a segment (binary)
- Confusion between C++ and OpenGL matrix order (row-major vs column-major)
- How to validate a International Securities Identification Number (ISIN) number
- Finding intersection points between 3 spheres
- Simple way to interpolate between points in 3D space to form a smooth surface
- Get a vector that starts at a given point and is a tangent to some given object
- Getting decimal value from division
- Why aren’t posit arithmetic representations commonly used?
- Can you please explain Reed Solomon encoding part's Identity matrix?
- Ruby Floating Point Math - Issue with Precision in Sum Calc
- How do you calculate the average of a set of circular data?