Jump to content
• Advertisement

# Interception estimation algorithm - Accelerate towards and 0/0 matching

This topic is 3030 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

## Recommended Posts

The following is a description of the technique, not the problem itself. One of the things I've made for my 2D graphics/physics library is a generic interception method. It takes two motion handlers, does math to prepare them for interception (Puts the seeker at 0, 0 position/velocity and adjusts the other relative) and then points one at the other and moves it forward x Seconds. It then tests to see wether it went too far or not far enough, adjusts the Seconds and repeats. MotionHandler is abstract and, for the purposes of this question, is NewtonianMotionHandler (Handles position, velocity, acceleration and forces, using Velocity Verlet) The problem: It acts like an effective, but indecisive mix between accelerating directly towards the seekee and going for a 0/0 position/velocity intercept. That is to say, it starts decelerating as it nears the target, but not enough for an actual 0/0 intercept. What I'd like: 1) An explanation of why (I think at some point, it starts calculating an intercept "behind" itself) 2) Help in converting it into two methods, one of which accelerates continuously towards the target and the other which results in a 0/0 position/velocity intercept. Thanks for any and all help; I know this isn't simple. That's why I'm asking. :)
        public static bool SeekCalculate(MotionHandler seeker, MotionHandler seekee, out Vector2 pointOfInterception)
{
double seconds = 500.0 /*, highSeconds = 2.0, lowSeconds = 0.0 */;
IMotionData seekerMD = seeker.MotionDataGet,
seekeeMD = seekee.MotionDataGet;
seekerMD.ForcesGS = new List<Force>();
seekeeMD.ForcesGS = new List<Force>();

Double lowHighTime = 1000.0;
Double highLowTime = 0.0;
do
{
seekerMD = seeker.MotionDataGet;
seekeeMD = seekee.MotionDataGet;
// seekerMD.Forces = new List<Force>(seeker.motionData.Forces);
// seekeeMD.Forces = new List<Force>(seekee.motionData.Forces);
seekerMD.ForcesGS.Clear();
seekeeMD.ForcesGS.Clear();

seekeeMD.PositionGS = seekeeMD.PositionGS - seekerMD.PositionGS;
seekerMD.PositionGS = Vector2.Zero;
seekeeMD.VelocityGS = seekeeMD.VelocityGS - seekerMD.VelocityGS;
seekerMD.VelocityGS = Vector2.Zero;

// seekerMD.Forces.Add(new Force(seekeeMD.Position.Normalized, 100.0));

seekerMD.MoveTo(seekeeMD.PositionGS, 1.0);

seeker.Simulate(seconds, ref seekerMD);
seekee.Simulate(seconds, ref seekeeMD);

if ((seekerMD.PositionGS.Length / seekeeMD.PositionGS.Length) > 1.000)
// if (((seekerMD.Position + seekerMD.Velocity * seconds).Length / (seekeeMD.Position + seekeeMD.Velocity * seconds).Length) > 1.000)
{
if (seconds < lowHighTime)
lowHighTime = seconds;
}
else if ((seekerMD.PositionGS.Length / seekeeMD.PositionGS.Length) < 1.000)
// else if (((seekerMD.Position + seekerMD.Velocity * seconds).Length / (seekeeMD.Position + seekeeMD.Velocity * seconds).Length) < 1.000)
{
if (seconds > highLowTime)
highLowTime = seconds;
}
seconds = MathExtensions.MathExt.Lerp(highLowTime, lowHighTime, 0.5);
} while (Math.Abs((seekeeMD.PositionGS.Length / seekerMD.PositionGS.Length) - 1.0) > 0.0001);
// } while (Math.Abs(((seekerMD.Position + seekerMD.Velocity * seconds).Length / (seekeeMD.Position + seekeeMD.Velocity * seconds).Length) - 1.0) < 0.001);

pointOfInterception = seekeeMD.PositionGS + seeker.MotionDataGet.PositionGS;

return true;
}



#### Share this post

