Parabola

Hi,

first of all my name is Christoph and I am from Germany. So feel free to ask me if you can't understand me.

Right now I am attending a programming class in school. We have the assingment to calculate the trajectory of an object (without air resistance etc.). The calculation part is working so far. But I have problems with the output as a parabola on the screen. Maybe you can help me.

Thats what I got so far.
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
//---------------------------------------------------------------------------

#pragma hdrstop
#include <stdio.h>
#include <conio.h>
#include <math.h>

//---------------------------------------------------------------------------

#pragma argsused

int main(int argc, char* argv[])
{
        double i; //Counter for the for loop
        double x; //X-Position of the Parabola
        double y; //Y-Position of the Parabola
        double t; //Time
        double alpha; //Angle of the "throw"
        double v0; //Initial speed

        v0 = 20;
        alpha = 45;

        t = 2 * (v0 * sin(alpha) / 9.81);
        t = ceil(t);

        for(i=0; i<=t; i=i+0.25)
        {
                x = v0 * cos(alpha) * i;
                y = -0.5 * 9.81 * (i*i) + v0 * sin(alpha) *i;

                if((int)y > 0)
                {
                        gotoxy((int)x,25-(int)y);
                        printf("*");
                }
        }


        getch();

        return 0;
}
//--------------------------------------------------------------------------- 


I know that the way I calculate the parabola isn't perfect because it's too exact so it takes some time to calculate all of the.

But anyways I need some ideas on how to "perfect" the calculation and a proper way to "print" the parabola.

Thanks for you help!

Edit:

I guess it would be easier to program the parabola with this formula:
y = tan(alpha) *x - (g/2v0^2 * cos(alpha)^2) * x^2

But somehow I couldn't get it to work.
Last edited on
Uh, what's gotoxy? It's definitely not a standard function, but you didn't include any nonstandard header except conio.h, so I gotta wonder where that one's coming from.
You won't be able to print out a really high precision parabola anyways.

You could create a 2d char array, and just perform a view transformation to get the appropitiate character for each character of the array, and then print it out line by line, but really, having you draw a parabola with ascii graphics is kinda meh.

Do you have skype? I'm german too, so I might help you out there, but as far as I know non-english posts aren't allowed in these forums.

EDIT: How exactly is the second formula easier?
Last edited on
Gotoxy is part of conio.h.
The idea with the 2d array sounds good but I think it makes it more complicated since I need the parabola for a game. The goal is to shoot over a obstacle and then hit certain area as a goal. But I dont need to think about the rest. First the parabola.

The second parabola formular is easier since I dont need the time and I could just make a for loop for the x value and I would get the y value.

Edit:

If I write the second formula like this
1
2
x=1;
y = (tan(alpha) * x) - (9.81 / (2*(v0*v0)) * (cos(alpha) * cos(alpha))) * (x*x);

I get very strange errors. I think it has probably something to do with my braces but I don't know how exactly I tried already many ways. (Also I know I could write it with pow(2, x); but I just typed it in fast.)
Last edited on
What kind of strange errors are you getting?
You should do some math to get the proper resolution.
I don't really recommend doing this in the console. It looks like this is an assignment so I guess you don't have a choice.
Just for the record, It's okay to post in non English, but you're unlikely to get very many responses.

Edit: This looks like an interesting assignment, I think I'll try it myself.
Last edited on
Don't sacrifice clarity for little more efficiency.
I guess the simpler is
x = x_0 + v_x * t
y = y_0 + v_y0 * t + 1/2 g * t^2

Besides it will easier to obtain a continuous representation with something like Digital Differential Analyzer (DDA).
[edit] the idea of DDA:
find the dt that produces a deviation of 1 pixel (either in x or y).[/edit]

However you better find a graphic library. IIRC you can represent a parabola with a NURBS, but maybe there are more efficient or simpler implementations. way overkill
Sorry, the parabola is polynomial, you just need a second degree bezier.
You just need to specify 3 points.
_Start
_End
_Interjection of the prolongation of the tangents to the start and end points (see the figure).
http://en.wikipedia.org/wiki/B%C3%A9zier_curve#Quadratic_curves
Last edited on
I'm pretty much done with the program in the console. It's not very pretty though. ;)
I think your equation should be a y as a function of x rather than y as a function of t. I'll post my solution after you're done with yours.

Edit: Oh, and the sin() function computes in radians, not degrees.
Last edited on
I thought yeserday night about i as a function of x too. I reworte the program like that and it works much better.

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
//---------------------------------------------------------------------------

