Rotation of a body around custom point.

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.
Kir
Prole
Posts: 6
Joined: Thu Dec 22, 2016 5:00 am

Re: Rotation of a body around custom point.

Post by Kir »

I just realized that there might have been some confusion, because I was talking about moving the center of mass and applying Force/Torque. I wanted to move the center of mass, because the "back" is much heavier than the front and the applyTorque() is needed, because the object is able to move and rotate on its own. The wheels for movement happen to be close to where the center of mass is, which is why I wanted applyTorque() to cause a rotation around that point. Sorry for the confusion. The body I'm trying to replicate basically is a little vehicle with two motorized wheels and a carrying wheel.
s-ol wrote:when you create a fixture you need to pass which body it is supposed to be added to, if you reuse the same they should 'stick'.
I'm guessing not like this? They just pass through each other.

Code: Select all

  objects.block1 = {}
  objects.block1.body = love.physics.newBody(world, 325, 200, "dynamic")
  objects.block1.shape = love.physics.newRectangleShape(0, 0, 100, 50)
  objects.block1.fixture = love.physics.newFixture(objects.block1.body, objects.block1.shape, 1)
  
  objects.block2 = {}
  objects.block2.body = love.physics.newBody(world, 325, 200, "dynamic")
  objects.block2.shape = love.physics.newRectangleShape(0, 0, 100, 50)
  objects.block2.fixture = love.physics.newFixture(objects.block1.body, objects.block2.shape, 1)
pgimeno wrote:To change the centre of mass, you have to alter the moment of inertia. Otherwise that assertion triggers
That looks just like what I wanted. Thanks. I'm just not sure how the parameters for Body:setMassData(x, y, mass, inertia) work together. It seems that if I want to push the center of mass further out, I need to increase the value for inertia, like you mentioned. I just don't understand the connection. Either way, this is indeed what I was trying to do, thanks.

Thanks everyone for your help.
User avatar
pgimeno
Party member
Posts: 3713
Joined: Sun Oct 18, 2015 2:58 pm

Re: Rotation of a body around custom point.

Post by pgimeno »

Kir wrote:That looks just like what I wanted. Thanks. I'm just not sure how the parameters for Body:setMassData(x, y, mass, inertia) work together. It seems that if I want to push the center of mass further out, I need to increase the value for inertia, like you mentioned. I just don't understand the connection.
Me neither, to be honest. A MoI value of 1 makes it happy when it's centered, but you need to go as high as 300 when it's off center. That doesn't seem to make sense according to the MoI of a rotating rectangle: https://en.wikipedia.org/wiki/List_of_m ... of_inertia (it's near the end of the first list; there's one for when the axis is at the centre and another one for when it's at the side. I'd expect a factor of at most 4, not 300).

Anyway, according to your description, using two shapes and two fixtures, and playing with the fixture's density, can probably model your desired behaviour better. You can even make one fixture be completely contained within the other, so that its collisions don't need to be calculated.
Kir
Prole
Posts: 6
Joined: Thu Dec 22, 2016 5:00 am

Re: Rotation of a body around custom point.

Post by Kir »

I finally figured out how to handle multiple fixtures (felt a bit oblivious) and tried that by creating a body with two shapes. I'll play around with the density to see what approach works better.
Thanks again for the help.
User avatar
Ref
Party member
Posts: 702
Joined: Wed May 02, 2012 11:05 pm

Re: Rotation of a body around custom point.

Post by Ref »

Two bodies (one interior to the other and of greater density) held together with a weld joint may or may not be what you want.
It will definitely solve your off-center rotation, however, the interior body will not respond as you might expect on impact, momentarily continuing to move when the exterior body stops.
I don't know.
Maybe you would want the center of gravity to momentarily shift on impact.
Gives sort of a bucket of water effect.
User avatar
pgimeno
Party member
Posts: 3713
Joined: Sun Oct 18, 2015 2:58 pm

Re: Rotation of a body around custom point.

Post by pgimeno »

This is probably already a dead topic, but in case someone finds it looking for a solution, here's one example of the code I had in mind when I was talking about using two fixtures and playing with density.

Code: Select all

local world = love.physics.newWorld(0, 0, false)

love.physics.setMeter(10)
local body = love.physics.newBody(world, 400, 300, "dynamic")