##### Share on other sites
Advertisement
Ok, I've got it to match course and speed; working on a straight-line intercept. The second equation is my tired attempt. I've been doing collision physics work.

        public static bool SeekCalculate(SeekType type, MotionHandler seeker, MotionHandler seekee, out Vector2 pointOfInterception)        {            double seconds = 500.0 /*, highSeconds = 2.0, lowSeconds = 0.0 */;            IMotionData seekerMD = seeker.MotionDataGet,                seekeeMD = seekee.MotionDataGet;            seekerMD.ForcesGS = new List<Force>();            seekeeMD.ForcesGS = new List<Force>();            Double lowHighTime = 1000.0;            Double highLowTime = 0.0;            Vector2 temp1, temp2, temp3;            do            {                seekerMD = seeker.MotionDataGet;                seekeeMD = seekee.MotionDataGet;                // seekerMD.Forces = new List<Force>(seeker.motionData.Forces);                // seekeeMD.Forces = new List<Force>(seekee.motionData.Forces);                seekerMD.ForcesGS.Clear();                seekeeMD.ForcesGS.Clear();                // seekerMD.Forces.Add(new Force(seekeeMD.Position.Normalized, 100.0));                if (type == SeekType.MatchCourseAndSpeed)                {                    seekeeMD.PositionGS = seekeeMD.PositionGS - seekerMD.PositionGS;                    seekerMD.PositionGS = Vector2.Zero;                    seekeeMD.VelocityGS = seekeeMD.VelocityGS - seekerMD.VelocityGS;                    seekerMD.VelocityGS = Vector2.Zero;                    seekee.Simulate(seconds, ref seekeeMD);                    seekerMD.MoveTo(seekeeMD.PositionGS, 1.0);                    seeker.Simulate(seconds, ref seekerMD);                }                else if (type == SeekType.MissileAttackVector)                {                    temp1 = seekerMD.VelocityGS;                    seekeeMD.PositionGS = seekeeMD.PositionGS - seekerMD.PositionGS;                    seekerMD.PositionGS = Vector2.Zero;                    seekeeMD.VelocityGS = seekeeMD.VelocityGS - seekerMD.VelocityGS;                    seekerMD.VelocityGS = Vector2.Zero;                    temp2 = seekeeMD.VelocityGS;                    temp3 = temp1 + temp2;                    seekeeMD.VelocityGS *= temp3.Length;                    seekee.Simulate(seconds, ref seekeeMD);                    seekerMD.MoveTo(seekeeMD.PositionGS, 1.0);                                        seeker.Simulate(seconds, ref seekerMD);                }                                if ((seekerMD.PositionGS.Length / seekeeMD.PositionGS.Length) > 1.000)                // if (((seekerMD.Position + seekerMD.Velocity * seconds).Length / (seekeeMD.Position + seekeeMD.Velocity * seconds).Length) > 1.000)                {                    if (seconds < lowHighTime)                        lowHighTime = seconds;                }                else if ((seekerMD.PositionGS.Length / seekeeMD.PositionGS.Length) < 1.000)                // else if (((seekerMD.Position + seekerMD.Velocity * seconds).Length / (seekeeMD.Position + seekeeMD.Velocity * seconds).Length) < 1.000)                {                    if (seconds > highLowTime)                        highLowTime = seconds;                }                seconds = MathExtensions.MathExt.Lerp(highLowTime, lowHighTime, 0.5);            } while (Math.Abs((seekeeMD.PositionGS.Length / seekerMD.PositionGS.Length) - 1.0) > 0.0001);            // } while (Math.Abs(((seekerMD.Position + seekerMD.Velocity * seconds).Length / (seekeeMD.Position + seekeeMD.Velocity * seconds).Length) - 1.0) < 0.001);            pointOfInterception = seekeeMD.PositionGS + seeker.MotionDataGet.PositionGS;            return true;        }

#### Share this post

##### Share on other sites

• Advertisement

### Announcements

• Advertisement

• ### Popular Now

• 10
• 17
• 9
• 13
• 41
• Advertisement
• Advertisement
×

## Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!