Advertisement

Calculating projectile gravity velocity

Started by February 15, 2022 04:50 AM
6 comments, last by JoeJ 2 years, 8 months ago

I'll just start by saying I'm looking at the "projectile" code found in the game "Runescape" originally wrote in Javascript. The original code can be found somewhere half way down the page of this link https://github.com/zg/317-client titled "Projectile". Ultimately what it does is track an object a move towards it at a certain speed relative to the targets distance and the amount of ticks left. The reason I'm racking my brains on this, originally was because of the tan function for the direction of the velocity, but now I'm trying to figure out part of an equation used in calculating the up and downwards force.

I've translated a basic form of this code to Unity in C# to try and reverse engineer it.


   void Update()

   {

       if(x >= distance)

       {

           x = 0;

           z  = 0;

           duration = 20;

           velocityX = 0; velocityZ = 0; acceleration = 0f;

           mobile = false;

           target();

       }

       

       sim();

       duration-= interval;

   }





   void target()

   {

 velocityX = distance / duration;

       



 if (!mobile) {

  velocityZ =  -velocityX * Mathf.Tan(elevationPitch * 0.02454369f);

 }

   }



   void sim()

   {

 acceleration = 2f * (- z - velocityZ * duration) / (duration * duration);



       mobile = true;



       x += velocityX * interval;

 z += velocityZ * interval + 0.5f * acceleration * interval * interval;

 velocityZ += acceleration * interval;



       cube.transform.position = new Vector3(x,z,0);

   }

}

I understand how the velocity addition works in regard to interval, and that velocityX is set to move along x distance linearly over a given duration. If I understand the tan function correctly also, it is used to determine the angle of trajectory and thus the direction of velocity.

In the past couple of days that I have been analyzing this, I was googling a lot about parabolic trajectory and anything related to this topic. I found that the 0.5f * acceleration * interval * interval is the formula for calculating distance and gravity - with the google image here...

Now what I really don't understand is the acceleration formula :

acceleration = 2f * (- z - velocityZ * duration) / (duration * duration);

Does this look familiar to anyone? or can you figure out the maths behind it? I basically was hoping someone could explain this to me. I would also say that I don't fully understand the gravity formula use in this code, it looks like acceleration is being used in place of gravity.

Thanks for your time, guys!

Baraccuda said:
it looks like acceleration is being used in place of gravity.

Gravity basically is constant acceleration.
Acceleration and force are closely related, but a force also relates to mass.
A constant force applied to a heavy object does less than if applied to a light object. The affect of gravity is independent of mass, so i see it as an acceleration, not a force.
(I hope my conclusion is scientifically valid - correct me if not)

Thus, the formula you ask about can be probably derived from the formula given in the google screenshot, just by replacing gravity with acceleration. (code is a bit confusing to me, so not sure)

I have posted some related code here, also contains calculating velocity at a given point in time: https://www.gamedev.net/forums/topic/711272-calculate-3d-parabolic-trajectory/


Edit:: Oops, ofc gravity isn't constant in the real world. But working too much on (non space) games, i probably forgot about that : )

Advertisement

You may want to read Projectile motion - Wikipedia

That page is dedicated to your problem.

Note that horizontal and vertical motion are completely independent as long as you ignore air friction and air motion, you can just ignore horizontal movement until you understand vertical movement.

Hey, thanks for the replies - I will definitely look into those links above,

What I found last night was that yes acceleration is gravity as I suspected and you confirmed above. But the acceleration formula itself is used to determine the gravity (or acceleration) value, based on the duration of the projectile and the velocity of Z ..(defined by the angle evelationPitch and velocityX)

velocityZ = -velocityX * Mathf.Tan(elevationPitch * 0.02454369f);

It does this to make sure that the projectile Z position reaches 0 at the end of the duration, to keep the gravity consistent through different target distances and duration of travel. Now I know what its used for, I'm just trying to understand how the formula actually does that.

acceleration = 2f * (- z - velocityZ * duration) / (duration * duration);

Thanks for your time, again!

Baraccuda said:
But the acceleration formula itself is used to determine the gravity (or acceleration) value, based on the duration of the projectile and the velocity of Z ..(defined by the angle evelationPitch and velocityX)

