Skip to main content
gamedev.net
🔒 Locked

Projectile Motion Problem

Started by gp343 Apr 25, 2004 at 3:14 PM 6 replies 650+ views
Original Post
gp343
gp343
Hi there i''m new to the idea of projectile motion and is trying to create a simple projectile application called cannon. Now, i''ve read and tried all of the forums messages on GameDev.net. My problem is getting one of them to work. All i want is the user should set an angle, set an initial charge and click a button to see the tragectory in motion. I''ve declare gravity as-> private double gravity = 9.8; below is the code i wrote to fire the cannon ball. I tried the code with an angle of 50 degrees and an initialvelocity of 100 and the ball only move a little bit. If the set the initialvelocity of 1000 the ball never comes down. Can some body please help, i''m going crazy on this. Thanks James private void btnFire_Click(object sender, System.EventArgs e){ initialiseBallPosition(); angle = ConvertDegreesToRadians((double)this.trackBar1.Value); double inc = 1.0; double dt = inc / 60.0; initialVelocity = (double)this.numericUpDown2.Value; xVelocity = initialVelocity * Math.Cos(ConvertDegreesToRadians(angle)); yVelocity = initialVelocity * Math.Sin(ConvertDegreesToRadians(angle)); ballX+=(int)xVelocity; ballY+=(int)yVelocity; yVelocity-=gravity; int i = 0; const int SLEEP_TIME = 10; do { Thread.Sleep(SLEEP_TIME); Application.DoEvents(); ballX+=(int)(xVelocity * dt); ballY+=(int)(yVelocity * dt); yVelocity-=gravity*dt; Invalidate(); i = i + 1; }while(i < 20); }
__filip
__filip
You convert your degrees to radians twice:
First time:
angle = ConvertDegreesToRadians((double)this.trackBar1.Value);
Second time:
xVelocity = initialVelocity * Math.Cos(ConvertDegreesToRadians(angle));
yVelocity = initialVelocity * Math.Sin(ConvertDegreesToRadians(angle));

Instead try:
xVelocity = initialVelocity * Math.Cos(angle);
yVelocity = initialVelocity * Math.Sin(angle);

BTW, if this is just a game or a simple test you should use floats, they are faster than doubles. I don''t think you need 64 bit precision here
Atheist
Atheist
What about chosing imax>20 (4get this idea if it´s stupid, I don´t really bother looking through other people''s code)?

Nevertheless, even if it´s not what you asked for: The path of your cannonball is quite simple to integrate, so why don´t you use:
x(t) = x(t=0) + v.x*t
y(t) = y(t=0) + v.y*t + 0.5*g*t²
where v=(v.x, v.y) is the initial velocity, g the gravitation and t time (oh, and x(t)and y(t) are the position at time t, of course).
At least for me explicit functions are much easier to understand and to trace than "adjust this, then that, and then add it somewhere"-algos.

Oh, and now that I thought about "do I tell him that g might be negative, depending on his coordinate system" ... check the sign of your gravitational constant (why 9.8? do you work with a metric system?). Also, I´d prefer yVelocity += gravity*dt and hiding a possible gravitational force in negative y-direction by chosing gravity = -9.8. But that´s more or less a question of personal preferences, of course.
gp343
gp343
I''ve tried it but only a little difference is done.
__filip
__filip
I havn''t seen all your code so I can''t help you much further, but a few questions:

How do you calculate your dt value?

Are your inputs correct?, call System.Out.print() or something just before the loop and check the velocity and angle.

If your dt-value is very small, it might result in (int)(xVelocity * dt) = 0
gp343
gp343
This is how my code looks know after modifications. I increased the dt as: dt = dt + 0.5. However, the ball goes the other way, e.g instead of left to right, it goes right to left.

private void btnFire_Click(object sender, System.EventArgs e)
{
initialiseBallPosition();
double dt = 1.0 / 60.0;
initialVelocity = (double)this.numericUpDown2.Value;
xVelocity = initialVelocity * Math.Cos(angle);
yVelocity = -initialVelocity * Math.Sin(angle);
int i = 0;
const int SLEEP_TIME = 10;
do
{
Thread.Sleep(SLEEP_TIME);
Application.DoEvents();
ballX+=(int)(xVelocity * dt);
ballY+=(int)(yVelocity * dt);
yVelocity-=gravity*dt;
Invalidate();
dt = dt + 0.5;

i = i + 1;
}while(i < 20);
}
__filip
__filip
It''s midnight here and i''m tired, i''ll have another look at this tomorrow if you havn''t solved it by then, One thought first:

You shouldn''t increase your dt-value each frame. dt is supposed to be the number of seconds since the last update, NOT the first update. If you are going to use time based movement you need a timer to calculate the dt-value. However, if you don''t need time based movement you can just set dt to a constant 0.01 (you sleep 10 ms between every update so dt will roughly equal 0.01 s)
PDHB
PDHB
you might also consider replacing your while condition.

while(ballY >= 0)

this way you get to see the whole trajectory of the ball, reguardless of the initial y velocity.
Behold the nascent power of Semejant!

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.