I came across a few issues related to accuracy in my ballistics app, both expected and unexpected. As these have wider application than ballistics simulations and are interesting in their own right I thought them worth their own post.
The first and expected inaccuracy arises whenever a motion is divided into a series of identical smaller motions, which are then applied over time to carry out the motion. For example the varying speed/fixed time rotation in the app works by dividing the angle by 30 then rotating by that each frame. The problem with that is any errors in the calculations are multiplied by being applied repeatedly. Further calculations such as the sine and cosine can amplify this.
The error though is quite small provided the calculations are carried out with enough accuracy. It can be seen in the app: click outside the range to enable varying speed rotation. Then click twice in the same spot (after waiting for the first rotation to complete). The two angles shown are the target angle and the angle actually rotated to. The errors I am seeing are less than one in a billion, far too small to worry about.
When it is rotating with a fixed speed a second error occurs: it rotates in steps of 30° a second, or a degree every frame. It always stops short of the angle it is aiming for so can be out by up to a degree. This is too small to notice with such small art but would be easily noticeable with something larger, closer the width and height of the game. The code could snap the rotation to the target angle as it finishes but I never bothered with this. It can be seen in the 'angle from', the angle it starts from and so the angle it stops the previous motion at. This changes in whole numbers of degrees, one for each frame it rotates, with an error that is again too small to worry about.
The third accuracy issue is more interesting, if only as it was more unexpected than the others. Before adding rotation, while adding code to deal with ballistic motion to a higher or lower target, I noticed the targeting was out. It was overshooting or undershooting which I was expecting, but was also following a different path from one that would take it to the target. This would normally be invisible except with the trail marking the path and the target the same size as the missile even an error of a couple of pixels was noticeable.
The problem was that the code moving the missile used a difference equation: it updated the missile position using the velocity, and the velocity was updated (for the vertical part of the motion) using gravity. This was missing the target. I changed it to use the equations of motion, the same ones given in shooting up and down, and the problem disappeared. I could have improved the difference equations but the equations of motion act as a check that the mathematics is correct, as the quadratic equation is derived from them.
Difference equations are better for more general ballistics such as under non-uniform gravity, with air resistance or involving rotation, as the equations of motion become to complex to use. And in most games difference equations are fine even for motions like this.
No comments:
Post a Comment