Improving Projectile Motion Graphing in C++

  • C/C++
  • Thread starter chaoseverlasting
  • Start date
  • Tags
    C++ Graphing
In summary: If you have an object, an array or whatever, that you can access the x and y values from, and have the focus at 0,0, then you could just add/subtract the focus coordinates from each point before plotting it, to move the focus around.If you don't have an array for storing the points, you could calculate the values twice, once for plotting, and once for deciding when to move the focus. That's not the most efficient way, but it's very easy to implement.So, the idea is to use two coordinate systems: the "real" one, and the one you're plotting on, which you can
  • #1
chaoseverlasting
1,050
3
Hi,
I've a basic knowledge of c++, but I've never learned graphing. What little I know, I've picked up myself. I am trying to graph the motion of a projectile launched with a given speed and at a given angle, but the graph doesn't complete. Also, its very spaced out. I know its a parabola so I can recognise it, otherwise, it very broken up. Can anyone tell me a better way to do this? Here's the code:

r=pow(v,2)*(sin(2*a))/10; //Range
s=v*sin(a);
c=v*cos(a);

for(t=0;x<=r;t=t+0.5) /*Here, instead of the range, I've also tried to use total time taken, but still the graph doesn't go to completion*/
{
x=c*t;
y=s*t - 5*t*t;
gotoxy(x,y);
cout<<".";
}

getch();


If anyone wants to see the whole program, Ill put it up.
 
Technology news on Phys.org
  • #2
You need to use a graphics library of some sort. The reason that the resolution of your graph is so low at the moment is because you are using text to draw with. The "." character is as tall and wide as any other, its just mostly empty space.

There might be a library out there for creating and rendering to a simple window from the console... but I don't know of one off of the top of my head.
 
  • #3
You are sampling the curve at intervals of 0.5s but what you really want to do is 'ray tracing', which means you find the y for an x or find the x for a y.

Depending on the gradient, one of these will be more precise and you would choose the more precise one. I'm thinking you would have two procedures, one f:x->y and one g:y->x. Then you choose the more precise one initially and at each step you check the gradient to see if you should swap procs.

For instance, if you are using f and your previous point was (2,2) but this point is (3,4) then you know you should have used g, so you use g(3) instead of f(3).
 
  • #4
Yes, verty's method would definitely help. How you're doing it right now is pretty awkward.

To get it looking nice, you could use the Simple Direct Media Layer. But that is advanced, and I'm not sure how well you could cope with it.

It might help if you posted your whole code too.
 
  • #5
Ahh.. SDL looks way beyond me... there's a graphics header file, graphics.h in c++ which looks similar (the examples initialize a graphics driver which looks somewhat similar) but my attempts to use it haven't exactly been brilliant.

Here's the rest of the code:
#include<iostream.h>
#include<conio.h>
#include<math.h>
int main(void)
{
float v,a,t,r,s,c,x,y;

clrscr();

cout<<"Projectile Motion Program"<<endl;
cout<<"Enter initial velocity (floating point number): "<<endl;
cin>>v;
cout<<"Enter the angle of projection (in degrees): "<<endl;
cin>>a;
a=0.0175*a; //Converting degrees into radians

cout<<"The range of the projectile is: "<<pow(v,2)*(sin(2*a))/10<<endl;
cout<<"Press any key to trace the path of the projectile: ";
getch();
clrscr();
r=pow(v,2)*(sin(2*a))/10; //Range
s=v*sin(a);
c=v*cos(a);

for(t=0;x<=r;t=t+0.5)
{
x=c*t;
y=s*t - 5*t*t;
gotoxy(x,y);
cout<<".";
}

getch();

}
 
  • #6
Hey all,
I just figured out how to use graphics.h. The program works much better, its a continuous curve, but sometimes, it runs out of space to plot on and I only see a part of the graph. How could I work around that?
 
  • #7
Here's the code I've written:

#include<graphics.h>
#include<iostream.h>
#include<stdio.h>
#include<math.h>
#include<stdlib.h>
#include<conio.h>
int main(void)
{
float v,a,t,r,s,c,x,y;

clrscr();

cout<<"Projectile Motion Program"<<endl;
cout<<"Enter initial velocity (floating point number): "<<endl;
cin>>v;
cout<<"Enter the angle of projection (in degrees): "<<endl;
cin>>a;
a=0.0175*a; //Converting degrees into radians

cout<<"The range of the projectile is: "<<pow(v,2)*(sin(2*a))/10<<endl;
cout<<"Press any key to compute the path of the projectile: ";
r=pow(v,2)*(sin(2*a))/10; //Range
s=v*sin(a);
c=v*cos(a);
getch();
clrscr();

/* request auto detection */
int gdriver = DETECT, gmode, errorcode;

/* initialize graphics mode */
initgraph(&gdriver, &gmode, "");

/* read result of initialization */
errorcode = graphresult();

if (errorcode != grOk) /* an error occurred */
{
printf("Graphics error: %s\n", grapherrormsg(errorcode));
printf("Press any key to halt:");
getch();
exit(1); /* return with error code */
}

for(t=0;x<=r;t=t+0.01)
{
x=c*t;
y=s*t - 5*t*t;
outtextxy(x,y,".");
}

getch();
closegraph();

}
 
  • #8
It could have to do with non-standard initialization or buffering of your display. I don't have Turbo C++, nor graphics.h, nor do I know how to use it, so I wouldn't be able to test that theory.

If you're just talking about a consistent breaking point for any arbitrary function, that's because you need to do what verty said. Right now, you're just testing arbitrary points at intervals of t. What you should really be doing is using the function f(x), that way you can directly control the domain. As you could control the range with g(x). Then limit the range or domain, respectively, by conditioning the output from whichever function you use.
 
