Physics body misaligned with irregular polygon

I have this situation, The asteroids on the left. I don’t understand, why display object and physics body are misaligned?

v2014.2393

[lua]

local vertices={}

vertices= {   -40.5, -88  ,  79.5, -80  ,  105.5, -18  ,  62.5, 34  ,  -36.5, 66  ,  -94.5, -17  ,  -116.5, -86  }

local function A1()

local astX=math.random(-100,0)

local astY=math.random(0,display.contentHeight)

local asteroid=display.newPolygon(astX,astY,vertices)

asteroid:setFillColor( 0,0,0,0 )

asteroid.strokeWidth=5

asteroid:setStrokeColor( 1,1,1 )

physics.addBody( asteroid, “dynamic”, {density=500, friction=100, bounce=0, shape=vertices } )

local astVx=math.random(-50,50)

local astVy=math.random(-50,50)

asteroid:setLinearVelocity( astVx+50, astVy )

end

[/lua]

And I have not even changed the anchor point, although in the official documentation says:

If you change the anchorX or anchorY property of a display object before adding a physics body, the body will be positioned properly relative to the adjusted anchor. However, you should not change the anchor point after adding the body or the object and body will be misaligned.

 

Thus if I change the anchor of the display objects before addbody everthing should work, but they are misaligned with default anchor point or custom anchor point.

This happen in physics.setDrawMode(“hybrid”) as in physics.setDrawMode(“normal”).

Hi @marcoguerrera84,

By chance, did you add the asteroid object to a display group, and then move that entire group (reposition it)? This is not allowed, as it will move the objects visually, but the physics bodies will be regarded as if the group was never moved (as in, it’s in the relative 0,0 position that it started).

Best regards,

Brent

Asteroids are not part of any group, not their display objects and not physical bodies associated with them. Other object are parte of sceneGroup, I’m using composer.

Hi again,

In this case, I can only think that the vertices you defined are not quite accurate in comparison to the visual object. How did you gather these coordinates? Did you use a tracing tool like PhysicsEditor or similar?

Brent

I have used Physic editor, but only for get the vector of coordinates inside the generated lua file. And the vector is the same for the display object and the physics body, so I don’t understand, in debug mode I can see this two shape identical but misaligned. 

Anyway, this happens also if I set a simple vector manually like local vertices={ 0,0, 20,20, 20,-20 } and without composer.

Creating a new simple project, all code in these lines:

[lua]


– main.lua


local physics = require (“physics”)

physics.start( )

physics.setGravity( 0, 0 )

physics.setDrawMode(“hybrid”)

local vertices={ 0,0, 20,20, 20,-20 }

local asteroid=display.newPolygon(200,200,vertices)

physics.addBody( asteroid, “dynamic”, {density=500, friction=0, bounce=0, shape=vertices } )

[/lua]

Hi @marcoguerrera84,

Are you setting a non-center anchor point on any of these objects?

Brent

No, default anchor point.

Hi @marcoguerrera84,

I think I see the reason now… this is some issue with how the center point of polygon objects in specific are treated differently than the overall body center related to physics.

Fortunately, a Corona developer ported over a utility which will solve this for you. It will require that you include his code in your project, but then, you can just call his function with your asteroids and the body should line up perfectly.

https://gist.github.com/H4ch1k0/8629419/

So, with the necessary require() to get the module in your project, your code would look something like this:

[lua]

–require the module (the .lua file should be placed in your core project directory alongside main.lua)

local bodySeparator = require( “bodySeparator” )

–your asteroid

local vertices = { -40,-88, 109,-80, 105,-18, 62,34, -36,66, -94,-17, -116,-86 }

local polygon = display.newPolygon( 240, 160, vertices )

bodySeparator.addNonConvexBody( polygon, { shape=vertices, bodyType=“dynamic”, bounce=0, friction=1, density=1 } )

[/lua]

Also, the author states that this works with non-convex bodies, which means you could create asteroids with concave bends (not a straightforward default process with Box2D bodies which expect to be convex only).

Brent

Works like a charm, thank you Brent !

Two questions:

  1. I have to remove this? Something like physics.removeBody( object ) ?

  2. How insert a collision filter in this instruction?

  3. If exist a number vertex limit , how try to create multielement body? In physics api the way is:

Multi-Element Body local nebula = display.newImage( “nebula.png” )
nebula.x, nebula.y = display.contentCenterX, display.contentCenterY