#pragma hdrstop
#include <stdio.h>
#include <conio.h>
#include <math.h>

//---------------------------------------------------------------------------

#pragma argsused

void wurf(double v0, double alpha)
{
        double x,y;
        double xw;
        double tx;
        double pi = 3.14159;

        alpha = alpha * (2 * pi / 360);

        xw = ((v0*v0) * sin(2*alpha)) / 9.81;
        printf("%lf\n", xw);

        for(x=0; x<=xw; x++)
        {
                tx = x / (v0 * cos(alpha));
                y = -0.5 * 9.81 * (tx*tx) + v0 * sin(alpha) *tx;

                if((int)y > 0)
                {
                        gotoxy((int)x,25-(int)y);
                        printf("*");
                }

        }
}

int main(int argc, char* argv[])
{

        wurf(20,45);


        getch();

        return 0;
}
//--------------------------------------------------------------------------- 


But I still need a good way of rounding the numbers in order to draw the parabola nicely.
Anyways thanks so far for your help.

Okay I don't know the thing with the radiant and the angle. That helps a lot.

Also if gotoxy isn't standard is there any otherway of moving the cursor?
Last edited on
No, that's the problem here, having a cursor in the first place is not standard so moving the cursor obviously isn't either.
Oh okay. Thats new to me. So anyway how could I do it better?
Last edited on
This is a pulse.Pulse's amplitude~=81
82?doesn't it?
Better is relative. If your solution with conio.h works, then you can pretty much leave it at that (if you'd do something like that in real life, you'd probably do the output with the GDI, DirectX or OpenGL anyways).

A sort of platform independent approach would be (as I mentioned earlier) writing the parabola into a char array, and then outputting that array. Of course, that would also mean that you would have to output the entire parabola all at once, and you would have to find out how many characters fit into one line of the terminal etc...

Other than that, ncurses would also work- but that's pretty much overkill for such a small application, and if you were using external libraries you could also just use real graphics libraries to begin with.
Okay thanks a lot for all your help. The Code works fine now. I just need to rewrite it in a good way.
But something else would be interesting. I am thinking to extend the code so, that the parabola is influenced by wind. Right now I have no idea about the formular or where to start maybe somebody has an idea?
If anybody is interested here it is:
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
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
//---------------------------------------------------------------------------

#pragma hdrstop
#include <stdio.h>
#include <conio.h>
#include <math.h>
#include <stdlib.h>
#include <time.h>

//---------------------------------------------------------------------------

#pragma argsused

int goal(int wx)
{
 int i;

 int zufallsZahl;

 srand ( time(NULL) );
 zufallsZahl = rand() % 10 + 1;

 gotoxy(60 + zufallsZahl,24);
 printf("%c", 219);

 gotoxy(60 + zufallsZahl,25);
 printf("%c", 219);

 gotoxy(60 + zufallsZahl + 1, 25);
 printf("%c", 219);

 gotoxy(60 + zufallsZahl + 2, 25);
 printf("%c", 219);

 gotoxy(60 + zufallsZahl + 3, 25);
 printf("%c", 219);

 gotoxy(60 + zufallsZahl + 3, 24);
 printf("%c", 219);

 if(wx == 60 + zufallsZahl || wx == 60 + zufallsZahl + 1 || wx == 60 + zufallsZahl + 2 || wx == 60 + zufallsZahl + 3)
 {
  return(1);
 }
 else
 {
  return(0);
 }
}

int collision(int x, int y, int pHausX, int pHausY)
{
 int i;


 for(i=0;i<=5;i++)
 {
  if(x == pHausX+i && y < pHausY)
  {
       gotoxy(10,10);
       printf("Fail");
       return(-1);
  }
 }

 return(0);
}

int wurf(double v0, double alpha, int *pHausX, int *pHausY, int *pXw )
{
 double x,y;
 double xw;
 double tx;
 double pi = 3.14159;

 alpha = alpha * (2 * pi / 360);

 xw = ((v0*v0) * sin(2*alpha)) / 9.81;

 *pXw = xw;


 for(x=0; x<=xw; x++)
 {
    tx = x / (v0 * cos(alpha));
    y = -0.5 * 9.81 * (tx*tx) + v0 * sin(alpha) *tx;
    if(collision(x,(int)y, *pHausX, *pHausY) == 0)
    {
     if((int)y > 0)
     {
      if(y<25)
      {
       if(x<=80) //Abfrage falls größer als Bildschirm
       {
        gotoxy((int)x,25-(int)y);
        printf("*");
       }
      }
     }
    }
    else
    {
      return(-1);
    }
  }
 return(0);
}

