Unable to detect collision for rotating objects

Hi all,

rotatecollision.png

I have a semi circle shape thingy that is made from polygons that is rotating using transition.to ( Orange object in picture ).

I can’t seem to detect the collision for when the polygon rotates into the blue dot.

If the blue dot moves into the polygon however, it gets detected.

So it seems an object that has been transition.to rotation cannot trigger a collision event ?

I have tried precollision also.

I have seen in the documentation that there are some issues with rotating objects and detecting collisions, but not sure if this is the same thing.

Thanks in advance,

Set hybrid draw mode and see where your bodies are:

https://docs.coronalabs.com/daily/api/library/physics/setDrawMode.html

physics.setDrawMode( 'hybrid' )

My guess is your body is not where you think during the rotation.  Are you offsetting groups?

Hi roaminggamer,

Thanks for the reply.

rotatecollisionhybrid.png

The bounds look just about right, and they do rotate correctly.

But the collision still does not seem to be detected.

Some other information :

– This is for the small blue point

physics.addBody(circleWheel.circlePoint,“dynamic”,{radius=3,isSensor=true})

– This is for the orange polygon

physics.addBody( polygon , “static”,{density=3.0,isSensor=true})

– Adding the listener

Runtime:addEventListener( “collision”, onGlobalCollision )

And just try to do a print() at the beginning of onGlobalCollision.

To re-iterate when I move the blue point into the orange polygon using transition.to() the collision is detected but when the orange

polygon rotates into the blue point using transition.to({rotation}) it is not detected.

In the docs this is mentioned about rotation “This cannot be used on a physical body during a collision event”.

But I believe it is about initiating a rotation on a collision event and is not relevant to this ?

Anyway thanks for any help!

Ah, I think I see the problem.  This body looks concave :

-- This is for the orange polygon physics.addBody( polygon , "static",{density=3.0,isSensor=true})

In that case I don’t think it will work at all and definitely not if you try to rotate it.  

As far as I know, the physics engine can only accurately detect collisions between convex bodies.  (This is common for physics engines because of the extra number of steps and some mathematical ambiguities associated with calculating collision detection for concave bodies.)

I think you’ll need to make that single-body into a multi-body object, where each sub-body is _ convex _.

This article talks about: multi-bodies, convex, and concave: https://coronalabs.com/blog/2013/01/08/working-with-multi-element-physics-bodies/

-Ed

Hi @wuhu.apps,

How did you construct those big “C” shape bodies? Can I see that code?

Brent

Thanks for the replies all.

@roaminggamer

Thanks for the info! That link is very helpful, will try some things out, only rotating simpler shapes is also an option for me.

@Brent

I drew the ‘level’ in inkscape and used an inkscape extension to export the vertices

polygons ={ {680,972,678,953,674,933,668,914,659,896,648,880,636,864,621,851,605,839,588,829,570,821,551,815,531,812,511,812,494,813,477,816,461,821,445,827,451,841,458,855,474,848,490,844,507,842,524,842,541,844,559,849,575,856,591,865,605,876,617,889,628,904,637,920,644,937,648,954,649,972,649,974,649,989,646,1004,661,1008,676,1012,679,992}, {616,978,614,996,609,1015,601,1032,591,1047,577,1060,562,1071,545,1079,527,1084,508,1085,489,1084,471,1079,454,1071,439,1060,426,1047,415,1032,407,1015,402,996,401,978,402,959,407,941,415,924,426,909,439,895,454,885,471,877,489,872,508,870,527,872,545,877,562,885,577,895,591,909,601,924,609,941,614,959}, {341,966,340,986,342,1006,346,1025,353,1044,361,1062,372,1078,385,1094,399,1107,415,1119,433,1129,451,1137,470,1142,490,1145,507,1146,524,1144,541,1141,558,1137,553,1122,548,1108,531,1113,514,1115,497,1115,480,1113,464,1109,447,1103,431,1094,417,1083,404,1070,393,1056,384,1040,377,1023,373,1006,370,988,371,970,371,968,373,953,377,938,363,933,349,928,344,947}, {50,1407,55,1392,59,1377,63,1361,45,1356,29,1348,14,1337,2,1324,-8,1309,-16,1293,-21,1275,-23,1256,-21,1236,-15,1217,-6,1199,5,1183,19,1170,36,1159,54,1151,73,1148,92,1148,111,1151,129,1158,146,1167,161,1179,173,1194,183,1210,190,1228,191,1234,206,1231,222,1227,237,1224,235,1215,229,1197,221,1180,211,1164,199,1150,185,1137,170,1126,154,1116,137,1109,119,1104,100,1101,82,1100,63,1101,44,1105,27,1111,10,1119,-5,1129,-20,1141,-33,1155,-44,1170,-54,1186,-61,1203,-66,1221,-69,1240,-70,1259,-68,1277,-65,1296,-59,1313,-51,1330,-41,1346,-29,1361,-15,1374,0,1385,15,1395,32,1402} }

