Page 1 of 1

Box2d offset shape from body

Posted: Wed Mar 25, 2015 2:30 am
by TomatoSoup
My understanding of Box2d is that, upon creating a shape, it will be centered on the body that you attach it to via newFixture.

Two questions stem from this.

Firstly, how do I compute the center of an arbitrary polygon?

Second, how would I position a shape offset from the body that it belongs to?

For instance, if I wanted to make a submarine I'd do two circles with an overlapping rectangle in the middle and a second rectangle for the sail, and then I'd attach all of these shapes to one body. Or I could just make a submarine shaped polygon, but then I run into the first problem in that it will not be centered relative to the body object and I'll need to be able to either offset it so that, say, I can get the torpedoes and missiles to come out of the right places, or I would need to calculate where the center of that polygon is so that I can offset the torpedo and missile origins.

I understand that I can get the mass of the body from the density of the attached shapes, and that I can get the center of mass from that. But how would I then change the relative location of the body or shapes so that, when forces cause it to rotate, it always rotates about the center of mass?

Re: Box2d offset shape from body

Posted: Wed Mar 25, 2015 5:24 am
by ivan
Firstly, how do I compute the center of an arbitrary polygon?
Depends on what you mean by "center", you can get the average of all vertices:
c.x = (v1.x + v2.x ... vK.x)/K
c.y = (v1.y + v2.y ... vK.y)/K
where K is the number of points

Another approach is to get the extents and use that:
minX = math.min(v1.x, v2.x ... vK.x)
maxX = math.max(v1.x, v2.x ... vK.x)
...
c.x = (minX + maxX)/2
c.y = (minY + maxY)/2
Second, how would I position a shape offset from the body that it belongs to?
For polygonal shapes, just translate all vertices:

Code: Select all

for i = 1, K do
  v[i].x = v[i].x + ox
  v[i].y = v[i].y + oy
end
where ox,oy is the offset

For circles, box2d has:
shape = love.physics.newCircleShape( x, y, radius )
where x,y is the offset relative to the body's origin
say, I can get the torpedoes and missiles to come out of the right places, or I would need to calculate where the center of that polygon is so that I can offset the torpedo and missile origins.
You can just store the spawn point relative to the body's origin and use that.
I understand that I can get the mass of the body from the density of the attached shapes, and that I can get the center of mass from that. But how would I then change the relative location of the body or shapes so that, when forces cause it to rotate, it always rotates about the center of mass?
Note: the position/origin of the body is not always the center of mass.
Once you have the spawn point relative to the body's origin you can use:

Code: Select all

world_x, world_y = Body:getWorldPoint( local_x, local_y )

Re: Box2d offset shape from body

Posted: Wed Mar 25, 2015 9:38 pm
by TomatoSoup
Ah, so I see that I have entirely misunderstood the tutorials! So, to clarify, only when using the shortcut to create Rectangles will it be centered upon the body. Otherwise it positions the points that I provide relative to the body.

Well that answers a large number of my questions!

However, while I see how I can get the location of the center of mass, both in world and in local positions, how do I move the shapes relative to the body so that the body coincides with the shapes' center of mass?