Last edited:
  • #9
My suggestions weren't all that good because they assume that the graph won't turn too quickly, or have lines too close to each other.
 
  • #10
The thing is, the function y=f(x), usually involves terms with square roots which would take more time to compute (I think). Since I've used parametric equations of the curves, I can just vary the parameter to get the curve.

What I meant was, that sometimes the curve is so big that it doesn't show on the screen. If I could somehow vary the resolution of the screen if the curve is that big, then that would solve the problem...
 
  • #11
You could easily translate the co-ordinates.
 
  • #12
chaoseverlasting said:
Hey all,
I just figured out how to use graphics.h. The program works much better, its a continuous curve, but sometimes, it runs out of space to plot on and I only see a part of the graph. How could I work around that?


Remember basic coordinate transformations?

Just scale and translate the result accordingly. This is very easy and looks like this in code:

x0 = x0*sx + ox;
y0 = y0*sy + oy;
z0 = z0*sz + oz; // neglect for 2 dimensions

Where the ox/oy/oz are the offsets in the relevant directions and the sx/sy/sz are the scale factors.

e.g. sx=sy=sz=0.5; will draw more graph on the screen (4 times as much area!)

If you are familiar with keyboard input (not cin!) you could make these parameters adjustable by keypresses for ease of use.

If you want more speed btw you should not use pow(x,2) for squaring. The C++ pow function uses a series expansion to calculate the result iirc. In practice this means that it is very slow compared to x*x, x*x*x etc. If you write your own (even quite sloppy) integer pow() function it will probably outperform the double precision C++ math lib pow(). e.g.

double ipow(double d, int n)
{
double ret = 1;
for(int i = 0; i < n; i++) ret*=d;
return ret;
}

There might already be an integer power function but I have never used it... so I don't know its name. That would be better to use than the above code snippet, since it would likely contain all the common optimisations and have been refined and improved over the years...

Another speed tip is to avoid division by constants. Multiply by inverses instead. e.g.

x/10 --> x*0.1

Don't worry too much about optimisation though, not everything needs to be as fast as possible, but it is good practice to get used to writing things with some optimisation in the first place.

EDIT: some further advice, instead of rendering with "." characters you should be writing individual pixels, this will further increase the resolution, and his how a graphics library is supposed to be used. Even better is to use lines, this way you can decimate the curve a bit without it looking too bad (if you want). Most graphics library have a line function, if not the Bresenham algorithm is well described and documented on the internet and fast to implement.

Looking up graphics.h there is void far drawpoly(int numpoints, int far *points) and void far line(int startx, int starty, int endx, int endy) which fill this purpose. Also from looking it up I found out that it is a Borland specific library and not part of the C++ standard libraries.. so be warned that your code may not be portable.
 
Last edited:
  • #13
Thank you, that helps... I didnt think about transformations... How do you write individual pixels though?
 
  • #14
chaoseverlasting said:
Thank you, that helps... I didnt think about transformations... How do you write individual pixels though?

I can't find the page I found earlier which had a nice list of all of the graphics.h functions, nor do I have the facilities to look up the actual file...

I'm not sure if this one that I have just found is the same or not: http://www.uniqueness-template.com/devcpp/graphics.h

It looks like it should be... according to this there is

void putpixel( int x, int y, int color );

Hopefully this is what you are looking for...

EDIT: for future reference you can often find .h files on the internet by using google with filetype:h, this is occasionally useful when you are cut off from other more immediate sources of information like online help and such, but not very often (since you should have the .h file you want to look up!).
 
Last edited by a moderator:
  • #15
Thanks a lot man. That helps a lot.
 
  • #16
Thanks! I'm not a specialist in graphing, but try to better my knowledge in it myself. So, i highly appreciate your codes)))
 

Related to Improving Projectile Motion Graphing in C++

1. How do I create a graph in C++?

To create a graph in C++, you will need to use a graphics library such as OpenGL or Direct3D. These libraries provide functions for drawing shapes, lines, and other graphics elements on the screen. You will also need to have a basic understanding of C++ programming concepts, such as variables, loops, and functions.

2. How can I plot data points on a graph in C++?

To plot data points on a graph in C++, you will need to use the drawing functions provided by your chosen graphics library. You will also need to have your data stored in variables or arrays, and use these values to determine the position and size of the data points on the graph.

3. What is the best way to label the axes on a C++ graph?

The best way to label the axes on a C++ graph is to use the text drawing functions provided by your graphics library. You can use variables or arrays to store the labels, and then use these values to position the labels on the graph.

4. How can I add a legend to my C++ graph?

To add a legend to your C++ graph, you will need to use the text drawing functions provided by your graphics library. You can use variables or arrays to store the legend labels, and then use these values to position the labels on the graph.

5. Can I save my C++ graph as an image or file?

Yes, you can save your C++ graph as an image or file by using the functions provided by your graphics library. These functions allow you to save the image as a bitmap, png, or other image file format. You can also use third-party libraries to save the graph as a PDF or other file format.

Similar threads

  • Programming and Computer Science
Replies
2
Views
1K
  • Programming and Computer Science
Replies
5
Views
2K
  • Introductory Physics Homework Help
Replies
5
Views
792
  • Calculus and Beyond Homework Help
Replies
3
Views
170
  • Introductory Physics Homework Help
Replies
6
Views
748
  • Introductory Physics Homework Help
Replies
8
Views
608
  • Programming and Computer Science
Replies
2
Views
913
  • Introductory Physics Homework Help
Replies
1
Views
1K
  • Programming and Computer Science
Replies
17
Views
2K
Replies
5
Views
1K
Back
Top