Skip to content

Instantly share code, notes, and snippets.

@jaames
Last active May 1, 2024 11:46
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jaames/5de95dd62d4522b86b8409f095b3925f to your computer and use it in GitHub Desktop.
Save jaames/5de95dd62d4522b86b8409f095b3925f to your computer and use it in GitHub Desktop.
Simple bezier curve drawing functions for the Playdate Lua SDK
-- bezier curve drawing functions for playdate lua
-- these are based on de Casteljau's algorithm
-- this site has a nice interactive demo to compare both types of curve: https://pomax.github.io/bezierinfo/#flattening
-- draws a curve starting at x1,y1, ending at x3,y3, with x2,y2 being a control point that "pulls" the curve towards it
-- steps is the number of line segments to use, lower is better for performance, higher makes your curve look smoother
-- the playdate is kinda slow, so it's recommended to find a relatively low step number that looks passable enough!
function drawQuadraticBezier(x1, y1, x2, y2, x3, y3, steps)
steps = steps or 8
local d = 1 / steps
local prevX = x1
local prevY = y1
local x, y
for t = d, 1, d do
x = (1 - t) ^ 2 * x1 + 2 * (1 - t) * t * x2 + t ^ 2 * x3
y = (1 - t) ^ 2 * y1 + 2 * (1 - t) * t * y2 + t ^ 2 * y3
playdate.graphics.drawLine(prevX, prevY, x, y)
prevX = x
prevY = y
end
end
-- draws a curve starting at x1,y1, ending at x4,y4, with x2,y2 and x3,y3 being a control point that "pulls" the curve towards them
-- (nb: this is the kind of curve you make using the pen tool in vector drawing apps like Adobe Illustator!)
-- steps is the number of line segments to use, lower is better for performance, higher makes your curve look smoother
-- the playdate is kinda slow, so it's recommended to find a relatively low step number that looks passable enough!
function drawCubicBezier(x1, y1, x2, y2, x3, y3, x4, y4, steps)
steps = steps or 12
local d = 1 / steps
local prevX = x1
local prevY = y1
local x, y
for t = d, 1, d do
x = (1 - t) ^ 3 * x1 + 3 * (1 - t) ^ 2 * t * x2 + 3 * (1 - t) * t ^ 2 * x3 + t ^ 3 * x4
y = (1 - t) ^ 3 * y1 + 3 * (1 - t) ^ 2 * t * y2 + 3 * (1 - t) * t ^ 2 * y3 + t ^ 3 * y4
playdate.graphics.drawLine(prevX, prevY, x, y)
prevX = x
prevY = y
end
end
-- example usage:
function playdate.update()
-- curves are just drawn as a bunch of lines, so you can tweak line settings like width, cap, color, etc
gfx.setLineWidth(2)
drawQuadraticBezier(
10, 80, -- curve start x,y coordinate
200, 50, -- control x,y coordinate - your curve will be "pulled" towards this point
390, 80, -- curve end x,y coordinate
8 -- number of line segments used to draw the curve, 8 is probably plenty to get a smooth curve
)
drawCubicBezier(
10, 160, -- curve start x,y coordinate
100, 110, -- first control x,y coordinate
300, 210, -- seccond control x,y coordinate
390, 160, -- curve end x,y coordinate
12 -- number of line segments used to draw the curve
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment