# Finding force for trajectory

Using the trajectory equations provided on hyperphysics, I have developed some code to plot the trajectory of an object. I now need to work out the x and y forces to apply to make the object follow said path.

I know that F=MA but I can't seem to reverse this to find the x and y force values to cause an object of given mass to follow the trajectory curve plotted by general ballistic code.

Sorry for the lengthy question but I can provide code and more of my equations if necessary. Sorry if this if the wrong forum.

EDIT: The equations I am working with are:

velocity = Impulse / mass

velocity = Distance / time

Velocity = speed / time

Force = mass * acceleration

Momentum = mass * velocity

Impulse = avg force * time

[2ND EDIT:] The code follows - lua language, using the Corona SDK...

Matt

main.lua

local trajlibapi = require("trajectorylib")
local mathlibapi = require("mathlib")
local physics = require("physics")

physics.start()
physics.setGravity(0,10)

--[[ environment setup ]]--

local start, sling = nil, nil

local offsetX, offsetY = 50, 300

local iteration = 0.1 -- gap between increments of trajectory points
--local velocity = 40 -- launch velocity v/ms
--local angle = 60 -- launch angle (theta) degrees

--[[ trajectory plotting ]]--

function trajectory( velocity, angle, iteration )
local points, r, h, f = trajlibapi.calcTrajectoryPoints( 0, 0, velocity, angle, iteration )

print( 'angle: ', angle )
print( 'velocity: ', velocity )
print( 'range: ', r )
print( 'height: ', h )
print( 'flight time: ', f )

for i=1, #points do
--print( math.round( points[i].x ), math.round( points[i].y ) )
display.newCircle( start.x + points[i].x, start.y - points[i].y, (points[i].velocityx + points[i].velocityy) * 0.1 )
end

return points
end

--[[ throwing the ball ]]--

function throw( points, sling, start, distance, angle )
local ball = display.newCircle( start.x, start.y, radius )
ball.alpha = .7
ball:setFillColor( 90,90,200 )

local point = points[2]
local area = trajlibapi.calcAreaOfCircle( radius )
local gm = 1 * area
local g = 2.1
print('area: '..area)
print('gm: '..gm)
print('dist: '.. distance)

--ball:applyLinearImpulse( start.x-sling.x, start.y-sling.y, ball.x, ball.y )
--ball:applyForce( (start.x-sling.x)*gm, (start.y-sling.y)*gm, ball.x, ball.y )

local vx, vy = trajlibapi.calcInitialVelocity( start.x, start.y, angle, distance )
print('velocity: '..vx,vy)
ball:setLinearVelocity( vx, vy )

--print('applied: ', point.x, -point.y )

function ball:timer(event)
timer.cancel( ball.t )
Runtime:removeEventListener("enterFrame", ball)
ball:removeSelf()
end
ball.t = timer.performWithDelay(2000, ball, 1)

function ball:enterFrame(event)
local c = display.newCircle(ball.x,ball.y,2)
c:setFillColor(255,0,0)
end
end

--[[ initial point capture ]]--

function touch(event)
if (not start) then
start = event
display.newCircle( event.x, event.y, 2 )
elseif (not sling) then
sling = event
display.newCircle( event.x, event.y, 2 )
local c = display.newCircle( start.x, start.y, mathlibapi.lengthOf( start, sling ) )
c:setStrokeColor( 0,0,255 )
c:setFillColor( 0,0,0,0 )
c.strokeWidth = 2

local angle = math.abs( mathlibapi.angleOf( sling, start ) )
local distance = mathlibapi.lengthOf( sling, start )
local points = trajectory( distance, angle, iteration )
throw( points, sling, start, distance, angle )
end
end



trajlib.lua:

module(..., package.seeall)

--[[ references ]]--

-- The code in this listing was derived from this first URL:
-- http://hyperphysics.phy-astr.gsu.edu/hbase/traj.html
-- http://en.wikipedia.org/wiki/Trajectory_of_a_projectile

--[[ support functions ]]--

local function vxf( velocity, acceleration )
return velocity * math.cos( acceleration * math.pi / 180 )
end

local function vyt( velocity, acceleration, time )
return velocity * math.sin( acceleration * math.pi / 180 ) - 9.8 * time
end

local function yt( velocity, acceleration, time )
return velocity * math.sin( acceleration * math.pi / 180 ) * time - 0.5 * 9.8 * time * time
end

--[[ worker functions ]]--

function totalRangeHeightFlightTime( v, ag )
local h = vyt(v, ag, 0) * vyt(v, ag, 0) / (2 * 9.8)
local t = 2 * vyt(v, ag, 0) / 9.8
local r = v * v * math.sin( 2 * ag * math.pi / 180 ) / 9.8
return r, h, t
end

function positionAtTime(v, ag, t)
local vx = vxf(v,ag) -- horizontal velocity
local x = vxf(v,ag) * t -- horizontal distance
local vy = vyt(v, ag, t) -- vertical velocity
local y = yt(v, ag, t) -- height at time 't'

return x, y, vx, vy
end

--[[ calculate trajectories ]]--

-- returns a collection of points determined as the trajectory of the object
function calcTrajectoryPoints( startX, startY, velocity, angle, iteration )
if (not iteration) then
iteration = 0.1
end

local r, h, f = totalRangeHeightFlightTime(velocity, angle) -- total range, height and flight time
local points = {}

