- Home /
Calculating trajectory with PhysX drag
Between posts at http://forum.unity3d.com/threads/drag-factor-what-is-it.85504/ and more from stackoverflow which I cannot manage to locate again, I've been working on creating a toolset for calculating trajectory to match PhysX's systems. To that end, I have the calculations completed without drag factored in.
In short, I calculate the velocity to launch from point A to point B in X seconds with
HorizontalVelocity = HorizontalDistance * TimeInFlight;
VerticalVelocity = (VerticalDistance + ((0.5f * GravityMagnitude) * (TimeInFlight * TimeInFlight))) / TimeInFlight;
and then calculate resultant positions along that curve by multiplying that initial velocity vector (per direction) by a chosen timestep and any applicable gravitational influence.
HorizontalPoint = HorizontalVelocity * TimeStep;
VerticalPoint = (VerticalVelocity * TimeStep) - ((0.5f * GravityMagnitude) * (TimeStep * TimeStep));
From the aforementioned post, Physx is very definitely defining motion which can be recreated with:
void FixedUpdate()
{
velocity = velocity + (Physics.gravity * Time.fixedDeltaTime);
velocity = velocity * (1 - (GetComponent<Rigidbody>().drag * Time.fixedDeltaTime));
transform.position += (velocity * Time.fixedDeltaTime);
}
What I have been unable to manage to do, however, is implement that drag into the trajectory calculations. I would presume that drag should be able to be simplified into something like
Mathf.Clamp01(Mathf.Pow(1.0f - (drag * Time.fixedDeltaTime), targetTime / Time.fixedDeltaTime))
in order to simulate the effects of drag over time, but I have had no success in joining it together with either of the initial velocity calculation or the stepped calculations (to create preview lines, for example) in a way which matches up with the actual physics calculations.
In general, I've been aiming for a single formula for these calculations (represented by essentially only using starting point and velocity vector, then getting points at specific times) rather than working incrementally (for example, calculate each physics step one at a time to catch up to the destination point). Am I overlooking something in how I'm attempting to factor in drag ahead of time, or is it even more complicated than I'm realizing?
Answer by Bunny83 · May 08, 2015 at 12:18 PM
Your mentioned Math.Pow would work for your HorizontalPoint but not for VerticalPoint. The problem is that the calculations involved are addition and multiplication each step. An addition is a "fix-amount-change" while the multiplication is a "percentage-change". Since those things happen each step they are alternating.
So drag isn't a factor of the whole progression but of each step since each step is based on the last value plus the gravity vector the whole thing scaled down by drag. You can write it as endless progression like that:
((((initialVel + g)*d+g)*d+g)*d+g)*d...
// btw d = 1 - drag * Time.fixedDeltaTime
Just look at the result after 1, 2, 3 iterations:
// i = initialVel
0 iterations i
1 iterations i*d + g*d
2 iterations i*d*d + g*d*d + g*d
3 iterations i*d*d*d + g*d*d*d + g*d*d + g*d
4 iterations i*d^4 + g*d^4 + g*d^3 + g*d^2 + g*d
5 iterations i*d^5 + g*d^5 + g*d^4 + g*d^3 + g*d^2 + g*d
...
This progression can't be liniarized. So i see no way beside iterating it.
Floating point math nowadays is extremely fast. You can do thousands or millions of those calculations without much problems.
Also keep in mind that this doesn't even consider friction or collisions (which of course can't be predicted without iterating).
btw: The mandelbrot and Julia sets have a similar problem. You just have to iterate the function
z = z² + c
though with complex numbers. However the problem is the same that you can't directly calculate the result of the nth iteration without actually iterating from 0 up to n.
ps: here's a visualizer i've made in Unity. At the moment the zoom is fixed but you can click and drag to see the iterations for a given point. The definition of the set is simply: each point "c" for which the above equation doesn't escape to infinity after infinite iterations is inside the mandelbrot set. You always have to stop iterating at some point. I used 150 iterations to draw the set and 30000 to draw the lines which represents the progression for the point you aim at. Technically you can never be sure if a point is in the set since you would need infinite iterations to work it out. What you can say for sure is which points are not in the set ^^.
The colors are simply picked depending on how fast (after how many iterations) a point escapes the radius of 2 (in which case it always escapes since a value greater than 2 can only grow larger in magnitude).
Thank you very much for the feedback. I was a little too focused on avoiding simulation that I lost sight of whether I was actually approaching it from the right perspective.
(By the way, your $$anonymous$$andelbrot visualizer rocks!)
Your answer
Follow this Question
Related Questions
[3D] How do I display debug trajectory based on launch velocity? 2 Answers
Trajectory of a projectile formula. Does anyone know maths? 5 Answers
How to make an arrow fly realistically. 3 Answers
Bomb Trajectory for a "Water Canon" (Maths) 1 Answer
How to calculate the angle of a trajectory to hit the target 1 Answer