The I iterate through them and call this function passing in one set of vertices

local function createLevelPolygon(parent,vertices,strokeWidth,strokeAlpha,globalYOffset,isPhysics) local polygon = display.newPolygon( 0,0, vertices ) polygon:setFillColor(0) polygon.strokeWidth = strokeWidth polygon:setStrokeColor( colors.levelColor[1],colors.levelColor[2],colors.levelColor[3],strokeAlpha ) parent:insert(polygon) offsetObject(polygon,vertices) polygon.y = polygon.y + globalYOffset if isPhysics then physics.addBody( polygon , "static",{density=3.0,isSensor=true}) end table.insert(items, polygon) return polygon end

local function offsetObject(obj,vertices) local minX = math.huge local minY = math.huge local maxX = -math.huge local maxY = -math.huge for i=1, #vertices, 2 do &nbsp; &nbsp;local px = vertices[i] &nbsp; &nbsp;local py = vertices[i+1] &nbsp; &nbsp;if px \> maxX then maxX = px end &nbsp; &nbsp;if py \> maxY then maxY = py end &nbsp; &nbsp;if px \< minX then minX = px end &nbsp; &nbsp;if py \< minY then minY = py end end local centerX = (maxX - minX)/2 local centerY = (maxY - minY)/2 local offsetX = centerX + minX local offsetY = centerY + minY &nbsp; obj.x = obj.x+offsetX obj.y = obj.y+offsetY end

Thanks in advance for any help!

Hi @wuhu.apps,

You definitely can’t have a physics body with a single polygon of that many vertices. In Box2D, a polygon (shape) body is limited to 8 sides, and it must be entirely convex (no concave bends).

That being said, you can construct the giant “C” shape from a series of polygons by using a multi-element body:

https://docs.coronalabs.com/guide/physics/physicsBodies/index.html#multi-element-bodies

Alternatively, you might be able to use the “image trace” feature of graphics.newOutline() and pass that to the physics addBody() API:

https://docs.coronalabs.com/api/library/graphics/newOutline.html

As a final alternative, you might be able to construct it using a chain “edge shape” body. That is outlined in the same guide as above:

https://docs.coronalabs.com/guide/physics/physicsBodies/index.html#edge-shape-chain-body

Best regards,

Brent

Alright Brent/roaminggamer thanks for the info. Will work something out with the info given.

Thanks!

Set hybrid draw mode and see where your bodies are:

https://docs.coronalabs.com/daily/api/library/physics/setDrawMode.html

physics.setDrawMode( 'hybrid' )

My guess is your body is not where you think during the rotation.  Are you offsetting groups?

Hi roaminggamer,

Thanks for the reply.

rotatecollisionhybrid.png

The bounds look just about right, and they do rotate correctly.

But the collision still does not seem to be detected.

Some other information :

– This is for the small blue point

physics.addBody(circleWheel.circlePoint,“dynamic”,{radius=3,isSensor=true})

– This is for the orange polygon

physics.addBody( polygon , “static”,{density=3.0,isSensor=true})

– Adding the listener

Runtime:addEventListener( “collision”, onGlobalCollision )

And just try to do a print() at the beginning of onGlobalCollision.

To re-iterate when I move the blue point into the orange polygon using transition.to() the collision is detected but when the orange

polygon rotates into the blue point using transition.to({rotation}) it is not detected.

In the docs this is mentioned about rotation “This cannot be used on a physical body during a collision event”.

But I believe it is about initiating a rotation on a collision event and is not relevant to this ?

Anyway thanks for any help!

Ah, I think I see the problem.  This body looks concave :

-- This is for the orange polygon physics.addBody( polygon , "static",{density=3.0,isSensor=true})

In that case I don’t think it will work at all and definitely not if you try to rotate it.  

As far as I know, the physics engine can only accurately detect collisions between convex bodies.  (This is common for physics engines because of the extra number of steps and some mathematical ambiguities associated with calculating collision detection for concave bodies.)

I think you’ll need to make that single-body into a multi-body object, where each sub-body is _ convex _.

This article talks about: multi-bodies, convex, and concave: https://coronalabs.com/blog/2013/01/08/working-with-multi-element-physics-bodies/

-Ed

Hi @wuhu.apps,

How did you construct those big “C” shape bodies? Can I see that code?

Brent

Thanks for the replies all.

@roaminggamer

Thanks for the info! That link is very helpful, will try some things out, only rotating simpler shapes is also an option for me.

