About this Blog

This is my first blog. Ever.

It is simply going to be about my hobby; playing with computer programming. I do not know much about blogging, but I will use this one to learn a bit more about it.

Programming has always been a bit of a passion for me, as from those early days when I first tapped in a sample BASIC program on my old Sinclair Spectrum back in 1986. I have been through many platforms, languages and OS's since, but always carried the hobby with me. I am not particularly good at it; perfection requires a large time investment and continuous practice. I do not have the luxury of the amount of time required to keep the fire burning constantly, so the hobby has inevitably gone through periods of extreme withering. I have, however, finally settled for C++, as the title of this blog implies, and play around with it for some entertainment when ever I can.

This here will serve me as a written record of what I am up to, and hopefully be a reinforcement to my memory every now and then. That is all there is to it.

So, if you read this blog, please don't expect anything snazzy, but be you welcome just the same!

Sunday 2 October 2011

Increasing the time resolution

Okay, I said I would conclude the installments on the naval gun, but as it is now familiar, I will use it here (once more) to introduce time update resolution problems. Yeah, I lied! Imagine that...

In the naval gun example, the time update was at X1. Because gravity and velocity is "rated", let's say, on a "once per second" basis, I elected to do the update of the shell "state" once every second. This is all very well for a demo, but let's say I want to include the naval gun in a real time "HMS Exeter in The Java Sea" type of game. If I left the screen update at 1 second, it would be a very "chuggy" game indeed, a bit like the old days when over ambitious simulators were made to run on 286's.

So, here's a simple example of a ballistic model;

while(y_pos >= 0) // while the shell is above the sea
{
x_vel = cos(angle) * vel;
y_vel = sin(angle) * vel;

angle = atan2f((y_vel - grav), x_vel);
vel = sqrtf((pow((y_vel - grav), 2) + pow(x_vel, 2)));

x_pos += x_vel;
y_pos += (y_vel - grav);

usleep(1000000);
}


This updates every second (usleep(1000000)), with a second based physics model. But I want it to update, say, 4 times every second! Here's what I do;

double FPS = 4;
// Could be an int, but it is better to stay compatible with the types it will be used with.
useconds_t t_factor = useconds_t(1000000 / FPS);

while(y_pos >= 0) // while the shell is above the sea
{

x_vel = cos(angle) * vel;
y_vel = sin(angle) * vel;

angle = atan2f((y_vel - (grav / FPS)), x_vel);
vel = sqrtf((pow((y_vel - (grav / FPS)), 2) + pow(x_vel, 2)));

x_pos += (x_vel / FPS);
y_pos += ((y_vel / FPS) - (grav / FPS));


usleep(t_factor);

}

What I have to consider here is that gravity is only going to be doing a quarter of its work (as it is 9.807 m/s²). Also, velocity is going to need to go only a quarter of the distance (m/s) per update. However, the velocity itself should not really be played with until it is turned into its components (read on).

It is also important to consider that the gravity "reduction" needs to be included in the angle recalculation. If it is not, the the rate of change stays as if on a one second basis, and considerably shortens the range (as the angle would be changing at X4 of what it should). Finally, the usleep function is modified by the t_factor, making the real screen update run at 4 times a second, so a real time simulation is retained.

Where drag is concerned, the force of drag would need to be quartered (drag / FPS), and this would be subtracted from the "real" momentum (velocity * mass). That is why it is important not to affect the net velocity by FPS (ie; do NOT turn an 800 m/s velocity into a 200 m/s to simplify the calculations), and to modify the computed components instead, when they are being added to the positions.

Dang! I wish I had been able to see that BBC program on Exeter!

No comments:

Post a Comment