How To Calculate Pitch For A Projectile Affected By Gravity

Archive of the old editing forum
Forum rules
Before asking on how to use a ZDoom feature, read the ZDoom wiki first. This forum is archived - please use this set of forums to ask new questions.
Locked
User avatar
22alpha22
Posts: 308
Joined: Fri Feb 21, 2014 5:04 pm
Graphics Processor: nVidia with Vulkan support
Location: Montana, USA

How To Calculate Pitch For A Projectile Affected By Gravity

Post by 22alpha22 »

I'm trying to make a zombie who fires a rocket that travels for five tics normally without being affected by gravity, but on the sixth tic and for the rest of the missile's life it is affected by a gravity value of 0.1. Since the missile begins falling after five tics, the zombie will need to adjust his aim pitch higher to hit targets at longer distances, otherwise the missile will fall short and explode on the floor. I'm currently stuck on figuring out how to calculate the necessary pitch angle to hit a target with the missile with a given target distance, let alone how to have the zombie do it in real time. I've spent several hours doing research and experimenting and so far haven't come up anything that works. Several of the formulas I've tried have made the zombie shoot the ground at his feet and gib himself.

The first part of the problem was calculating the distance between the target and the zombie which I manged to solve with some research and the wiki.
Spoiler:
The final part which I'm stuck on is what formula to use to calculate the pitch now that we can calculate the range.

Here is all relevant data on the missile and the zombie's firing state.

The Missile:
Spoiler:
The Zombies Missile State:
Spoiler:
From what I can gather, the important information to make the necessary calculations is as follows:

Distance between shooter and target: Variable, the necessary function for this is above.
Speed of missile: 30
Gravity value of missile: 0.1

My research revealed this formula, but I can't seem to find an Arc Tangent function for Decorate or ACS, and I'm not even sure this is a formula the would work if Arc Tangent does exist.
Image

Any help would be greatly appreciated.
User avatar
Gutawer
Posts: 469
Joined: Sat Apr 16, 2016 6:01 am
Preferred Pronouns: She/Her

Re: How To Calculate Pitch For A Projectile Affected By Grav

Post by Gutawer »

The arctangent function for ACS is actually VectorAngle, normally called atan2 in other languages (DECORATE/ZScript has an atan2 function as well as VectorAngle) - if you want to use VectorAngle as atan, just pass 1.0 as the first argument. The wiki says - To get the value of atan(x), use VectorAngle(1.0, x).

I actually had a similar problem to you recently (albeit in ZScript) where I had to estimate where an actor would land after a velocity change so it could determine whether it would fall off a ledge by doing a vel change. The way I solved it was just by running a while loop like this:

Code: Select all

if (gravity != 0) {
    // run a mini-physics loop
    do {
	    simPos += velVector;
	    velVector.z -= GetGravity();
	    velVector.xy *= level.airfriction;
    } while (simPos.z > startVector.z);
}
simPos is the simulated position (this is a vector, so you will have to modify this to use arrays or something to work in ACS), velVector is the velocity I want to add, and startVector is the starting position.
Basically, every tick, velVector is added to the current simulated position, then GetGravity() is subtracted from velVector's Z value (1 is the default gravity value, and gravity is the actor's current gravity) to simulate gravity, then the X and Y of velVector are multiplied by 0.99672421875 (default ZDoom air friction). This is then done until simPos is at a lower or equal Z coordinate to the starting position - then you can use simPos to determine where the actor should have landed (assuming nothing changed & that there is a level ground). It's not perfect, but it may at least help you (likely with some modification).
User avatar
22alpha22
Posts: 308
Joined: Fri Feb 21, 2014 5:04 pm
Graphics Processor: nVidia with Vulkan support
Location: Montana, USA

Re: How To Calculate Pitch For A Projectile Affected By Grav

Post by 22alpha22 »

Thank you for trying to help Gutawer, but even with your explanation, I'm afraid I still don't understand your code. I did however use your suggestion to use VectorAngle as Arc Tangent so I could try out the formula I found, unfortunately, it didn't work. I created the necessary functions, set up the formula, and the resultant pitch always came out came out "0" no matter the distance or height.

