Box2d offset shape from body

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
TomatoSoup
Prole
Posts: 11
Joined: Sat Jul 19, 2014 2:57 am

Box2d offset shape from body

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

Re: Box2d offset shape from body

Post 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 )
TomatoSoup
Prole
Posts: 11
Joined: Sat Jul 19, 2014 2:57 am

Re: Box2d offset shape from body

Post 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?
Post Reply

Who is online

Users browsing this forum: No registered users and 128 guests