Any way to create rounded polygons?

Is there any way to created polygons with rounded path joins–that is, rounded corners/edges. Similar to the display.newRoundedRect but for polygons.

If not, any ideas for how to achieve such an effect? Should I rely on image assets? Perhaps there is a way to create a path which is made of straight and curved lines?

Thanks!

You could make a wrapper around it that would add in some extra points as you go around the corner, say as half-ellipses. At a certain (fixed?) distance from each corner along each of two segments, find the midpoint between them. Those form your x-axes. Then from the midpoint to the corner is your y-axis. Then just sample along the arc between them.

What follows is a rather rough attempt at modifying the newPolygon() sample along these ideas. Doesn’t hold up very well with heavier strokes.  :slight_smile: I imagine it could be refined a bit.

local halfW = display.contentWidth \* 0.5 local halfH = display.contentHeight \* 0.5 local vertices = { 0,-110, 27,-35, 105,-35, 43,16, 65,90, 0,45, -65,90, -43,15, -105,-35, -27,-35, } local sqrt = math.sqrt local newPolygon = display.newPolygon local Cos = {} local Sin = {} local N = 5 for i = 1, N - 1 do local angle = math.pi \* i / N Cos[i], Sin[i] = math.cos(angle), math.sin(angle) end local Distance = 3 local function GetSegmentInfo (x1, y1, x2, y2) local dx, dy = x2 - x1, y2 - y1 local len = sqrt(dx^2 + dy^2) -- extra credit: adapt to handle segments shorter than Distance local t = Distance / len -- fraction of length covered by Distance return t, dx, dy end local function AddVerts (my\_verts, x1, y1, x2, y2, x3, y3) local t1, dx1, dy1 = GetSegmentInfo(x1, y1, x2, y2) local t2, dx2, dy2 = GetSegmentInfo(x2, y2, x3, y3) my\_verts[#my\_verts + 1] = x1 + t1 \* dx1 -- from 1 toward 2... my\_verts[#my\_verts + 1] = y1 + t1 \* dy1 local lx, ly = x2 - t1 \* dx1, y2 - t1 \* dy1 ...from 2 toward 1... local rx, ry = x2 + t2 \* dx2, y2 + t2 \* dy2 ...and from 2 toward 3 my\_verts[#my\_verts + 1] = lx -- start of arc my\_verts[#my\_verts + 1] = ly local cx, cy = (lx + rx) / 2, (ly + ry) / 2 local xaxis, yaxis = lx - cx, y2 - cy for i = 1, #Cos do my\_verts[#my\_verts + 1] = cx + Cos[i] \* xaxis -- inside the arc (will be closed when next segment begins) my\_verts[#my\_verts + 1] = cy + Sin[i] \* yaxis end end local function MyNewPolygon (x, y, verts) local my\_verts, n = {}, #verts for i = 1, n - 1, 2 do local i2, i3 if i == n - 3 then -- wrapping around? i2, i3 = i + 2, 1 elseif i == n - 1 then i2, i3 = 1, 3 else -- nope i2, i3 = i + 2, i + 4 end AddVerts(my\_verts, verts[i], verts[i + 1], verts[i2], verts[i2 + 1], verts[i3], verts[i3 + 1]) end return newPolygon(x, y, my\_verts) end local o = MyNewPolygon( halfW, halfH, vertices ) --o.fill = { type="image", filename="mountains.png" } o.strokeWidth = 3--10 o:setStrokeColor( 1, 0, 0 )

You could make a wrapper around it that would add in some extra points as you go around the corner, say as half-ellipses. At a certain (fixed?) distance from each corner along each of two segments, find the midpoint between them. Those form your x-axes. Then from the midpoint to the corner is your y-axis. Then just sample along the arc between them.

What follows is a rather rough attempt at modifying the newPolygon() sample along these ideas. Doesn’t hold up very well with heavier strokes.  :slight_smile: I imagine it could be refined a bit.

local halfW = display.contentWidth \* 0.5 local halfH = display.contentHeight \* 0.5 local vertices = { 0,-110, 27,-35, 105,-35, 43,16, 65,90, 0,45, -65,90, -43,15, -105,-35, -27,-35, } local sqrt = math.sqrt local newPolygon = display.newPolygon local Cos = {} local Sin = {} local N = 5 for i = 1, N - 1 do local angle = math.pi \* i / N Cos[i], Sin[i] = math.cos(angle), math.sin(angle) end local Distance = 3 local function GetSegmentInfo (x1, y1, x2, y2) local dx, dy = x2 - x1, y2 - y1 local len = sqrt(dx^2 + dy^2) -- extra credit: adapt to handle segments shorter than Distance local t = Distance / len -- fraction of length covered by Distance return t, dx, dy end local function AddVerts (my\_verts, x1, y1, x2, y2, x3, y3) local t1, dx1, dy1 = GetSegmentInfo(x1, y1, x2, y2) local t2, dx2, dy2 = GetSegmentInfo(x2, y2, x3, y3) my\_verts[#my\_verts + 1] = x1 + t1 \* dx1 -- from 1 toward 2... my\_verts[#my\_verts + 1] = y1 + t1 \* dy1 local lx, ly = x2 - t1 \* dx1, y2 - t1 \* dy1 ...from 2 toward 1... local rx, ry = x2 + t2 \* dx2, y2 + t2 \* dy2 ...and from 2 toward 3 my\_verts[#my\_verts + 1] = lx -- start of arc my\_verts[#my\_verts + 1] = ly local cx, cy = (lx + rx) / 2, (ly + ry) / 2 local xaxis, yaxis = lx - cx, y2 - cy for i = 1, #Cos do my\_verts[#my\_verts + 1] = cx + Cos[i] \* xaxis -- inside the arc (will be closed when next segment begins) my\_verts[#my\_verts + 1] = cy + Sin[i] \* yaxis end end local function MyNewPolygon (x, y, verts) local my\_verts, n = {}, #verts for i = 1, n - 1, 2 do local i2, i3 if i == n - 3 then -- wrapping around? i2, i3 = i + 2, 1 elseif i == n - 1 then i2, i3 = 1, 3 else -- nope i2, i3 = i + 2, i + 4 end AddVerts(my\_verts, verts[i], verts[i + 1], verts[i2], verts[i2 + 1], verts[i3], verts[i3 + 1]) end return newPolygon(x, y, my\_verts) end local o = MyNewPolygon( halfW, halfH, vertices ) --o.fill = { type="image", filename="mountains.png" } o.strokeWidth = 3--10 o:setStrokeColor( 1, 0, 0 )