Ideas?

Pages: 12
No, no, no, no.
You can't simulate movement with a single expression.
Allow me to exemplify:
1
2
3
4
5
6
7
8
9
10
11
double heigth=100;
double v=0;
double t=0;
double step=.0001; //(i.e. one 10000th of a second)
const double g=-9.806*step;
while (height>0){
	v+=g;
	t+=step;
	height+=v*step;
}
//t contains the time it takes for an object to free-fall 100 meters 

Notice that both the acceleration and the motion vector (v) are multiplied by the time step.

Hey, I just ran it and... Well, this is surprisingly fun. I had forgotten how much fun making physics simulations was. (by the way, t=4.5162)
Last edited on
Told you :P

Thought we weren't using single character identifiers?

Personally, I think their easier to use. You don't see Einstein going "Energy is equal to Mass multiplied by celeritas to the power of Two."

Further to your post, helios, with the 'step' variable, is that the amount of times we are going to refresh the counters & image?
Last edited on
(sqrt(pow(mov.initialVelocity * sin(initialAngle), 2))

Is that not pointless? You are are squaring a number that you then square root?


Yes it would be, except I just realised that's a mistake. It should be:
1
2
                     (sqrt(pow((mov.initialVelocity * sin(initialAngle) +
                     (2 * (mov.GravAcceleration + mov.initialAlt))), 2));


Which isn't pointless, as that is the
square root of (initial velocity * sin (intial angle) + 2 * (gravitational acceleration + intial altitude))
Last edited on
Thought we weren't using single character identifiers?
An example is an example. Also, I'm not the one learning why I shouldn't use single-character identifiers.

You don't see Einstein going "Energy is equal to Mass multiplied by celeritas to the power of Two."
According to Wikipedia, he wrote m=L/V^2. And we don't hand-write our programs, so a little more typing will help more than it will hurt.

step is the time step. Since we can't simulate indiscrete time in finite real time, we'll do the closest thing and simulate very small discrete units of time. So, to answer your question, no. The two are independent. For example, you could simulate with a time resolution of a microsecond but only redraw at 10 Hz.
By the way, I get t=4.284 and a distance travelled of -1482.67 when the velocity, initial altitude and angle of direction are all set to 90, but surely if the angle is exactly 90 and you threw it, then horizontally it would not move? Must be an error in the code. I'll think of a way to have the loop work out the distance travelled...

I think this is close:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
#define WIN32_LEAN_AND_MEAN
#define VC_EVENLEANER
#include <iostream>
#include <cmath>
#include <conio.h>
#include <windows.h>

using namespace std;

void animate(double theta, double veloc, double alt) {
double cur_alt=alt;
double cur_veloc=0;
double cur_t=0;
double dist_trav=0;
double step=0.001;
const double gra_force=-9.806*step;
double gra_accel=9.806;

/*
(veloc * cos(theta)/gra_accel) *
                 (veloc * sin(theta) +
                 (sqrt(pow(veloc * sin(theta), 2)) +
                 (2 * (gra_accel + alt))));
*/

do {
  cur_veloc+=gra_force;
  cur_t+=step;
  cur_alt+=(cur_veloc*step);
  dist_trav+=(cur_veloc * cos(theta)/gra_force) *
             (cur_veloc * sin(theta)) +
             (sqrt(pow(cur_veloc * sin(theta), 2)) +
             (2 * (gra_force + cur_alt)));
  cout << "Current Altitude: " << cur_alt << "  || Current Velocity: " << cur_veloc << endl;
  system("cls");
  Sleep(1);
} while (cur_alt>0);

cout << "Distance travelled (h): " << dist_trav << endl;
cout << "Highest altitude reached: " << alt << endl;
cout << "Final Velocity: " << cur_veloc << endl;
cout << "Duration of flight: " << cur_t << endl;
}

int main() {

double theta, veloc=0, alt=0;
system("cls");
while (true) {
    cout << "Input angle of trajectory (between -90 and 90) ";
    cin >> theta;
    cin.ignore();
    if (theta>=91 || theta<=-91) continue;
    else break;
}

while (true) {
    cout << endl << "Input initial velocity (m/s) ";
    cin >> veloc;
    cin.ignore();
    if (veloc>=10001 || veloc<=0) continue;
    else break;
}

while (true) {
    cout << endl << "Input initial altitude (m) ";
    cin >> alt;
    cin.ignore();
    if (alt>=10001 || veloc<=0) continue;
    else break;
}

animate(theta, veloc, alt);
cin.get();
return 0;
}


With all 3 variable set to 90, I get:

Distance travelled (h): 1.03575e+008
Highest altitude reached: 90
Final Velocity: -42.0089
Duration of flight: 4.284

By the way, is the velocity meant to go instantly into negative numbers? Does that mean it is moving downwards at that speed?
Last edited on
if (theta>=91 || theta<=-91) continue;

I think thats meant to be 90 not 91.
By the way, is the velocity meant to go instantly into negative numbers? Does that mean it is moving downwards at that speed?
Yes, since the y axis grows upwards (sin(pi/2)==1, sin(pi/-2)==-1).

if the angle is exactly 90 and you threw it, then horizontally it would not move? Must be an error in the code.
Depends on how you defined "distance traveled". Is it delta x or the length of the imaginary line traced by the projectile? Considering you're using polar coordinates as your vector (I... think), your formula looks way too complicated.
For polar vectors (that is, an angle-speed pair), the formula should be distance+=speed/step, or delta_x+=cos(angle)*speed/step.
For rectangular vectors (a horizontal-vertical speed pair), the formula should be distance+=sqrt(x*x/step+y*y/step), or delta_x+=x/step.
I have no idea what you're doing, there.
It's 91 because I want the option to be from -90 to 90, and nothing above or below.
-91 is smaller than -90, so if the inputted number is not -90 or bigger then it will re-iterate the loop until it is.

Also, I've got some code here that I'm liking:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
#define WIN32_LEAN_AND_MEAN
#define VC_EXTRALEAN
#include <iostream>
#include <cmath>
#include <conio.h>
#include <windows.h>

using namespace std;

void animate(double theta, double veloc, double alt) {
double cur_alt=alt;
double cur_veloc=0;
double cur_t=0;
double dist_trav=0;
double step=0.001;
const double gra_force=-9.806*step;
double gra_accel=9.806;

/*
(veloc * cos(theta)/gra_accel) *
                 (veloc * sin(theta) +
                 (sqrt(pow(veloc * sin(theta), 2)) +
                 (2 * (gra_accel + alt))));
*/

do {
  cur_veloc+=gra_force;
  cur_t+=step;
  cur_alt+=(cur_veloc*step);
  dist_trav+=cur_veloc/step;
  cout << "Current Altitude: " << cur_alt << "  || Current Velocity: " << cur_veloc << endl;
  cout << "Distance travelled so far: " << dist_trav << endl;
  system("cls");
  Sleep(1);
} while (cur_alt>0);

cout << "Distance travelled (h): " << dist_trav << endl;
cout << "Highest altitude reached: " << alt << endl;
cout << "Final Velocity: " << cur_veloc << endl;
cout << "Duration of flight: " << cur_t << endl;
}

int main() {

double theta, veloc=0, alt=0;
system("cls");
while (true) {
    cout << "Input angle of trajectory (between -90 and 90) ";
    cin >> theta;
    cin.ignore();
    if (theta>=91 || theta<=-91) continue;
    else break;
}

while (true) {
    cout << endl << "Input initial velocity (m/s) ";
    cin >> veloc;
    cin.ignore();
    if (veloc>=10001 || veloc<=0) continue;
    else break;
}

while (true) {
    cout << endl << "Input initial altitude (m) ";
    cin >> alt;
    cin.ignore();
    if (alt>=10001 || veloc<=0) continue;
    else break;
}

animate(theta, veloc, alt);
cin.get();
return 0;
}


Thanks for your post Helios. It's made the program much better. It looks about right now.

I also added sleep(1) to the end of the loop, to free up clock cycles. As an unexpected result, the refresh rate of the counter is now 1Hz, i.e it reiterates the loop once per second, so now, if I set the altitude to 100 it takes 100 seconds to complete the program.

Got any more simulations ideas?
Last edited on
It's 91 because I want the option to be from -90 to 90, and nothing above or below.
What if I input +/-90.5?

I also added sleep(1) to the end of the loop, to free up clock cycles.
Um... Why?
The program is not doing nothing. It's calculating results. Using anything less than all available computing power is a waste.
Yielding is only acceptable if the thread is waiting for something to complete, like a lengthy I/O operation (network and users being the biggest bottlenecks), or perhaps a different thread doing an operation on shared data, but not when the thread is doing something useful.
Actually, I've heard of people sprinkling Sleep()s in code to not make it too fast. Apparently some people (lusers, mostly) think that if the computer responds immediately, it's not doing anything important.

As an unexpected result, the refresh rate of the counter is now 1Hz
It's not unexpected, it only looks that way to you:
The granularity of Sleep() is 10 ms (actually, that's the granularity of the kernel's scheduler which is responsible of allocating CPU time to the different threads), so even if you Sleep(1), on average you'll Sleep(10).
Now, what I do find surprising is that the program is simulating at 1x, even though the time step is 1 ms. If the minimum Sleep() is 10 ms, then it should simulate at .1x. Are you by chance running a 9x/ME kernel? I've read that those schedulers have a finer granularity.

In any case, You should remove that Sleep(). And while you're at it, get rid of conio.h (ugh).
Last edited on
I'm not sure why I put conio.h there.

I'm pretty pleased with how it's turned out so far - thanks for the help.
Topic archived. No new replies allowed.
Pages: 12