Creating vertices for a circle

Hey!

So, after reading another forum post, I realised that I might need to create a chain body for a circle in one of my projects at some point, so I decided to write a function for doing so and share it here.

Feel free to play around with the function and use it as you see fit. The function requires two inputs, r and n , where r stands for the circle radius and n stands for how many sides you want to create for the circle. The more sides, the more accurate the resulting circle will be. The function needs a minimum of 3 sides to work properly.

 

-- r = radius, n = number of sides local function circleVertices(r,n) if n \>= 3 then local mathCos, mathSin, pi = math.cos, math.sin, math.pi local angle = 360/n local v = {} for i = 1, n do v[i\*2-1] = mathCos(angle\*(i-1)\*(pi/180))\*r v[i\*2] = -1\*mathSin(angle\*(i-1)\*(pi/180))\*r end return v end end local t = circleVertices(120,32) local circle = display.newPolygon(240,160,t)

Finally, I’ve been thoroughly inspired by a few Corona developers, like roaminggamer and horacebury, who freely share numerous functions, modules and more on GitHub and I will very likely follow in suite and create myself a GitHub account and start sharing some more cool things with everyone. 

@Xedur   I spent a long time combining physics bodies (usually four 2-D arcs) in order to make a hollow circle and then I discovered chain bodies which is essentially what I use for all landscapes and borders now.  Thanks for sharing with the community! 

Yeah, when this is combined with the chain physics body, it’ll work just perfectly.

I’ve also opted to use chain bodies whenever possible because that way I don’t have to worry about the shapes being convex or consist of 8 vertices or less.

Also I use a function similar to this and I feel good.

The only thing I noticed and that the rope in high speed cases could be less stable than a fixed body. In particular with very fast projectiles there are cases in which the strings are crossed.

But I repeat I talk about situations that are critical…

fwiw, strength reduction:

local function regularPolygonVertices(r,n) assert(r~=0, "ERROR regularPolygonVertices(): a non-zero radius is required to form a valid polygon.") assert(n\>=3, "ERROR regularPolygonVertices(): at least three vertices are required to form a valid polygon.") local cos, sin = math.cos, math.sin local v, theta, dtheta = {}, 0, math.pi\*2/n for i = 1, n\*2, 2 do v[i] = r \* cos(theta) v[i+1] = r \* sin(theta) theta = theta + dtheta end return v end

It really pays off to work on one’s functions for more than 5 minutes and perform proper optimisation. Thanks!

Oh, by the way, does anyone have a clue if it is possible to dynamically create multi-element physics bodies?

To be precise, if I were to run the following code:
 

local physics = require("physics") physics.start() physics.setDrawMode( "hybrid" ) local function circleVertices(r,n) local cos, sin = math.cos, math.sin local v, theta, dtheta = {}, 0, math.pi\*2/n for i = 1, n\*2, 2 do v[i] = r \* cos(theta) v[i+1] = r \* sin(theta) theta = theta + dtheta end return v end local wallWidth = 16 local circleRadius = 120 local circleSides = 16 local innerT = circleVertices(circleRadius-wallWidth\*0.5,circleSides) local outerT = circleVertices(circleRadius+wallWidth\*0.5,circleSides) local collisionShape = {} for i = 1, circleSides do if i == circleSides then collisionShape[i] = { density=1.0, friction=1.0, bounce=0.2, shape={ innerT[i\*2-1], innerT[i\*2], innerT[1], innerT[2], outerT[1], outerT[2], outerT[i\*2-1], outerT[i\*2] }} else collisionShape[i] = { density=1.0, friction=1.0, bounce=0.2, shape={ innerT[i\*2-1], innerT[i\*2], innerT[i\*2+1], innerT[i\*2+2], outerT[i\*2+1], outerT[i\*2+2], outerT[i\*2-1], outerT[i\*2] }} end end local t = circleVertices(circleRadius,circleSides) local circle = display.newPolygon(240,160,t) circle:setFillColor(0.8,0,0) circle.strokeWidth = wallWidth physics.addBody( circle, "static", collisionShape[1], collisionShape[2], collisionShape[3], collisionShape[4], collisionShape[5], collisionShape[6], collisionShape[7], collisionShape[8], collisionShape[9], collisionShape[10], collisionShape[11], collisionShape[12], collisionShape[13], collisionShape[14], collisionShape[15], collisionShape[16] )

