Take the 2-minute tour ×
Mathematics Stack Exchange is a question and answer site for people studying math at any level and professionals in related fields. It's 100% free, no registration required.

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 radius = 50
    local ball = display.newCircle( start.x, start.y, radius )
    ball.alpha = .7
    ball:setFillColor( 90,90,200 )
    physics.addBody( ball, "dynamic", {friction=.1, bounce=.1, density=1, radius=radius } )

    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
    Runtime:addEventListener("enterFrame", ball)
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

Runtime:addEventListener("tap", touch)

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

-- http://answers.yahoo.com/question/index?qid=20080617223556AA8DD8M
function calcInitialVelocity( startX, startY, angle, force )
    return force * math.cos(angle), force * math.sin(angle)
end


--[[ area functions ]]--

function calcAreaOfCircle( radius )
    return math.pi * radius * radius
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
function convertDegreesToRadians( degrees )
--  return (math.pi * degrees) / 180
    return math.rad(degrees)
end

function convertRadiansToDegrees( radians )
    return math.deg(radians)
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
    local radian = math.atan2(y,x)
    --print('radian: '..radian)
    local angle = radian*180/math.pi
    --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)))
]]--
share|improve this question
    
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

1 Answer 1

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}$.

share|improve this answer
    
I'm afraid I don't understand differential equations and your notation is unfamiliar to me as I am not educated above GCSE maths. I do hate the fact that I have not learned higher and find it extremely hard, but I am trying. My need to learn here is based on a programming requirement of personal interest. Perhaps another forum is better suited? –  Matt W Dec 23 '11 at 22:32

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.