Predicting path of a body/shape

Questions about the LÖVE API, installing LÖVE and other support related questions go here.
Forum rules
Before you make a thread asking for help, read this.
arahlf
Prole
Posts: 12
Joined: Tue Sep 13, 2011 2:14 am

Predicting path of a body/shape

Post 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:
User avatar
ivan
Party member
Posts: 1915
Joined: Fri Mar 07, 2008 1:39 pm
Contact:

Re: Predicting path of a body/shape

Post 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.
arahlf
Prole
Posts: 12
Joined: Tue Sep 13, 2011 2:14 am

Re: Predicting path of a body/shape

Post 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 ^^
User avatar
Taehl
Dreaming in associative arrays
Posts: 1025
Joined: Mon Jan 11, 2010 5:07 am
Location: CA, USA
Contact:

Re: Predicting path of a body/shape

Post 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.
Earliest Love2D supporter who can't Love anymore. Let me disable pixel shaders if I don't use them, dammit!
Lenovo Thinkpad X60 Tablet, built like a tank. But not fancy enough for Love2D 0.10.0+.
arahlf
Prole
Posts: 12
Joined: Tue Sep 13, 2011 2:14 am

Re: Predicting path of a body/shape

Post 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?
User avatar
Taehl
Dreaming in associative arrays
Posts: 1025
Joined: Mon Jan 11, 2010 5:07 am
Location: CA, USA
Contact:

Re: Predicting path of a body/shape

Post 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.
Earliest Love2D supporter who can't Love anymore. Let me disable pixel shaders if I don't use them, dammit!
Lenovo Thinkpad X60 Tablet, built like a tank. But not fancy enough for Love2D 0.10.0+.
User avatar
Robin
The Omniscient
Posts: 6506
Joined: Fri Feb 20, 2009 4:29 pm
Location: The Netherlands
Contact:

Re: Predicting path of a body/shape

Post 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.
Help us help you: attach a .love.
User avatar
ivan
Party member
Posts: 1915
Joined: Fri Mar 07, 2008 1:39 pm
Contact:

Re: Predicting path of a body/shape

Post 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.
arahlf
Prole
Posts: 12
Joined: Tue Sep 13, 2011 2:14 am

Re: Predicting path of a body/shape

Post 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.
User avatar
slime
Solid Snayke
Posts: 3161
Joined: Mon Aug 23, 2010 6:45 am
Location: Nova Scotia, Canada
Contact:

Re: Predicting path of a body/shape

Post by slime »

Post Reply

Who is online

Users browsing this forum: Ahrefs [Bot], Bing [Bot] and 7 guests