Then I end up with a rough circular shape that consists of 16 unique physics elements. However, for a circle of that size, 16 sides isn’t really enough to make it look like a real circle, but 32 sides should just about do it.

Is there a way to create a multi-element physics body during runtime so that I could avoid declaring each additional element individually like in the example?

unpack(), fe read bottom of this

Works like a charm! Thanks!
 

physics.addBody( circle, "static", unpack(collisionShape))

@Xedur   I spent a long time combining physics bodies (usually four 2-D arcs) in order to make a hollow circle and then I discovered chain bodies which is essentially what I use for all landscapes and borders now.  Thanks for sharing with the community! 

Yeah, when this is combined with the chain physics body, it’ll work just perfectly.

I’ve also opted to use chain bodies whenever possible because that way I don’t have to worry about the shapes being convex or consist of 8 vertices or less.

Also I use a function similar to this and I feel good.

The only thing I noticed and that the rope in high speed cases could be less stable than a fixed body. In particular with very fast projectiles there are cases in which the strings are crossed.

But I repeat I talk about situations that are critical…

fwiw, strength reduction:

local function regularPolygonVertices(r,n) assert(r~=0, "ERROR regularPolygonVertices(): a non-zero radius is required to form a valid polygon.") assert(n\>=3, "ERROR regularPolygonVertices(): at least three vertices are required to form a valid polygon.") local cos, sin = math.cos, math.sin local v, theta, dtheta = {}, 0, math.pi\*2/n for i = 1, n\*2, 2 do v[i] = r \* cos(theta) v[i+1] = r \* sin(theta) theta = theta + dtheta end return v end

It really pays off to work on one’s functions for more than 5 minutes and perform proper optimisation. Thanks!

Oh, by the way, does anyone have a clue if it is possible to dynamically create multi-element physics bodies?

To be precise, if I were to run the following code:
 

local physics = require("physics") physics.start() physics.setDrawMode( "hybrid" ) local function circleVertices(r,n) local cos, sin = math.cos, math.sin local v, theta, dtheta = {}, 0, math.pi\*2/n for i = 1, n\*2, 2 do v[i] = r \* cos(theta) v[i+1] = r \* sin(theta) theta = theta + dtheta end return v end local wallWidth = 16 local circleRadius = 120 local circleSides = 16 local innerT = circleVertices(circleRadius-wallWidth\*0.5,circleSides) local outerT = circleVertices(circleRadius+wallWidth\*0.5,circleSides) local collisionShape = {} for i = 1, circleSides do if i == circleSides then collisionShape[i] = { density=1.0, friction=1.0, bounce=0.2, shape={ innerT[i\*2-1], innerT[i\*2], innerT[1], innerT[2], outerT[1], outerT[2], outerT[i\*2-1], outerT[i\*2] }} else collisionShape[i] = { density=1.0, friction=1.0, bounce=0.2, shape={ innerT[i\*2-1], innerT[i\*2], innerT[i\*2+1], innerT[i\*2+2], outerT[i\*2+1], outerT[i\*2+2], outerT[i\*2-1], outerT[i\*2] }} end end local t = circleVertices(circleRadius,circleSides) local circle = display.newPolygon(240,160,t) circle:setFillColor(0.8,0,0) circle.strokeWidth = wallWidth physics.addBody( circle, "static", collisionShape[1], collisionShape[2], collisionShape[3], collisionShape[4], collisionShape[5], collisionShape[6], collisionShape[7], collisionShape[8], collisionShape[9], collisionShape[10], collisionShape[11], collisionShape[12], collisionShape[13], collisionShape[14], collisionShape[15], collisionShape[16] )

Then I end up with a rough circular shape that consists of 16 unique physics elements. However, for a circle of that size, 16 sides isn’t really enough to make it look like a real circle, but 32 sides should just about do it.

Is there a way to create a multi-element physics body during runtime so that I could avoid declaring each additional element individually like in the example?

unpack(), fe read bottom of this

Works like a charm! Thanks!
 

physics.addBody( circle, "static", unpack(collisionShape))