(physics) complex polygon tool

I thought I’d post this separate to my “level editor” post to keep the discussions apart.

At the moment I’ve been using this tool in flash to turn shape definitions (drawn with pen tool, traced over sprites etc) into Box2D coordinates. These (with some parsing) can then be plugged into Corona’s complex body construction.

for example:
I’ve taken the banana image from here: http://www.wpclipart.com/food/fruit/banana/banana.png

and traced it in flash using trace bitmap

then run the JSFL which decomposes it into triangles

this isnt very optimized so let’s fix that by using a more optimzed shape to approximate the banana… i’ve traced a rough outline around it

now let’s run the JSFL decomposition tool again

that’s a far more optimized, and should be a good enough fit it. Well it’s not perfect but could be improved with some tweaking

(sorry about the typos, i can’t find an “edit” button!)

just found another that’s quite interesting.
http://www.box2d.org/forum/viewtopic.php?f=8&t=5824

it scans a bitmap at runtime (this is AS3 not JSFL) and traces around discrete shapes…
in his demo he then turns the physics on. you can see the result here…

[import]uid: 6645 topic_id: 3369 reply_id: 10034[/import]

this site lets you import a graphic and draw around it, then output the shape data as XML, but the shape can be convex so i dont know if that will cause a problem for Box2D

http://www.nuvorm.nl/start/index.php?option=com_content&view=category&layout=blog&id=40&Itemid=53 [import]uid: 6645 topic_id: 3369 reply_id: 10038[/import]

I have written a Delaunay trianglulator for corona, if anyone wants it.

[import]uid: 5652 topic_id: 3369 reply_id: 10251[/import]

definitely, please post/share!

thanks
j [import]uid: 6645 topic_id: 3369 reply_id: 10256[/import]

righto, here’s the code, created for ipad. There’s a ton of ways to make it do what you want. A fast way would be to make a corona utility app; you load a picture, tap on points around the outline, and print the delaunay coordinates out to the console. Then you can cut-and-paste them diectly into you application code.

--[[  
   
Copyright (c) 2010 David Ng  
   
Permission is hereby granted, free of charge, to any person obtaining a copy  
of this software and associated documentation files (the "Software"), to deal  
in the Software without restriction, including without limitation the rights  
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell  
copies of the Software, and to permit persons to whom the Software is  
furnished to do so, subject to the following conditions:  
   
The above copyright notice and this permission notice shall be included in  
all copies or substantial portions of the Software.  
   
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR  
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,  
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE  
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER  
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,  
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN  
THE SOFTWARE.  
   
Based of the work of Paul Bourke (1989), Efficient Triangulation   
Algorithm Suitable for Terrain Modelling.  
http://local.wasp.uwa.edu.au/~pbourke/papers/triangulate/index.html  
  
--]]  
  
