How would I calculate Altitude. EX: I throw a rock up and I want to calculate how far it will go and how high up it will go and drop. How would I do this using math? We could use magic numbers and do this, but what would be the equation for this. Please keep it simple, I’m in early Trig.
I just wrote it as a lua code to explain it better
basically the max height is the initial upward velocity squared, then divided by the downward acceleration (gravity) multiplied by 2.
local gravity = 10 -- acceleration per second downwards
local speed = 20 -- initial vertical velocity
local max_height = (speed^2)/(2*gravity)
print(max_height)
TL;DR: Go to the end of the answer.
Maximum Altitude
Since we only need to calculate the maximum altitude, we only need to work in the vertical component of space (Y axis). We must to have 2 things in consideration:
Vertical speed right after you launch it;
Gravity acceleration pointed towards the ground.
In order to calculate this, we can resort to the movement equations. Adapting them to the situation:
y(t) = y0 + v0y * t - 0.5 * g * t^2
vy(t) = v0y - g * t
Acceleration takes a negative value because we’re considering that the positive values are upwards, and gravity points downwards.
Considering that:
- y(t) is the altitude of the rock, at any given time;
- vy(t) is the vertical speed of the rock, at any given time.
- y0 is the initial altitude of the rock. For this sample, y0 = 0;
- v0y is the initial vertical speed;
- g is the gravity acceleration.
We know that, when an object in free falling hits it’s maximum altitude, it’s vertical speed is equal to zero. So:
vy(t) = 0 <=> v0y - g x t = 0 <=> g x t = v0y <=> t = (v0y/g)
Applying t to the position equation:
y(t) = y0 + v0y * t - 0.5 * g * t^2 = 0 + v0y * (v0y/g) - 0.5 * g * (v0y/g)^2 = (v0y^2/g) - 0.5 * (v0y^2/g) = 0.5 * (v0y^2 / g) = (v0y^2/2g)
As SnakeWorl concluded, we have:
local gravity = 10 -- acceleration per second downwards (studs per second sqaure in Roblox units)
local speed = 20 -- initial vertical velocity (studs per second in Roblox units)
local max_height = (speed^2)/(2*gravity)
print(max_height) -- equal to (20^2 / 2*10) = 400/20 = 20 studs
On a Roblox environment:
-- default gravity in Roblox is 196.2 studs a second
local gravity = game.Workspace.Gravity -- acceleration per second downwards (studs per second sqaure in Roblox units)
local speed = speedVector.Y -- initial vertical velocity (studs per second in Roblox units)
local max_height = (speed^2)/(2*gravity)
print(max_height) -- equal to (20^2 / 2*10) = 400/20 = 20 studs
If you want the absolute value of how high will the rock go, just add the y0 value (that we considered 0 - in most situations, it isn’t.) to the final max_height
value we calculated.
If you want to calculate the altitude of said rock using a reference point with an altitude h
, you should add (y0 - h) to the final value instead.
But…
For this one calculation we’ll need to take all the three components. I am assuming the floor is horizontal.
The first thing is to join the X and Z components of your speed vector, and transform it into an horizontal speed value. We’ll do a trick here and pretend that the world is 2D instead of 3D:
local horizontal_speed = math.sqrt(speedVector.X^2 + speedVector.Z^2)
This value is calculated based on the Pythagorean Theorem.
Then, we will apply once again the movement equations, but for both horizontal and vertical axes.
Since gravity only points downwards, the horizontal speed isn’t altered by any acceleration (ax = 0). So:
This time we won’t take y0 as 0, but as the initial height of the rock subtracted by the height of the floor;
x0 = 0;
x(t) = x0 + v0x * t - 0.5 * 0 * t^2 = v0x * t
vx(t) = v0x - 0 * t = v0x
y(t) = y0 + v0y * t - 0.5 * g * t^2 = (rH - fH) + v0y * t - 0.5 * g * t^2
vy(t) = v0y - g * t
Considering that:
- x(t) is the distance of the rock to the point it was launched - only the horizontal component;
- v0x is the horizontal speed of the rock.
- y(t) is the altitude of the rock, at any given time;
- vy(t) is the vertical speed of the rock, at any given time.
- y0 is the initial altitude of the rock. For this sample, y0 = (rH - fH);
- v0y is the initial vertical speed;
- g is the gravity acceleration.
- rH is the absolute height of the rock immediately before it is launched.
- fH is the absolute height of the floor.
Please note, we’re assuming that the rock will stop once it collides with the floor for the first time. These equations do not predict bouncing!
So, we know that at the maximum range, the rock’s altitude will be the same as the floor’s altitude. So:
y(t) = fH <=> (rH - fH) + v0y * t - 0.5 * g * t^2 = fH <=> rH - 2fH + v0y * t - 0.5g * t^2 = 0 <=> t = ((-v0y)±√(v0y^2 - 4* (-0.5) * (rH - 2fH)))/2 * (-0.5) <=> t = -(-v0y ± √(v0y^2 + 2rH - 4fH)) <=> t = v0y + √(v0y^2 + 2rH - 4fH) OR t = v0y - √(v0y^2 + 2rH - 4fH)
We got two results, but only the biggest one matters:
If the floor is above the place where the rock was launched, then the lowest value would mean the time that the rock hit the floor altitude during climbing stage; otherwise, said value is <= 0.
We know that the argument of a square root is never below 0, this is, if we have √x, then x >= 0. This also means that √x >= 0
So, √(v0y^2 + 2rH - 4fH) >= 0. We then come to the conclusion that √(v0y^2 + 2rH - 4fH) >= -√(v0y^2 + 2rH - 4fH) <=> v0y + √(v0y^2 + 2rH - 4fH) >= v0y - √(v0y^2 + 2rH - 4fH)
Hence, we’ll always choose v0y + √(v0y^2 + 2rH - 4fH)
Now we can apply that to the horizontal equation:
x(t) = v0x * t = v0x * (v0y + √(v0y^2 + 2rH - 4fH))
TLDR: JOINING EVERYTHING TOGETHER
With these values now you can build the code
We’ll assume you have a Part variable (floor
), and two vector3 variables (rockPos
and rockVelocity
). With everyting, we have:
-- getting our values.
local fH = floor.CFrame.Y
local rH = rockPos.Y
local v0y = rockVelocity.Y
local v0x = math.sqrt(rockVelocity.X^2 + rockVelocity.Z^2)
local g = game.Workspace.Gravity -- default value is 196.2
local max_height = (rH - fH) + (v0y^2)/(2*g) -- maximum height
local range = v0x * (v0y + math.sqrt(v0y^2 + 2*rH - 4*fH)) -- how far will the rock go