velocityZ = -velocityX * Mathf.Tan(elevationPitch * 0.02454369f);

When you throw or shoot something up at an angle, you must decompose the initial speed into a purely vertical and a purely horizontal component. That decomposition depends on the angle of course. Not sure what the magic constant is about, at least it's not

math.pi/180 = 0.017453292519943295

so the value is contaminated with some other problem variable

Baraccuda said:
Now I know what its used for, I'm just trying to understand how the formula actually does that.

What do you mean? Formulas don't “do” anything, they just express a relation between variables. At any time, the left side and the right side of the “=” must be the same value. If that is the case, the formula holds, and the used values of the variables is “valid” for this formula.

In other words, it acts as a filter, keeping only the relevant variable value combinations.

As an example consider a + b = 10. This expresses that the sum of a and b must be 10.

Does this hold for a=7 and b=4? 7+4 = 10 isn't correct, so a=7 and b=4 lies outside the above relation.

Does this hold for a=-2 and b=12? -2 + 12 = 10 is correct, so a=-2 and b=12 is part of the relation.

You can do this for all values of a and b and only keep the pairs that are in the relation. You can draw a graph of these value pairs.

I also do not really understand the question, but i guess you wonder why the given formula works to describe physics.

In my experience, the quadratic equation of motion (exact closed form solution) is harder to understand than doing the same thing in iterative steps (only gives us an approximation by integrating, including small error).

Here a snippet to do both and compare, with some object falling under gravity :

	const float start = 1.0f; // initial position
	float p = start; // changing position
	float v = 0; // changing velocity, initially zero
	const float a = -5.0f; // constant accleration
, e.g. gravity
	const float timestep = 0.16f;
	
	for (float t = 0; t <= 2; t += timestep) // we iterate small steps in time
	{
		// iterative approximation (which we usually use if a closed form solution is not possible, e.g. if there were additional drag from air resistance, or non constant external forces, etc.)
		v += a * timestep;
		p += v * timestep;


		// exact closed form solution, giving solution at any time in one step
		float pA = start + 0.5f * a * t*t; // the quadratic equation in quastion. you can derive
 your asked one from that.
		float vA = a * t;
		
		
// todo: print values to show v == vA, and p == pA, within some small error
	}

Running this proofs correctness, which is enough for me. (I hope i did not include some bug.)

But i keep asking myself: Why this factor of 0.5 in the analytical solution?
I think this is because things are at zero initially, but that's quite vague and does not really explain anything. I don't know. : )

Advertisement

JoeJ said:
Why this factor of 0.5 in the analytical solution?

x = v * t

v is however not constant, it linearly increases by the acceleration constant (v' = g), thus

v = integral 0 → t over g . At time 0, the value is 0, at time t the value is t * g, so the covered area is ½ * g * t.

thus x = (½ * g * t) * t

If starting position is non-zero you need to add x0 (initial position), and if initial velocity is not 0 you need to add v0 * t as well to the position.

Thanks for the replies, apologies I'm a bit late, I've had some uni work to do this week. I feel I didn't address my question clear enough, I think images should speak a lot better than I can.

When the projectile goes up into the air and does not land at the duration end time, acceleration has an arbitrary value of 0.2. But with the acceleration formula that was used, it lands perfectly at the end of the duration, and you can change the duration time to anything and it will land the same. I'm curious as to how it does this / how this works…

Baraccuda said:
But with the acceleration formula that was used, it lands perfectly at the end of the duration, and you can change the duration time to anything and it will land the same. I'm curious as to how it does this / how this works…

Probably it still works by adjusting launch velocity / angle accordingly.
Basically you can fix one variable of the equation to a certain value you want, and calculate all the others so it hits the goal.
For example, you could ask questions like those:

I have my projectile launching at fixed velocity x. Please calculate launch angle so i hit the target.
I have fixed launch angle and velocity. Please calculate under which gravity i would hit the target.
I want to hit my target after a duration of x seconds. What would be the physical initial conditions of the other variables so i would hit the target.
etc.

Likely you have a certain question matching your games mechanics, with some variables open, others fixed, then you derive the question to answer just that case.
If multiple variables remain open, you can add an additional objective, e.g. minimizing energy, to deal with such underdetermined system.

This topic is closed to new replies.

Advertisement