local shape = love.physics.newRectangleShape(40, 30)
local fixture = love.physics.newFixture(body, shape, 0.001)
local shape2 = love.physics.newPolygonShape(-18,-13, -18,13, -16,13, -16,-13)
local fixture2 = love.physics.newFixture(body, shape2, 1)

body:setAngularVelocity(math.pi) -- 30 rpm

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

function love.draw()
  love.graphics.polygon("line", body:getWorldPoints(shape:getPoints()))
  love.graphics.polygon("line", body:getWorldPoints(shape2:getPoints()))
  local x, y = body:getWorldCenter()
  love.graphics.rectangle("fill", x-1, y-1, 3, 3)
end
The advantages over using setMassData are that it will look physically correct with no need to guess the correct value of the parameter, and it won't suddenly crash if you change the parameters.

The advantages over using a weld joint are that you don't need another body, and that a weld joint is actually somewhat flexible, while this is 100% rigid. The latter could be a drawback too, depending on what you want to accomplish (like the water effect that Ref mentions; it can be desirable to have a flexible heavy weight inside the shape for certain purposes).
User avatar
Ref
Party member
Posts: 702
Joined: Wed May 02, 2012 11:05 pm

Re: Rotation of a body around custom point.

Post by Ref »

This is probably already a dead topic, but in case someone finds it looking for a solution, here's one example of the code I had in mind when I was talking about using two fixtures and playing with density.
Must admit that box2d is pretty much a "black box" for me.

Tried you code suggestion and the object I got rotated around the center coordinates of the body, not offset. Not sure a body can be created with two shapes and two fixtures. Did you actually try your code?

Can't rule out the possibility that I screw up something else but the only way I go off center rotation is the use of two offset, overlapping bodies connected with a weld joint.

Maybe someone else has some ideas.
User avatar
pgimeno
Party member
Posts: 3713
Joined: Sun Oct 18, 2015 2:58 pm

Re: Rotation of a body around custom point.

Post by pgimeno »

Well, this is [a cropped version of] what I see. Is that not what you see?

Image

Edit: And this shows the problem (or the feature) of weld joints. They are too elastic:

Code: Select all

local world = love.physics.newWorld(0, 50, false)

love.physics.setMeter(10)
local body = love.physics.newBody(world, 400, 300, "dynamic")
local shape = love.physics.newRectangleShape(40, 30)
local fixture = love.physics.newFixture(body, shape, 0.05)

local body2 = love.physics.newBody(world, 400, 300, "dynamic")
local shape2 = love.physics.newPolygonShape(-18,-13, -18,13, -16,13, -16,-13)
local fixture2 = love.physics.newFixture(body2, shape2, 800)
fixture2:setFilterData(0, 0, -1)

local joint = love.physics.newWeldJoint(body, body2, 400, 300)

-- box everything in a ChainShape
local body3 = love.physics.newBody(world, 400, 300, "static")
local shape3 = love.physics.newChainShape(true,
   -200.5, -200.5, 200.5, -200.5, 200.5, 200.5, -200.5, 200.5)
local fixture3 = love.physics.newFixture(body3, shape3, 1)

body2:setAngularVelocity(math.pi) -- 30 rpm

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

function love.draw()
  love.graphics.polygon("line", body:getWorldPoints(shape:getPoints()))
  love.graphics.polygon("line", body2:getWorldPoints(shape2:getPoints()))
  love.graphics.line( body3:getWorldPoints(shape3:getPoints()))
  local x, y = body2:getWorldCenter()
  love.graphics.rectangle("fill", x-1, y-1, 3, 3)
end
User avatar
Ref
Party member
Posts: 702
Joined: Wed May 02, 2012 11:05 pm

Re: Rotation of a body around custom point.

Post by Ref »

OK! Found out what my problem was.
I was using Love 0.10.1 and object rotate about the body center.
When I used the same code on Love 0.10.2 I get your off center rotation.
Go figure.
Agree that weld joints are too elastic.
Thanks for your help.
User avatar
pgimeno
Party member
Posts: 3713
Joined: Sun Oct 18, 2015 2:58 pm

Re: Rotation of a body around custom point.

Post by pgimeno »

Weird, it works for me (under Linux) in 0.8.0, 0.9.0, 0.9.1, 0.9.2, 0.10.0, 0.10.1 and 0.10.2. It fails in 0.7.2, which doesn't support that form of love.physics.newWorld.

Must be a Windows issue.
Post Reply

Who is online

Users browsing this forum: Google [Bot] and 5 guests