playdate.graphics.drawArc(arc) draws every arc as if it is clockwise. I’m using SDK 1.12.0 on macOS 12.4, but the issue occurs on device as well (OS 1.12.0).
Unless I’m misunderstanding the documentation for how to create an arc, I would expect the following two pieces of Lua code to produce different results:
looks like drawArc isn't checking the clockwise flag. Here's a version with that fixed:
local lineWidthNag = true
function playdate.graphics.drawArc(x, ...)
local y, radius, startAngle, endAngle
local tempLineWidth = nil
if (type(x) == "userdata") then
if x.clockwise then
startAngle = x.startAngle
endAngle = x.endAngle
else
startAngle = x.endAngle
endAngle = x.startAngle
end
x, y, radius = x.x, x.y, x.radius
tempLineWidth = select(1, ...)
else
y, radius, startAngle, endAngle, tempLineWidth = select(1, ...)
end
if lineWidthNag == true and tempLineWidth ~= nil then
print("Warning: playdate.graphics.drawRoundRect no longer accepts a lineWidth argument, please set the line width using playdate.graphics.setLineWidth() instead")
lineWidthNag = false
end
local d = radius * 2
g.drawEllipseInRect(x-radius, y-radius, d, d, startAngle, endAngle)
end
I'm no Lua expert, but at a glance is that version not considering the case where clockwise == nil? The API documentation states that if the argument is absent, the winding is determined from the angles automatically. Without checking for nil explicitly, I feel like it gets dumped into the else clause and gets processed as counter-clockwise.
Ah yes, Arc is an object. My C brain has certain forms of autopilot.
Does this account for situations where the angles are not in the [0, 360) range, or where they "wrap" around 360? I feel like start=350 end=10 should be drawn in a clockwise direction unless specified, but I can see a case to be made either way. Inside Playdate doesn't specify how the direction is determined.
If the direction is specified and the spread angle is at or above 360 degrees, does it switch to drawing only one full circle?
Also, because I'm a pedantic stinker, I'm obligated to point out that the < operator in C explicitly yields the integer value 0 or 1. And that < has higher precedence than ?: so those parentheses aren't necessary. (-:
Hm, I'm not sure how I could test it. If the arc exceeds 360 degrees, it would just retrace over existing pixels and I wouldn't be able to gauge any difference.
Unless you're suggesting there's some kind of exception case that happens when you attempt it. In that case, disregard!
Okay, I tried it. Drawing from 1 to 405 degrees gives the same result as drawing from 1 to 45. When I glanced at the source I didn't see any checking against 360 degrees, just sin and cos to convert angles to coordinates, so that's what I expected.
I guess I'll file that as a bug so we have it in the system, but it's so low priority I don't expect we'll ever change that behavior
Ran into this today too, this little snippet seemed to do the trick for me, but it's not rigorously tested:
local origDrawArc = playdate.graphics.drawArc
function playdate.graphics.drawArc(arc)
if arc:isClockwise() then
origDrawArc(arc.x, arc.y, arc.radius, arc.startAngle, arc.endAngle)
else
origDrawArc(arc.x, arc.y, arc.radius, arc.endAngle, arc.startAngle)
end
end