Last active
January 17, 2025 22:51
-
-
Save jaames/5de95dd62d4522b86b8409f095b3925f to your computer and use it in GitHub Desktop.
Simple bezier curve drawing functions for the Playdate Lua SDK
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-- 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