Missile acceleration and velocity

Started by
3 comments, last by JohnBolton 17 years, 6 months ago
I'm in a position to create a simple acceleration algorithm for a missile. However, it's proving most difficult. I'm not a huge math whiz, so reading math books is entirely cryptic to me. I really don't understand most of the symbols and terminology used. Here's my scenario: The game is a top down scroller. The player controls a ship and moves up, down, left or right shooting things. The player also can shoot missiles. These missiles initially are released and float behind the ship a little bit, because they haven't had a chance to fire off their rockets yet. Several milliseconds later, the rocket boosters fire and the missiles go zooming past the ship towards its target. Here's what I have so far: 1. A facing vector - This vector represents where the missile is pointing. Even though the missiles are slighly moving sideways and back when they are released from the ship, they are still always pointing at the target (basically it would appear as if the missiles are moving side-ways for a bit). 2. Velocity - The velocity is set one time before the missile is released. The direction is pointing behind the ship slighly, so that the missiles appear to be falling backwards due to moving slower than the ship until the boosters for the missiles fire off. 3. Acceleration - This is a vector which modifies the velocity vector over time. The acceleration is calculated every tick. The vector is always facing the target, and when the missile is moving, the vector is modified to face the target constantly. This is the same as the facing vector essentially. I haven't personally implemented the facing vector yet, I may use the acceleration as the facing vector instead. For now I haven't decided yet. Currently here's the math I'm doing:

// Assume that 'velocity' has been given an initial direction and magnitude
// before reaching the 'for' loop. The direction is somewhat pointing behind
// the ship.
for each tick, until position == target, do:
    acceleration = normalize( target - position ) / 1000;
    velocity = velocity + acceleration * deltaTime;
    position = position + velocity * deltaTime;
end


First of all, I divide the acceleration by 1000 because acceleration is based on milliseconds. Every 1000 milliseconds, use that amount of acceleration. Deltatime is the amount of change in time, in milliseconds, Normally 30, but it can't be guaranteed. The problem I'm finding is that most of the positions I place my target, the missile doesn't quite hit. In terms of Y axis movement, the missile works fine. On the X-axis, however, it makes very WIDE turns, when sometimes sharp turns are required. Normally I find the missile completely passing the target to the left or right. It's never dead on. I'm sure my math is too simple, and I can't think of any other way to do it. If anyone could help out I would greatly appreciate it. Thanks!
Advertisement
You're experiencing, more or less, simple harmonic motion. The Y motion seems fine because the missile has no option to stop moving forward, so the X motion gets all the blame. If you ignore the Y motion for the minute, projecting the system onto the X axis, you'll see that the normalisation brings an element of 'cosineness' to X's time-development.
Basically, the missile is acting as a pendulum: The further it is from the B-line, the harder it tries to get back there. Also, the further the missile initially is pointing from its target, the wilder it will swing about the B-line it's trying so hard to get to. So by the time the missile has reached its B-line, it has stored up a lot of transverse velocity, and overshoots. If the missile's target was a fixed distance ahead of it, you'd see that the missile traces out sine waves in space as it swings from one extreme to the other.

You have a few options, but I'll only suggest one for the moment. As I see it, you can solve the problem quite simply by adding a damping factor. If you simulate some air resistance to the motion, by decreasing the velocity by a fixed proportion of its speed per unit time, you'll introduce a terminal velocity (which is a good thing) and perhaps more importantly will cause the missile to converge upon its target.

Regards
Admiral
Ring3 Circus - Diary of a programmer, journal of a hacker.
Based on the code snippet you posted:
You are setting the missile Acceleration to point at the target.
This in no way guarantees that the missile's actual path will end up going that way too.

(Take centripetal motion for example, acceleration is a always a full 90* off from the actual velocity...)

So while having your Acceleration be towards the target, it will pull the velocity to match that direction over time, however if you have initial velocity largely pointing in some other direction; this pull will take so long as to miss the target...

What I would do, is rather than set Acceleration to target direction, is attempt to make the Velocity point that way.

something like this:
forloopdirection=normalize(target-position)goalvelocity=direction*cruisespeed //missile has some normal speed...acceleration=goalvelocity-velocityClamp(acceleration) //acceleration is limited by engine power and time...Up to Youvelocity = velocity + acceleration * deltaTime;position = position + velocity * deltaTime;
What I found that works, is for every tick, set norm(A)=norm(R)-norm(V). This is self dampening.
We''re sorry, but you don''t have the clearance to read this post. Please exit your browser at this time. (Code 23)
It is not always possible to hit a target by simply accelerating the direction of the target, especially if the target is moving and the acceleration is proportional to the distance. Here's a suggestion: cheat. Regardless, of the missile's direction and acceleration, move it an additional amount toward the target at a fixed velocity.

Two other comments:

1. Instead of dividing the acceleration by 1000, consider dividing the time by 1000. The units might be easier to deal with if they are "per second" rather than "per millisecond".

2. Keep in mind that your computations of velocity and position are approximations. It's called "Euler Integration". One effect is that the results will vary depending on the frame rate. Here are the exact formulas for constant acceleration. But since your acceleration is not constant, these are also only approximations, though they are more accurate.
    position += velocity * deltaTime + 0.5f * acceleration * deltaTime * deltaTime;    velocity += acceleration * deltaTime; 
Note that the order is important because the computation of the position must use the previous velocity.
John BoltonLocomotive Games (THQ)Current Project: Destroy All Humans (Wii). IN STORES NOW!

This topic is closed to new replies.

Advertisement