local podT = {1,-89, 14,-83, 20,-70, 14,-57, 1,-51, -12,-57, -18,-70, -12,-83}
local podR = {69,-20, 82,-14, 88,-1, 82,12, 69,18, 56,12, 50,-1, 56,-14}
local podB = {1,49, 14,55, 20,68, 14,81, 1,87, -12,81, -18,68, -12,55}
local podL = {-70,-20, -57,-14, -51,-1, -57,12, -70,18, -83,12, -89,-1, -83,-14}

physics.addBody( nebula, “dynamic”,
{ friction=0.2, bounce=0.4, shape=podT },
{ friction=0.8, bounce=0.0, shape=podR },
{ friction=0.8, bounce=0.0, shape=podB },
{ friction=0.2, bounce=0.4, shape=podL }
)

Hi @marcoguerrera84,

By chance, did you add the asteroid object to a display group, and then move that entire group (reposition it)? This is not allowed, as it will move the objects visually, but the physics bodies will be regarded as if the group was never moved (as in, it’s in the relative 0,0 position that it started).

Best regards,

Brent

Asteroids are not part of any group, not their display objects and not physical bodies associated with them. Other object are parte of sceneGroup, I’m using composer.

Hi again,

In this case, I can only think that the vertices you defined are not quite accurate in comparison to the visual object. How did you gather these coordinates? Did you use a tracing tool like PhysicsEditor or similar?

Brent

I have used Physic editor, but only for get the vector of coordinates inside the generated lua file. And the vector is the same for the display object and the physics body, so I don’t understand, in debug mode I can see this two shape identical but misaligned. 

Anyway, this happens also if I set a simple vector manually like local vertices={ 0,0, 20,20, 20,-20 } and without composer.

Creating a new simple project, all code in these lines:

[lua]


– main.lua


local physics = require (“physics”)

physics.start( )

physics.setGravity( 0, 0 )

physics.setDrawMode(“hybrid”)

local vertices={ 0,0, 20,20, 20,-20 }

local asteroid=display.newPolygon(200,200,vertices)

physics.addBody( asteroid, “dynamic”, {density=500, friction=0, bounce=0, shape=vertices } )

[/lua]

Hi @marcoguerrera84,

Are you setting a non-center anchor point on any of these objects?

Brent

No, default anchor point.

Hi @marcoguerrera84,

I think I see the reason now… this is some issue with how the center point of polygon objects in specific are treated differently than the overall body center related to physics.

Fortunately, a Corona developer ported over a utility which will solve this for you. It will require that you include his code in your project, but then, you can just call his function with your asteroids and the body should line up perfectly.

https://gist.github.com/H4ch1k0/8629419/

So, with the necessary require() to get the module in your project, your code would look something like this:

[lua]

–require the module (the .lua file should be placed in your core project directory alongside main.lua)

local bodySeparator = require( “bodySeparator” )

–your asteroid

local vertices = { -40,-88, 109,-80, 105,-18, 62,34, -36,66, -94,-17, -116,-86 }

local polygon = display.newPolygon( 240, 160, vertices )

bodySeparator.addNonConvexBody( polygon, { shape=vertices, bodyType=“dynamic”, bounce=0, friction=1, density=1 } )

[/lua]

Also, the author states that this works with non-convex bodies, which means you could create asteroids with concave bends (not a straightforward default process with Box2D bodies which expect to be convex only).

Brent

Works like a charm, thank you Brent !

Two questions:

  1. I have to remove this? Something like physics.removeBody( object ) ?

  2. How insert a collision filter in this instruction?

  3. If exist a number vertex limit , how try to create multielement body? In physics api the way is:

Multi-Element Body local nebula = display.newImage( “nebula.png” )
nebula.x, nebula.y = display.contentCenterX, display.contentCenterY

local podT = {1,-89, 14,-83, 20,-70, 14,-57, 1,-51, -12,-57, -18,-70, -12,-83}
local podR = {69,-20, 82,-14, 88,-1, 82,12, 69,18, 56,12, 50,-1, 56,-14}
local podB = {1,49, 14,55, 20,68, 14,81, 1,87, -12,81, -18,68, -12,55}
local podL = {-70,-20, -57,-14, -51,-1, -57,12, -70,18, -83,12, -89,-1, -83,-14}

physics.addBody( nebula, “dynamic”,
{ friction=0.2, bounce=0.4, shape=podT },
{ friction=0.8, bounce=0.0, shape=podR },
{ friction=0.8, bounce=0.0, shape=podB },
{ friction=0.2, bounce=0.4, shape=podL }
)