-- Uber l33t maths to calcluate the angle needed to throw a projectile a distance, given the altitude of the end point and the projectile's velocity function AngleOfReach(distance, altitude, velocity) local theta = math.atan((velocity^2 + math.sqrt(velocity^4 -196.2*(50*distance^2 + 2*altitude*velocity^2)))/(196.2*distance)) if theta ~= theta then theta = math.pi/4 end return(theta) end
****This code is from Explosive Grenade, written by DeviousDeviation
I do not understand how math.atan can calculate the angle using velocity, distance, and altitude with some arithmetic.
For these calculations, neglect "air resistance" (slowing down while traveling through the air); ROBLOX doesn't have any (though the real world does).
When you throw a projectile, the horizontal speed over the whole length of its arc is the same. If you throw it at speed
speed with an angle angle
to the horizontal, the horizontal speed will be speed * cos(angle)
.
Thus after t
time has passed, the horizontal position will be t * speed * cos(angle)
.
The vertical speed varies over time; it starts at speed * sin(angle)
, and after t
time it has decrease to speed * sin(angle) - t * gravity
(where gravity
is the acceleration due to gravity; it's 196.2
studs/second^2 in ROBLOX).
The vertical position ends up being a parabola, the integral of the above.
Thus after t
time has passed, the vertical position will be -gravity/2 * t^2 + t * speed * sin(angle)
.
We want the projectile to go horizontal_distance
horizontally. Solve for the time t
that that will happen at:
horizontal_distance = t * speed * cos(angle) t = horizontal_distance / (speed * cos(angle))
We want the projectile to go altitude
displacement vertically at the above time t
. i.e., we need to find the angle
such that
altitude = -gravity/2 * t^2 + t * speed with t = horizontal_distance / (speed * cos(angle))
Solving this is a little tricker. Start by solving for t
in the first equation, using the quadratic formula.
t = [ speed +- sqrt(speed^2 - 2 * altitude * gravity) ] / gravity
Now, use the two t =
equations (by transitivity) to create the relation
horizontal_distance / (speed * cos(angle)) = [ speed +- sqrt(speed^2 - 2 * altitude * gravity) ] / gravity
Solve for cos(angle)
:
gravity * horizontal_distance / [speed +- sqrt(speed^2 - 2 * altitude * gravity)] / speed = cos(angle)
You can solve cos(angle) = ...
using acos
, getting:
angle = math.acos(gravity * horizontal_distance / (speed + math.sqrt(speed^2 - 2 * altitude * gravity)) / speed)
The formula here is a little different from the one in the script, but they should be equivalent (assuming I didn't make any algebra mistakes).