4
$\begingroup$

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))) ]]-- 
  • 0
    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.2011-12-23

1 Answers 1

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

  • 0
    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?2011-12-23