Can't get accurate trajectory predictions with Box2d

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.
Post Reply
User avatar
akopyl
Prole
Posts: 21
Joined: Fri Jun 27, 2014 1:20 pm

Can't get accurate trajectory predictions with Box2d

Post by akopyl »

As the title says the trajectories that I predict don't line up with the path that the body ends up taking.
I'd also like to note that the innacuracy is proportional to the gravity. (world.lua line 8)
I'm attaching the .love file but please note that it's for v0.10.2. Sorry for all the bad code, any feedback is appreciated.

Here's the code that sets the player flying. (player.lua line 60)

Code: Select all

function player.mousereleased(x, y, mb, istouch)
  obj.player.body:setLinearVelocity((player.onScreenX-x)*ui.pullStrength, (obj.player.body:getY()-y)*ui.pullStrength)
end
Here's the trajectory drawing chunk of code. (Starts at ui.lua line 55)

Code: Select all

function ui.drawBackground()
  love.graphics.setColor(230, 100, 60)
  love.graphics.setLineWidth(H*0.006)
  love.graphics.setPointSize(H*0.006)
  if love.mouse.isDown(1) then
    love.graphics.line(player.onScreenX, obj.player.body:getY(), love.mouse.getX(), love.mouse.getY())
    -- Per second approach
    for n = .01, .8, .02 do
      love.graphics.setColor(230, 100, 60, 255-255*n/.8)
      love.graphics.line(player.onScreenX+(player.onScreenX-love.mouse.getX())*ui.pullStrength*n,
      obj.player.body:getY()+(obj.player.body:getY()-love.mouse.getY())*ui.pullStrength*n+(world.g*world.meter*n^2)/2,
      player.onScreenX+(player.onScreenX-love.mouse.getX())*ui.pullStrength*(n+.01),
      obj.player.body:getY()+(obj.player.body:getY()-love.mouse.getY())*ui.pullStrength*(n+.01)+(world.g*world.meter*(n+.01)^2)/2)
    end
    -- Per timestep approach
    love.graphics.setColor(51, 244, 88)
    for n = 1, 60, 1 do
      love.graphics.points(player.onScreenX + (player.onScreenX-love.mouse.getX())*ui.pullStrength*n/60,
      obj.player.body:getY() + (obj.player.body:getY()-love.mouse.getY())*ui.pullStrength*n/60 + (n*n+n)*(world.g*world.meter)/(60*60)/2)
    end
  end
end
game.love
Love version 0.10.2
(251.06 KiB) Downloaded 125 times
User avatar
pgimeno
Party member
Posts: 3579
Joined: Sun Oct 18, 2015 2:58 pm

Re: Can't get accurate trajectory predictions with Box2d

Post by pgimeno »

I haven't checked your units in detail, so there may be a bug there, but what I consider most likely is that you're hitting some internal Box2D clamping.

I've made this experiment:

Code: Select all

local lph, lg = love.physics, love.graphics

local metre = 10
local gravity = 40
local Vx, Vy = 40, -400

lph.setMeter(metre)

local world = lph.newWorld(0, metre * gravity)
local body = lph.newBody(world, 400, 300, "dynamic")
local shape = lph.newRectangleShape(20, 20)
local fixture = lph.newFixture(body, shape)
body:setLinearDamping(0)

body:setLinearVelocity(Vx, Vy)

local obj = {vx = Vx, vy = Vy, x = 400, y = 300}

function love.update(dt)
  dt = 1/60

  world:update(dt)

  local vx,vy = body:getLinearVelocity()
  obj.vy = obj.vy + gravity * metre * dt
  obj.x = obj.x + obj.vx * dt
  obj.y = obj.y + obj.vy * dt
end

local img = love.graphics.newImage(love.image.newImageData(1, 1, '\255\255\255\255'))

function love.draw()
  lg.setColor(255,255,255)
  lg.polygon("fill", body:getWorldPoints(shape:getPoints()))
  lg.setColor(0,255,0)
  lg.draw(img, obj.x, obj.y, 0, 10, 10, .5, .5)
end

function love.keypressed(k) return k == "escape" and love.event.quit() end
Most of the time, the green and the white squares are in sync, but for some values, things change. In particular, using the above parameters but changing metre to 3 or less causes a desync.

Adjusting your metre (and everything else accordingly) might help.

Besides that, I don't think the (n*n+n) you use in your formula is correct, but I guess that was some wild shot.

And while I'm here, it's a good idea to avoid defining functions inside other functions unless you specifically need it, e.g. when creating a closure for some upvalues. Each time you redefine the function, a new one needs to be created and the old one destroyed, which wastes CPU.
User avatar
akopyl
Prole
Posts: 21
Joined: Fri Jun 27, 2014 1:20 pm

Re: Can't get accurate trajectory predictions with Box2d

Post by akopyl »

Thanks! Turns out the bigger the meter the more accurate my prediction will be up to a certain extent.
Post Reply

Who is online

Users browsing this forum: Ahrefs [Bot] and 1 guest