# 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
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.