Recently I've been messing with projectiles that follow some mathematically defined trajectory, e.g. parabolas. Making a script that updates the position of a projectile every tick according to a function that maps from time to position is simple enough. I'll use a fireball that's swinging up and down as a simple example. It's z coordinate is z(t) = z0 + 50 * sin(0.015t), where t is time, given by Timer(). The sine wave causes a swinging movement from -50 to +50 vertically. No problem here.
But a projectile generally does not behave having its position updated every tic. Instead, it has velocity, so a proper projectile would define its velocity instead. And since the position can be specified in terms of time, I would imagine the velocity should just be the derivative of this. The derivative of the z(t) is z'(t) = 50 * 0.015 * cos(0.015 * t) = 0.75 * cos(0.015 * t). So this should be velz, where velx and vely are both 0.
This doesn't work anymore. The shape of the trajectory is produced as expected, but the swing is much smaller now. Why cannot I just specify the velocity in this way?
Position and velocity calculus doesn't match up
Moderator: GZDoom Developers
Forum rules
Before asking on how to use a ZDoom feature, read the ZDoom wiki first. If you still don't understand how to use a feature, then ask here.
Please bear in mind that the people helping you do not automatically know how much you know. You may be asked to upload your project file to look at. Don't be afraid to ask questions about what things mean, but also please be patient with the people trying to help you. (And helpers, please be patient with the person you're trying to help!)
Before asking on how to use a ZDoom feature, read the ZDoom wiki first. If you still don't understand how to use a feature, then ask here.
Please bear in mind that the people helping you do not automatically know how much you know. You may be asked to upload your project file to look at. Don't be afraid to ask questions about what things mean, but also please be patient with the people trying to help you. (And helpers, please be patient with the person you're trying to help!)
Position and velocity calculus doesn't match up
- Attachments
-
velocitytest.wad
- Cacodemon ball is defined by position, imp ball is by velocity. They should behave identically but they don't.
- (3.1 KiB) Downloaded 38 times
Re: Position and velocity calculus doesn't match up
It has been a very long time since I did any calculus. You probably weren't born yet. Maybe try z'(t) = 50 * cos(0.015*t), based on the possibly-erroneous guess that you weren't supposed to multiply it all by 0.015. If that doesn't look right, play around with the constant you multiply by the cos until it looks right to you.
- Graf Zahl
- Lead GZDoom+Raze Developer
- Posts: 49230
- Joined: Sat Jul 19, 2003 10:19 am
- Location: Germany
Re: Position and velocity calculus doesn't match up
It's not that simple. If you use calculus you assume a constant movement. Doom doesn't work like that - it alters the position only in intervals. As long as something is moving in a straight line, it's all fine and well, but if your velocity changes things may become quite a bit more tricky.
Re: Position and velocity calculus doesn't match up
And it wouldnt, since you apply it to "discontinuous" gzdoom/games as a whole environment. The math is right.Position and velocity calculus doesn't match up
Find value of an integral of 0.75 * cos(0.015 * t) from 0 to pi/2 using infinitisimal/limits/etc.
Then find same integral using rieman sum approach, with division of all interval in 34 subintervals with selecting "main", or how it named correctly?, number for it from the beginning (from the left) of each interval.
And then compare this two numbers.
You see, every single game works as discrete machine. In another words, game engine calculate, for example actor position, only in some intervals (which called ticks) which happens several times within one second. For gzdoom this value equal to 35, i.e. gzdom "thinks" for every single actor on map 34 times in second.
So it dont continuously, smoothly compute every single game simulation action, like actor moving. It rather extrapolate/evaluate current step using previous step as a base and then send that data to videocard with mark "move this on the screen from A to B, so it looks smoothly for humies". This is in short...
So video games is a one big deception just to make you believe that this triangles on the screen actually alive, not just a result of work of the soulless piece of silicium.
Re: Position and velocity calculus doesn't match up
This is quite literally how a projectile works in Doom. Doom uses a fixed time step for it's physics updating every 1/35th of a second. The velocity value is not an actual continuous velocity, it just tells the game how many units to shift every update. So if a projectile has an xy position of (0, 0) and its x velocity is 0 and y velocity is 5, then after 1/35th of a second its position will be updated to (0, 5), and then (0, 10) after another 1/35th and so on and so forth. It's never updated between those intervals, interpolation in the renderer only gives the illusion of this. If you turn that feature off you'll notice that the game looks like it's playing at 35 fps despite the the fps counter saying otherwise. So if I'm getting this right, your initial calculation actually is correct which is why you were seeing the results you wanted.Nightfall wrote:But a projectile generally does not behave having its position updated every tic.
Re: Position and velocity calculus doesn't match up
What's been said about the fixed timestep of Doom is true but it wouldn't explain the huge difference in behaviour. What matters here is that the maths is wrong. The derivative of sin(at) is only acos(at) if the trig functions are in radians, and the ZDoom trig functions are either in fixed-point angle or degrees. This needs to be adjusted for to get the right result. Specifically in this case it needs to be 0.75 * 2pi * cos(0.015t) or 1.5pi * cos(0.015t), because fixed-point angles go from 0.0 to 1.0, therefore the conversion from fixed to radians is to multiply by 2pi. After editing the ACS to account for this the projectiles largely line up, with any remaining small discrepancy being explained by the fixed timestep.
Re: Position and velocity calculus doesn't match up
Ah, of course! Thanks for explaining.Gutawer wrote:What's been said about the fixed timestep of Doom is true but it wouldn't explain the huge difference in behaviour. What matters here is that the maths is wrong. The derivative of sin(at) is only acos(at) if the trig functions are in radians, and the ZDoom trig functions are either in fixed-point angle or degrees. This needs to be adjusted for to get the right result. Specifically in this case it needs to be 0.75 * 2pi * cos(0.015t) or 1.5pi * cos(0.015t), because fixed-point angles go from 0.0 to 1.0, therefore the conversion from fixed to radians is to multiply by 2pi. After editing the ACS to account for this the projectiles largely line up, with any remaining small discrepancy being explained by the fixed timestep.
I also found a better way to approaching this in general. Instead of computing the velocity manually, the position formula can be used to determine the velocity. Tracking the z used in the last tic and specifying "dz = z - lastz" also produces the correct velocity.