function delaunay(points\_list)  
 local triangle\_list = {}  
 local numpoints = #points\_list  
  
 --Insertion sort by x  
 local w = points\_list[1].x  
 for i = 1, numpoints do  
 local p = points\_list[i]  
 local x = p.x  
 if x \< w then  
 local j = i  
 while j\>1 and points\_list[j -1].x \> x do  
 points\_list[j] = points\_list[j - 1]  
 j = j - 1  
 end   
 points\_list[j] = p;  
 else  
 w = x  
 end   
 end  
 --Create Supertriangle  
 table.insert(points\_list, {x = -5000, y = -5000})  
 table.insert(points\_list, {x = 5000, y = 0})  
 table.insert(points\_list, {x = 0, y = 5000})  
 table.insert(triangle\_list, {numpoints+1,numpoints+2,numpoints+3})  
   
 local function inCircle(point, triangle\_counter)  
 --[[  
 '''Series of calculations to check if a certain point lies inside lies inside the circumcircle  
 made up by points in triangle (x1,y1) (x2,y2) (x3,y3)'''  
 #adapted from Dimitrie Stefanescu's Rhinoscript version  
  
 #Return TRUE if the point (xp,yp)   
 #The circumcircle centre is returned in (xc,yc) and the radius r  
 #NOTE: A point on the edge is inside the circumcircle --]]  
 if triangle\_list[triangle\_counter].done then  
 return false  
 end   
  
 local xp = point.x  
 local yp = point.y  
  
 if triangle\_list[triangle\_counter].r then  
  
  
 local r = triangle\_list[triangle\_counter].r  
 local xc = triangle\_list[triangle\_counter].xc  
 local yc = triangle\_list[triangle\_counter].yc  
  
 local dx = xp - xc  
 local dy = yp - yc  
 local rsqr = r\*r  
 local drsqr = dx \* dx + dy \* dy  
  
 if xp \> xc + r then  
 triangle\_list[triangle\_counter].done = true  
 end   
  
 if drsqr \<= rsqr then  
 return true  
 else  
 return false  
 end  
 end   
  
 local x1 = points\_list[triangle\_list[triangle\_counter][1]].x  
 local y1 = points\_list[triangle\_list[triangle\_counter][1]].y  
 local x2 = points\_list[triangle\_list[triangle\_counter][2]].x  
 local y2 = points\_list[triangle\_list[triangle\_counter][2]].y  
 local x3 = points\_list[triangle\_list[triangle\_counter][3]].x  
 local y3 = points\_list[triangle\_list[triangle\_counter][3]].y  
 local eps = 0.0001  
  
 if math.abs(y1-y2) \< eps and math.abs(y2-y3) \< eps then   
 return false   
 end  
  
 if math.abs(y2-y1) \< eps then  
 m2 = -(x3 - x2) / (y3 - y2)  
 mx2 = (x2 + x3) / 2  
 my2 = (y2 + y3) / 2  
 xc = (x2 + x1) / 2  
 yc = m2 \* (xc - mx2) + my2  
 elseif math.abs(y3-y2) \< eps then  
  
 m1 = -(x2 - x1) / (y2 - y1)  
  
 mx1 = (x1 + x2) / 2  
 my1 = (y1 + y2) / 2  
 xc = (x3 + x2) / 2  
 yc = m1 \* (xc - mx1) + my1  
 else  
 m1 = -(x2 - x1) / (y2 - y1)  
 m2 = -(x3 - x2) / (y3 - y2)  
 mx1 = (x1 + x2) / 2  
 mx2 = (x2 + x3) / 2  
 my1 = (y1 + y2) / 2  
 my2 = (y2 + y3) / 2  
 xc = (m1 \* mx1 - m2 \* mx2 + my2 - my1) / (m1 - m2)  
 yc = m1 \* (xc - mx1) + my1  
 end  
  
  
 dx = x2 - xc  
 dy = y2 - yc  
 rsqr = dx \* dx + dy \* dy  
 r = math.sqrt(rsqr)  
  
 triangle\_list[triangle\_counter].r = r  
 triangle\_list[triangle\_counter].xc = xc  
 triangle\_list[triangle\_counter].yc = yc  
  
 dx = xp - xc  
 dy = yp - yc  
 drsqr = (dx \* dx) + (dy \* dy)  
  
 if drsqr \<= rsqr then  
 return true  
 else  
 return false  
 end   
 end   
  
 for i = 1, numpoints do  
 local edges = {}  
 local point = points\_list[i]  
  
 local triangles\_remain = true  
 local j = 1  
  
 while triangles\_remain do  
  
 if inCircle(point, j) then  
 table.insert(edges, {triangle\_list[j][1],triangle\_list[j][2]})  
 table.insert(edges, {triangle\_list[j][2],triangle\_list[j][3]})  
 table.insert(edges, {triangle\_list[j][3],triangle\_list[j][1]})  
 table.remove(triangle\_list,j)  
 j = j - 1  
 end  
  
 j = j + 1  
 if j == (#triangle\_list + 1) then  
 triangles\_remain = false  
 end   
 end  
 --Remove duplicates  
 local k = 1  
 while k \< #edges do  
 l = k + 1  
 while l \<= #edges do  
 if edges[k][1] == edges[l][2] and edges[k][2] == edges[l][1] then  
 edges[k][1] = nil  
 edges[k][2] = nil  
 edges[l][1] = nil  
 edges[l][2] = nil  
 end  
 l = l + 1   
 end  
 k = k + 1  
 end   
  
 -- Make triangles from edges  
 for k = 1, #edges do  
 if edges[k][1] then   
 table.insert(triangle\_list, {i,edges[k][1],edges[k][2]})  
 end  
 end  
 end  
  
 --remove Super Triangle and its verticies  
 local i = 1  
 while i \< #triangle\_list + 1 do   
 if triangle\_list[i][1] \> numpoints then  
 table.remove(triangle\_list,i)  
 i = i-1   
 elseif triangle\_list[i][2] \> numpoints then  
 table.remove(triangle\_list,i)  
 i = i-1   
 elseif triangle\_list[i][3] \> numpoints then  
 table.remove(triangle\_list,i)  
 i = i-1   
 end  
 i = i+1  
 end  
 points\_list[numpoints+1] = nil  
 points\_list[numpoints+2] = nil   
 points\_list[numpoints+3] = nil   
  
 return triangle\_list  
end  
  
  
  
stars = {}  
lines = {}  
points\_list = {}  
speed\_list = {}  
for i = 1,30 do  
 points\_list[i] = {x = math.random(0,768),y = math.random(0,1024),dx = math.random(-2,2), dy = math.random(-2,2)}  
end  
function stars:enterFrame( event )  
  
 for i = #lines,1,-1 do  
 lines[i]:removeSelf()  
 lines[i] = nil  
 end   
 lines = {}  
  
  
  
 for i = 1,#points\_list do  
  
 points\_list[i].x = points\_list[i].x + points\_list[i].dx  
 if points\_list[i].x \< 0 then  
 points\_list[i].x = 0  
 points\_list[i].dx = -1\*points\_list[i].dx  
 end  
 if points\_list[i].x \> 768 then  
 points\_list[i].x = 768  
 points\_list[i].dx = -1\*points\_list[i].dx  
 end  
  
 points\_list[i].y = points\_list[i].y + points\_list[i].dy  
 if points\_list[i].y \< 0 then  
 points\_list[i].y = 0  
 points\_list[i].dy = -1\*points\_list[i].dy  
 end  
 if points\_list[i].y \> 1024 then  
 points\_list[i].y = 1024  
 points\_list[i].dy = -1\*points\_list[i].dy  
 end  
  
 end  
  
 local tri = delaunay(points\_list)  
  
 ---[[  
 for i = 1, #tri do  
 local x  
  
 x = display.newLine(points\_list[tri[i][1] ].x, points\_list[tri[i][1] ].y, points\_list[tri[i][2] ].x, points\_list[tri[i][2] ].y)  
 x:setColor( 255, 0, 255, 255 )  
 x.width = 3  
 table.insert(lines, x)  
 x = nil  
 x = display.newLine(points\_list[tri[i][2] ].x, points\_list[tri[i][2] ].y, points\_list[tri[i][3] ].x, points\_list[tri[i][3] ].y)  
 x:setColor( 255, 255, 0, 255 )  
 x.width = 3   
 table.insert(lines, x)  
 x = nil  
 x = display.newLine(points\_list[tri[i][3] ].x, points\_list[tri[i][3] ].y, points\_list[tri[i][1] ].x, points\_list[tri[i][1] ].y)  
 x:setColor( 0, 255, 255, 255 )  
 x.width = 3  
 table.insert(lines, x)  
 x = nil  
 end  
 --]]  
  
end   
--stars:enterFrame( )  
Runtime:addEventListener( "enterFrame", stars )  
  

[import]uid: 5652 topic_id: 3369 reply_id: 10263[/import]

Hey how’s it going? You helped me earlier with some simple coding and it was a real help so thanks again. Anyways this ( http://www.nuvorm.nl/start/index.phpoption=com_content&view=category&layout=blog&id=40&Itemid=53)looks really helpful to me but being new to all of this I got lost in it all. I uploaded an image of an egg to the site and in a clockwise fashion I outlined the egg exactly but I get stuck on what to do soon after. I have the option to save it as well as process it which gives me a code thing with lots of “”. Where do I paste this into for my sample game I’m making? Thanks and I really do appreciate the help. [import]uid: 35535 topic_id: 3369 reply_id: 23508[/import]

Hi guys. Great info. I am trying to do this for lines and paths. As to draw a ground on the floor. Any progress on any of this? I am checking out physics Editor to see how that one works. [import]uid: 8192 topic_id: 3369 reply_id: 25682[/import]