See if this gives you an idea to work from:
local dlg = Dialog { title = "Pie Slice" }
dlg:slider { id = "startDeg", label = "Start:", min = 0, max = 360, value = 0 }
dlg:slider { id = "stopDeg", label = "Stop:", min = 0, max = 360, value = 90 }
dlg:number { id = "xCenter", label = "Pos:", text = "160" }
dlg:number { id = "yCenter", text = "90" }
dlg:number { id = "radius", label = "Radius:", text = "50" }
dlg:slider { id = "resolution", label = "Res:", min = 3, max = 360, value = 360 }
dlg:color { id = "strokeColor", label = "Stroke:", color = Color(255, 255, 255, 255) }
dlg:color { id = "fillColor", label = "Fill:", color = Color(0, 0, 0, 255) }
dlg:button { id = "okButton", text = "&OK", onclick = function()
local sprite = app.sprite
if not sprite then return end
local brsh = Brush { size = 1 }
local frame = app.frame or sprite.frames[1]
local layer = app.layer or sprite.layers[1]
local args <const> = dlg.data
local startDeg, stopDeg = args.startDeg --[[@as integer]],
args.stopDeg --[[@as integer]]
local xCenter, yCenter = args.xCenter --[[@as integer]],
args.yCenter --[[@as integer]]
local radius = args.radius --[[@as number]]
local sectors = math.max(3, args.resolution --[[@as integer]])
local strokeColor, fillColor = args.strokeColor --[[@as Color]],
args.fillColor --[[@as Color]]
local startDegVerif = startDeg % 360
local stopDegVerif = stopDeg % 360
local arcLenDeg = (stopDegVerif - startDegVerif) % 360
local docPrefs = app.preferences.document(sprite)
local symmetryPrefs = docPrefs.symmetry
local oldSymmetry = symmetryPrefs.mode or 0 --[[@as integer]]
symmetryPrefs.mode = 0
if arcLenDeg < 1 then
local topLeft = Point(xCenter - radius, yCenter - radius)
local bottomRight = Point(xCenter + radius, yCenter + radius)
app.transaction("Arc", function()
app.useTool {
tool = "filled_ellipse",
brush = brsh,
color = fillColor,
frame = frame,
layer = layer,
ink = Ink.SIMPLE,
points = { topLeft, bottomRight }
}
app.useTool {
tool = "ellipse",
brush = brsh,
color = strokeColor,
frame = frame,
layer = layer,
ink = Ink.SIMPLE,
points = { topLeft, bottomRight }
}
end)
else
local arcLen1 = arcLenDeg / 360.0
local reqSectors = math.ceil(1 + sectors * arcLen1)
local toStep = 1.0 / (reqSectors - 1.0)
local origRadians = startDegVerif * math.pi / 180.0
local destRadians = stopDegVerif * math.pi / 180.0
---@type Point[]
local vs = {}
local lenVs = 0
local xSum, ySum = 0, 0
lenVs = lenVs + 1
vs[lenVs] = Point(xCenter, yCenter)
xSum, ySum = xSum + xCenter, ySum + yCenter
local i = 0
while i < reqSectors do
local step = i * toStep
local theta = (1.0 - step) * origRadians + step * destRadians
local cosa = math.cos(-theta)
local sina = math.sin(-theta)
local x = math.floor(xCenter + radius * cosa)
local y = math.floor(yCenter + radius * sina)
xSum, ySum = xSum + x, ySum + y
lenVs = lenVs + 1
vs[lenVs] = Point(x, y)
i = i + 1
end
local xAvg = math.floor(xSum / reqSectors)
local yAvg = math.floor(ySum / reqSectors)
local fillTarget = Point(xAvg, yAvg)
local paintPrefs = app.preferences.tool("paint_bucket")
local floodPrefs = paintPrefs.floodfill
local oldStopAtGrid = floodPrefs.stop_at_grid or 0 --[[@as integer]]
local oldReferTo = floodPrefs.refer_to or 0 --[[@as integer]]
local oldPxMatrix = floodPrefs.pixel_connectivity or 0 --[[@as integer]]
floodPrefs.stop_at_grid = 0 -- Never
floodPrefs.refer_to = 0 -- Active Layer
floodPrefs.pixel_connectivity = 0 -- Four connected
app.transaction("Arc", function()
local vPrev = vs[lenVs]
local j = 0
while j < lenVs do
j = j + 1
local vCurr = vs[j]
app.useTool {
tool = "line",
brush = brsh,
color = strokeColor,
frame = frame,
layer = layer,
ink = Ink.SIMPLE,
points = { vPrev, vCurr }
}
vPrev = vCurr
end
app.useTool {
tool = "paint_bucket",
brush = brsh,
color = fillColor,
contiguous = true,
frame = frame,
ink = Ink.SIMPLE,
layer = layer,
points = { fillTarget },
tolerance = 0,
}
end)
floodPrefs.stop_at_grid = oldStopAtGrid
floodPrefs.refer_to = oldReferTo
floodPrefs.pixel_connectivity = oldPxMatrix
end
symmetryPrefs.mode = oldSymmetry
app.refresh()
end }
dlg:button { id = "cancelButton", text = "&CANCEL" }
dlg:show { wait = false }
app.useTool
is not reliable, so I’ll emphasize that this is a hack. It draws short little line segments to make a polygon that approximates an arc. Then, it finds a center from the average of all vertices and calls the paint bucket to make a fill. [Edit: Such an approach is more for regular convex shapes than arcs.]