@Brent

I drew the ‘level’ in inkscape and used an inkscape extension to export the vertices

polygons ={ {680,972,678,953,674,933,668,914,659,896,648,880,636,864,621,851,605,839,588,829,570,821,551,815,531,812,511,812,494,813,477,816,461,821,445,827,451,841,458,855,474,848,490,844,507,842,524,842,541,844,559,849,575,856,591,865,605,876,617,889,628,904,637,920,644,937,648,954,649,972,649,974,649,989,646,1004,661,1008,676,1012,679,992}, {616,978,614,996,609,1015,601,1032,591,1047,577,1060,562,1071,545,1079,527,1084,508,1085,489,1084,471,1079,454,1071,439,1060,426,1047,415,1032,407,1015,402,996,401,978,402,959,407,941,415,924,426,909,439,895,454,885,471,877,489,872,508,870,527,872,545,877,562,885,577,895,591,909,601,924,609,941,614,959}, {341,966,340,986,342,1006,346,1025,353,1044,361,1062,372,1078,385,1094,399,1107,415,1119,433,1129,451,1137,470,1142,490,1145,507,1146,524,1144,541,1141,558,1137,553,1122,548,1108,531,1113,514,1115,497,1115,480,1113,464,1109,447,1103,431,1094,417,1083,404,1070,393,1056,384,1040,377,1023,373,1006,370,988,371,970,371,968,373,953,377,938,363,933,349,928,344,947}, {50,1407,55,1392,59,1377,63,1361,45,1356,29,1348,14,1337,2,1324,-8,1309,-16,1293,-21,1275,-23,1256,-21,1236,-15,1217,-6,1199,5,1183,19,1170,36,1159,54,1151,73,1148,92,1148,111,1151,129,1158,146,1167,161,1179,173,1194,183,1210,190,1228,191,1234,206,1231,222,1227,237,1224,235,1215,229,1197,221,1180,211,1164,199,1150,185,1137,170,1126,154,1116,137,1109,119,1104,100,1101,82,1100,63,1101,44,1105,27,1111,10,1119,-5,1129,-20,1141,-33,1155,-44,1170,-54,1186,-61,1203,-66,1221,-69,1240,-70,1259,-68,1277,-65,1296,-59,1313,-51,1330,-41,1346,-29,1361,-15,1374,0,1385,15,1395,32,1402} }

The I iterate through them and call this function passing in one set of vertices

local function createLevelPolygon(parent,vertices,strokeWidth,strokeAlpha,globalYOffset,isPhysics) local polygon = display.newPolygon( 0,0, vertices ) polygon:setFillColor(0) polygon.strokeWidth = strokeWidth polygon:setStrokeColor( colors.levelColor[1],colors.levelColor[2],colors.levelColor[3],strokeAlpha ) parent:insert(polygon) offsetObject(polygon,vertices) polygon.y = polygon.y + globalYOffset if isPhysics then physics.addBody( polygon , "static",{density=3.0,isSensor=true}) end table.insert(items, polygon) return polygon end

local function offsetObject(obj,vertices) local minX = math.huge local minY = math.huge local maxX = -math.huge local maxY = -math.huge for i=1, #vertices, 2 do &nbsp; &nbsp;local px = vertices[i] &nbsp; &nbsp;local py = vertices[i+1] &nbsp; &nbsp;if px \> maxX then maxX = px end &nbsp; &nbsp;if py \> maxY then maxY = py end &nbsp; &nbsp;if px \< minX then minX = px end &nbsp; &nbsp;if py \< minY then minY = py end end local centerX = (maxX - minX)/2 local centerY = (maxY - minY)/2 local offsetX = centerX + minX local offsetY = centerY + minY &nbsp; obj.x = obj.x+offsetX obj.y = obj.y+offsetY end

Thanks in advance for any help!

Hi @wuhu.apps,

You definitely can’t have a physics body with a single polygon of that many vertices. In Box2D, a polygon (shape) body is limited to 8 sides, and it must be entirely convex (no concave bends).

That being said, you can construct the giant “C” shape from a series of polygons by using a multi-element body:

https://docs.coronalabs.com/guide/physics/physicsBodies/index.html#multi-element-bodies

Alternatively, you might be able to use the “image trace” feature of graphics.newOutline() and pass that to the physics addBody() API:

https://docs.coronalabs.com/api/library/graphics/newOutline.html

As a final alternative, you might be able to construct it using a chain “edge shape” body. That is outlined in the same guide as above:

https://docs.coronalabs.com/guide/physics/physicsBodies/index.html#edge-shape-chain-body

Best regards,

Brent

Alright Brent/roaminggamer thanks for the info. Will work something out with the info given.

Thanks!