miscellaneous physics questions

I would like to make a device which will propel a body in a certain direction. My question is; should use motor joints and other bodies to catapult the body or should i just use body:applyForce() with some simple maths for angle and force. I am looking for the most realistic affect(favouring realisticness(realisim?) over efficiency. Thanks in advance for any answers.

@Coder See this link. Sounds like it might be close to what you want.

http://codea.io/talk/discussion/5197/starter-game-2#Item_2

Thanks, that seems to be the cleanest approach

Edit: sorry if I was a little cryptic in my question

@Coder just something different if you’re open to another approach, sling shot with a ball and towers of squares, this was one of my first projects:


--# Main
-- flick

-- Use this function to perform your initial setup
function setup()
    displayMode(FULLSCREEN)
    scr = vec2()
    scr.x = 0
    scr.y = 0
    vel = vec2()
    PhysCreate:setup()
    -- ball 
    ball = physics.body(CIRCLE,40)
    ball.x = WIDTH/4
    ball.y = HEIGHT/2
    ball.interpolate = true
    ball.friction = 1
    ball.restitution = 0.35
    ballup = vec2(ball.x,ball.y+40)
    ang=vec2(0,40)
    -- walls
    vert={vec2(WIDTH*5,HEIGHT),vec2(0,HEIGHT),vec2(0,0),vec2(WIDTH*5,0),vec2(WIDTH*5,HEIGHT)}
    floor = physics.body(CHAIN,unpack(vert))
    
    -- store catapult variables
    pos = vec2(150,400)
    tpos = vec2(150,400)
    force = 0
    
    -- create boxes in grid
    bodies = {}
    local y = 1
    local x = 1
    for i = 1,45 do
        bodies[i] = PhysCreate:create(vec2(600+x*200,y*40),vec2(2,2))
        -- x < n, n sets the grid width
        if x < 5 then
            x=x+1
        else 
            y=y+1
            x=1
        end
    end
end

function touchPos()
    --print(vec2(CurrentTouch.x,CurrentTouch.y))
    if CurrentTouch ~= nil then
        return vec2(CurrentTouch.x,CurrentTouch.y)
    else 
        return vec2(150,400)
    end
end

function moveScreen()
    if ball.x > WIDTH - 300 - scr.x then
        scr.x = WIDTH - 300 - ball.x
    elseif ball.x < scr.x*-1 + 40 then
        scr.x = 40 - ball.x
    end 
    translate(scr.x,0)
end


-- This function gets called once every frame
function draw()
    -- This sets a dark background color 
    background(40, 40, 50)
    moveScreen()
    -- start touch and store first position
    if CurrentTouch ~= nil and CurrentTouch.state == BEGAN and touchPos().x < 300 then
        holding = 1
        if touchPos().x > 40 then
            pos = touchPos() 
        end
    end
    
    -- keep ball in the air while in red zone
    if ball.x < 300 then
        if ball.y < 100 then
            ball.linearVelocity = vec2(ball.linearVelocity.x*0.3,(100-ball.y)*5)
        end
    end
    
    -- grab ball and set force
    if holding == 1 then
        local bl = (touchPos()-vec2(ball.x,ball.y)):normalize()
        ball.linearVelocity = bl*touchPos():dist(vec2(ball.x,ball.y))*10

        force = touchPos():dist(pos)*0.1
    end
    
    -- release catapult and set ball velocity    
    if holding == 1 and CurrentTouch.state == ENDED and touchPos():dist(vec2(ball.x,ball.y)) < 40 then
        vel = (pos-touchPos())*force
        ball.linearVelocity = vel
        holding = 0
    end

    -- Set catapult starting variable if in red zone
    if ball.x > 300 and CurrentTouch.state == BEGAN and touchPos().x < 300 and holding == 0 then
        holding = 1
    elseif ball.x > 300 and touchPos().x > 300 and CurrentTouch.state == MOVING then
        holding = 0
    end
    
    -- draw boxes
    PhysCreate:draw()
    
    -- draw gui
    -- catapult area (red zone)
    line(300,0,300,HEIGHT)
    strokeWidth(0)
    fill(250,50,50,50)
    rect(-100,0,400,HEIGHT)
    -- catapult
    if holding == 1 then
        strokeWidth(15)
        fill(255)
        line(scr.x*-1+pos.x,pos.y,scr.x*-1+touchPos().x,touchPos().y)
        
        strokeWidth(3)
        fill(186, 186, 186, 255)
        ellipse(scr.x*-1+pos.x,pos.y,30)
    end
    -- draw ball
    strokeWidth(5)
    fill(100)
    ellipse(ball.x,ball.y,80)

    ang = ang:rotate(ball.angularVelocity/2000)
    ballup = ball.position + (ang):normalize()*35
    line(ball.x,ball.y,ballup.x,ballup.y)
end




--# PhysCreate
PhysCreate = class()

function PhysCreate:init(x)
    self.x = x
end

function PhysCreate:setup()
    Di = 0
    DTbl = {}
end

function PhysCreate:create(vpos,vsize)
    local vert = {vec2(-10*vsize.x,10*vsize.y),vec2(-10*vsize.x,-10*vsize.y),
    vec2(10*vsize.x,-10*vsize.y),vec2(10*vsize.x,10*vsize.y)}
    
    local p = physics.body(POLYGON,unpack(vert))
    p.mass = 2
    p.x = vpos.x
    p.y = vpos.y
    p.w = vsize.x*10*2
    p.h = vsize.y*10*2
    p.interpolate = true
    p.sleepingAllowed = false
    
    p.m = mesh()
    local mr = p.m:addRect(p.x,p.y,p.w,p.h,0)
    p.m:setRectTex(mr,0,0,1,1)
    
    Di = Di + 1
    DTbl[Di] = {p.m,mr,p}
end

function PhysCreate:draw()
    for i=1,#DTbl do
        local d = DTbl[i]
        d[1]:draw()
        d[1]:setRect(d[2],d[3].x,d[3].y,d[3].w,d[3].h,d[3].angle/57.3)
    end
end

function PhysCreate:touched(touch)
    -- Codea does not automatically call this method
end

@Luatee thanks