Hi, I wrote this program to teach my children about fractions. In some fractions, e.g. 1/13 or 1/15 the slices don’t quite fill the pie. Can someone suggest how to improve the arc calculation to fix this, please? Thank you.
http://www.youtube.com/watch?v=_uBVfcVVlfM
Main class
-- Fractions
function setup()
Pick = 1
Slices = 4
parameter.integer("Pick", 1, 20, Pick, pick)
parameter.integer("Slices", 1, 20, Slices, slice)
end
function draw()
background(40, 40, 50)
for _,p in pairs(pies) do
p:draw()
end
if #pies > 1 then
fontSize(40)
fill(255, 255, 255, 255)
text(Pick.."/"..Slices, WIDTH/2, HEIGHT-50)
end
end
function slice(n)
pick(Pick)
end
function pick(n)
local reqPies = math.ceil(n / Slices)
local cols = math.ceil(math.sqrt(reqPies))
local rows = math.ceil(reqPies / cols)
local radius = HEIGHT / cols / 4
pies = {}
for i = 1,reqPies do
local col = (i - 1) % cols + 1
local row = math.ceil(i / cols)
local x = radius * col * 3 - radius
local y = radius * row * 3 - radius
local thisPick = Slices
if i == reqPies then
thisPick = Pick % Slices
if thisPick == 0 then
thisPick = Slices
end
end
table.insert(pies, Pie(x, y, radius, Slices, thisPick))
end
end
Arc class
Arc = class()
local delta = math.pi / 36
-- If the Arc is closed, radius will be drawn
function Arc:init(startAngle, endAngle, radius, closed)
self.startAngle = startAngle
self.endAngle = endAngle
self.radius = radius
if closed ~= nil then
self.closed = closed
else
self.closed = false
end
self.points = {vec2(0, 0)}
for angle = startAngle, endAngle, delta do
local b = math.cos(angle) * radius
local h = math.sin(angle) * radius
table.insert(self.points, vec2(b, h))
end
end
function Arc:draw()
local n = #self.points
local startPoint = 1
local endPoint = n-2
if self.closed then
startPoint = 0
endPoint = n-1
end
for i = startPoint, endPoint do
local p1 = self.points[i%n + 1]
local p2 = self.points[(i+1)%n + 1]
line(p1.x, p1.y, p2.x, p2.y)
end
end
Slice class
Slice = class()
function Slice:init(x, y, startAngle, endAngle, radius, colour)
self.x = x
self.y = y
self.arc = Arc(startAngle, endAngle, radius, true)
local vertices = {}
local colours = {}
for i = 2, (#self.arc.points-1) do
table.insert(vertices, vec2(0, 0))
table.insert(vertices, self.arc.points[i])
table.insert(vertices, self.arc.points[i+1])
table.insert(colours, colour)
table.insert(colours, colour)
table.insert(colours, colour)
end
self.mesh = mesh()
self.mesh.vertices = vertices
self.mesh.colors = colours
end
function Slice:draw()
pushMatrix()
translate(self.x, self.y)
self.mesh:draw()
popMatrix()
strokeWidth(5)
stroke(0, 0, 0, 255)
self.arc:draw()
end
Pie class
Pie = class()
function Pie:init(x, y, radius, sliceCount, selected)
self.x = x
self.y = y
self.radius = radius
self.sliceCount = sliceCount
self.selected = selected
self.label = self.selected.."/"..self.sliceCount
local delta = 2 * math.pi / self.sliceCount
self.slices = {}
local colour
for i = 1,self.sliceCount do
if i <= selected then
colour = color(87, 64, 168, 255)
else
colour = color(127, 127, 127, 255)
end
table.insert(self.slices, Slice(0, 0, delta*(i-1), delta*i, radius, colour))
end
end
function Pie:draw()
pushMatrix()
translate(self.x, self.y)
for i,slice in ipairs(self.slices) do
slice:draw()
end
fontSize(self.radius / 4)
self.labelW, self.labelH = textSize(self.label)
fill(255, 255, 255, 255)
text(self.label, 0, self.radius + self.labelH)
popMatrix()
end