void haus(int x, int w, int *pHausX, int *pHausY)
{
 int zufallsZahl;
 int y,i;

 srand ( time(NULL) );
 zufallsZahl = rand() % 10 + 1;

 *pHausX = x+zufallsZahl;
 *pHausY = zufallsZahl;

 for(y=0;y<zufallsZahl;y++)
 {
  gotoxy(x+zufallsZahl,25-y);
  for(i=0;i<=w;i++)
  {
   printf("%c", 219);
  }
 }
}

int main(int argc, char* argv[])
{

 int hausX = 0;
 int hausY = 0;
 int still;
 int xw;
 int *pXw = &xw;
 still = 1;

 do{

 clrscr();
 haus(30,5, &hausX, &hausY);

 gotoxy(1,1);
 printf("Haus X:%d", hausX);
 printf("Haus Y:%d", hausY);

 if(wurf(25,45, &hausX, &hausY, &pXw) == -1)
 {

  gotoxy(1,1);
  printf("Du hast das Hindernis getroffen... Du Luschen");
  printf("Noch mal? Ja(1) Nein(0)");
  scanf("%i", &still);
  clrscr();

 }
 else
 {

 gotoxy(1,1);
 printf("Wow... Du hast das Haus mal stehen gelassen.");
 if(goal(63) == 1)
  {

   getch();
   clrscr();
   gotoxy(1, 1);
   printf("Sieg!!!");
   getch();

  }
 getch();

 }

 }while(still == 1);

 printf("Lass dich hier nie mehr blicken.");
 getch();

 return 0;

 }
//--------------------------------------------------------------------------- 
I think you are taking this a bit too far here. Though you can easily implement some sort of wind as a constant horizontal acceleration, or as a acceleration vector.
Nice!

Line 149 should read
if(wurf(25,45, &hausX, &hausY, pXw) == -1)

Also, the program should also give the user the option to quit if he fails... As I don't read German I couldn't follow the prompts and had to kill the process using the Windows Task Manager.

Hope this helps.
I think he does so, but while(still == 1); should be while(still == '1');
Yes its a good idea to do it as a constant vector. I will do that next and connect it with the obstacle so that it will just effect the object if its over the obstacle.

But two questions.
What do you mean with
Line 149 should read
if(wurf(25,45, &hausX, &hausY, pXw) == -1)

Sorry I get what you mean. I don't need the Pointer Operator there. Thanks didn't thought about it.


And why should I write still == '1' instead of still == 1 ? The compiler dosn't say anything about it so I am curious.
Last edited on
closed account (D80DSL3A)
For a simple wind resistance model you could take the force of the wind as proportional to the objects speed.

Your object already has position variables = x, y . Add variables for its velocity components, say Vx and Vy (with Vy positive upwards). Initial values for Vx and Vy would be:
Vx = v0*cos(alpha); and Vy = v0*sin(alpha);

Let acceleration of gravity = g = 9.81 m/s^2 as you have it already.
Let k = the wind resistance coefficient = a small value > 0 (0 = no wind resistance)

Let the objects acceleration components be Ax and Ay, though you won't need these as variables in the program - just for setting up equations below.

The equations of motion would then be:
Ax = -k*Vx and Ay = -( g + k*Vy )

Let dt = time step between calculations = amount that tx changes in your existing code.
From line 85 it looks like dt = 1.0 / (v0 * cos(alpha)); would do it.

Then you can find the change in Vx and Vy in a time dt:
Vx += Ax*dt; and Vy += Ay*dt;

Using the equations above for Ax and Ay gives code for the program:
1
2
Vx -= k*Vx*dt;
Vy -= (g + k*Vy)*dt;


After incrementing the velocities you can then increment x and y:
1
2
x += Vx*dt;
y += Vy*dt;

You will have to change your loop though as you are no longer incrementing x directly. More like:
1
2
3
4
5
6
7
8
9
10
11
12
double dt = 1.0 / (v0 * cos(alpha));// check this!
double Vx = v0*cos(alpha);
double Vy = v0*sin(alpha);

do
{
    Vx -= k*Vx*dt;
    Vy -= (g + k*Vy)*dt;
    x += Vx*dt;
    y += Vy*dt;
    // your code for plotting the point lines 87 - 100
}while( y > 0.0 );


Hope that makes sense!
Last edited on
And why should I write still == '1' instead of still == 1 ? The compiler dosn't say anything about it so I am curious.


Sorry, misread your code, I thought you were reading a char.
Topic archived. No new replies allowed.