简体   繁体   中英

Find the better intersection of two moving objects

I would like to optimize dramaticaly one of my algorithm, i will try to explain it the best way that i can.

The subject

We are in a 2D euclidian system at the time t = 0 . In this system there is two object : O1 and O2 .

O1 and O2 are respectively situated at the point PA and PC .

O1 moves at a constant and known speed in direction of the point PB . The object will stop when it reach PB.

O2 can move at a constant and known speed different or not of O1's in any direction. At the time 0, O2 has no direction , we will need to find one for it.

The knowns parameters:

  • O1 : Position, direction, speed
  • O2 : Position, speed

Here is a little diagram of the system.

系统图

We would like to find the point PI and the time ti for which : Position of O1 at the time ti = Position of O2 at the time ti = PI . Then we will make the object O2 move to the point PI to get the O2 direction .

When the direction of O2 (the point PI) is chosen and both objects O1 and O2 are on the move, the objects will never stop or wait for each other.

In this case, the result would be something like this (PI is noted D on this picture). 最佳交集

The algorithm

You can find the working algorithm written in JS at this jsfiddle , it is also a great way to understand the problem.

At this time i use a simple algorithm who works, but can take a lot of operations, i will get the best intersection time, and get the intersection position afterwards.

To get this time, i will check the position of O1 at a moment, and check if O2 could possibly go to this position at this time. If O2 could not reach the object in time, we will increase the time by 150%, however if O2 could cross the O1-B line at the time, we will decrease the time by 50%.

Eventually, after many approximations, we will find the perfect time where both objects could meet.

PseudoCode

function getOptimalIntersectionTime time
   if distance between O1 and O2 at the time `time` < 1
       return time
   else if O2 could not reach the object O1 at the time `time`
       return getOptimalIntersectionTime time * 1.5
   else
       return getOptimalIntersectionTime time * 0.5

Why am I concern ?

My algorithm works, but in some case (eg the "Reverse Case" in the jsFiddle) it will take a large amount of calculus to find the best point.

In this jsFiddle, we are using little values for position (-1000 to 1000) and speed (1-200) but this algorithm is dramaticaly slower with bigger numbers.

I know that premature optimization is a bad idea, but I'm at the end of the project (which consists on databases insertions / selection and data analysis, including this algorithm called many many times) and this algorithm take up to 80% of the project system ressources in certain cases so an improvement could really improve the stability and the responsiveness of the system.

Without loss of generality, let O2 be located at (0,0).

Let s and v the location and velocity vectors of O1, v2 the speed of O2, and t the time to intercept. We then have:

|s + v * t| = t * v2

By the definition of distance:

(sx + vx * t) ^ 2 + (sy + vy * t) ^ 2 = (t * v2) ^ 2

Multiplying this out and reordering terms gives:

  sx^ 2 + 2 * sx * vx * t + vx^2 * t^2
+ sy^ 2 + 2 * sy * vy * t + vy^2 * t^2
-                           v2^2 * t^2
= 0

ie

  sx^2 + sy^2 + (2 * sx * vx + 2 * sy * vy) * t + (vx^2 + vy^2 - v2^2) * t^2 = 0
  \---   ---/   \------------   ----------/       \--------   ------/
      \ /                    \ /                           \ /
       c                      b                             a

As you can see, this a quadratic equation in t. We can simply apply the quadratic formula to find the two possible values for t (if the equation has no solution, that's because no interception is possible). You'll probably want to use the earliest future interception, ie the smaller t that is > 0.

Once you have computed the t , finding the interception point and from that the interception direction should be easy.

To summarize, this problem can be solved in constant time, no iteration is necessary.

You appear to be over-thinking the problem, it should just be simple geometry.

Leaving aside the problem of how you define the nearest point , let's solve for the situation where the desired point is midway between PA and PB .

We have to assume a time period for the entire cycle, let's call that T .

PI = (PB - PA) / 2;  // simplified
TI = T / 2;          // simplified

[decompose all formulae for the x and y coordinates separately].

There are relatively simple formulae for determining the closest intersection of a point (PC) with a line (PA -> PB), although how that's defined is complicated when that line isn't infinitely long.

Then you need:

V1 = (PB - PA) / T;  // O1's velocity
V2 = (PI - PC) / T;  // O2's velocity

These last two lines don't depend on the earlier assumptions - if you know the interception point then the velocity is simply the distance travelled divided by the time taken.

Hence unless you impose some additional constraints on V2, there is always a solution and it's calculated in a few trivial math operations.

Update: @Meriton's later answer is better than mine. I recommend trying his first.

As you realize, we have three, simultaneous equations in the three unknowns vx2, vy2 and t -- respectively the x and y velocities of 02, and time. The equations unfortunately are not all linear:

x1o + vx1*t == x2o + vx2*t
y1o + vy1*t == y2o + vy2*t
vx2*vx2 + vy2*vy2 == vy*vy

(Here, x1o, y1o, x2o and y2o are coordinates of the initial positions.)

If there is a way to linearize the problem, I don't see it. You can however solve iteratively, and quickly, by the same Newton-Raphson technique GPS uses to work out your position from satellite signals. Of course, to fill in the details and implement this will demand some work!

Update: I think that @Alnitak may have linearized your problem rather neatly. Perhaps a combination of his approach and mine therefore would prosper. (I still think that you'll want to use a Newton-Raphson iteration to converge on @Altinak's T .)

Since the speeds are fixed, this should be solvable using the idea of parallel navigation. Think of it this way. At time 0, there is a line between O1 and O2 (the LOS, or line of sight). If O2 follows the optimal intersect path, then at time 1, the line between O1 and O2 will be parallel to the time 0 LOS. Since you have O2's speed, you can calculate the distance it will travel between time 0 and time 1, and from that can calculate where that intersects the time 1 LOS. Think of scribing a circle around O2's original position with radius equal to the distance it will travel in that interval of time. The intersection(s) of that circle with the second LOS will contain the solution. If there is no intersect, there is no solution. The beginning of this online book has a diagram and formulas that show the concept:

http://www.crcnetbase.com/doi/abs/10.1201/9781420062281.ch2

This problem has real world applications where you may also find this solution talked about. For instance submarines can use this to plot and maintain an intercept course with their target by keeping the LOS bearing to their target constant as they close on their target.

Edit:

在此输入图像描述

This diagram shows what I'm talking about. This can be solved using trigonometry except for the special case where the target O1 is moving directly towards or away from the missile O2 (which can be solved trivially).

In the diagram above we can take some arbitrary small amount of time. During that time t1, O1 will have traveled distance b, and O2 will have traveled distance f. The line between O1 and O2 at time t0 is parallel to the line between O1 and O2 at time t1. Since we are given the initial positions of O1 and O2 we know distance d, and since we are given O1's direction, we can simply calculate the angle A.

So given A, b, f, and d, using the law of Cosines,
a = sqrroot(c^2 + b^2 - (2cb * cos(A)))
and
B = arccos((a^2 + c^2 - b^2)/2ac)
Using the law of Sines
E = arcsin((a * sin(B))/f)  or the ambiguous value of 180 - that value
and with that
BC = 180 - E   (because C = 180 - B - E so C+B = 180 - E

with BC we have the solution, and the any other aspects of the triangle of the initial locations of O1 and O2 and the intersection point can be similarly calculated. It's been many years since I used my high school trig, so there may be a simplification of this that I've missed, but this hopefully explains the solution approach I initially described.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM