How to calculate ballistic trajectory in advance?

Hello
I use ApplyImpulse to push a sphere with a known mass towards a target. I use a known Force, which is enough to push the sphere to the target. Any idea how can I calculate the vertical angle which I need to use (the Y coordinate of the directional vector)?

Thanks

1 Like

I tried it but it does not work for me. The calculated angle is not correct.
It does not take into account the mass of the part (sphere), which I am pushing?

Mass does not affect actually affect trajectory calculations—heavier objects have more inertia, but they’re also pulled by gravity more, and it all cancels out in the equations.

Could you share how you’re using the code?

	local sphere2 = workspace.Sphere:Clone()
	sphere2.CanCollide = true
	sphere2.Anchored = false
	sphere2.Parent = workspace.Shells



	local function MaxDistance(v, g, d, h)
		local m = h / d
		local v2 = v * v
		return (v2*math.sqrt(m*m + 1) - m*v2) / g
	end

	-- Compute 2D launch angle. First return value is true if within range, second is the angle.
	-- v: launch velocity
	-- g: gravity (positive) e.g. 196.2
	-- d: horizontal distance
	-- h: vertical distance
	-- higherArc: if true, use the higher arc. If false, use the lower arc.
	local function LaunchAngle(v: number, g: number, d: number, h: number, higherArc: boolean): (boolean, number)
		local max_x = MaxDistance(v, g, d, h)
		local v2 = v * v

		if d > max_x then
			return false, math.atan(v2 / (g * max_x))
		end

		local v4 = v2 * v2
		local root = math.sqrt(v4 - g*(g*d*d + 2*h*v2))
		if not higherArc then root = -root end
		return true, math.atan((v2 + root) / (g * d))
	end

	-- Compute 3D launch direction from. First return value is true if within range, second is the direction.
	-- start: start position
	-- target: target position
	-- v: launch velocity
	-- g: gravity (positive) e.g. 196.2
	-- higherArc: if true, use the higher arc. If false, use the lower arc.
	local function LaunchDirection(start, target, v, g, higherArc: boolean)
		-- get the direction flattened:
		local horizontal = Vector3.new(target.X - start.X, 0, target.Z - start.Z)

		local h = target.Y - start.Y
		local d = horizontal.Magnitude
		local inRange, a = LaunchAngle(v, g, d, h, higherArc)

		-- speed if we were just launching at a flat angle:
		local vec = horizontal.Unit * v

		-- rotate around the axis perpendicular to that direction...
		local rotAxis = Vector3.new(-horizontal.Z, 0, horizontal.X)

		-- ...by the angle amount
		return inRange, CFrame.fromAxisAngle(rotAxis, a) * vec
	end

	local target = workspace.Target 

	local power = 6600
	
	local inRange, dir = LaunchDirection(sphere2.Position, target.Position, 6600, workspace.Gravity, false)
	
	sphere2:ApplyImpulse(dir)
	


Ah I see

The function provides you with a velocity, not a force. So either:

  • Set sphere2.LinearAssemblyVelocity to dir directly, or

  • Continue using impulses but multiply dir by sphere2.AssemblyMass

I tried, but unfortunately neither of these 2 work for me
what should I put in the 3d parameter “v” here?
local inRange, dir = LaunchDirection(sphere2.Position, target.Position, 6600, workspace.Gravity, false)
I want to push a part with a certain mass (in my case 23.457) with a force of 6600

I got it, sorry :slight_smile:
I must put force/mass

It’s your desired launch velocity magnitude (which you can derive from mass and force if you prefer).

You may want to print out inRange, it’s possible that it’s not possible to meet the target with the given velocity.

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.