for t=0, f, iteration do
local x, y, vx, vy = positionAtTime(velocity, angle, t)
points[ #points+1 ] = { x=x, y=y, time=t, velocityx=vx, velocityy=vy }
end

return points, r, h, f
end

function calcInitialVelocity( startX, startY, angle, force )
return force * math.cos(angle), force * math.sin(angle)
end

--[[ area functions ]]--

end


mathlib.lua:

module(..., package.seeall)

-- returns the distance between points a and b
function lengthOf( a, b )
local width, height = b.x-a.x, b.y-a.y
return math.sqrt(width*width + height*height)
end

-- converts degree value to radian value, useful for angle calculations
--  return (math.pi * degrees) / 180
end

end

-- rotates a point around the (0,0) point by degrees
-- returns new point object
function rotatePoint( point, degrees )
local x, y = point.x, point.y

local theta = convertDegreesToRadians( degrees )

local pt = {
x = x * math.cos(theta) - y * math.sin(theta),
y = x * math.sin(theta) + y * math.cos(theta)
}

return pt
end

-- rotates point around the centre by degrees
-- rounds the returned coordinates using math.round() if round == true
-- returns new coordinates object
function rotateAboutPoint( point, centre, degrees, round )
local pt = { x=point.x - centre.x, y=point.y - centre.y }
pt = rotatePoint( pt, degrees )
pt.x, pt.y = pt.x + centre.x, pt.y + centre.y
if (round) then
pt.x = math.round(pt.x)
pt.y = math.round(pt.y)
end
return pt
end

-- returns the degrees between (0,0) and pt
-- note: 0 degrees is 'east'
function angleOfPoint( pt )
local x, y = pt.x, pt.y
--print('angle: '..angle)
if angle < 0 then angle = 360 + angle end
--print('final angle: '..angle)
return angle
end

-- returns the degrees between two points
-- note: 0 degrees is 'east'
function angleBetweenPoints( a, b )
local x, y = b.x - a.x, b.y - a.y
return angleOfPoint( { x=x, y=y } )
end

function angleOf( a, b )
return math.atan2( b.y - a.y, b.x - a.x ) * 180 / math.pi
end

-- Takes a centre point, internal point and radius of a circle and returns the location of the extruded point on the circumference
-- In other words: Gives you the intersection between a line and a circle, if the line starts from the centre of the circle
function calcCirclePoint( centre, point, radius )
local distance = lengthOf( centre, point )
local fraction = distance / radius

local remainder = 1 - fraction

local width, height = point.x - centre.x, point.y - centre.y

local x, y = centre.x + width / fraction, centre.y + height / fraction

local px, py = x - point.x, y - point.y

return px, py
end

-- returns the smallest angle between the two angles
-- ie: the difference between the two angles via the shortest distance
function smallestAngleDiff( target, source )
local a = target - source

if (a > 180) then
a = a - 360
elseif (a < -180) then
a = a + 360
end

return a
end

-- is clockwise is false this returns the shortest angle between the points
--[[
function AngleDiff( pointA, pointB, clockwise )
local angleA, angleB = AngleOfPoint( pointA ), AngleOfPoint( pointB )

if angleA == angleB then
return 0
end

if clockwise then
if angleA > angleB then
return angleA - angleB
else
return 360 - (angleB - angleA)
end
else
if angleA > angleB then
return angleB + (360 - angleA)
else
return angleB - angleA
end
end

end
]]--

-- test code...
--[[
local pointA = { x=10, y=-10 } -- anticlockwise 45 deg from east
local pointB = { x=-10, y=-10 } -- clockwise 45 deg from east

print('Angle of point A: '..tostring(AngleOfPoint( pointA )))
print('Angle of point B: '..tostring(AngleOfPoint( pointB )))

print('Clockwise: '..tostring(AngleDiff(pointA,pointB,true)))
print('Anti-Clockwise: '..tostring(AngleDiff(pointA,pointB,false)))
]]--

-
You should include your trajectory equations in your post. That way potential answer-ers don't have to go searching to help you. –  matt Dec 23 '11 at 9:59
Could you show the entire code? And if you have the trajectory, why do you need to know the forces? I suppose you just want to simulate something moving. What are you trying to achieve? –  Raskolnikov Dec 23 '11 at 22:36
I can definitely post the code. I had not done that so far as I thought it would tilt my post towards a more programming orientation and this is a math forum. I am using the Box2D physics engine within the Corona SDK, using the lua language. Using hyperphysics' information I have coded a little app to plot the course of an object's trajectory given launch velocity and angle. Using Box2D I can launch a physics object, but it has mass which requires it to be taken into account when calculating the force to accurately traverse the given trajectory. I'm probably not explaining this well. –  Matt W Dec 23 '11 at 22:50

This can be analyzed easily using differential equations. Given that you refer to x and y coordinates, I'll restrict my answer to trajectories which can be modeled as $(x(t),y(t))$, $t$ representing time, for some continuous functions $x(t),y(t)$. I will use $\vec{F}(t) = (f_x(t),f_y(t))$ to denote the force applied to the object at time $t$. Your problem can then be written as the system of differential equations $$x''(t) = Mf_x(t)$$ $$y''(t) = Mf_y(t)$$ so the desired force vector is simply $\vec{F}(t) = \begin{pmatrix}x''(t)/M \\ y''(t)/M\end{pmatrix}$.
Also, is the trajectory is given by a function $y = h(x)$, then set $t = x$ to get $\vec{F}(x) = \begin{pmatrix}0 \\ h''(x)/M\end{pmatrix}$.