How do I calculate an assembly's parabolic trajectory?

I have a part that i’ll move with ApplyImpulse and I’d like to know where it’s gonna be given t

1 Like
-- s_x = u_x * t
-- s_y = u_y * t + 1/2 at²
-- s_z = u_z * t

ImpulseVelocity = ... -- set it here IG (Vector3)
ImpulseX = ImpulseVelocity.X
ImpulseY = ImpulseVelocity.Y
ImpulseZ = ImpulseVelocity.Z

t =  ... -- Number

DeltaX = ImpulseX * t
DeltaY = ImpulseY * t - 0.5 * workspace.Gravity * t * t
DeltaZ = ImpulseZ * t

InitialPosition = ... -- Vector3
FinalPosition = InitialPosition + Vector3.new(DeltaX, DeltaY, DeltaZ)

Note that this code does NOT account for the ball colliding with anything, including the floor - it acts as though the ball is non-collide completely.
Code is also untested :slight_smile:

Thanks for the reply, but it’s not working as expected, would that be because it doesnt take mass into account? It sure is doing a parabolic trajectory at least:

Here’s the code:

local cube = workspace.CFrameCube
local origin = cube.Position
local mass = cube.Mass
local force = (-Vector3.zAxis + Vector3.yAxis * 2).Unit * 50

local function compute(t)
	return origin + Vector3.new(force.X * t, force.Y * t - 0.5 * workspace.Gravity * t * t, force.Z * t)
end

for t = 0, 1, 1 / 60 do
	local p = point()
	p.Position = compute(t)
	p.Parent = workspace
end

cube.Anchored = false
cube:ApplyImpulse(force)

Yeah that’s completely fine, it is to be expected

The code does not appear to interact with mass. Try multiplying the input with the part mass.

I’m using the physic formulas for it, and they do NOT require mass. I’ll start up a test location and see if I can figure out why the code isn’t functioning correctly

Oooh Actually yeah IK why. The assembly thing is giving a force, not a direct acceleration, isn’t it? That would mean that mass IS important. Let me adjust my script

Just because I’m not entirely sure how Roblox treats Impulses (I imagine it would be different than in real life due to the simulated nature of Roblox), is it fine if it gets the velocity 0.1 seconds after the impulse is applied?

I am not sure I understand what you mean, while it is different from real life, the equations should be similar to give valid results on roblox. Although to be fair ApplyImpluse could be faulty

Should be similar, yeah, but the equations I use are related to the velocity, not the acceleration.

For all intents and purposes, it should be fine using the velocity 0.1 seconds after the impulse, but I’m just wanting to ensure it doesn’t conflict with your use case.

My use case requires me to know the trajectory of the assembly before the impulse gets applied to it

I’ll do a bit of testing and determine the correlation between the velocity and the impulse’s accelleration then.

1 Like

As it turns out, ApplyImpulse seems to be odd, your equation did work when I directly set the AssemblyLinearVelocity

Your equation:

local function compute(t)
	return origin + Vector3.new(force.X * t, force.Y * t - 0.5 * workspace.Gravity * t ^ 2, force.Z * t)
end

Simplified? (it works at least)

local g = Vector3.new(0, -workspace.Gravity, 0)
local function compute(t)
	return origin + force * t + g * t * t / 2
end

I’ll bench the two and see which one is faster

Full code:

local cube = workspace.CFrameCube
local origin = cube.Position
local force = (-Vector3.zAxis + Vector3.yAxis * 2).Unit * 50

local function compute(t)
	return origin + Vector3.new(force.X * t, force.Y * t - 0.5 * workspace.Gravity * t ^ 2, force.Z * t)
end

for t = 0, 1, 1 / 60 do
	local p = point()
	p.Position = compute(t)
	p.Parent = workspace
end

cube.Anchored = false
cube.AssemblyLinearVelocity = force

Yeah, the code should be correct, however it was accounting for the ImpulseX variables being velocity, not force. Because the impulse thing applies a force, I’m having to adjust the code.

How would I take the initial velocity into account tho? Because my assembly could be moving as I try to calculate its trajectory given a force

I’ll add that to my code when I get the force accounted for

1 Like

Does this code work to your expectations?

local cube = workspace.CFrameCube
local origin = cube.Position
local mass = cube.Mass
local force = (-Vector3.zAxis + Vector3.yAxis * 2).Unit * 50 -- Vector3.new(0, 44.72..., -22.36...)
local InitialVelocity = cube.AssemblyLinearVelocity
local function compute(t)
	return origin 
		+ Vector3.new(force.X * t / mass, force.Y * t / mass - 0.5 * workspace.Gravity * t * t , force.Z * t / mass)
		+ InitialVelocity
end

local function point()
	local a = Instance.new("Part")
	a.Color = Color3.new(0,1,0)
	a.Anchored = true
	a.CanCollide = false
	a.Size = Vector3.new(1,1,1)
	return a	
end

for t = 0, 1, 1 / 60 do
	local p = point()
	p.Position = compute(t)
	p.Parent = workspace
end

cube.Anchored = false
cube:ApplyImpulse(force)

Sorry for the late reply, but it seems like that + InitialVelocity doesnt do what we’d like it to do, it just offsets the parabolic trajectory instead of changing it

Actually this seems to solve the issue

local function compute(t, origin, vel)
    local force = force + vel
	return origin
		+ Vector3.new(force.X * t / mass, force.Y * t / mass - 0.5 * workspace.Gravity * t * t, force.Z * t / mass)
end

Oh, my bad. easy enough fix.

local cube = workspace.CFrameCube
local origin = cube.Position
local mass = cube.Mass
local force = (-Vector3.zAxis + Vector3.yAxis * 2).Unit * 50 -- Vector3.new(0, 44.72..., -22.36...)
local InitialVelocity = cube.AssemblyLinearVelocity
local function compute(t)
	return origin 
		+ Vector3.new(force.X * t / mass, force.Y * t / mass - 0.5 * workspace.Gravity * t * t , force.Z * t / mass)
		+ InitialVelocity * t
end

local function point()
	local a = Instance.new("Part")
	a.Color = Color3.new(0,1,0)
	a.Anchored = true
	a.CanCollide = false
	a.Size = Vector3.new(1,1,1)
	return a	
end

for t = 0, 1, 1 / 60 do
	local p = point()
	p.Position = compute(t)
	p.Parent = workspace
end

cube.Anchored = false
cube:ApplyImpulse(force)
2 Likes

That works super nice, thanks for the help!