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

Rotation of a body around custom point.

Post by Kir »

Hi, I couldn't find anything on this other than one solution that wasn't satisfying.

I want to rotate a rectangle body, but not around its center. I want to rotate it around one of its short edges.
A proposed solution here in the forum was changing something in the love.draw call for the rectangle/image (I think x and y offset). This works visually, but its actual position is different, which means that collisions don't work properly anymore.

Is there some way to change the rotation anchor of a body? I use the body:applyTorque( ) function to rotate.

Thanks
User avatar
s-ol
Party member
Posts: 1080
Joined: Mon Sep 15, 2014 7:41 pm
Location: Milan, Italy
Contact:

Re: Rotation of a body around custom point.

Post by s-ol »

You can't have a body spin around a point that is not it's center of mass without constantly applied forces because that's just not how physics work in reality, which box2d is modelled after.

You can apply a force at a position using the second overloaded cariant of https://love2d.org/wiki/Body:applyForce or Body:applyImpulse but depending on what younare trying to do it might be more appropriate to have a joint or compose the body of two fixtures with different densities to push the center of mass closer to the edge.

s-ol.nu

Code: Select all

print( type(love) )
if false then
  baby:hurt(me)
end
Kir
Prole
Posts: 6
Joined: Thu Dec 22, 2016 5:00 am

Re: Rotation of a body around custom point.

Post by Kir »

I'm aware of that, but I haven't found a way to do so. Is there a way to change the center of mass? I can get its center, but I haven't found a way to set it. Body:setMassData( x, y, mass, inertia ) seems like a function that would do so, since x and y are the center of mass positions, but picking anything greater than 1 gives me an error "Box2D assertion failed: m_l > 0.0f"

My setup for my body "block" is as follows.

Code: Select all

  objects.block= {}
  objects.block.body = love.physics.newBody(world, love.window.getWidth()/2, love.window.getHeight()/2, "dynamic")
  objects.block.shape = love.physics.newRectangleShape(0, 0, 100, 50)
  objects.block.fixture = love.physics.newFixture(objects.block.body, objects.block.shape, 1)
  objects.block.body:setLinearDamping(4)
  objects.block.body:setAngularDamping(4)
  objects.block.body:setAngle(math.rad(-90))
  objects.block.fixture:setRestitution(0.6)
Composing the body of two fixtures sounds like it could work. Thanks.
User avatar
ivan
Party member
Posts: 1939
Joined: Fri Mar 07, 2008 1:39 pm
Contact:

Re: Rotation of a body around custom point.

Post by ivan »

Yes, it's possible to change the center of mass and then rotate the body using something like SetAngularVelociy or ApplyTorque.
You can also create your rectangle shape with an offset and use SetAngle to rotate the body manually around that offset.
But there is a more general concern here - the point of Box2D is to setup your bodies and let the physics simulation do its thing.
When go in manually and adjust how objects move then you are unnecessarily going against the grain.
Kir
Prole
Posts: 6
Joined: Thu Dec 22, 2016 5:00 am

Re: Rotation of a body around custom point.

Post by Kir »

That's completely fine. All I want is the center of mass to be not in the center of the rectangle and let the physics simulation do its thing. I am actually trying to replicate a real life scenario.
User avatar
s-ol
Party member
Posts: 1080
Joined: Mon Sep 15, 2014 7:41 pm
Location: Milan, Italy
Contact:

Re: Rotation of a body around custom point.

Post by s-ol »

Kir wrote:That's completely fine. All I want is the center of mass to be not in the center of the rectangle and let the physics simulation do its thing. I am actually trying to replicate a real life scenario.
s-ol wrote:You can't have a body spin around a point that is not it's center of mass without constantly applied forces because that's just not how physics work in reality, which box2d is modelled after.

You can apply a force at a position using the second overloaded cariant of https://love2d.org/wiki/Body:applyForce or Body:applyImpulse but depending on what younare trying to do it might be more appropriate to have a joint or compose the body of two fixtures with different densities to push the center of mass closer to the edge.
you cannot have the center of mass exactly on the edge of the object (because math) but you can split your shape 10%/90% and make the 10% heavier for example. Alternatively, leave it as it is, and add a small extra fixture with lots of density close to where you want the COM to be.

s-ol.nu

Code: Select all

print( type(love) )
if false then
  baby:hurt(me)
end
Kir
Prole
Posts: 6
Joined: Thu Dec 22, 2016 5:00 am

Re: Rotation of a body around custom point.

Post by Kir »

I should have been more precise. The center of mass is not exactly on the edge, but very close to it. Two fixtures like you said should work and it's what I'm currently trying. I just haven't got it to work yet, because I'm not completely sure how to add two fixtures to a body or I'm missing something. I will look more into this later today when I have more time. Thank you for your answers.
User avatar
s-ol
Party member
Posts: 1080
Joined: Mon Sep 15, 2014 7:41 pm
Location: Milan, Italy
Contact:

Re: Rotation of a body around custom point.

Post by s-ol »

Kir wrote:I should have been more precise. The center of mass is not exactly on the edge, but very close to it. Two fixtures like you said should work and it's what I'm currently trying. I just haven't got it to work yet, because I'm not completely sure how to add two fixtures to a body or I'm missing something. I will look more into this later today when I have more time. Thank you for your answers.
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'.

s-ol.nu

Code: Select all

print( type(love) )
if false then
  baby:hurt(me)
end
User avatar
raidho36
Party member
Posts: 2063
Joined: Mon Jun 17, 2013 12:00 pm

Re: Rotation of a body around custom point.

Post by raidho36 »

s-ol wrote:you cannot have the center of mass exactly on the edge of the object (because math)
You can, but that requires that 100% of body mass is on the edge, and the rest weighs nothing. Not physically meaningful since everything has mass or mass equivalent, but so is negative friction or super-unit restitution (or rigid bodies just in general). If you combine one massive object and another massless one, you get an object with centre of gravity at massive object's center.
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 »

To change the centre of mass, you have to alter the moment of inertia. Otherwise that assertion triggers

Code: Select all

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

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

local fixture = love.physics.newFixture(body, shape, 1)

body:setMassData(15, 0, 1, 300)
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()))
  local x, y = body:getWorldCenter()
  love.graphics.rectangle("fill", x-1, y-1, 3, 3)
end
I'm not convinced that that is what you need, but since you haven't explained what you're trying to replicate, I can't say for sure if you actually need a revolute joint.
Post Reply

Who is online

Users browsing this forum: No registered users and 9 guests