Here are the functions and script I used.
Spoiler:
I initially thought either the height or distance function wasn't working properly, so I tested them in-game with PrintBold and they seemed to working correctly. Then I thought that running a couple functions from within a function, that each relied on being able to get the calling actor's Target TID might not be working properly, so I moved the main pitch calculation out of a function and directly into the calling script below.
Spoiler:
The resultant pitch still always turned out "0" no matter what. I don't know what I did wrong or if this formula simply isn't the right one. Any ideas?
User avatar
KeksDose
 
 
Posts: 596
Joined: Thu Jul 05, 2007 6:13 pm
Location: my laboratory
Contact:

Re: How To Calculate Pitch For A Projectile Affected By Grav

Post by KeksDose »

That formula is wrong in zdoom because it runs on 35 tics per second. More on that later. Plus, you would have to find a gravity constant by experimentation. :p

The first thing I want to note is that you do not need to write your own distance function. Just use [wiki=VectorLength]VectorLength[/wiki]. I am willing to bet even Zandronum has it at this point. You can also make the problem easier by setting the horizontal velocity constant, instead trying to find the vertical starting velocity.

Anyhow, here is my homebaked solution using algebra:
Image
The most important part really lies in the first three equations. The rest is housekeeping with signs, fractions and sums. In particular, for the sum of t I used Gauß' sum formula. Then you can solve for v0z in terms of the distances and horizontal projectile speed as we imagined. It could be that you need to mess with the signs.

(III) means that the horizontal projectile speed remains constant. (II) describes the z-position of the object at any time t. Basically, every tic, the current velocity is added on top of the actor's position, so if we want it at 't', we sum up all the velocities we can have up to that point (it is basically an integral, but not so complicated because the changes in velocity are finite). [wiki=Gravity]And (I) describes the z-velocity at any point in time.[/wiki] It has a starting velocity and it subtracts the "air time + 1". This is because gravity is applied twice on the first tic. Basically, just what the wiki page described about gravity.

Note that due to the way (I) is set up, this ONLY works for default gravity. If zdoom were to, in half gravity, add 0.5 instead of 1 to the falling velocity, I have no idea if it does that, then you can easily do the same thing again but with r*t - r instead of t - 1. Then r is the "gravity factor".

The interesting portion for your problem is at the bottom: vx is the horizontal projectile speed and dx the horizontal distance between the shooter and target. z0 - ztarget makes the vertical distance between the shooter and target. Like this, you do not need the full 3D distance. You calculate the horizontal and vertical distances as you are used to and put in any horizontal distance that is not 0. The projectile will then need its z-velocity set to the result, and its x- and y-velocities to the horizontal velocity with regards to its angle (vx = cos(ang) * vel, vy = sin(ang) * vel).

Anyhow, I feel like this could be a good resource, too, if it works reliably enough. My testing at least says yes.
User avatar
22alpha22
Posts: 308
Joined: Fri Feb 21, 2014 5:04 pm
Graphics Processor: nVidia with Vulkan support
Location: Montana, USA

Re: How To Calculate Pitch For A Projectile Affected By Grav

Post by 22alpha22 »

KeksDose wrote:Image
Wow, that is a lot of maths just to find the correct pitch. I never thought it would be that complex since it seems fairly simple for a human to guesstimate the pitch just by eye balling it after firing one shot. Anyway, my algebra is "lacking" to say the least. It has been more than a couple of years since I've used algebra, not since I was still in high school. Lack of practice has led me to forget most of what I've learned, and needless to say, your formulas look more than a little intimidating. I've read and reread your post but I still can't make heads or tails of the formulas. To be honest, I don't fully understand the much simpler formula I found and initially tried.

As a temporary and maybe permanent solution, I've made a table like function through trial and error, that tests the distance between the shooter and the target returns a pre-calculated pitch assigned to that distance. It works remarkably well so long as the shooter and the target are on the same Z height. However, if the player is lower than the zombie, he fires a rocket at a higher pitch, and vice versa if the player is higher. I thought having the assigned pitch simply being an offset added to the zombies own targeting pitch would have worked but apparently had no effect. So I'm stuck either finding a better solution or manually adding a ton of entries to my function to cover all relevant heights at all relevant distances.

My table function in its current form.
Spoiler:
Locked

Return to “Editing (Archive)”