Can anyone see what I’m doing wrong?
Yes. You’re playing fast and loose with gravity. I’m not sure where you got those formulae from. If I knew that, I could maybe unpick them and show where you’re going wrong with those formulae. I could have a go at working out where they came from, but actually it would be much easier just to explain the right way to do what you want to do. I don’t know what level to pitch this at, so I apologise in advance if I get it wrong.
You have some object that you want to move according to some physical law. We’ve known for quite some time how that works: there’s a force field acting on the object and we use Newton’s second law to connect that to the motion:
F = m a
In this case, F
is the gravitational pull. From what you write, I’m assuming that we’re dealing with gravity on or near the Earth’s surface and that the heights are insignificant when compared to the Earth’s radius (about 6000km). So we can approximate the force of gravity by a downward pull of 9.82 N. Assuming constant mass, this means that Newton’s second law translates to:
a = [0, -9.82]
(writing vectors as row vectors for ease of typing)
Now acceleration is the second derivative of position, so we could write this as
x'' = [0, -9.82]
That seems quite succinct. There’s a problem with it, though. It is a Differential Equation. Whilst we can solve that one explicitly, it is more robust to implement differential equations via a step-by-step method. The general method for this has also been known for quite some time (there’s not much that’s new in mathematics!) and is called Euler’s method. It says that if we have an ordinary differential equation of the form x' = f(x)
then the estimate for x(t + h)
is x(t) + h f(x)
.
So we want to apply this to the ODE (Ordinary Differential Equation) above. There’s a problem, though. Euler’s method, as I’ve written it, works for 1st order (one derivative) but the one above is 2nd order (two derivatives). It is possible to modify Euler’s method to arbitrary order, but it is neater (and easier to code!) to modify the ODE to 1st order. To do that, we introduce velocity. We already have it as x'
but we want to give it a different name and treat it as a new quantity. Let’s call it v
. Note that this is a vector-valued function (“speed” is the magnitude of velocity).
So now we have a system:
x' = v
v' = [0,-9.82]
We solve this using Euler’s method to see that
x(t + h) = x(t) + h v(t)
v(t + h) = v(t) + h[0,-9.82]
Note that we use the old value of v(t)
to compute x(t + h)
, not the new value. So when implementing, keep the old values until the new values have been fully computed (in this example it’s possible to choose the order of computation to avoid this but in more complicated situations you need to do it properly).
We also need the initial conditions, x(0)
and v(0)
. With those, we’re done. Incidentally, v(0) = vec2(touch.x,touch.y) - origin
and you don’t ever have to compute the angle.