This is a Super Ellipse function, not much to explain here haha
Pretty basic, xOff and yOff are the positions of the center of the Ellipse, a, b, and n are variables to play with at your leisure(A and B are w and h, n is the gud stuff, detail is line segments
Code: Select all
function love.graphics.superEllipse(xOff, yOff, a, b, n, detail)
local function sgn(x) --Function for stuff :3
return x > 0 and 1 or x < 0 and -1 or 0
end
xOff, yOff, a, b, n, na, detail = xOff or 0, yOff or 0, a or 100, b or 100, n or 2, n/2, detail or 0.1
local PointTable = {}
for i=0, math.pi*2, (math.pi*2) / detail or 0.1 do
table.insert(PointTable, {x=math.pow(math.abs(math.cos(i)), na) * a * sgn(math.cos(i)),y=math.pow(math.abs(math.sin(i)), na) * b * sgn(math.sin(i))})
end
for k,v in pairs(PointTable) do
local thisVec = v
local nextVec = PointTable[k+1] or PointTable[1]
love.graphics.line(v.x + xOff, v.y + yOff, nextVec.x + xOff, nextVec.y + yOff)
end
end
Once again, xOff and yOff are positions, n1, n2, n3, m, a, and b are your children.. Don't abuse them... Naw, jk do what you want fam, it's just a letter. Detail is segments, and radius is.. well radius
Code: Select all
function love.graphics.superShape(xOff, yOff, n1, n2, n3, m, a, b, detail, radius)
--[[ Default values ]]--
n1, n2, n3, m, a, b, detail, radius, xOff, yOff = n1 or 1, n2 or 1, n3 or 1, m or 0, a or 1, b or 1, detail or 500, radius or 100, xOff or 0, yOff or 0
--[[ Function for stuff :3 ]]--
local function spshpe(theta)
local formula = math.pow((math.pow(math.abs((1 / a) * math.cos(theta * m / 4)), n2)) + (math.pow(math.abs((1 / b) * math.sin(theta * m / 4)), n3)), 1 / n1)
return formula == 0 and 0 or 1 / formula
end
local PointTable = {}
for i=0, math.pi * 2, (math.pi*2) / detail do
table.insert(PointTable, {x=radius * spshpe(i) * math.cos(i),y=radius * spshpe(i) * math.sin(i)})
end
for k,v in pairs(PointTable) do
local thisVec = v
local nextVec = PointTable[k+1] or PointTable[1]
love.graphics.line(v.x + xOff, v.y + yOff, nextVec.x + xOff, nextVec.y + yOff)
end
end
EDIT:
Here's the more optimized and ability to use outside of LOVE2D with credit from the all mighty Positive07
Positive07 wrote:Okey I had a go with the first function, trying to optimize and making it nicre, Also with lot's of comments so you can understand why I changed what I changedNo comments versionCode: Select all
--Declare variables that are gonna be used EVERY time the function is called outside of it --This is so that Lua doesn't calculate them every single time local tau = math.pi*2 local func = { math.cos, math.sin } function superEllipse(x, y, a, b, n, detail) -- I used tables here because I'm actually cheating later local offset = { x or 0, y or 0 } local v = { a or 100, b or 100 } --It didn't look like you needed n after all local na = (n or 2)/2 --I declared all variables in different lines because it's easier to know which one gets which value local detail = detail or 0.1 --ranamed for consistency local points = {} for i=0, tau, tau / detail do --x and y are calculated the same so we can do it in a loop for j=1, 2 do --This are only used here so they must be locals --we don't want to pollute the global scope local f = func[j](i) local abs = math.abs(f) --I removed the sign function and used this which ivan suggested local sgn = math.floor(f/abs + 0.5) --We apply the offset directly to the points local result = (math.pow(abs, na) * v[j] * sgn) + offset[j] --All points are in a single list, odd enrties are x values, even are y values --table.insert is slow in common Lua (Not that it matters with LuaJIT though) points[#points + 1] = result end end --Return the list of points return points end --LÖVE specific function, the other is just math function superEllipseDraw (...) --love.graphics.polygon has a line mode which do the same job as your second loop love.graphics.polygon("line", supperEllipse(...)) end
Code: Select all
local tau = math.pi*2 local func = { math.cos, math.sin } function superEllipse(x, y, a, b, n, detail) local offset = { x or 0, y or 0 } local v = { a or 100, b or 100 } local na = (n or 2)/2 local detail = detail or 0.1 local points = {} for i=0, tau, tau / detail do for j=1, 2 do local f = func[j](i) local abs = math.abs(f) local sgn = math.floor(f/abs + 0.5) local result = (math.pow(abs, na) * v[j] * sgn) + offset[j] points[#points + 1] = result end end return points end function superEllipseDraw (...) love.graphics.polygon("line", supperEllipse(...)) end