Page 1 of 2

Predicting path of a body/shape

Posted: Tue Oct 11, 2011 5:02 am
by arahlf
I'm trying to predict the path of a moving ball ahead of time, but am running into a variety of difficulties. The example program below helps demonstrate what I'm trying to simulate. Press spacebar to make the ball start moving.

Code: Select all

require 'rectangle'

local world = love.physics.newWorld(0, 0, love.graphics.getWidth(), love.graphics.getHeight())
local height = 200
local y = (love.graphics.getHeight() - height) / 2
local x1 = 200
local y1 = 250
local angle = 1.2
local moving = false

local ball = {}
ball.body = love.physics.newBody(world, x1, y1, 1)
ball.shape = love.physics.newCircleShape(ball.body, 0, 0, 10)
ball.shape:setFriction(0)
ball.body:setBullet(true)

local topWall = {}
topWall.body = love.physics.newBody(world, 0, y)
topWall.shape = love.physics.newRectangleShape(topWall.body, love.graphics.getWidth() / 2, 0, love.graphics.getWidth(), 1)
topWall.shape:setFriction(0)

local bottomWall = {}
bottomWall.body = love.physics.newBody(world, 0, y + height)
bottomWall.shape = love.physics.newRectangleShape(bottomWall.body, love.graphics.getWidth() / 2, 0, love.graphics.getWidth(), 1)
bottomWall.shape:setFriction(0)

function love.update(dt)
    world:update(dt)
end

function love.draw()
    love.graphics.line(0, y, love.graphics.getWidth(), y)
    love.graphics.line(0, y + height, love.graphics.getWidth(), y + height)
    love.graphics.circle('line', ball.body:getX(), ball.body:getY(), ball.shape:getRadius(), 50)

    local lastX, lastY = x1, y1

    -- draw the zig zag lines
    for i=1, 6 do
        local currX, currY, knownSide

        if (angle < 0) then
            knownSide = lastY - y
            currY = y
        else
            knownSide = y + height - y1
            currY = y + height
        end

        local missingSide = math.abs(knownSide / math.tan(angle))
        currX = lastX + missingSide

        love.graphics.line(lastX, lastY, currX, currY)

        lastX, lastY = currX, currY
        angle = angle * -1
    end
end


function love.keypressed(key)
    if (key == ' ' and not moving) then
        moving = true

        local factor = 10

        ball.body:applyImpulse(math.cos(angle) * factor, math.sin(angle) * factor)
    end
end
In the current state, the ball obviously doesn't even remotely follow the predicted path. If I set the ball's restitution to 1, then it becomes pretty close, but the center of the ball does not follow the guide lines. I think the problem might be that the circle actually collides with the wall sooner than the guide line expects, by a factor of ~ the radius, but I'm not positive. I'm also not even sure if my "expected" path for the ball is even technically/physically correct.

Any ideas? Sorry if this is confusing :crazy:

Re: Predicting path of a body/shape

Posted: Tue Oct 11, 2011 7:52 am
by ivan
arahlf wrote:If I set the ball's restitution to 1, then it becomes pretty close, but the center of the ball does not follow the guide lines.
Your projected line touches the walls. In order for the center of the circle to touch the walls then it would have to penetrate the walls. It can't do that since its radius is greater than zero. Other than that, your projected path is correct if both the ball and the walls have a restitution of 1 and there are no outside forces acting upon the circle.

Generally, it doesn't make sense to try and predict the result of colisions in Box2D. Why use Box2D at all if you are going to calculate the collisions yourself? It also becomes increasingly complicated if you factor in joints, dapming, gravity and so on.

Re: Predicting path of a body/shape

Posted: Wed Oct 12, 2011 12:20 am
by arahlf
Ok that makes sense, thanks! I was almost to the same conclusion :oops:

I'm making a pool (billiards) game where I draw some "guide" lines to help show the path of the cue ball (off walls primarily) up until contact with other balls to help line up shots. More than anything, I'm using it as a nice refresher in geometry/trig ^^

Re: Predicting path of a body/shape

Posted: Wed Oct 12, 2011 12:37 am
by Taehl
Hmm... I guess one way you could do things if you wanted to use Box2D would be to pre-simulate the simulation (in one frame, with no graphics), recording the position of whatever it is you need to know, then when the player says "go", you run the simulation normally. Make sure you use a fixed timestep or accumulator approach so that your simulations play out the same way.

Re: Predicting path of a body/shape

Posted: Wed Oct 12, 2011 1:39 am
by arahlf
I'm not quite sure I follow. Would I basically have 2 duplicate worlds, but per love.update, I would run the "simulation" world's update method x number of times until I gather enough pathing data?

Re: Predicting path of a body/shape

Posted: Wed Oct 12, 2011 3:09 am
by Taehl
That would work. Personally, I, instead of having two worlds, would just save the data of the one, run sim A until I had the results I wanted, then reset it with the saved data and run sim B.

Re: Predicting path of a body/shape

Posted: Wed Oct 12, 2011 6:25 am
by Robin
Taehl wrote:That would work. Personally, I, instead of having two worlds, would just save the data of the one, run sim A until I had the results I wanted, then reset it with the saved data and run sim B.
Of course, that way you have to commit to a certain future before you can see the results, which would make the whole thing a bit moot.

Re: Predicting path of a body/shape

Posted: Wed Oct 12, 2011 6:39 am
by ivan
Taehl wrote:That would work. Personally, I, instead of having two worlds, would just save the data of the one, run sim A until I had the results I wanted, then reset it with the saved data and run sim B.
Box2D is a non-deterministic library, that is the results of sim B will probably be just slightly different each time.

Another approach might be to simulate the world (with a constant timestep) and just record the positions/angles of bodies (without rendering!).
If the user decides to take the shot, you can just animate the bodies as they move to the resulting position.
Otherwise you just reset the world to its initial position.
This might be a nice approach since the number of bodies is fairly manageable in a 2D billiards game.

Re: Predicting path of a body/shape

Posted: Wed Oct 12, 2011 5:27 pm
by arahlf
So that would basically be the 2-worlds approach right?

I'm definitely leaning towards the "simulation" using box2d instead of trying to calculate/predict what box2d will do because even when I offset my calculations for the ball hitting earlier it doesn't seem to hit the lines as I'd expect... not sure if I'm just doing it wrong or something.

Re: Predicting path of a body/shape

Posted: Wed Oct 12, 2011 5:39 pm
by slime